diff options
author | Ronghua Wu <ronghuawu@google.com> | 2015-10-13 21:20:27 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-10-13 21:20:27 +0000 |
commit | e5200ea76c5d180b53087ae7825326ec61cc4687 (patch) | |
tree | d18a0e7d46858f79d0009f2ae29faa14be40c65c | |
parent | c4c68f63192ae7af09a6158b2e72ca7a1a7f4364 (diff) | |
parent | 4b710f086070fabe022b3a1f474bfcbec842b8fc (diff) | |
download | frameworks_av-e5200ea76c5d180b53087ae7825326ec61cc4687.zip frameworks_av-e5200ea76c5d180b53087ae7825326ec61cc4687.tar.gz frameworks_av-e5200ea76c5d180b53087ae7825326ec61cc4687.tar.bz2 |
Merge "libstagefright: don't reclaim codec when there's buffer owned by client. Notify the client and try to reclaim again in 0.5s." into mnc-dr-dev
-rw-r--r-- | include/media/stagefright/MediaCodec.h | 5 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 42 |
2 files changed, 45 insertions, 2 deletions
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index c10963d..cdfa159 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -176,7 +176,7 @@ protected: private: // used by ResourceManagerClient - status_t reclaim(); + status_t reclaim(bool force = false); friend struct ResourceManagerClient; private: @@ -385,6 +385,9 @@ private: uint64_t getGraphicBufferSize(); void addResource(const String8 &type, const String8 &subtype, uint64_t value); + bool hasPendingBuffer(int portIndex); + bool hasPendingBuffer(); + /* called to get the last codec error when the sticky flag is set. * if no such codec error is found, returns UNKNOWN_ERROR. */ diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 7019537..dc6009b 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -63,6 +63,7 @@ static bool isResourceError(status_t err) { } static const int kMaxRetry = 2; +static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s struct ResourceManagerClient : public BnResourceManagerClient { ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} @@ -74,6 +75,12 @@ struct ResourceManagerClient : public BnResourceManagerClient { return true; } status_t err = codec->reclaim(); + if (err == WOULD_BLOCK) { + ALOGD("Wait for the client to release codec."); + usleep(kMaxReclaimWaitTimeInUs); + ALOGD("Try to reclaim again."); + err = codec->reclaim(true /* force */); + } if (err != OK) { ALOGW("ResourceManagerClient failed to release codec with err %d", err); } @@ -571,10 +578,26 @@ status_t MediaCodec::stop() { return PostAndAwaitResponse(msg, &response); } -status_t MediaCodec::reclaim() { +bool MediaCodec::hasPendingBuffer(int portIndex) { + const Vector<BufferInfo> &buffers = mPortBuffers[portIndex]; + for (size_t i = 0; i < buffers.size(); ++i) { + const BufferInfo &info = buffers.itemAt(i); + if (info.mOwnedByClient) { + return true; + } + } + return false; +} + +bool MediaCodec::hasPendingBuffer() { + return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput); +} + +status_t MediaCodec::reclaim(bool force) { ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str()); sp<AMessage> msg = new AMessage(kWhatRelease, this); msg->setInt32("reclaimed", 1); + msg->setInt32("force", force ? 1 : 0); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); @@ -1787,6 +1810,23 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { msg->findInt32("reclaimed", &reclaimed); if (reclaimed) { mReleasedByResourceManager = true; + + int32_t force = 0; + msg->findInt32("force", &force); + if (!force && hasPendingBuffer()) { + ALOGW("Can't reclaim codec right now due to pending buffers."); + + // return WOULD_BLOCK to ask resource manager to retry later. + sp<AMessage> response = new AMessage; + response->setInt32("err", WOULD_BLOCK); + response->postReply(replyID); + + // notify the async client + if (mFlags & kFlagIsAsync) { + onError(DEAD_OBJECT, ACTION_CODE_FATAL); + } + break; + } } if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 |