MediaBuffer: ABuffer will release MediaBuffer when it's destructed.

Bug: 17454455
Change-Id: Ia423bcc2e1fa39137f114eac44912ed15357bb99
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 511871d..a0870fd 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1097,8 +1097,8 @@
     if (mIsWidevine && !audio) {
         // data is already provided in the buffer
         ab = new ABuffer(NULL, mb->range_length());
-        ab->meta()->setPointer("mediaBuffer", mb);
         mb->add_ref();
+        ab->setMediaBufferBase(mb);
     } else {
         ab = new ABuffer(outLength);
         memcpy(ab->data(),
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 87f85e7..601cd40 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -283,14 +283,9 @@
 
     // handle widevine classic source - that fills an arbitrary input buffer
     MediaBuffer *mediaBuffer = NULL;
-    if (hasBuffer && buffer->meta()->findPointer(
-            "mediaBuffer", (void **)&mediaBuffer)) {
-        if (mediaBuffer == NULL) {
-            // received no actual buffer
-            ALOGW("[%s] received null MediaBuffer %s",
-                    mComponentName.c_str(), msg->debugString().c_str());
-            buffer = NULL;
-        } else {
+    if (hasBuffer) {
+        mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase());
+        if (mediaBuffer != NULL) {
             // likely filled another buffer than we requested: adjust buffer index
             size_t ix;
             for (ix = 0; ix < mInputBuffers.size(); ix++) {
@@ -598,16 +593,6 @@
         {
             if (!isStaleReply(msg)) {
                 onInputBufferFilled(msg);
-            } else {
-                /* release any MediaBuffer passed in the stale buffer */
-                sp<ABuffer> buffer;
-                MediaBuffer *mediaBuffer = NULL;
-                if (msg->findBuffer("buffer", &buffer) &&
-                    buffer->meta()->findPointer(
-                            "mediaBuffer", (void **)&mediaBuffer) &&
-                    mediaBuffer != NULL) {
-                    mediaBuffer->release();
-                }
             }
 
             break;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9b03b71..3c04859 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3782,23 +3782,12 @@
     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
     info->mStatus = BufferInfo::OWNED_BY_US;
 
-    const sp<AMessage> &bufferMeta = info->mData->meta();
-    void *mediaBuffer;
-    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
-            && mediaBuffer != NULL) {
-        // We're in "store-metadata-in-buffers" mode, the underlying
-        // OMX component had access to data that's implicitly refcounted
-        // by this "mediaBuffer" object. Now that the OMX component has
-        // told us that it's done with the input buffer, we can decrement
-        // the mediaBuffer's reference count.
-
-        ALOGV("releasing mbuf %p", mediaBuffer);
-
-        ((MediaBuffer *)mediaBuffer)->release();
-        mediaBuffer = NULL;
-
-        bufferMeta->setPointer("mediaBuffer", NULL);
-    }
+    // We're in "store-metadata-in-buffers" mode, the underlying
+    // OMX component had access to data that's implicitly refcounted
+    // by this "MediaBuffer" object. Now that the OMX component has
+    // told us that it's done with the input buffer, we can decrement
+    // the mediaBuffer's reference count.
+    info->mData->setMediaBufferBase(NULL);
 
     PortMode mode = getPortMode(kPortIndexInput);
 
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 1a80dcc..27cd231 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -37,19 +37,6 @@
 
 namespace android {
 
-static void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) {
-    void *mbuf;
-    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
-            && mbuf != NULL) {
-        ALOGV("releasing mbuf %p", mbuf);
-
-        accessUnit->meta()->setPointer("mediaBuffer", NULL);
-
-        static_cast<MediaBuffer *>(mbuf)->release();
-        mbuf = NULL;
-    }
-}
-
 struct MediaCodecSource::Puller : public AHandler {
     Puller(const sp<MediaSource> &source);
 
@@ -477,7 +464,7 @@
 
     for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) {
         sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i);
-        ReleaseMediaBufferReference(accessUnit);
+        accessUnit->setMediaBufferBase(NULL);
     }
 
     mEncoderInputBuffers.clear();
@@ -608,8 +595,8 @@
             if (mIsVideo) {
                 // video encoder will release MediaBuffer when done
                 // with underlying data.
-                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
-                        ->setPointer("mediaBuffer", mbuf);
+                mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase(
+                        mbuf);
             } else {
                 mbuf->release();
             }
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/libstagefright/foundation/ABuffer.cpp
index c93c7e8..b214870 100644
--- a/media/libstagefright/foundation/ABuffer.cpp
+++ b/media/libstagefright/foundation/ABuffer.cpp
@@ -19,11 +19,13 @@
 #include "ADebug.h"
 #include "ALooper.h"
 #include "AMessage.h"
+#include "MediaBufferBase.h"
 
 namespace android {
 
 ABuffer::ABuffer(size_t capacity)
-    : mData(malloc(capacity)),
+    : mMediaBufferBase(NULL),
+      mData(malloc(capacity)),
       mCapacity(capacity),
       mRangeOffset(0),
       mRangeLength(capacity),
@@ -32,7 +34,8 @@
 }
 
 ABuffer::ABuffer(void *data, size_t capacity)
-    : mData(data),
+    : mMediaBufferBase(NULL),
+      mData(data),
       mCapacity(capacity),
       mRangeOffset(0),
       mRangeLength(capacity),
@@ -59,6 +62,8 @@
     if (mFarewell != NULL) {
         mFarewell->post();
     }
+
+    setMediaBufferBase(NULL);
 }
 
 void ABuffer::setRange(size_t offset, size_t size) {
@@ -80,5 +85,19 @@
     return mMeta;
 }
 
+MediaBufferBase *ABuffer::getMediaBufferBase() {
+    if (mMediaBufferBase != NULL) {
+        mMediaBufferBase->add_ref();
+    }
+    return mMediaBufferBase;
+}
+
+void ABuffer::setMediaBufferBase(MediaBufferBase *mediaBuffer) {
+    if (mMediaBufferBase != NULL) {
+        mMediaBufferBase->release();
+    }
+    mMediaBufferBase = mediaBuffer;
+}
+
 }  // namespace android
 
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index c74c3e7..a03f6f9 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -254,11 +254,6 @@
             int32_t oldDiscontinuityType;
             if (!oldBuffer->meta()->findInt32(
                         "discontinuity", &oldDiscontinuityType)) {
-                MediaBuffer *mbuf = NULL;
-                oldBuffer->meta()->findPointer("mediaBuffer", (void**)&mbuf);
-                if (mbuf != NULL) {
-                    mbuf->release();
-                }
                 it = mBuffers.erase(it);
                 continue;
             }
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index 753b3ec..2834a66 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -74,19 +74,6 @@
     }
 }
 
-static void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) {
-    void *mbuf;
-    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
-            && mbuf != NULL) {
-        ALOGV("releasing mbuf %p", mbuf);
-
-        accessUnit->meta()->setPointer("mediaBuffer", NULL);
-
-        static_cast<MediaBuffer *>(mbuf)->release();
-        mbuf = NULL;
-    }
-}
-
 void Converter::releaseEncoder() {
     if (mEncoder == NULL) {
         return;
@@ -95,18 +82,7 @@
     mEncoder->release();
     mEncoder.clear();
 
-    while (!mInputBufferQueue.empty()) {
-        sp<ABuffer> accessUnit = *mInputBufferQueue.begin();
-        mInputBufferQueue.erase(mInputBufferQueue.begin());
-
-        ReleaseMediaBufferReference(accessUnit);
-    }
-
-    for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) {
-        sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i);
-        ReleaseMediaBufferReference(accessUnit);
-    }
-
+    mInputBufferQueue.clear();
     mEncoderInputBuffers.clear();
     mEncoderOutputBuffers.clear();
 }
@@ -328,7 +304,7 @@
                     sp<ABuffer> accessUnit;
                     CHECK(msg->findBuffer("accessUnit", &accessUnit));
 
-                    ReleaseMediaBufferReference(accessUnit);
+                    accessUnit->setMediaBufferBase(NULL);
                 }
                 break;
             }
@@ -351,15 +327,16 @@
                         ALOGI("dropping frame.");
                     }
 
-                    ReleaseMediaBufferReference(accessUnit);
+                    accessUnit->setMediaBufferBase(NULL);
                     break;
                 }
 
 #if 0
-                void *mbuf;
-                if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
-                        && mbuf != NULL) {
+                MediaBuffer *mbuf =
+                    (MediaBuffer *)(accessUnit->getMediaBufferBase());
+                if (mbuf != NULL) {
                     ALOGI("queueing mbuf %p", mbuf);
+                    mbuf->release();
                 }
 #endif
 
@@ -647,13 +624,13 @@
                    buffer->data(),
                    buffer->size());
 
-            void *mediaBuffer;
-            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
-                    && mediaBuffer != NULL) {
-                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
-                    ->setPointer("mediaBuffer", mediaBuffer);
+            MediaBuffer *mediaBuffer =
+                (MediaBuffer *)(buffer->getMediaBufferBase());
+            if (mediaBuffer != NULL) {
+                mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase(
+                        mediaBuffer);
 
-                buffer->meta()->setPointer("mediaBuffer", NULL);
+                buffer->setMediaBufferBase(NULL);
             }
         } else {
             flags = MediaCodec::BUFFER_FLAG_EOS;
diff --git a/media/libstagefright/wifi-display/source/MediaPuller.cpp b/media/libstagefright/wifi-display/source/MediaPuller.cpp
index 7e8891d..86b918f 100644
--- a/media/libstagefright/wifi-display/source/MediaPuller.cpp
+++ b/media/libstagefright/wifi-display/source/MediaPuller.cpp
@@ -179,7 +179,7 @@
                 } else {
                     // video encoder will release MediaBuffer when done
                     // with underlying data.
-                    accessUnit->meta()->setPointer("mediaBuffer", mbuf);
+                    accessUnit->setMediaBufferBase(mbuf);
                 }
 
                 sp<AMessage> notify = mNotify->dup();