[Decode] release decode context buffer when destroy decode context
Decode context buffer is binded to decode context, should be release before
destroy decode context. Currently it is deleted when vaterminate.
diff --git a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
index 45f5178..1a2f25a 100644
--- a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
+++ b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
@@ -621,6 +621,78 @@
return va;
}
+
+//!
+//! \brief Get ctx from VA buffer ID
+//!
+//! \param [in] mediaCtx
+//! pddi media context
+//! \param [in] bufferID
+//! VA Buffer ID
+//!
+//! \return void*
+//! Pointer to buffer heap element context
+//!
+static void* DdiMedia_GetDecCtxFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID)
+{
+ DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr);
+
+ uint32_t i = (uint32_t)bufferID;
+ DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr);
+ DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex);
+ PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase;
+ bufHeapElement += i;
+ void *temp = bufHeapElement->pCtx;
+ DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex);
+
+ return temp;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//! \Free allocated bufferheap elements
+//! \params
+//! [in] VADriverContextP
+//! [out] none
+//! \returns
+/////////////////////////////////////////////////////////////////////////////
+static void DdiMedia_FreeBufferHeapElements(VADriverContextP ctx, PDDI_DECODE_CONTEXT decCtx)
+{
+ PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
+ if (nullptr == mediaCtx)
+ return;
+
+ PDDI_MEDIA_HEAP bufferHeap = mediaCtx->pBufferHeap;
+ if (nullptr == bufferHeap)
+ return;
+
+ PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase;
+ if (nullptr == mediaBufferHeapBase)
+ return;
+
+ int32_t bufNums = mediaCtx->uiNumBufs;
+ for (int32_t elementId = 0; bufNums > 0; ++elementId)
+ {
+ PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = &mediaBufferHeapBase[elementId];
+ if (nullptr == mediaBufferHeapElmt->pBuffer)
+ continue;
+
+ void *pDecContext =DdiMedia_GetDecCtxFromVABufferID(mediaCtx, mediaBufferHeapElmt->uiVaBufferID);
+ if(pDecContext == decCtx)
+ {
+ DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, mediaBufferHeapElmt->uiVaBufferID);
+ if(buf->uiType == VASliceDataBufferType ||
+ buf->uiType == VAProtectedSliceDataBufferType ||
+ buf->uiType == VASliceParameterBufferType)
+ {
+ DdiMedia_DestroyBuffer(ctx, mediaBufferHeapElmt->uiVaBufferID);
+ }
+ }
+ //Ensure the non-empty buffer to be destroyed.
+ --bufNums;
+ }
+}
+
VAStatus DdiDecode_DestroyContext (
VADriverContextP ctx,
VAContextID context
@@ -640,6 +712,8 @@
mediaCtx->uiNumDecoders--;
DdiMediaUtil_UnLockMutex(&mediaCtx->DecoderMutex);
+ DdiMedia_FreeBufferHeapElements(ctx, decCtx);
+
if (decCtx->m_ddiDecode) {
DdiDecodeCleanUp(ctx,decCtx);
return VA_STATUS_SUCCESS;
diff --git a/media_driver/linux/common/ddi/media_libva.cpp b/media_driver/linux/common/ddi/media_libva.cpp
index 59d2776..1cdc576 100755
--- a/media_driver/linux/common/ddi/media_libva.cpp
+++ b/media_driver/linux/common/ddi/media_libva.cpp
@@ -117,22 +117,6 @@
VABufferID buf_id /* in */
);
-//!
-//! \brief Destroy buffer
-//!
-//! \param [in] ctx
-//! Pointer to VA driver context
-//! \param [in] buffer_id
-//! VA buffer ID
-//!
-//! \return VAStatus
-//! VA_STATUS_SUCCESS if success, else fail reason
-//!
-VAStatus DdiMedia_DestroyBuffer (
- VADriverContextP ctx,
- VABufferID buffer_id
-);
-
VAStatus DdiMedia_DestroyImage (
VADriverContextP ctx,
VAImageID image
diff --git a/media_driver/linux/common/ddi/media_libva.h b/media_driver/linux/common/ddi/media_libva.h
index 42cf322..e0c74a5 100755
--- a/media_driver/linux/common/ddi/media_libva.h
+++ b/media_driver/linux/common/ddi/media_libva.h
@@ -343,6 +343,24 @@
VABufferID buf_id
);
+
+//!
+//! \brief Destroy buffer
+//!
+//! \param [in] ctx
+//! Pointer to VA driver context
+//! \param [in] buffer_id
+//! VA buffer ID
+//!
+//! \return VAStatus
+//! VA_STATUS_SUCCESS if success, else fail reason
+//!
+VAStatus DdiMedia_DestroyBuffer (
+ VADriverContextP ctx,
+ VABufferID buffer_id
+);
+
+
#ifdef __cplusplus
extern "C" {
#endif