diff options
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r-- | media/libstagefright/ACodec.cpp | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index c68dfc1..f2354b4 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -365,6 +365,7 @@ ACodec::ACodec() mIsEncoder(false), mUseMetadataOnEncoderOutput(false), mShutdownInProgress(false), + mIsConfiguredForAdaptivePlayback(false), mEncoderDelay(0), mEncoderPadding(0), mChannelMaskPresent(false), @@ -372,7 +373,9 @@ ACodec::ACodec() mDequeueCounter(0), mStoreMetaDataInOutputBuffers(false), mMetaDataBuffersToSubmit(0), - mRepeatFrameDelayUs(-1ll) { + mRepeatFrameDelayUs(-1ll), + mMaxPtsGapUs(-1l), + mCreateInputBuffersSuspended(false) { mUninitializedState = new UninitializedState(this); mLoadedState = new LoadedState(this); mLoadedToIdleState = new LoadedToIdleState(this); @@ -1114,6 +1117,16 @@ status_t ACodec::configureCodec( &mRepeatFrameDelayUs)) { mRepeatFrameDelayUs = -1ll; } + + if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) { + mMaxPtsGapUs = -1l; + } + + if (!msg->findInt32( + "create-input-buffers-suspended", + (int32_t*)&mCreateInputBuffersSuspended)) { + mCreateInputBuffersSuspended = false; + } } // Always try to enable dynamic output buffers on native surface @@ -1121,6 +1134,7 @@ status_t ACodec::configureCodec( int32_t haveNativeWindow = msg->findObject("native-window", &obj) && obj != NULL; mStoreMetaDataInOutputBuffers = false; + mIsConfiguredForAdaptivePlayback = false; if (!encoder && video && haveNativeWindow) { err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE); if (err != OK) { @@ -1165,12 +1179,14 @@ status_t ACodec::configureCodec( ALOGW_IF(err != OK, "[%s] prepareForAdaptivePlayback failed w/ err %d", mComponentName.c_str(), err); + mIsConfiguredForAdaptivePlayback = (err == OK); } // allow failure err = OK; } else { ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str()); mStoreMetaDataInOutputBuffers = true; + mIsConfiguredForAdaptivePlayback = true; } int32_t push; @@ -3318,11 +3334,11 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { mCodec->mInputEOSResult = err; } break; - - default: - CHECK_EQ((int)mode, (int)FREE_BUFFERS); - break; } + + default: + CHECK_EQ((int)mode, (int)FREE_BUFFERS); + break; } } @@ -3413,7 +3429,7 @@ bool ACodec::BaseState::onOMXFillBufferDone( sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, mCodec->id()); - if (!mCodec->mSentFormat) { + if (!mCodec->mSentFormat && rangeLength > 0) { mCodec->sendFormatChange(reply); } @@ -3773,6 +3789,7 @@ void ACodec::LoadedState::stateEntered() { mCodec->mDequeueCounter = 0; mCodec->mMetaDataBuffersToSubmit = 0; mCodec->mRepeatFrameDelayUs = -1ll; + mCodec->mIsConfiguredForAdaptivePlayback = false; if (mCodec->mShutdownInProgress) { bool keepComponentAllocated = mCodec->mKeepComponentAllocated; @@ -3921,6 +3938,37 @@ void ACodec::LoadedState::onCreateInputSurface( } } + if (err == OK && mCodec->mMaxPtsGapUs > 0l) { + err = mCodec->mOMX->setInternalOption( + mCodec->mNode, + kPortIndexInput, + IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP, + &mCodec->mMaxPtsGapUs, + sizeof(mCodec->mMaxPtsGapUs)); + + if (err != OK) { + ALOGE("[%s] Unable to configure max timestamp gap (err %d)", + mCodec->mComponentName.c_str(), + err); + } + } + + if (err == OK && mCodec->mCreateInputBuffersSuspended) { + bool suspend = true; + err = mCodec->mOMX->setInternalOption( + mCodec->mNode, + kPortIndexInput, + IOMX::INTERNAL_OPTION_SUSPEND, + &suspend, + sizeof(suspend)); + + if (err != OK) { + ALOGE("[%s] Unable to configure option to suspend (err %d)", + mCodec->mComponentName.c_str(), + err); + } + } + if (err == OK) { notify->setObject("input-surface", new BufferProducerWrapper(bufferProducer)); @@ -3978,6 +4026,7 @@ status_t ACodec::LoadedToIdleState::allocateBuffers() { bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { + case kWhatSetParameters: case kWhatShutdown: { mCodec->deferMessage(msg); @@ -4044,6 +4093,7 @@ void ACodec::IdleToExecutingState::stateEntered() { bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { + case kWhatSetParameters: case kWhatShutdown: { mCodec->deferMessage(msg); @@ -4313,6 +4363,22 @@ status_t ACodec::setParameters(const sp<AMessage> ¶ms) { } } + int64_t skipFramesBeforeUs; + if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) { + status_t err = + mOMX->setInternalOption( + mNode, + kPortIndexInput, + IOMX::INTERNAL_OPTION_START_TIME, + &skipFramesBeforeUs, + sizeof(skipFramesBeforeUs)); + + if (err != OK) { + ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err); + return err; + } + } + int32_t dropInputFrames; if (params->findInt32("drop-input-frames", &dropInputFrames)) { bool suspend = dropInputFrames != 0; |