summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/OMXCodec.cpp
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2014-01-31 22:08:54 +0800
committerSteve Kondik <steve@cyngn.com>2015-11-07 12:03:16 -0800
commite79ee6494c2a1f2d3b1f1b1393ca85beee41a29d (patch)
tree26430e8fe59a53da3d0161b6123b575bef05b49e /media/libstagefright/OMXCodec.cpp
parent5d9ec7585ad39f73690fddbd864f3e3f5c1bde4d (diff)
downloadframeworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.zip
frameworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.tar.gz
frameworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.tar.bz2
stagefright: Squashed commit of pause/resume features
Add 2 APIs (suspend/resume) in MediaPlayer - API:suspend() will just pause the player and release all the decoders to replace release() which will release the whole player - API:resume() will just init the decoders again, then start() will be called to restart streaming playback - Add a check in AwesomePlayer::onVideoEvent() to make sure the first seek operation will always seek to the next i-frame Change-Id: Ie4c82906a2a056378119921a656128ebdc1007c4 audio: Add pause support for hardware omx component - ADSP doesn't enter sleep state after wma playback is paused and power suspended. - No support for NT session pause in case of hardware component. NT session need to be paused to put ADSP into power collapse. - Add support of pause in stagefright to ensure device enters suspend mode. Also add intermediate states to avoid concurrency issues between read and pause. Change-Id: I41b946b8c8805e6ee303646b63513b5b16514ef6 libstagefright: Drain input buffer on resume - Buffers returned from codec in paused state are not drained. When codec is resumed these buffers are not drained until the next flush, and may cause timed out issue. - Added change to drain input buffers for sw decoders when resuming. Change-Id: Ida2ab1d5dc3a1910accdd6fb89548262a912d8e7 CRs-Fixed: 569585, 574967 libstagefright: camcorder pause-resume implementation - Add pause resume feature in camcorder app. So that user can pause recording and resume later which results in a single recorded clip. Change-Id: Id19c45ae5bb85265aa4d5304b160ebf119d9575a libstagefright: support pause/resume for timelapse recording Modify the timestamp calculation mechanism in CameraSourceTimeLapse in order to support pause/resume. Change-Id: Icb02ea798b0b807ffb7ada2d1ef5b2414b74edfb
Diffstat (limited to 'media/libstagefright/OMXCodec.cpp')
-rw-r--r--media/libstagefright/OMXCodec.cpp92
1 files changed, 86 insertions, 6 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index b2bfceb..3ec02d4 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1614,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;
}
@@ -2665,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);
@@ -2780,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]),
@@ -2830,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
@@ -2857,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];
@@ -3604,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;
@@ -3714,6 +3729,7 @@ status_t OMXCodec::stopOmxComponent_l() {
isError = true;
}
+ case PAUSED:
case EXECUTING:
{
setState(EXECUTING_TO_IDLE);
@@ -3785,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;
}
@@ -3841,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);
@@ -3870,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;
}
@@ -4303,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;
+}
- return OK;
+status_t OMXCodec::resumeLocked(bool drainInputBuf) {
+ CODEC_LOGV("resume mState=%d", mState);
+
+ 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;
+ }
}
////////////////////////////////////////////////////////////////////////////////