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

Commit 52185ff7 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 49dad771 687b32d8
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ struct ACodec : public AHierarchicalStateMachine {
        kWhatEOS                 = 'eos ',
        kWhatEOS                 = 'eos ',
        kWhatShutdownCompleted   = 'scom',
        kWhatShutdownCompleted   = 'scom',
        kWhatFlushCompleted      = 'fcom',
        kWhatFlushCompleted      = 'fcom',
        kWhatOutputFormatChanged = 'outC',
    };
    };


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


    void post(int64_t delayUs = 0);
    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;
    sp<AMessage> dup() const;


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

    void sendFormatChange();


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


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


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

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


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


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


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


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

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

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

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

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


                notify->post();
                notify->post();
            }
            break;
            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()
DecoderWrapper::DecoderWrapper()
@@ -327,24 +387,33 @@ void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) {


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

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

            sp<AMessage> notify;
            sp<AMessage> notify;
            CHECK(msg->findMessage("real-notify", &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 =
                sp<AMessage> reply =
                    new AMessage(kWhatOutputBufferDrained, id());
                    new AMessage(kWhatOutputBufferDrained, id());


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


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

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

            notify->post();
            break;
            break;
        }
        }


+15 −12
Original line number Original line Diff line number Diff line
@@ -198,6 +198,21 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    mFlushingAudio = NONE;
                    mFlushingAudio = NONE;
                    mFlushingVideo = 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 {
            } else {
                CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
                CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);


@@ -365,18 +380,6 @@ status_t NuPlayer::instantiateDecoder(
    const sp<MetaData> &meta = source->getFormat();
    const sp<MetaData> &meta = source->getFormat();
    (*decoder)->configure(meta);
    (*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;
    return OK;
}
}


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


            case kTypeObject:
            case kTypeObject:
            case kTypeMessage:
            {
            {
                to->u.refValue = from->u.refValue;
                to->u.refValue = from->u.refValue;
                to->u.refValue->incStrong(msg.get());
                to->u.refValue->incStrong(msg.get());
                break;
                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:
            default:
            {
            {
                to->u = from->u;
                to->u = from->u;