diff options
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index c005f3f..c505096 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -34,10 +34,14 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> +#include <stagefright/AVExtensions.h> +#include <stagefright/FFMPEGSoftCodec.h> #include <gui/Surface.h> #include "avc_utils.h" #include "ATSParser.h" +#include "mediaplayerservice/AVNuExtensions.h" + namespace android { @@ -69,7 +73,6 @@ NuPlayer::Decoder::Decoder( mIsSecure(false), mFormatChangePending(false), mTimeChangePending(false), - mPaused(true), mResumePending(false), mComponentName("decoder") { mCodecLooper = new ALooper; @@ -78,7 +81,9 @@ NuPlayer::Decoder::Decoder( } NuPlayer::Decoder::~Decoder() { - mCodec->release(); + if (mCodec != NULL) { + mCodec->release(); + } releaseAndResetMediaBuffers(); } @@ -251,8 +256,17 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { mComponentName.append(" decoder"); ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); - mCodec = MediaCodec::CreateByType( - mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid); + mCodec = AVUtils::get()->createCustomComponentByName(mCodecLooper, mime.c_str(), false /* encoder */, format); + FFMPEGSoftCodec::overrideComponentName(0, format, &mComponentName, &mime, false); + + if (mCodec == NULL) { + if (!mComponentName.startsWith(mime.c_str())) { + mCodec = MediaCodec::CreateByComponentName(mCodecLooper, mComponentName.c_str()); + } else { + mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); + } + } + int32_t secure = 0; if (format->findInt32("secure", &secure) && secure != 0) { if (mCodec != NULL) { @@ -357,7 +371,14 @@ void NuPlayer::Decoder::onResume(bool notifyComplete) { if (notifyComplete) { mResumePending = true; } - mCodec->start(); + + if (mCodec != NULL) { + mCodec->start(); + } else { + ALOGW("Decoder %s onResume without a valid codec object", + mComponentName.c_str()); + handleError(NO_INIT); + } } void NuPlayer::Decoder::doFlush(bool notifyComplete) { @@ -558,6 +579,11 @@ bool NuPlayer::Decoder::handleAnOutputBuffer( sp<ABuffer> buffer; mCodec->getOutputBuffer(index, &buffer); + if (buffer == NULL) { + handleError(UNKNOWN_ERROR); + return false; + } + if (index >= mOutputBuffers.size()) { for (size_t i = mOutputBuffers.size(); i <= index; ++i) { mOutputBuffers.add(); @@ -569,6 +595,10 @@ bool NuPlayer::Decoder::handleAnOutputBuffer( buffer->setRange(offset, size); buffer->meta()->clear(); buffer->meta()->setInt64("timeUs", timeUs); + setPcmFormat(buffer->meta()); +#ifdef TARGET_8974 + AVNuUtils::get()->addFlagsInMeta(buffer, flags, mIsAudio); +#endif bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; // we do not expect CODECCONFIG or SYNCFRAME for decoder @@ -592,6 +622,12 @@ bool NuPlayer::Decoder::handleAnOutputBuffer( } mSkipRenderingUntilMediaTimeUs = -1; + } else if ((flags & MediaCodec::BUFFER_FLAG_DATACORRUPT) && + AVNuUtils::get()->dropCorruptFrame()) { + ALOGV("[%s] dropping corrupt buffer at time %lld as requested.", + mComponentName.c_str(), (long long)timeUs); + reply->post(); + return true; } mNumFramesTotal += !mIsAudio; @@ -636,7 +672,7 @@ void NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { } status_t err = mRenderer->openAudioSink( - format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */); + format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */, mSource->isStreaming()); if (err != OK) { handleError(err); } @@ -711,6 +747,7 @@ status_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { // treat seamless format change separately formatChange = !seamlessFormatChange; } + AVNuUtils::get()->checkFormatChange(&formatChange, accessUnit); // For format or time change, return EOS to queue EOS input, // then wait for EOS on output. |