summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MediaCodec.cpp
diff options
context:
space:
mode:
authorRonghua Wu <ronghuawu@google.com>2015-03-13 10:47:08 -0700
committerRonghua Wu <ronghuawu@google.com>2015-05-08 09:59:42 -0700
commit47a2e875bdd2bd25cb8500208940ff1488b01e08 (patch)
tree1efa5ac26dcc85af40e50241392e04bb228434d5 /media/libstagefright/MediaCodec.cpp
parent6ff06612638a13faa85c6219d42a9c4b645003d9 (diff)
downloadframeworks_av-47a2e875bdd2bd25cb8500208940ff1488b01e08.zip
frameworks_av-47a2e875bdd2bd25cb8500208940ff1488b01e08.tar.gz
frameworks_av-47a2e875bdd2bd25cb8500208940ff1488b01e08.tar.bz2
libstagefright: report special error when codec is released by resource manager.
Bug: 19620911 Change-Id: I3403da361adbf2ea6979fcadb0d5ad0889d3513e
Diffstat (limited to 'media/libstagefright/MediaCodec.cpp')
-rw-r--r--media/libstagefright/MediaCodec.cpp56
1 files changed, 44 insertions, 12 deletions
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 44f6542..4080391 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -62,7 +62,7 @@ static int64_t getId(sp<IResourceManagerClient> client) {
}
static bool isResourceError(status_t err) {
- return (err == OMX_ErrorInsufficientResources);
+ return (err == NO_MEMORY);
}
static const int kMaxRetry = 2;
@@ -76,7 +76,7 @@ struct ResourceManagerClient : public BnResourceManagerClient {
// codec is already gone.
return true;
}
- status_t err = codec->release();
+ status_t err = codec->reclaim();
if (err != OK) {
ALOGW("ResourceManagerClient failed to release codec with err %d", err);
}
@@ -336,6 +336,7 @@ sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
MediaCodec::MediaCodec(const sp<ALooper> &looper)
: mState(UNINITIALIZED),
+ mReleasedByResourceManager(false),
mLooper(looper),
mCodec(NULL),
mReplyID(0),
@@ -377,10 +378,15 @@ status_t MediaCodec::PostAndAwaitResponse(
return err;
}
-// static
void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
+ int32_t finalErr = err;
+ if (mReleasedByResourceManager) {
+ // override the err code if MediaCodec has been released by ResourceManager.
+ finalErr = DEAD_OBJECT;
+ }
+
sp<AMessage> response = new AMessage;
- response->setInt32("err", err);
+ response->setInt32("err", finalErr);
response->postReply(replyID);
}
@@ -654,6 +660,14 @@ status_t MediaCodec::stop() {
return PostAndAwaitResponse(msg, &response);
}
+status_t MediaCodec::reclaim() {
+ sp<AMessage> msg = new AMessage(kWhatRelease, this);
+ msg->setInt32("reclaimed", 1);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
status_t MediaCodec::release() {
sp<AMessage> msg = new AMessage(kWhatRelease, this);
@@ -920,6 +934,10 @@ status_t MediaCodec::getBufferAndFormat(
sp<ABuffer> *buffer, sp<AMessage> *format) {
// use mutex instead of a context switch
+ if (mReleasedByResourceManager) {
+ return DEAD_OBJECT;
+ }
+
buffer->clear();
format->clear();
if (!isExecuting()) {
@@ -1009,20 +1027,19 @@ bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool n
}
bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
- sp<AMessage> response = new AMessage;
-
if (!isExecuting() || (mFlags & kFlagIsAsync)
|| (newRequest && (mFlags & kFlagDequeueOutputPending))) {
- response->setInt32("err", INVALID_OPERATION);
+ PostReplyWithError(replyID, INVALID_OPERATION);
} else if (mFlags & kFlagStickyError) {
- response->setInt32("err", getStickyError());
+ PostReplyWithError(replyID, getStickyError());
} else if (mFlags & kFlagOutputBuffersChanged) {
- response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
+ PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
mFlags &= ~kFlagOutputBuffersChanged;
} else if (mFlags & kFlagOutputFormatChanged) {
- response->setInt32("err", INFO_FORMAT_CHANGED);
+ PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
mFlags &= ~kFlagOutputFormatChanged;
} else {
+ sp<AMessage> response = new AMessage;
ssize_t index = dequeuePortBuffer(kPortIndexOutput);
if (index < 0) {
@@ -1057,10 +1074,9 @@ bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool
}
response->setInt32("flags", flags);
+ response->postReply(replyID);
}
- response->postReply(replyID);
-
return true;
}
@@ -1818,6 +1834,20 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
+ // already stopped/released
+ if (mState == UNINITIALIZED && mReleasedByResourceManager) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", OK);
+ response->postReply(replyID);
+ break;
+ }
+
+ int32_t reclaimed = 0;
+ msg->findInt32("reclaimed", &reclaimed);
+ if (reclaimed) {
+ mReleasedByResourceManager = true;
+ }
+
if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
&& mState != INITIALIZED
&& mState != CONFIGURED && !isExecuting()) {
@@ -1831,6 +1861,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
// and it should be in this case, no harm to allow a release()
// if we're already uninitialized.
sp<AMessage> response = new AMessage;
+ // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
+ // the previous stop/release completes and then reply with OK.
status_t err = mState == targetState ? OK : INVALID_OPERATION;
response->setInt32("err", err);
if (err == OK && targetState == UNINITIALIZED) {