Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0c5158d authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Properly announce decoder output format changes, make sure AMessage::dup does."

parents a6256238 2c2814b9
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ struct ACodec : public AHierarchicalStateMachine {
        kWhatEOS                 = 'eos ',
        kWhatShutdownCompleted   = 'scom',
        kWhatFlushCompleted      = 'fcom',
        kWhatOutputFormatChanged = 'outC',
    };

    ACodec();
+3 −0
Original line number Diff line number Diff line
@@ -64,6 +64,9 @@ struct AMessage : public RefBase {

    void post(int64_t delayUs = 0);

    // Performs a deep-copy of "this", contained messages are in turn "dup'ed".
    // Warning: RefBase items, i.e. "objects" are _not_ copied but only have
    // their refcount incremented.
    sp<AMessage> dup() const;

    AString debugString(int32_t indent = 0) const;
+89 −20
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ private:
    sp<MediaSource> mDecoder;
    sp<AMessage> mNotify;
    bool mEOS;
    bool mSentFormat;

    void sendFormatChange();

    DISALLOW_EVIL_CONSTRUCTORS(WrapperReader);
};
@@ -174,7 +177,8 @@ DecoderWrapper::WrapperReader::WrapperReader(
        const sp<MediaSource> &decoder, const sp<AMessage> &notify)
    : mDecoder(decoder),
      mNotify(notify),
      mEOS(false) {
      mEOS(false),
      mSentFormat(false) {
}

DecoderWrapper::WrapperReader::~WrapperReader() {
@@ -215,12 +219,17 @@ void DecoderWrapper::WrapperReader::onMessageReceived(
            MediaBuffer *src;
            status_t err = mDecoder->read(&src, &options);

            if (err == OK) {
                if (!mSentFormat) {
                    sendFormatChange();
                    mSentFormat = true;
                }

                sp<AMessage> notify = mNotify->dup();

                sp<AMessage> realNotify;
                CHECK(notify->findMessage("real-notify", &realNotify));

            if (err == OK) {
                realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer);

                sp<ABuffer> dst = new ABuffer(src->range_length());
@@ -236,12 +245,23 @@ void DecoderWrapper::WrapperReader::onMessageReceived(
                dst->meta()->setInt64("timeUs", timeUs);

                realNotify->setObject("buffer", dst);

                notify->post();
            } else if (err == INFO_FORMAT_CHANGED) {
                sendFormatChange();

                readMore(false /* flush */);
            } else {
                sp<AMessage> notify = mNotify->dup();

                sp<AMessage> realNotify;
                CHECK(notify->findMessage("real-notify", &realNotify));

                realNotify->setInt32("what", ACodec::kWhatEOS);
                mEOS = true;
            }

                notify->post();
            }
            break;
        }

@@ -251,6 +271,46 @@ void DecoderWrapper::WrapperReader::onMessageReceived(
    }
}

void DecoderWrapper::WrapperReader::sendFormatChange() {
    sp<AMessage> notify = mNotify->dup();

    sp<AMessage> realNotify;
    CHECK(notify->findMessage("real-notify", &realNotify));

    realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged);

    sp<MetaData> meta = mDecoder->getFormat();

    const char *mime;
    CHECK(meta->findCString(kKeyMIMEType, &mime));

    realNotify->setString("mime", mime);

    if (!strncasecmp("audio/", mime, 6)) {
        int32_t numChannels;
        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));

        int32_t sampleRate;
        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));

        realNotify->setInt32("channel-count", numChannels);
        realNotify->setInt32("sample-rate", sampleRate);
    } else {
        CHECK(!strncasecmp("video/", mime, 6));

        int32_t width, height;
        CHECK(meta->findInt32(kKeyWidth, &width));
        CHECK(meta->findInt32(kKeyHeight, &height));

        realNotify->setInt32("width", width);
        realNotify->setInt32("height", height);
    }

    notify->post();

    mSentFormat = true;
}

////////////////////////////////////////////////////////////////////////////////

DecoderWrapper::DecoderWrapper()
@@ -327,24 +387,33 @@ void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {

        case kWhatFillBufferDone:
        {
            CHECK_GT(mNumPendingDecodes, 0);
            --mNumPendingDecodes;

            if (mFlushing) {
                completeFlushIfPossible();
                break;
            }

            sp<AMessage> notify;
            CHECK(msg->findMessage("real-notify", &notify));

            int32_t what;
            CHECK(notify->findInt32("what", &what));

            if (what == ACodec::kWhatDrainThisBuffer) {
                CHECK_GT(mNumPendingDecodes, 0);
                --mNumPendingDecodes;

                sp<AMessage> reply =
                    new AMessage(kWhatOutputBufferDrained, id());

                notify->setMessage("reply", reply);
            notify->post();

                ++mNumOutstandingOutputBuffers;
            } else if (what == ACodec::kWhatEOS) {
                CHECK_GT(mNumPendingDecodes, 0);
                --mNumPendingDecodes;

                if (mFlushing) {
                    completeFlushIfPossible();
                    break;
                }
            }

            notify->post();
            break;
        }

+15 −12
Original line number Diff line number Diff line
@@ -198,6 +198,21 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    mFlushingAudio = NONE;
                    mFlushingVideo = NONE;
                }
            } else if (what == ACodec::kWhatOutputFormatChanged) {
                CHECK(audio);

                int32_t numChannels;
                CHECK(codecRequest->findInt32("channel-count", &numChannels));

                int32_t sampleRate;
                CHECK(codecRequest->findInt32("sample-rate", &sampleRate));

                LOGI("Audio output format changed to %d Hz, %d channels",
                     sampleRate, numChannels);

                mAudioSink->close();
                CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
                mAudioSink->start();
            } else {
                CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);

@@ -365,18 +380,6 @@ status_t NuPlayer::instantiateDecoder(
    const sp<MetaData> &meta = source->getFormat();
    (*decoder)->configure(meta);

    if (audio) {
        int32_t sampleRate;
        int32_t channelCount;
        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
        CHECK(meta->findInt32(kKeyChannelCount, &channelCount));

        channelCount = 2;  // XXX

        CHECK_EQ(mAudioSink->open(sampleRate, channelCount), (status_t)OK);
        mAudioSink->start();
    }

    return OK;
}

+10 −1
Original line number Diff line number Diff line
@@ -224,13 +224,22 @@ sp<AMessage> AMessage::dup() const {
            }

            case kTypeObject:
            case kTypeMessage:
            {
                to->u.refValue = from->u.refValue;
                to->u.refValue->incStrong(msg.get());
                break;
            }

            case kTypeMessage:
            {
                sp<AMessage> copy =
                    static_cast<AMessage *>(from->u.refValue)->dup();

                to->u.refValue = copy.get();
                to->u.refValue->incStrong(msg.get());
                break;
            }

            default:
            {
                to->u = from->u;