Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +54 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> Loading Loading @@ -221,6 +222,10 @@ void NuPlayer::setDataSourceAsync( || strstr(url, ".sdp?"))) { source = new RTSPSource( notify, httpService, url, headers, mUIDValid, mUID, true); } else if ((!strncasecmp(url, "widevine://", 11))) { source = new GenericSource(notify, httpService, url, headers, true /* isWidevine */, mUIDValid, mUID); mSourceFlags |= Source::FLAG_SECURE; } else { source = new GenericSource(notify, httpService, url, headers); } Loading Loading @@ -512,6 +517,17 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mNumFramesDropped = 0; mStarted = true; /* instantiate decoders now for secure playback */ if (mSourceFlags & Source::FLAG_SECURE) { if (mNativeWindow != NULL) { instantiateDecoder(false, &mVideoDecoder); } if (mAudioSink != NULL) { instantiateDecoder(true, &mAudioDecoder); } } mSource->start(); uint32_t flags = 0; Loading Loading @@ -540,7 +556,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { new AMessage(kWhatRendererNotify, id()), flags); looper()->registerHandler(mRenderer); mRendererLooper = new ALooper; mRendererLooper->setName("NuPlayerRenderer"); mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); mRendererLooper->registerHandler(mRenderer); postScanSources(); break; Loading Loading @@ -1055,6 +1074,10 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); mCCDecoder = new CCDecoder(ccNotify); if (mSourceFlags & Source::FLAG_SECURE) { format->setInt32("secure", true); } } sp<AMessage> notify = Loading @@ -1073,6 +1096,28 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { (*decoder)->init(); (*decoder)->configure(format); // allocate buffers to decrypt widevine source buffers if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { Vector<sp<ABuffer> > inputBufs; CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); Vector<MediaBuffer *> mediaBufs; for (size_t i = 0; i < inputBufs.size(); i++) { const sp<ABuffer> &buffer = inputBufs[i]; MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); mediaBufs.push(mbuf); } status_t err = mSource->setBuffers(audio, mediaBufs); if (err != OK) { for (size_t i = 0; i < mediaBufs.size(); ++i) { mediaBufs[i]->release(); } mediaBufs.clear(); ALOGE("Secure source didn't support secure mediaBufs."); return err; } } return OK; } Loading Loading @@ -1184,6 +1229,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { dropAccessUnit = false; if (!audio && !(mSourceFlags & Source::FLAG_SECURE) && mVideoLateByUs > 100000ll && mVideoIsAVC && !IsAVCReferenceFrame(accessUnit)) { Loading Loading @@ -1497,6 +1543,13 @@ void NuPlayer::performReset() { ++mScanSourcesGeneration; mScanSourcesPending = false; if (mRendererLooper != NULL) { if (mRenderer != NULL) { mRendererLooper->unregisterHandler(mRenderer->id()); } mRendererLooper->stop(); mRendererLooper.clear(); } mRenderer.clear(); if (mSource != NULL) { Loading media/libmediaplayerservice/nuplayer/NuPlayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ private: sp<Decoder> mAudioDecoder; sp<CCDecoder> mCCDecoder; sp<Renderer> mRenderer; sp<ALooper> mRendererLooper; List<sp<Action> > mDeferredActions; Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +121 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> Loading Loading @@ -54,6 +55,22 @@ NuPlayer::Decoder::Decoder( NuPlayer::Decoder::~Decoder() { } static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response) { status_t err = msg->postAndAwaitResponse(response); if (err != OK) { return err; } if (!(*response)->findInt32("err", &err)) { err = OK; } return err; } void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { CHECK(mCodec == NULL); Loading @@ -72,8 +89,20 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get()); mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); int32_t secure = 0; if (format->findInt32("secure", &secure) && secure != 0) { if (mCodec != NULL) { mCodec->getName(&mComponentName); mComponentName.append(".secure"); mCodec->release(); ALOGI("[%s] creating", mComponentName.c_str()); mCodec = MediaCodec::CreateByComponentName( mCodecLooper, mComponentName.c_str()); } } if (mCodec == NULL) { ALOGE("Failed to create %s decoder", mime.c_str()); ALOGE("Failed to create %s%s decoder", (secure ? "secure " : ""), mime.c_str()); handleError(UNKNOWN_ERROR); return; } Loading Loading @@ -107,6 +136,7 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { // the following should work after start CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers)); releaseAndResetMediaBuffers(); CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers)); ALOGV("[%s] got %zu input and %zu output buffers", mComponentName.c_str(), Loading @@ -117,6 +147,18 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { mPaused = false; } void NuPlayer::Decoder::releaseAndResetMediaBuffers() { for (size_t i = 0; i < mMediaBuffers.size(); i++) { if (mMediaBuffers[i] != NULL) { mMediaBuffers[i]->release(); mMediaBuffers.editItemAt(i) = NULL; } } mMediaBuffers.resize(mInputBuffers.size()); mInputBufferIsDequeued.clear(); mInputBufferIsDequeued.resize(mInputBuffers.size()); } void NuPlayer::Decoder::requestCodecNotification() { if (mCodec != NULL) { sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); Loading @@ -141,6 +183,14 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { msg->post(); } status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); msg->setPointer("buffers", buffers); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } void NuPlayer::Decoder::handleError(int32_t err) { sp<AMessage> notify = mNotify->dup(); Loading @@ -163,6 +213,12 @@ bool NuPlayer::Decoder::handleAnInputBuffer() { CHECK_LT(bufferIx, mInputBuffers.size()); if (mMediaBuffers[bufferIx] != NULL) { mMediaBuffers[bufferIx]->release(); mMediaBuffers.editItemAt(bufferIx) = NULL; } mInputBufferIsDequeued.editItemAt(bufferIx) = true; sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); reply->setSize("buffer-ix", bufferIx); reply->setInt32("generation", mBufferGeneration); Loading @@ -183,6 +239,44 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { sp<ABuffer> buffer; bool hasBuffer = msg->findBuffer("buffer", &buffer); // handle widevine classic source - that fills an arbitrary input buffer MediaBuffer *mediaBuffer = NULL; if (hasBuffer && buffer->meta()->findPointer( "mediaBuffer", (void **)&mediaBuffer)) { if (mediaBuffer == NULL) { // received no actual buffer ALOGW("[%s] received null MediaBuffer %s", mComponentName.c_str(), msg->debugString().c_str()); buffer = NULL; } else { // likely filled another buffer than we requested: adjust buffer index size_t ix; for (ix = 0; ix < mInputBuffers.size(); ix++) { const sp<ABuffer> &buf = mInputBuffers[ix]; if (buf->data() == mediaBuffer->data()) { // all input buffers are dequeued on start, hence the check CHECK(mInputBufferIsDequeued[ix]); ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", mComponentName.c_str(), ix, bufferIx); // TRICKY: need buffer for the metadata, so instead, set // codecBuffer to the same (though incorrect) buffer to // avoid a memcpy into the codecBuffer codecBuffer = buffer; codecBuffer->setRange( mediaBuffer->range_offset(), mediaBuffer->range_length()); bufferIx = ix; break; } } CHECK(ix < mInputBuffers.size()); } } mInputBufferIsDequeued.editItemAt(bufferIx) = false; if (buffer == NULL /* includes !hasBuffer */) { int32_t streamErr = ERROR_END_OF_STREAM; CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); Loading Loading @@ -236,6 +330,11 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { mComponentName.c_str(), err); handleError(err); } if (mediaBuffer != NULL) { CHECK(mMediaBuffers[bufferIx] == NULL); mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; } } } Loading Loading @@ -352,6 +451,8 @@ void NuPlayer::Decoder::onFlush() { return; } releaseAndResetMediaBuffers(); sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatFlushCompleted); notify->post(); Loading Loading @@ -379,6 +480,8 @@ void NuPlayer::Decoder::onShutdown() { mComponentName = "decoder"; } releaseAndResetMediaBuffers(); if (err != OK) { ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); handleError(err); Loading @@ -403,6 +506,23 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatGetInputBuffers: { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); Vector<sp<ABuffer> > *dstBuffers; CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); dstBuffers->clear(); for (size_t i = 0; i < mInputBuffers.size(); i++) { dstBuffers->push(mInputBuffers[i]); } (new AMessage)->postReply(replyID); break; } case kWhatCodecNotify: { if (!isStaleReply(msg)) { Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ namespace android { struct ABuffer; struct MediaCodec; struct MediaBuffer; struct NuPlayer::Decoder : public AHandler { Decoder(const sp<AMessage> ¬ify, Loading @@ -34,6 +35,7 @@ struct NuPlayer::Decoder : public AHandler { virtual void configure(const sp<AMessage> &format); virtual void init(); status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; virtual void signalFlush(); virtual void signalResume(); virtual void initiateShutdown(); Loading @@ -60,6 +62,7 @@ private: enum { kWhatCodecNotify = 'cdcN', kWhatConfigure = 'conf', kWhatGetInputBuffers = 'gInB', kWhatInputBufferFilled = 'inpF', kWhatRenderBuffer = 'rndr', kWhatFlush = 'flus', Loading @@ -77,11 +80,14 @@ private: Vector<sp<ABuffer> > mInputBuffers; Vector<sp<ABuffer> > mOutputBuffers; Vector<bool> mInputBufferIsDequeued; Vector<MediaBuffer *> mMediaBuffers; void handleError(int32_t err); bool handleAnInputBuffer(); bool handleAnOutputBuffer(); void releaseAndResetMediaBuffers(); void requestCodecNotification(); bool isStaleReply(const sp<AMessage> &msg); Loading media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <inttypes.h> namespace android { // static Loading Loading @@ -502,6 +504,7 @@ void NuPlayer::Renderer::postDrainVideoQueue() { } } ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); msg->post(delayUs); mDrainVideoQueuePending = true; Loading Loading
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +54 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> Loading Loading @@ -221,6 +222,10 @@ void NuPlayer::setDataSourceAsync( || strstr(url, ".sdp?"))) { source = new RTSPSource( notify, httpService, url, headers, mUIDValid, mUID, true); } else if ((!strncasecmp(url, "widevine://", 11))) { source = new GenericSource(notify, httpService, url, headers, true /* isWidevine */, mUIDValid, mUID); mSourceFlags |= Source::FLAG_SECURE; } else { source = new GenericSource(notify, httpService, url, headers); } Loading Loading @@ -512,6 +517,17 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mNumFramesDropped = 0; mStarted = true; /* instantiate decoders now for secure playback */ if (mSourceFlags & Source::FLAG_SECURE) { if (mNativeWindow != NULL) { instantiateDecoder(false, &mVideoDecoder); } if (mAudioSink != NULL) { instantiateDecoder(true, &mAudioDecoder); } } mSource->start(); uint32_t flags = 0; Loading Loading @@ -540,7 +556,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { new AMessage(kWhatRendererNotify, id()), flags); looper()->registerHandler(mRenderer); mRendererLooper = new ALooper; mRendererLooper->setName("NuPlayerRenderer"); mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); mRendererLooper->registerHandler(mRenderer); postScanSources(); break; Loading Loading @@ -1055,6 +1074,10 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); mCCDecoder = new CCDecoder(ccNotify); if (mSourceFlags & Source::FLAG_SECURE) { format->setInt32("secure", true); } } sp<AMessage> notify = Loading @@ -1073,6 +1096,28 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { (*decoder)->init(); (*decoder)->configure(format); // allocate buffers to decrypt widevine source buffers if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { Vector<sp<ABuffer> > inputBufs; CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); Vector<MediaBuffer *> mediaBufs; for (size_t i = 0; i < inputBufs.size(); i++) { const sp<ABuffer> &buffer = inputBufs[i]; MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); mediaBufs.push(mbuf); } status_t err = mSource->setBuffers(audio, mediaBufs); if (err != OK) { for (size_t i = 0; i < mediaBufs.size(); ++i) { mediaBufs[i]->release(); } mediaBufs.clear(); ALOGE("Secure source didn't support secure mediaBufs."); return err; } } return OK; } Loading Loading @@ -1184,6 +1229,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { dropAccessUnit = false; if (!audio && !(mSourceFlags & Source::FLAG_SECURE) && mVideoLateByUs > 100000ll && mVideoIsAVC && !IsAVCReferenceFrame(accessUnit)) { Loading Loading @@ -1497,6 +1543,13 @@ void NuPlayer::performReset() { ++mScanSourcesGeneration; mScanSourcesPending = false; if (mRendererLooper != NULL) { if (mRenderer != NULL) { mRendererLooper->unregisterHandler(mRenderer->id()); } mRendererLooper->stop(); mRendererLooper.clear(); } mRenderer.clear(); if (mSource != NULL) { Loading
media/libmediaplayerservice/nuplayer/NuPlayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,7 @@ private: sp<Decoder> mAudioDecoder; sp<CCDecoder> mCCDecoder; sp<Renderer> mRenderer; sp<ALooper> mRendererLooper; List<sp<Action> > mDeferredActions; Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +121 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> Loading Loading @@ -54,6 +55,22 @@ NuPlayer::Decoder::Decoder( NuPlayer::Decoder::~Decoder() { } static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response) { status_t err = msg->postAndAwaitResponse(response); if (err != OK) { return err; } if (!(*response)->findInt32("err", &err)) { err = OK; } return err; } void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { CHECK(mCodec == NULL); Loading @@ -72,8 +89,20 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get()); mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); int32_t secure = 0; if (format->findInt32("secure", &secure) && secure != 0) { if (mCodec != NULL) { mCodec->getName(&mComponentName); mComponentName.append(".secure"); mCodec->release(); ALOGI("[%s] creating", mComponentName.c_str()); mCodec = MediaCodec::CreateByComponentName( mCodecLooper, mComponentName.c_str()); } } if (mCodec == NULL) { ALOGE("Failed to create %s decoder", mime.c_str()); ALOGE("Failed to create %s%s decoder", (secure ? "secure " : ""), mime.c_str()); handleError(UNKNOWN_ERROR); return; } Loading Loading @@ -107,6 +136,7 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { // the following should work after start CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers)); releaseAndResetMediaBuffers(); CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers)); ALOGV("[%s] got %zu input and %zu output buffers", mComponentName.c_str(), Loading @@ -117,6 +147,18 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { mPaused = false; } void NuPlayer::Decoder::releaseAndResetMediaBuffers() { for (size_t i = 0; i < mMediaBuffers.size(); i++) { if (mMediaBuffers[i] != NULL) { mMediaBuffers[i]->release(); mMediaBuffers.editItemAt(i) = NULL; } } mMediaBuffers.resize(mInputBuffers.size()); mInputBufferIsDequeued.clear(); mInputBufferIsDequeued.resize(mInputBuffers.size()); } void NuPlayer::Decoder::requestCodecNotification() { if (mCodec != NULL) { sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); Loading @@ -141,6 +183,14 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { msg->post(); } status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); msg->setPointer("buffers", buffers); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } void NuPlayer::Decoder::handleError(int32_t err) { sp<AMessage> notify = mNotify->dup(); Loading @@ -163,6 +213,12 @@ bool NuPlayer::Decoder::handleAnInputBuffer() { CHECK_LT(bufferIx, mInputBuffers.size()); if (mMediaBuffers[bufferIx] != NULL) { mMediaBuffers[bufferIx]->release(); mMediaBuffers.editItemAt(bufferIx) = NULL; } mInputBufferIsDequeued.editItemAt(bufferIx) = true; sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); reply->setSize("buffer-ix", bufferIx); reply->setInt32("generation", mBufferGeneration); Loading @@ -183,6 +239,44 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { sp<ABuffer> buffer; bool hasBuffer = msg->findBuffer("buffer", &buffer); // handle widevine classic source - that fills an arbitrary input buffer MediaBuffer *mediaBuffer = NULL; if (hasBuffer && buffer->meta()->findPointer( "mediaBuffer", (void **)&mediaBuffer)) { if (mediaBuffer == NULL) { // received no actual buffer ALOGW("[%s] received null MediaBuffer %s", mComponentName.c_str(), msg->debugString().c_str()); buffer = NULL; } else { // likely filled another buffer than we requested: adjust buffer index size_t ix; for (ix = 0; ix < mInputBuffers.size(); ix++) { const sp<ABuffer> &buf = mInputBuffers[ix]; if (buf->data() == mediaBuffer->data()) { // all input buffers are dequeued on start, hence the check CHECK(mInputBufferIsDequeued[ix]); ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", mComponentName.c_str(), ix, bufferIx); // TRICKY: need buffer for the metadata, so instead, set // codecBuffer to the same (though incorrect) buffer to // avoid a memcpy into the codecBuffer codecBuffer = buffer; codecBuffer->setRange( mediaBuffer->range_offset(), mediaBuffer->range_length()); bufferIx = ix; break; } } CHECK(ix < mInputBuffers.size()); } } mInputBufferIsDequeued.editItemAt(bufferIx) = false; if (buffer == NULL /* includes !hasBuffer */) { int32_t streamErr = ERROR_END_OF_STREAM; CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); Loading Loading @@ -236,6 +330,11 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { mComponentName.c_str(), err); handleError(err); } if (mediaBuffer != NULL) { CHECK(mMediaBuffers[bufferIx] == NULL); mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; } } } Loading Loading @@ -352,6 +451,8 @@ void NuPlayer::Decoder::onFlush() { return; } releaseAndResetMediaBuffers(); sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatFlushCompleted); notify->post(); Loading Loading @@ -379,6 +480,8 @@ void NuPlayer::Decoder::onShutdown() { mComponentName = "decoder"; } releaseAndResetMediaBuffers(); if (err != OK) { ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); handleError(err); Loading @@ -403,6 +506,23 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatGetInputBuffers: { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); Vector<sp<ABuffer> > *dstBuffers; CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); dstBuffers->clear(); for (size_t i = 0; i < mInputBuffers.size(); i++) { dstBuffers->push(mInputBuffers[i]); } (new AMessage)->postReply(replyID); break; } case kWhatCodecNotify: { if (!isStaleReply(msg)) { Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ namespace android { struct ABuffer; struct MediaCodec; struct MediaBuffer; struct NuPlayer::Decoder : public AHandler { Decoder(const sp<AMessage> ¬ify, Loading @@ -34,6 +35,7 @@ struct NuPlayer::Decoder : public AHandler { virtual void configure(const sp<AMessage> &format); virtual void init(); status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; virtual void signalFlush(); virtual void signalResume(); virtual void initiateShutdown(); Loading @@ -60,6 +62,7 @@ private: enum { kWhatCodecNotify = 'cdcN', kWhatConfigure = 'conf', kWhatGetInputBuffers = 'gInB', kWhatInputBufferFilled = 'inpF', kWhatRenderBuffer = 'rndr', kWhatFlush = 'flus', Loading @@ -77,11 +80,14 @@ private: Vector<sp<ABuffer> > mInputBuffers; Vector<sp<ABuffer> > mOutputBuffers; Vector<bool> mInputBufferIsDequeued; Vector<MediaBuffer *> mMediaBuffers; void handleError(int32_t err); bool handleAnInputBuffer(); bool handleAnOutputBuffer(); void releaseAndResetMediaBuffers(); void requestCodecNotification(); bool isStaleReply(const sp<AMessage> &msg); Loading
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <inttypes.h> namespace android { // static Loading Loading @@ -502,6 +504,7 @@ void NuPlayer::Renderer::postDrainVideoQueue() { } } ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); msg->post(delayUs); mDrainVideoQueuePending = true; Loading