diff options
-rw-r--r-- | include/media/stagefright/ACodec.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 18 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 33 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 2 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 74 |
5 files changed, 64 insertions, 66 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index f13e9bb..e965f14 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -36,6 +36,7 @@ struct ACodec : public AHierarchicalStateMachine { kWhatShutdownCompleted = 'scom', kWhatFlushCompleted = 'fcom', kWhatOutputFormatChanged = 'outC', + kWhatError = 'erro', }; ACodec(); @@ -58,7 +59,6 @@ private: struct OutputPortSettingsChangedState; struct ExecutingToIdleState; struct IdleToLoadedState; - struct ErrorState; struct FlushingState; enum { @@ -102,7 +102,6 @@ private: sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState; sp<ExecutingToIdleState> mExecutingToIdleState; sp<IdleToLoadedState> mIdleToLoadedState; - sp<ErrorState> mErrorState; sp<FlushingState> mFlushingState; AString mComponentName; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index b06f20d..7fb141a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -340,6 +340,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } finishFlushIfPossible(); + } else if (what == ACodec::kWhatError) { + LOGE("Received error from %s decoder, aborting playback.", + audio ? "audio" : "video"); + + mRenderer->queueEOS(audio, UNKNOWN_ERROR); } else { CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer); @@ -358,13 +363,24 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); + int32_t finalResult; + CHECK(msg->findInt32("finalResult", &finalResult)); + if (audio) { mAudioEOS = true; } else { mVideoEOS = true; } - LOGV("reached %s EOS", audio ? "audio" : "video"); + if (finalResult == ERROR_END_OF_STREAM) { + LOGV("reached %s EOS", audio ? "audio" : "video"); + } else { + LOGE("%s track encountered an error (0x%08x)", + audio ? "audio" : "video", finalResult); + + notifyListener( + MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); + } if ((mAudioEOS || mAudioDecoder == NULL) && (mVideoEOS || mVideoDecoder == NULL)) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 828e008..35ed43f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -200,19 +200,6 @@ void NuPlayer::Renderer::signalAudioSinkChanged() { void NuPlayer::Renderer::onDrainAudioQueue() { for (;;) { - uint32_t numFramesPlayed; - CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); - - ssize_t numFramesAvailableToWrite = - mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); - - size_t numBytesAvailableToWrite = - numFramesAvailableToWrite * mAudioSink->frameSize(); - - if (numBytesAvailableToWrite == 0) { - break; - } - if (mAudioQueue.empty()) { break; } @@ -222,13 +209,26 @@ void NuPlayer::Renderer::onDrainAudioQueue() { if (entry->mBuffer == NULL) { // EOS - notifyEOS(true /* audio */); + notifyEOS(true /* audio */, entry->mFinalResult); mAudioQueue.erase(mAudioQueue.begin()); entry = NULL; return; } + uint32_t numFramesPlayed; + CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); + + ssize_t numFramesAvailableToWrite = + mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed); + + size_t numBytesAvailableToWrite = + numFramesAvailableToWrite * mAudioSink->frameSize(); + + if (numBytesAvailableToWrite == 0) { + break; + } + if (entry->mOffset == 0) { int64_t mediaTimeUs; CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs)); @@ -330,7 +330,7 @@ void NuPlayer::Renderer::onDrainVideoQueue() { if (entry->mBuffer == NULL) { // EOS - notifyEOS(false /* audio */); + notifyEOS(false /* audio */, entry->mFinalResult); mVideoQueue.erase(mVideoQueue.begin()); entry = NULL; @@ -352,10 +352,11 @@ void NuPlayer::Renderer::onDrainVideoQueue() { notifyPosition(); } -void NuPlayer::Renderer::notifyEOS(bool audio) { +void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatEOS); notify->setInt32("audio", static_cast<int32_t>(audio)); + notify->setInt32("finalResult", finalResult); notify->post(); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 703e971..2713031 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -111,7 +111,7 @@ private: void onPause(); void onResume(); - void notifyEOS(bool audio); + void notifyEOS(bool audio, status_t finalResult); void notifyFlushComplete(bool audio); void notifyPosition(); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 174ec92..5d91f6a 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -285,21 +285,6 @@ private: //////////////////////////////////////////////////////////////////////////////// -struct ACodec::ErrorState : public ACodec::BaseState { - ErrorState(ACodec *codec); - -protected: - virtual bool onMessageReceived(const sp<AMessage> &msg); - virtual void stateEntered(); - - virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); - -private: - DISALLOW_EVIL_CONSTRUCTORS(ErrorState); -}; - -//////////////////////////////////////////////////////////////////////////////// - struct ACodec::FlushingState : public ACodec::BaseState { FlushingState(ACodec *codec); @@ -335,7 +320,6 @@ ACodec::ACodec() mExecutingToIdleState = new ExecutingToIdleState(this); mIdleToLoadedState = new IdleToLoadedState(this); - mErrorState = new ErrorState(this); mFlushingState = new FlushingState(this); mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false; @@ -594,7 +578,10 @@ status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) { ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { ANativeWindowBuffer *buf; - CHECK_EQ(mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf), 0); + if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) { + LOGE("dequeueBuffer failed."); + return NULL; + } for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { BufferInfo *info = @@ -1263,10 +1250,12 @@ bool ACodec::BaseState::onOMXEvent( return false; } - LOGE("[%s] ERROR(0x%08lx, 0x%08lx)", - mCodec->mComponentName.c_str(), data1, data2); + LOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1); - mCodec->changeState(mCodec->mErrorState); + sp<AMessage> notify = mCodec->mNotify->dup(); + notify->setInt32("what", ACodec::kWhatError); + notify->setInt32("omx-error", data1); + notify->post(); return true; } @@ -1595,13 +1584,15 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { info = mCodec->dequeueBufferFromNativeWindow(); } - LOGV("[%s] calling fillBuffer %p", - mCodec->mComponentName.c_str(), info->mBufferID); + if (info != NULL) { + LOGV("[%s] calling fillBuffer %p", + mCodec->mComponentName.c_str(), info->mBufferID); - CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), - (status_t)OK); + CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), + (status_t)OK); - info->mStatus = BufferInfo::OWNED_BY_COMPONENT; + info->mStatus = BufferInfo::OWNED_BY_COMPONENT; + } } break; } @@ -1642,6 +1633,7 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { notify->post(); handled = true; + break; } case ACodec::kWhatFlush: @@ -1651,6 +1643,7 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) { notify->post(); handled = true; + break; } default: @@ -1696,7 +1689,16 @@ void ACodec::UninitializedState::onSetup( node = NULL; } - CHECK(node != NULL); + if (node == NULL) { + LOGE("Unable to instantiate a decoder for type '%s'.", mime.c_str()); + + sp<AMessage> notify = mCodec->mNotify->dup(); + notify->setInt32("what", ACodec::kWhatError); + notify->setInt32("omx-error", OMX_ErrorComponentNotFound); + notify->post(); + + return; + } sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id()); observer->setNotificationMessage(notify); @@ -2236,26 +2238,6 @@ bool ACodec::IdleToLoadedState::onOMXEvent( //////////////////////////////////////////////////////////////////////////////// -ACodec::ErrorState::ErrorState(ACodec *codec) - : BaseState(codec) { -} - -bool ACodec::ErrorState::onMessageReceived(const sp<AMessage> &msg) { - return BaseState::onMessageReceived(msg); -} - -void ACodec::ErrorState::stateEntered() { - LOGV("[%s] Now in ErrorState", mCodec->mComponentName.c_str()); -} - -bool ACodec::ErrorState::onOMXEvent( - OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { - LOGV("EVENT(%d, 0x%08lx, 0x%08lx)", event, data1, data2); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// - ACodec::FlushingState::FlushingState(ACodec *codec) : BaseState(codec) { } |