OSDN Git Service

IOMX: allow configuration after going to loaded state am: c13904014b am: 99accf6cdc
[android-x86/frameworks-av.git] / media / libstagefright / omx / OMXNodeInstance.cpp
index f39dc82..fa6df84 100644 (file)
@@ -117,12 +117,14 @@ OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
 OMXNodeInstance::OMXNodeInstance(
         OMX *owner, const sp<IOMXObserver> &observer, const char *name)
     : mOwner(owner),
-      mNodeID(NULL),
+      mNodeID(0),
       mHandle(NULL),
       mObserver(observer),
       mDying(false),
       mSailed(false),
-      mQueriedProhibitedExtensions(false) {
+      mQueriedProhibitedExtensions(false),
+      mBufferIDCount(0)
+{
     mUsingMetadata[0] = false;
     mUsingMetadata[1] = false;
     mIsSecure = AString(name).endsWith(".secure");
@@ -175,6 +177,11 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
     static int32_t kMaxNumIterations = 10;
 
+    // exit if we have already freed the node
+    if (mHandle == NULL) {
+        return OK;
+    }
+
     // Transition the node from its current state all the way down
     // to "Loaded".
     // This ensures that all active buffers are properly freed even
@@ -262,7 +269,7 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {
     }
 
     mOwner->invalidateNodeID(mNodeID);
-    mNodeID = NULL;
+    mNodeID = 0;
 
     ALOGV("OMXNodeInstance going away.");
     delete this;
@@ -305,6 +312,7 @@ bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) {
     static const char *restricted_extensions[] = {
         "OMX.google.android.index.storeMetaDataInBuffers",
         "OMX.google.android.index.prepareForAdaptivePlayback",
+        "OMX.google.android.index.configureVideoTunnelMode",
         "OMX.google.android.index.useAndroidNativeBuffer2",
         "OMX.google.android.index.useAndroidNativeBuffer",
         "OMX.google.android.index.enableAndroidNativeBuffers",
@@ -317,8 +325,10 @@ bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) {
             || (index > OMX_IndexVideoStartUnused && index <= OMX_IndexConfigVideoNalSize)
             || (index > OMX_IndexCommonStartUnused
                     && index <= OMX_IndexConfigCommonTransitionEffect)
+            || (index > (OMX_INDEXTYPE)OMX_IndexExtAudioStartUnused
+                    && index <= (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation)
             || (index > (OMX_INDEXTYPE)OMX_IndexExtVideoStartUnused
-                    && index <= (OMX_INDEXTYPE)OMX_IndexConfigVideoVp8ReferenceFrameType)) {
+                    && index <= (OMX_INDEXTYPE)OMX_IndexParamSliceSegments)) {
         return false;
     }
 
@@ -336,7 +346,7 @@ bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) {
 }
 
 status_t OMXNodeInstance::getParameter(
-        OMX_INDEXTYPE index, void *params, size_t size) {
+        OMX_INDEXTYPE index, void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
 
     if (isProhibitedIndex_l(index)) {
@@ -345,12 +355,12 @@ status_t OMXNodeInstance::getParameter(
     }
 
     OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
-
+    ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err);
     return StatusFromOMXError(err);
 }
 
 status_t OMXNodeInstance::setParameter(
-        OMX_INDEXTYPE index, const void *params, size_t size) {
+        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
 
     if (isProhibitedIndex_l(index)) {
@@ -360,12 +370,12 @@ status_t OMXNodeInstance::setParameter(
 
     OMX_ERRORTYPE err = OMX_SetParameter(
             mHandle, index, const_cast<void *>(params));
-
+    ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err);
     return StatusFromOMXError(err);
 }
 
 status_t OMXNodeInstance::getConfig(
-        OMX_INDEXTYPE index, void *params, size_t size) {
+        OMX_INDEXTYPE index, void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
 
     if (isProhibitedIndex_l(index)) {
@@ -378,7 +388,7 @@ status_t OMXNodeInstance::getConfig(
 }
 
 status_t OMXNodeInstance::setConfig(
-        OMX_INDEXTYPE index, const void *params, size_t size) {
+        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
     Mutex::Autolock autoLock(mLock);
 
     if (isProhibitedIndex_l(index)) {
@@ -479,12 +489,16 @@ status_t OMXNodeInstance::storeMetaDataInBuffers(
         OMX_U32 portIndex,
         OMX_BOOL enable) {
     Mutex::Autolock autolock(mLock);
-    return storeMetaDataInBuffers_l(portIndex, enable);
+    return storeMetaDataInBuffers_l(
+            portIndex, enable,
+            OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */);
 }
 
 status_t OMXNodeInstance::storeMetaDataInBuffers_l(
         OMX_U32 portIndex,
-        OMX_BOOL enable) {
+        OMX_BOOL enable,
+        OMX_BOOL useGraphicBuffer,
+        OMX_BOOL *usingGraphicBufferInMetadata) {
     if (mSailed) {
         android_errorWriteLog(0x534e4554, "29422020");
         return INVALID_OPERATION;
@@ -498,10 +512,25 @@ status_t OMXNodeInstance::storeMetaDataInBuffers_l(
     OMX_STRING name = const_cast<OMX_STRING>(
             "OMX.google.android.index.storeMetaDataInBuffers");
 
-    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
+    OMX_STRING graphicBufferName = const_cast<OMX_STRING>(
+            "OMX.google.android.index.storeGraphicBufferInMetaData");
+    if (usingGraphicBufferInMetadata == NULL) {
+        usingGraphicBufferInMetadata = &useGraphicBuffer;
+    }
+
+    OMX_ERRORTYPE err =
+        (useGraphicBuffer && portIndex == kPortIndexInput)
+                ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index)
+                : OMX_ErrorBadParameter;
+    if (err == OMX_ErrorNone) {
+        *usingGraphicBufferInMetadata = OMX_TRUE;
+    } else {
+        *usingGraphicBufferInMetadata = OMX_FALSE;
+        err = OMX_GetExtensionIndex(mHandle, name, &index);
+    }
+
     if (err != OMX_ErrorNone) {
         ALOGE("OMX_GetExtensionIndex %s failed", name);
-
         return StatusFromOMXError(err);
     }
 
@@ -516,6 +545,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers_l(
     params.bStoreMetaData = enable;
     if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
         ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
+        *usingGraphicBufferInMetadata = OMX_FALSE;
         if (enable) {
             mUsingMetadata[portIndex] = false;
         }
@@ -564,6 +594,53 @@ status_t OMXNodeInstance::prepareForAdaptivePlayback(
     return err;
 }
 
+status_t OMXNodeInstance::configureVideoTunnelMode(
+        OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
+        native_handle_t **sidebandHandle) {
+    Mutex::Autolock autolock(mLock);
+    if (mSailed) {
+        android_errorWriteLog(0x534e4554, "29422020");
+        return INVALID_OPERATION;
+    }
+
+    OMX_INDEXTYPE index;
+    OMX_STRING name = const_cast<OMX_STRING>(
+            "OMX.google.android.index.configureVideoTunnelMode");
+
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
+    if (err != OMX_ErrorNone) {
+        ALOGE("configureVideoTunnelMode extension is missing!");
+        return StatusFromOMXError(err);
+    }
+
+    ConfigureVideoTunnelModeParams tunnelParams;
+    tunnelParams.nSize = sizeof(tunnelParams);
+    tunnelParams.nVersion.s.nVersionMajor = 1;
+    tunnelParams.nVersion.s.nVersionMinor = 0;
+    tunnelParams.nVersion.s.nRevision = 0;
+    tunnelParams.nVersion.s.nStep = 0;
+
+    tunnelParams.nPortIndex = portIndex;
+    tunnelParams.bTunneled = tunneled;
+    tunnelParams.nAudioHwSync = audioHwSync;
+    err = OMX_SetParameter(mHandle, index, &tunnelParams);
+    if (err != OMX_ErrorNone) {
+        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
+        return UNKNOWN_ERROR;
+    }
+
+    err = OMX_GetParameter(mHandle, index, &tunnelParams);
+    if (err != OMX_ErrorNone) {
+        ALOGE("GetVideoTunnelWindow failed! (err %d).", err);
+        return UNKNOWN_ERROR;
+    }
+    if (sidebandHandle) {
+        *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
+    }
+
+    return err;
+}
+
 status_t OMXNodeInstance::useBuffer(
         OMX_U32 portIndex, const sp<IMemory> &params,
         OMX::buffer_id *buffer, OMX_BOOL crossProcess) {
@@ -613,7 +690,7 @@ status_t OMXNodeInstance::useBuffer(
 
     CHECK_EQ(header->pAppPrivate, buffer_meta);
 
-    *buffer = header;
+    *buffer = makeBufferID(header);
 
     addActiveBuffer(portIndex, *buffer);
 
@@ -669,7 +746,7 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(
     CHECK_EQ(header->pBuffer, bufferHandle);
     CHECK_EQ(header->pAppPrivate, bufferMeta);
 
-    *buffer = header;
+    *buffer = makeBufferID(header);
 
     addActiveBuffer(portIndex, *buffer);
 
@@ -733,7 +810,7 @@ status_t OMXNodeInstance::useGraphicBuffer(
 
     CHECK_EQ(header->pAppPrivate, bufferMeta);
 
-    *buffer = header;
+    *buffer = makeBufferID(header);
 
     addActiveBuffer(portIndex, *buffer);
 
@@ -745,15 +822,13 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta(
         OMX::buffer_id buffer) {
     Mutex::Autolock autoLock(mLock);
 
-    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)(buffer);
+    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
+    if (header == NULL) {
+        return BAD_VALUE;
+    }
     VideoDecoderOutputMetaData *metadata =
         (VideoDecoderOutputMetaData *)(header->pBuffer);
     BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
-    if (bufferMeta->getPortIndex() != portIndex) {
-        ALOGW("buffer %u has an incorrect port index.", buffer);
-        android_errorWriteLog(0x534e4554, "28816827");
-        return UNKNOWN_ERROR;
-    }
     bufferMeta->setGraphicBuffer(graphicBuffer);
     metadata->eType = kMetadataBufferTypeGrallocSource;
     metadata->pHandle = graphicBuffer->handle;
@@ -781,7 +856,10 @@ status_t OMXNodeInstance::createInputSurface(
     }
 
     // Input buffers will hold meta-data (gralloc references).
-    err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE);
+    OMX_BOOL usingGraphicBuffer = OMX_FALSE;
+    err = storeMetaDataInBuffers_l(
+            portIndex, OMX_TRUE,
+            OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer);
     if (err != OK) {
         return err;
     }
@@ -807,7 +885,7 @@ status_t OMXNodeInstance::createInputSurface(
 
     GraphicBufferSource* bufferSource = new GraphicBufferSource(
             this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
-            def.nBufferCountActual);
+            def.nBufferCountActual, usingGraphicBuffer);
     if ((err = bufferSource->initCheck()) != OK) {
         delete bufferSource;
         return err;
@@ -857,7 +935,7 @@ status_t OMXNodeInstance::allocateBuffer(
 
     CHECK_EQ(header->pAppPrivate, buffer_meta);
 
-    *buffer = header;
+    *buffer = makeBufferID(header);
     *buffer_data = header->pBuffer;
 
     addActiveBuffer(portIndex, *buffer);
@@ -909,7 +987,7 @@ status_t OMXNodeInstance::allocateBufferWithBackup(
     CHECK_EQ(header->pAppPrivate, buffer_meta);
     memset(header->pBuffer, 0, header->nAllocLen);
 
-    *buffer = header;
+    *buffer = makeBufferID(header);
 
     addActiveBuffer(portIndex, *buffer);
 
@@ -927,18 +1005,17 @@ status_t OMXNodeInstance::freeBuffer(
 
     removeActiveBuffer(portIndex, buffer);
 
-    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
-    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
-    if (buffer_meta->getPortIndex() != portIndex) {
-        ALOGW("buffer %u has an incorrect port index.", buffer);
-        android_errorWriteLog(0x534e4554, "28816827");
-        // continue freeing
+    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
+    if (header == NULL) {
+        return BAD_VALUE;
     }
+    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
 
     OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
 
     delete buffer_meta;
     buffer_meta = NULL;
+    invalidateBufferID(buffer);
 
     return StatusFromOMXError(err);
 }
@@ -946,18 +1023,14 @@ status_t OMXNodeInstance::freeBuffer(
 status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
     Mutex::Autolock autoLock(mLock);
 
-    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
+    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput);
+    if (header == NULL) {
+        return BAD_VALUE;
+    }
     header->nFilledLen = 0;
     header->nOffset = 0;
     header->nFlags = 0;
 
-    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
-    if (buffer_meta->getPortIndex() != kPortIndexOutput) {
-        ALOGW("buffer %u has an incorrect port index.", buffer);
-        android_errorWriteLog(0x534e4554, "28816827");
-        return UNKNOWN_ERROR;
-    }
-
     OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
 
     return StatusFromOMXError(err);
@@ -969,14 +1042,13 @@ status_t OMXNodeInstance::emptyBuffer(
         OMX_U32 flags, OMX_TICKS timestamp) {
     Mutex::Autolock autoLock(mLock);
 
-    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
-
     // no emptybuffer if using input surface
     if (getGraphicBufferSource() != NULL) {
         android_errorWriteLog(0x534e4554, "29422020");
         return INVALID_OPERATION;
     }
 
+    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
     // rangeLength and rangeOffset must be a subset of the allocated data in the buffer.
     // corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0.
     if (header == NULL
@@ -991,11 +1063,6 @@ status_t OMXNodeInstance::emptyBuffer(
 
     BufferMeta *buffer_meta =
         static_cast<BufferMeta *>(header->pAppPrivate);
-    if (buffer_meta->getPortIndex() != kPortIndexInput) {
-        ALOGW("buffer %u has an incorrect port index.", buffer);
-        android_errorWriteLog(0x534e4554, "28816827");
-        return UNKNOWN_ERROR;
-    }
     buffer_meta->CopyToOMX(header);
 
     OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
@@ -1042,6 +1109,8 @@ status_t OMXNodeInstance::setInternalOption(
         case IOMX::INTERNAL_OPTION_SUSPEND:
         case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
         case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
+        case IOMX::INTERNAL_OPTION_START_TIME:
+        case IOMX::INTERNAL_OPTION_TIME_LAPSE:
         {
             const sp<GraphicBufferSource> &bufferSource =
                 getGraphicBufferSource();
@@ -1066,7 +1135,8 @@ status_t OMXNodeInstance::setInternalOption(
                 int64_t delayUs = *(int64_t *)data;
 
                 return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
-            } else {
+            } else if (type ==
+                    IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){
                 if (size != sizeof(int64_t)) {
                     return INVALID_OPERATION;
                 }
@@ -1074,6 +1144,20 @@ status_t OMXNodeInstance::setInternalOption(
                 int64_t maxGapUs = *(int64_t *)data;
 
                 return bufferSource->setMaxTimestampGapUs(maxGapUs);
+            } else if (type == IOMX::INTERNAL_OPTION_START_TIME) {
+                if (size != sizeof(int64_t)) {
+                    return INVALID_OPERATION;
+                }
+
+                int64_t skipFramesBeforeUs = *(int64_t *)data;
+
+                bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);
+            } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE
+                if (size != sizeof(int64_t) * 2) {
+                    return INVALID_OPERATION;
+                }
+
+                bufferSource->setTimeLapseUs((int64_t *)data);
             }
 
             return OK;
@@ -1089,17 +1173,15 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
 
     if (msg.type == omx_message::FILL_BUFFER_DONE) {
         OMX_BUFFERHEADERTYPE *buffer =
-            static_cast<OMX_BUFFERHEADERTYPE *>(
-                    msg.u.extended_buffer_data.buffer);
+            findBufferHeader(msg.u.extended_buffer_data.buffer, kPortIndexOutput);
+        if (buffer == NULL) {
+            return;
+        }
 
         BufferMeta *buffer_meta =
             static_cast<BufferMeta *>(buffer->pAppPrivate);
-        if (buffer_meta->getPortIndex() != kPortIndexOutput) {
-            ALOGW("buffer %u has an incorrect port index.", buffer);
-            android_errorWriteLog(0x534e4554, "28816827");
-        } else {
-            buffer_meta->CopyFromOMX(buffer);
-        }
+
+        buffer_meta->CopyFromOMX(buffer);
 
         if (bufferSource != NULL) {
             // fix up the buffer info (especially timestamp) if needed
@@ -1119,8 +1201,10 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
             // be very confused.
 
             OMX_BUFFERHEADERTYPE *buffer =
-                static_cast<OMX_BUFFERHEADERTYPE *>(
-                        msg.u.buffer_data.buffer);
+                findBufferHeader(msg.u.buffer_data.buffer, kPortIndexInput);
+            if (buffer == NULL) {
+                return;
+            }
 
             bufferSource->codecBufferEmptied(buffer);
             return;
@@ -1164,7 +1248,7 @@ void OMXNodeInstance::onEvent(
 
 // static
 OMX_ERRORTYPE OMXNodeInstance::OnEvent(
-        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_HANDLETYPE /* hComponent */,
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_EVENTTYPE eEvent,
         OMX_IN OMX_U32 nData1,
@@ -1180,26 +1264,28 @@ OMX_ERRORTYPE OMXNodeInstance::OnEvent(
 
 // static
 OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
-        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_HANDLETYPE /* hComponent */,
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
     if (instance->mDying) {
         return OMX_ErrorNone;
     }
-    return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
+    return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
+            instance->findBufferID(pBuffer), pBuffer);
 }
 
 // static
 OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
-        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_HANDLETYPE /* hComponent */,
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
     if (instance->mDying) {
         return OMX_ErrorNone;
     }
-    return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
+    return instance->owner()->OnFillBufferDone(instance->nodeID(),
+            instance->findBufferID(pBuffer), pBuffer);
 }
 
 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
@@ -1234,4 +1320,60 @@ void OMXNodeInstance::freeActiveBuffers() {
     }
 }
 
+OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+    if (bufferHeader == NULL) {
+        return 0;
+    }
+    Mutex::Autolock autoLock(mBufferIDLock);
+    OMX::buffer_id buffer;
+    do { // handle the very unlikely case of ID overflow
+        if (++mBufferIDCount == 0) {
+           ++mBufferIDCount;
+        }
+        buffer = (OMX::buffer_id)mBufferIDCount;
+    } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
+    mBufferIDToBufferHeader.add(buffer, bufferHeader);
+    mBufferHeaderToBufferID.add(bufferHeader, buffer);
+    return buffer;
+}
+
+OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(
+        OMX::buffer_id buffer, OMX_U32 portIndex) {
+    if (buffer == 0) {
+        return NULL;
+    }
+    Mutex::Autolock autoLock(mBufferIDLock);
+    ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
+    if (index < 0) {
+        ALOGW("findBufferHeader: buffer %u not found", buffer);
+        return NULL;
+    }
+    OMX_BUFFERHEADERTYPE *header = mBufferIDToBufferHeader.valueAt(index);
+    BufferMeta *buffer_meta =
+        static_cast<BufferMeta *>(header->pAppPrivate);
+    if (buffer_meta->getPortIndex() != portIndex) {
+        ALOGW("findBufferHeader: buffer %u found but with incorrect port index.", buffer);
+        android_errorWriteLog(0x534e4554, "28816827");
+        return NULL;
+    }
+    return header;
+}
+
+OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+    if (bufferHeader == NULL) {
+        return 0;
+    }
+    Mutex::Autolock autoLock(mBufferIDLock);
+    return mBufferHeaderToBufferID.valueFor(bufferHeader);
+}
+
+void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
+    if (buffer == 0) {
+        return;
+    }
+    Mutex::Autolock autoLock(mBufferIDLock);
+    mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer));
+    mBufferIDToBufferHeader.removeItem(buffer);
+}
+
 }  // namespace android