summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-07-15 07:56:04 -0700
committerLajos Molnar <lajos@google.com>2014-07-15 16:06:40 -0700
commit671160ffe81592efa376dc1ff0fc3f4ddcdebc35 (patch)
treee80ced5238b2fac6f1a02c50223f7fa7afe20f9a
parentefebe3974d4ad5870f957b77450c26a499fc467e (diff)
downloadframeworks_av-671160ffe81592efa376dc1ff0fc3f4ddcdebc35.zip
frameworks_av-671160ffe81592efa376dc1ff0fc3f4ddcdebc35.tar.gz
frameworks_av-671160ffe81592efa376dc1ff0fc3f4ddcdebc35.tar.bz2
stagefright: add MediaCodec.reset()
Bug: 12034929 Change-Id: I326f1356df89474aa088c1c87f8505b33654139d
-rw-r--r--include/media/stagefright/MediaCodec.h9
-rw-r--r--media/libstagefright/MediaCodec.cpp43
2 files changed, 52 insertions, 0 deletions
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index a0ff997..3f7508b 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -73,6 +73,10 @@ struct MediaCodec : public AHandler {
// unconfigured.
status_t stop();
+ // Resets the codec to the INITIALIZED state. Can be called after an error
+ // has occured to make the codec usable.
+ status_t reset();
+
// Client MUST call release before releasing final reference to this
// object.
status_t release();
@@ -221,6 +225,11 @@ private:
sp<AMessage> mInputFormat;
sp<AMessage> mCallback;
+ // initial create parameters
+ AString mInitName;
+ bool mInitNameIsType;
+ bool mInitIsEncoder;
+
// Used only to synchronize asynchronous getBufferAndFormat
// across all the other (synchronous) buffer state change
// operations, such as de/queueIn/OutputBuffer, start and
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 24fd7ad..7a9cb0b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -106,6 +106,11 @@ void MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
}
status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
+ // save init parameters for reset
+ mInitName = name;
+ mInitNameIsType = nameIsType;
+ mInitIsEncoder = encoder;
+
// Current video decoders do not return from OMX_FillThisBuffer
// quickly, violating the OpenMAX specs, until that is remedied
// we need to invest in an extra looper to free the main event
@@ -235,6 +240,40 @@ status_t MediaCodec::release() {
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::reset() {
+ /* When external-facing MediaCodec object is created,
+ it is already initialized. Thus, reset is essentially
+ release() followed by init(), plus clearing the state */
+
+ status_t err = release();
+
+ // unregister handlers
+ if (mCodec != NULL) {
+ if (mCodecLooper != NULL) {
+ mCodecLooper->unregisterHandler(mCodec->id());
+ } else {
+ mLooper->unregisterHandler(mCodec->id());
+ }
+ mCodec = NULL;
+ }
+ mLooper->unregisterHandler(id());
+
+ mFlags = 0; // clear all flags
+
+ // reset state not reset by setState(UNINITIALIZED)
+ mReplyID = 0;
+ mDequeueInputReplyID = 0;
+ mDequeueOutputReplyID = 0;
+ mDequeueInputTimeoutGeneration = 0;
+ mDequeueOutputTimeoutGeneration = 0;
+ mHaveInputSurface = false;
+
+ if (err == OK) {
+ err = init(mInitName.c_str(), mInitNameIsType, mInitIsEncoder);
+ }
+ return err;
+}
+
status_t MediaCodec::queueInputBuffer(
size_t index,
size_t offset,
@@ -1553,6 +1592,7 @@ void MediaCodec::setState(State newState) {
mCrypto.clear();
setNativeWindow(NULL);
+ mInputFormat.clear();
mOutputFormat.clear();
mFlags &= ~kFlagOutputFormatChanged;
mFlags &= ~kFlagOutputBuffersChanged;
@@ -1566,6 +1606,9 @@ void MediaCodec::setState(State newState) {
}
if (newState == UNINITIALIZED) {
+ // return any straggling buffers, e.g. if we got here on an error
+ returnBuffersToCodec();
+
mComponentName.clear();
// The component is gone, mediaserver's probably back up already