Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +50 −15 Original line number Diff line number Diff line Loading @@ -756,7 +756,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); getDecoder(audio)->initiateShutdown(); if (audio) { mFlushingAudio = SHUTTING_DOWN_DECODER; Loading Loading @@ -1292,7 +1292,24 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { mTimeDiscontinuityPending = mTimeDiscontinuityPending || timeChange; if (mFlushingAudio == NONE && mFlushingVideo == NONE) { bool seamlessFormatChange = false; sp<AMessage> newFormat = mSource->getFormat(audio); if (formatChange) { seamlessFormatChange = getDecoder(audio)->supportsSeamlessFormatChange(newFormat); // treat seamless format change separately formatChange = !seamlessFormatChange; } bool shutdownOrFlush = formatChange || timeChange; // We want to queue up scan-sources only once per discontinuity. // We control this by doing it only if neither audio nor video are // flushing or shutting down. (After handling 1st discontinuity, one // of the flushing states will not be NONE.) // No need to scan sources if this discontinuity does not result // in a flush or shutdown, as the flushing state will stay NONE. if (mFlushingAudio == NONE && mFlushingVideo == NONE && shutdownOrFlush) { // And we'll resume scanning sources once we're done // flushing. mDeferredActions.push_front( Loading @@ -1300,16 +1317,17 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { &NuPlayer::performScanSources)); } if (formatChange || timeChange) { sp<AMessage> newFormat = mSource->getFormat(audio); sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { if (formatChange /* not seamless */) { // must change decoder flushDecoder(audio, /* needShutdown = */ true); } else { flushDecoder(audio, /* needShutdown = */ false); } else if (timeChange) { // need to flush flushDecoder(audio, /* needShutdown = */ false, newFormat); err = OK; } else if (seamlessFormatChange) { // reuse existing decoder and don't flush updateDecoderFormatWithoutFlush(audio, newFormat); err = OK; } } else { // This stream is unaffected by the discontinuity return -EWOULDBLOCK; Loading Loading @@ -1488,20 +1506,23 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { driver->notifyListener(msg, ext1, ext2, in); } void NuPlayer::flushDecoder(bool audio, bool needShutdown) { void NuPlayer::flushDecoder( bool audio, bool needShutdown, const sp<AMessage> &newFormat) { ALOGV("[%s] flushDecoder needShutdown=%d", audio ? "audio" : "video", needShutdown); if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { const sp<Decoder> &decoder = getDecoder(audio); if (decoder == NULL) { ALOGI("flushDecoder %s without decoder present", audio ? "audio" : "video"); return; } // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; mScanSourcesPending = false; (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); decoder->signalFlush(newFormat); mRenderer->flush(audio); FlushStatus newStatus = Loading @@ -1518,6 +1539,20 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) { } } void NuPlayer::updateDecoderFormatWithoutFlush( bool audio, const sp<AMessage> &format) { ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video"); const sp<Decoder> &decoder = getDecoder(audio); if (decoder == NULL) { ALOGI("updateDecoderFormatWithoutFlush %s without decoder present", audio ? "audio" : "video"); return; } decoder->signalUpdateFormat(format); } void NuPlayer::queueDecoderShutdown( bool audio, bool video, const sp<AMessage> &reply) { ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); Loading media/libmediaplayerservice/nuplayer/NuPlayer.h +8 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace android { struct ABuffer; struct AMessage; struct MetaData; struct NuPlayerDriver; Loading Loading @@ -169,6 +170,10 @@ private: bool mStarted; inline const sp<Decoder> &getDecoder(bool audio) { return audio ? mAudioDecoder : mVideoDecoder; } void openAudioSink(const sp<AMessage> &format, bool offloadOnly); void closeAudioSink(); Loading @@ -185,7 +190,9 @@ private: void finishFlushIfPossible(); void flushDecoder(bool audio, bool needShutdown); void flushDecoder( bool audio, bool needShutdown, const sp<AMessage> &newFormat = NULL); void updateDecoderFormatWithoutFlush(bool audio, const sp<AMessage> &format); static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL); Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +53 −4 Original line number Diff line number Diff line Loading @@ -71,6 +71,19 @@ status_t PostAndAwaitResponse( return err; } void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { mCSDsForCurrentFormat.clear(); for (int32_t i = 0; ; ++i) { AString tag = "csd-"; tag.append(i); sp<ABuffer> buffer; if (!format->findBuffer(tag.c_str(), &buffer)) { break; } mCSDsForCurrentFormat.push(buffer); } } void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { CHECK(mCodec == NULL); Loading Loading @@ -123,6 +136,8 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { handleError(err); return; } rememberCodecSpecificData(format); // the following should work in configured state CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); Loading Loading @@ -189,6 +204,12 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { msg->post(); } void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) { sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id()); msg->setMessage("format", format); msg->post(); } status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); msg->setPointer("buffers", buffers); Loading Loading @@ -229,6 +250,15 @@ bool NuPlayer::Decoder::handleAnInputBuffer() { reply->setSize("buffer-ix", bufferIx); reply->setInt32("generation", mBufferGeneration); if (!mCSDsToSubmit.isEmpty()) { sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); reply->setBuffer("buffer", buffer); mCSDsToSubmit.removeAt(0); reply->post(); return true; } sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatFillThisBuffer); notify->setBuffer("buffer", mInputBuffers[bufferIx]); Loading Loading @@ -312,10 +342,12 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { uint32_t flags = 0; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int32_t eos; // we do not expect CODECCONFIG or SYNCFRAME for decoder int32_t eos, csd; // we do not expect SYNCFRAME for decoder if (buffer->meta()->findInt32("eos", &eos) && eos) { flags |= MediaCodec::BUFFER_FLAG_EOS; } else if (buffer->meta()->findInt32("csd", &csd) && csd) { flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; } // copy into codec buffer Loading Loading @@ -448,6 +480,7 @@ void NuPlayer::Decoder::onFlush() { status_t err = OK; if (mCodec != NULL) { err = mCodec->flush(); mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator ++mBufferGeneration; } Loading Loading @@ -515,6 +548,14 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatUpdateFormat: { sp<AMessage> format; CHECK(msg->findMessage("format", &format)); rememberCodecSpecificData(format); break; } case kWhatGetInputBuffers: { uint32_t replyID; Loading Loading @@ -566,6 +607,10 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { case kWhatFlush: { sp<AMessage> format; if (msg->findMessage("new-format", &format)) { rememberCodecSpecificData(format); } onFlush(); break; } Loading @@ -588,8 +633,12 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { } } void NuPlayer::Decoder::signalFlush() { (new AMessage(kWhatFlush, id()))->post(); void NuPlayer::Decoder::signalFlush(const sp<AMessage> &format) { sp<AMessage> msg = new AMessage(kWhatFlush, id()); if (format != NULL) { msg->setMessage("new-format", format); } msg->post(); } void NuPlayer::Decoder::signalResume() { Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +6 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,8 @@ struct NuPlayer::Decoder : public AHandler { virtual void init(); status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; virtual void signalFlush(); virtual void signalFlush(const sp<AMessage> &format = NULL); virtual void signalUpdateFormat(const sp<AMessage> &format); virtual void signalResume(); virtual void initiateShutdown(); Loading Loading @@ -67,6 +68,7 @@ private: kWhatRenderBuffer = 'rndr', kWhatFlush = 'flus', kWhatShutdown = 'shuD', kWhatUpdateFormat = 'uFmt', }; sp<AMessage> mNotify; Loading @@ -80,6 +82,8 @@ private: Vector<sp<ABuffer> > mInputBuffers; Vector<sp<ABuffer> > mOutputBuffers; Vector<sp<ABuffer> > mCSDsForCurrentFormat; Vector<sp<ABuffer> > mCSDsToSubmit; Vector<bool> mInputBufferIsDequeued; Vector<MediaBuffer *> mMediaBuffers; Loading @@ -103,6 +107,7 @@ private: AString mComponentName; bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const; void rememberCodecSpecificData(const sp<AMessage> &format); DISALLOW_EVIL_CONSTRUCTORS(Decoder); }; Loading Loading
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +50 −15 Original line number Diff line number Diff line Loading @@ -756,7 +756,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); getDecoder(audio)->initiateShutdown(); if (audio) { mFlushingAudio = SHUTTING_DOWN_DECODER; Loading Loading @@ -1292,7 +1292,24 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { mTimeDiscontinuityPending = mTimeDiscontinuityPending || timeChange; if (mFlushingAudio == NONE && mFlushingVideo == NONE) { bool seamlessFormatChange = false; sp<AMessage> newFormat = mSource->getFormat(audio); if (formatChange) { seamlessFormatChange = getDecoder(audio)->supportsSeamlessFormatChange(newFormat); // treat seamless format change separately formatChange = !seamlessFormatChange; } bool shutdownOrFlush = formatChange || timeChange; // We want to queue up scan-sources only once per discontinuity. // We control this by doing it only if neither audio nor video are // flushing or shutting down. (After handling 1st discontinuity, one // of the flushing states will not be NONE.) // No need to scan sources if this discontinuity does not result // in a flush or shutdown, as the flushing state will stay NONE. if (mFlushingAudio == NONE && mFlushingVideo == NONE && shutdownOrFlush) { // And we'll resume scanning sources once we're done // flushing. mDeferredActions.push_front( Loading @@ -1300,16 +1317,17 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { &NuPlayer::performScanSources)); } if (formatChange || timeChange) { sp<AMessage> newFormat = mSource->getFormat(audio); sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { if (formatChange /* not seamless */) { // must change decoder flushDecoder(audio, /* needShutdown = */ true); } else { flushDecoder(audio, /* needShutdown = */ false); } else if (timeChange) { // need to flush flushDecoder(audio, /* needShutdown = */ false, newFormat); err = OK; } else if (seamlessFormatChange) { // reuse existing decoder and don't flush updateDecoderFormatWithoutFlush(audio, newFormat); err = OK; } } else { // This stream is unaffected by the discontinuity return -EWOULDBLOCK; Loading Loading @@ -1488,20 +1506,23 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { driver->notifyListener(msg, ext1, ext2, in); } void NuPlayer::flushDecoder(bool audio, bool needShutdown) { void NuPlayer::flushDecoder( bool audio, bool needShutdown, const sp<AMessage> &newFormat) { ALOGV("[%s] flushDecoder needShutdown=%d", audio ? "audio" : "video", needShutdown); if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { const sp<Decoder> &decoder = getDecoder(audio); if (decoder == NULL) { ALOGI("flushDecoder %s without decoder present", audio ? "audio" : "video"); return; } // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; mScanSourcesPending = false; (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); decoder->signalFlush(newFormat); mRenderer->flush(audio); FlushStatus newStatus = Loading @@ -1518,6 +1539,20 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) { } } void NuPlayer::updateDecoderFormatWithoutFlush( bool audio, const sp<AMessage> &format) { ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video"); const sp<Decoder> &decoder = getDecoder(audio); if (decoder == NULL) { ALOGI("updateDecoderFormatWithoutFlush %s without decoder present", audio ? "audio" : "video"); return; } decoder->signalUpdateFormat(format); } void NuPlayer::queueDecoderShutdown( bool audio, bool video, const sp<AMessage> &reply) { ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); Loading
media/libmediaplayerservice/nuplayer/NuPlayer.h +8 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace android { struct ABuffer; struct AMessage; struct MetaData; struct NuPlayerDriver; Loading Loading @@ -169,6 +170,10 @@ private: bool mStarted; inline const sp<Decoder> &getDecoder(bool audio) { return audio ? mAudioDecoder : mVideoDecoder; } void openAudioSink(const sp<AMessage> &format, bool offloadOnly); void closeAudioSink(); Loading @@ -185,7 +190,9 @@ private: void finishFlushIfPossible(); void flushDecoder(bool audio, bool needShutdown); void flushDecoder( bool audio, bool needShutdown, const sp<AMessage> &newFormat = NULL); void updateDecoderFormatWithoutFlush(bool audio, const sp<AMessage> &format); static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL); Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +53 −4 Original line number Diff line number Diff line Loading @@ -71,6 +71,19 @@ status_t PostAndAwaitResponse( return err; } void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { mCSDsForCurrentFormat.clear(); for (int32_t i = 0; ; ++i) { AString tag = "csd-"; tag.append(i); sp<ABuffer> buffer; if (!format->findBuffer(tag.c_str(), &buffer)) { break; } mCSDsForCurrentFormat.push(buffer); } } void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { CHECK(mCodec == NULL); Loading Loading @@ -123,6 +136,8 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { handleError(err); return; } rememberCodecSpecificData(format); // the following should work in configured state CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); Loading Loading @@ -189,6 +204,12 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { msg->post(); } void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) { sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id()); msg->setMessage("format", format); msg->post(); } status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); msg->setPointer("buffers", buffers); Loading Loading @@ -229,6 +250,15 @@ bool NuPlayer::Decoder::handleAnInputBuffer() { reply->setSize("buffer-ix", bufferIx); reply->setInt32("generation", mBufferGeneration); if (!mCSDsToSubmit.isEmpty()) { sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); reply->setBuffer("buffer", buffer); mCSDsToSubmit.removeAt(0); reply->post(); return true; } sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatFillThisBuffer); notify->setBuffer("buffer", mInputBuffers[bufferIx]); Loading Loading @@ -312,10 +342,12 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { uint32_t flags = 0; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); int32_t eos; // we do not expect CODECCONFIG or SYNCFRAME for decoder int32_t eos, csd; // we do not expect SYNCFRAME for decoder if (buffer->meta()->findInt32("eos", &eos) && eos) { flags |= MediaCodec::BUFFER_FLAG_EOS; } else if (buffer->meta()->findInt32("csd", &csd) && csd) { flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; } // copy into codec buffer Loading Loading @@ -448,6 +480,7 @@ void NuPlayer::Decoder::onFlush() { status_t err = OK; if (mCodec != NULL) { err = mCodec->flush(); mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator ++mBufferGeneration; } Loading Loading @@ -515,6 +548,14 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatUpdateFormat: { sp<AMessage> format; CHECK(msg->findMessage("format", &format)); rememberCodecSpecificData(format); break; } case kWhatGetInputBuffers: { uint32_t replyID; Loading Loading @@ -566,6 +607,10 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { case kWhatFlush: { sp<AMessage> format; if (msg->findMessage("new-format", &format)) { rememberCodecSpecificData(format); } onFlush(); break; } Loading @@ -588,8 +633,12 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { } } void NuPlayer::Decoder::signalFlush() { (new AMessage(kWhatFlush, id()))->post(); void NuPlayer::Decoder::signalFlush(const sp<AMessage> &format) { sp<AMessage> msg = new AMessage(kWhatFlush, id()); if (format != NULL) { msg->setMessage("new-format", format); } msg->post(); } void NuPlayer::Decoder::signalResume() { Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +6 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,8 @@ struct NuPlayer::Decoder : public AHandler { virtual void init(); status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; virtual void signalFlush(); virtual void signalFlush(const sp<AMessage> &format = NULL); virtual void signalUpdateFormat(const sp<AMessage> &format); virtual void signalResume(); virtual void initiateShutdown(); Loading Loading @@ -67,6 +68,7 @@ private: kWhatRenderBuffer = 'rndr', kWhatFlush = 'flus', kWhatShutdown = 'shuD', kWhatUpdateFormat = 'uFmt', }; sp<AMessage> mNotify; Loading @@ -80,6 +82,8 @@ private: Vector<sp<ABuffer> > mInputBuffers; Vector<sp<ABuffer> > mOutputBuffers; Vector<sp<ABuffer> > mCSDsForCurrentFormat; Vector<sp<ABuffer> > mCSDsToSubmit; Vector<bool> mInputBufferIsDequeued; Vector<MediaBuffer *> mMediaBuffers; Loading @@ -103,6 +107,7 @@ private: AString mComponentName; bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const; void rememberCodecSpecificData(const sp<AMessage> &format); DISALLOW_EVIL_CONSTRUCTORS(Decoder); }; Loading