OSDN Git Service

DO NOT MERGE
authorJames Dong <jdong@google.com>
Wed, 3 Nov 2010 01:43:03 +0000 (18:43 -0700)
committerJames Dong <jdong@google.com>
Wed, 3 Nov 2010 02:30:01 +0000 (19:30 -0700)
Fix premature release of recording frames when physical address or metadata is stored in input video buffers

- bug 3158459

Change-Id: If297189d2a87fc3abfda68c29ac75b490b30a902

include/media/stagefright/OMXCodec.h
media/libstagefright/OMXCodec.cpp

index 1d94160..fed6761 100644 (file)
@@ -109,6 +109,7 @@ private:
         kAvoidMemcopyInputRecordingFrames     = 2048,
         kRequiresLargerEncoderOutputBuffer    = 4096,
         kOutputBuffersAreUnreadable           = 8192,
+        kStoreMetaDataInInputVideoBuffers     = 16384,
     };
 
     struct BufferInfo {
index 9a49a9b..980da77 100644 (file)
@@ -412,6 +412,13 @@ uint32_t OMXCodec::getComponentQuirks(
         quirks |= kOutputBuffersAreUnreadable;
     }
 
+    if (!strncmp(componentName, "OMX.SEC.", 8) && isEncoder) {
+        // These input buffers contain meta data (for instance,
+        // information helps locate the actual YUV data, or
+        // the physical address of the YUV data).
+        quirks |= kStoreMetaDataInInputVideoBuffers;
+    }
+
     return quirks;
 }
 
@@ -1695,7 +1702,15 @@ void OMXCodec::on_message(const omx_message &msg) {
                      "an EMPTY_BUFFER_DONE.", buffer);
             }
 
-            buffers->editItemAt(i).mOwnedByComponent = false;
+            {
+                BufferInfo *info = &buffers->editItemAt(i);
+                info->mOwnedByComponent = false;
+                if (info->mMediaBuffer != NULL) {
+                    // It is time to release the media buffers storing meta data
+                    info->mMediaBuffer->release();
+                    info->mMediaBuffer = NULL;
+                }
+            }
 
             if (mPortStatus[kPortIndexInput] == DISABLING) {
                 CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
@@ -2202,6 +2217,7 @@ status_t OMXCodec::freeBuffersOnPort(
             CHECK_EQ(info->mMediaBuffer->refcount(), 0);
 
             info->mMediaBuffer->release();
+            info->mMediaBuffer = NULL;
         }
 
         buffers->removeAt(i);
@@ -2434,11 +2450,19 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
             break;
         }
 
+        // Do not release the media buffer if it stores meta data
+        // instead of YUV data. The release is delayed until
+        // EMPTY_BUFFER_DONE callback is received.
+        bool releaseBuffer = true;
         if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
             CHECK(mOMXLivesLocally && offset == 0);
             OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *) info->mBuffer;
             header->pBuffer = (OMX_U8 *) srcBuffer->data() + srcBuffer->range_offset();
         } else {
+            if (mQuirks & kStoreMetaDataInInputVideoBuffers) {
+                releaseBuffer = false;
+                info->mMediaBuffer = srcBuffer;
+            }
             memcpy((uint8_t *)info->mData + offset,
                     (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
                     srcBuffer->range_length());
@@ -2454,8 +2478,10 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
 
         offset += srcBuffer->range_length();
 
-        srcBuffer->release();
-        srcBuffer = NULL;
+        if (releaseBuffer) {
+            srcBuffer->release();
+            srcBuffer = NULL;
+        }
 
         ++n;