diff options
Diffstat (limited to 'media/libstagefright/OMXCodec.cpp')
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 148 |
1 files changed, 140 insertions, 8 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index b1dde80..3ec02d4 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -56,6 +56,11 @@ #include "include/avc_utils.h" +#ifdef USE_S3D_SUPPORT +#include "Exynos_OMX_Def.h" +#include "ExynosHWCService.h" +#endif + namespace android { // Treat time out as an error if we have not received any output @@ -1609,6 +1614,8 @@ bool OMXCodec::isIntermediateState(State state) { return state == LOADED_TO_IDLE || state == IDLE_TO_EXECUTING || state == EXECUTING_TO_IDLE + || state == PAUSING + || state == FLUSHING || state == IDLE_TO_LOADED || state == RECONFIGURING; } @@ -1821,6 +1828,10 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { if (mFlags & kEnableGrallocUsageProtected) { usage |= GRALLOC_USAGE_PROTECTED; +#ifdef GRALLOC_USAGE_PRIVATE_NONSECURE + if (!(mFlags & kUseSecureInputBuffers)) + usage |= GRALLOC_USAGE_PRIVATE_NONSECURE; +#endif } err = setNativeWindowSizeFormatAndUsage( @@ -1856,7 +1867,12 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { // plus an extra buffer to account for incorrect minUndequeuedBufs CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); - +#ifdef BOARD_CANT_REALLOCATE_OMX_BUFFERS + // Some devices don't like to set OMX_IndexParamPortDefinition at this + // point (even with an unmodified def), so skip it if possible. + // This check was present in KitKat. + if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { +#endif for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs + extraBuffers; @@ -1878,6 +1894,9 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { } CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); +#ifdef BOARD_CANT_REALLOCATE_OMX_BUFFERS + } +#endif err = native_window_set_buffer_count( mNativeWindow.get(), def.nBufferCountActual); @@ -2373,7 +2392,41 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { break; } #endif +#ifdef USE_S3D_SUPPORT + case (OMX_EVENTTYPE)OMX_EventS3DInformation: + { + if (mFlags & kClientNeedsFramebuffer) + break; + + sp<IServiceManager> sm = defaultServiceManager(); + sp<android::IExynosHWCService> hwc = interface_cast<android::IExynosHWCService>( + sm->getService(String16("Exynos.HWCService"))); + if (hwc != NULL) { + if (data1 == OMX_TRUE) { + int eS3DMode; + switch (data2) { + case OMX_SEC_FPARGMT_SIDE_BY_SIDE: + eS3DMode = S3D_SBS; + break; + case OMX_SEC_FPARGMT_TOP_BOTTOM: + eS3DMode = S3D_TB; + break; + case OMX_SEC_FPARGMT_CHECKERBRD_INTERL: // unsupport format at HDMI + case OMX_SEC_FPARGMT_COLUMN_INTERL: + case OMX_SEC_FPARGMT_ROW_INTERL: + case OMX_SEC_FPARGMT_TEMPORAL_INTERL: + default: + eS3DMode = S3D_NONE; + } + hwc->setHdmiResolution(0, eS3DMode); + } + } else { + ALOGE("Exynos.HWCService is unavailable"); + } + break; + } +#endif default: { CODEC_LOGV("EVENT(%d, %u, %u)", event, data1, data2); @@ -2614,6 +2667,14 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) { break; } + case OMX_StatePause: + { + CODEC_LOGV("Now paused."); + CHECK_EQ((int)mState, (int)PAUSING); + setState(PAUSED); + break; + } + case OMX_StateInvalid: { setState(ERROR); @@ -2646,7 +2707,8 @@ status_t OMXCodec::freeBuffersOnPort( status_t stickyErr = OK; - for (size_t i = buffers->size(); i-- > 0;) { + for (size_t i = buffers->size(); i > 0;) { + i--; BufferInfo *info = &buffers->editItemAt(i); if (onlyThoseWeOwn && info->mStatus == OWNED_BY_COMPONENT) { @@ -2728,7 +2790,7 @@ void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { bool OMXCodec::flushPortAsync(OMX_U32 portIndex) { CHECK(mState == EXECUTING || mState == RECONFIGURING - || mState == EXECUTING_TO_IDLE); + || mState == EXECUTING_TO_IDLE || mState == FLUSHING); CODEC_LOGV("flushPortAsync(%u): we own %zu out of %zu buffers already.", portIndex, countBuffersWeOwn(mPortBuffers[portIndex]), @@ -2778,7 +2840,7 @@ status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) { } void OMXCodec::fillOutputBuffers() { - CHECK_EQ((int)mState, (int)EXECUTING); + CHECK(mState == EXECUTING || mState == FLUSHING); // This is a workaround for some decoders not properly reporting // end-of-output-stream. If we own all input buffers and also own @@ -2805,7 +2867,7 @@ void OMXCodec::fillOutputBuffers() { } void OMXCodec::drainInputBuffers() { - CHECK(mState == EXECUTING || mState == RECONFIGURING); + CHECK(mState == EXECUTING || mState == RECONFIGURING || mState == FLUSHING); if (mFlags & kUseSecureInputBuffers) { Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; @@ -3552,6 +3614,11 @@ void OMXCodec::clearCodecSpecificData() { status_t OMXCodec::start(MetaData *meta) { Mutex::Autolock autoLock(mLock); + if (mPaused) { + status_t err = resumeLocked(true); + return err; + } + if (mState != LOADED) { CODEC_LOGE("called start in the unexpected state: %d", mState); return UNKNOWN_ERROR; @@ -3662,6 +3729,7 @@ status_t OMXCodec::stopOmxComponent_l() { isError = true; } + case PAUSED: case EXECUTING: { setState(EXECUTING_TO_IDLE); @@ -3733,6 +3801,14 @@ status_t OMXCodec::read( Mutex::Autolock autoLock(mLock); + if (mPaused) { + err = resumeLocked(false); + if(err != OK) { + CODEC_LOGE("Failed to restart codec err= %d", err); + return err; + } + } + if (mState != EXECUTING && mState != RECONFIGURING) { return UNKNOWN_ERROR; } @@ -3789,6 +3865,8 @@ status_t OMXCodec::read( mFilledBuffers.clear(); CHECK_EQ((int)mState, (int)EXECUTING); + //DSP supports flushing of ports simultaneously. Flushing individual port is not supported. + setState(FLUSHING); bool emulateInputFlushCompletion = !flushPortAsync(kPortIndexInput); bool emulateOutputFlushCompletion = !flushPortAsync(kPortIndexOutput); @@ -3818,6 +3896,11 @@ status_t OMXCodec::read( return UNKNOWN_ERROR; } + if (seeking) { + CHECK_EQ((int)mState, (int)FLUSHING); + setState(EXECUTING); + } + if (mFilledBuffers.empty()) { return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM; } @@ -4251,11 +4334,60 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { } status_t OMXCodec::pause() { - Mutex::Autolock autoLock(mLock); + CODEC_LOGV("pause mState=%d", mState); + + Mutex::Autolock autoLock(mLock); + + if (mState != EXECUTING) { + return UNKNOWN_ERROR; + } + + while (isIntermediateState(mState)) { + mAsyncCompletion.wait(mLock); + } + if (!strncmp(mComponentName, "OMX.qcom.", 9)) { + status_t err = mOMX->sendCommand(mNode, + OMX_CommandStateSet, OMX_StatePause); + CHECK_EQ(err, (status_t)OK); + setState(PAUSING); + + mPaused = true; + while (mState != PAUSED && mState != ERROR) { + mAsyncCompletion.wait(mLock); + } + return mState == ERROR ? UNKNOWN_ERROR : OK; + } else { + mPaused = true; + return OK; + } + +} - mPaused = true; +status_t OMXCodec::resumeLocked(bool drainInputBuf) { + CODEC_LOGV("resume mState=%d", mState); - return OK; + if (!strncmp(mComponentName, "OMX.qcom.", 9)) { + while (isIntermediateState(mState)) { + mAsyncCompletion.wait(mLock); + } + CHECK_EQ(mState, (status_t)PAUSED); + status_t err = mOMX->sendCommand(mNode, + OMX_CommandStateSet, OMX_StateExecuting); + CHECK_EQ(err, (status_t)OK); + setState(IDLE_TO_EXECUTING); + mPaused = false; + while (mState != EXECUTING && mState != ERROR) { + mAsyncCompletion.wait(mLock); + } + if(drainInputBuf) + drainInputBuffers(); + return mState == ERROR ? UNKNOWN_ERROR : OK; + } else { // SW Codec + mPaused = false; + if(drainInputBuf) + drainInputBuffers(); + return OK; + } } //////////////////////////////////////////////////////////////////////////////// |