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

Commit 687b32d8 authored by Andreas Huber's avatar Andreas Huber
Browse files

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

Change-Id: Ia77f6b6d5e5c5055583740dfe876b8a3c22be9b6
parent 6a4d0a6a
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;