[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