Skip to content

Commit

Permalink
[Decode] Add mutex to protect element in surface heap
Browse files Browse the repository at this point in the history
  • Loading branch information
Jexu committed Apr 18, 2024
1 parent d369ca9 commit 2d8855b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 6 deletions.
4 changes: 4 additions & 0 deletions media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ VAStatus DdiDecode_StatusReport(PDDI_MEDIA_CONTEXT mediaCtx, CodechalDecode *dec
(tempNewReport.m_codecStatus == CODECHAL_STATUS_INCOMPLETE) ||
(tempNewReport.m_codecStatus == CODECHAL_STATUS_RESET))
{
mediaCtx->pSurfaceHeap->lock.lock_shared();
PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;

uint32_t j = 0;
Expand All @@ -422,6 +423,7 @@ VAStatus DdiDecode_StatusReport(PDDI_MEDIA_CONTEXT mediaCtx, CodechalDecode *dec
break;
}
}
mediaCtx->pSurfaceHeap->lock.unlock_shared();
}
else
{
Expand Down Expand Up @@ -488,6 +490,7 @@ VAStatus DdiDecode_StatusReport(PDDI_MEDIA_CONTEXT mediaCtx, DecodePipelineAdapt
(tempNewReport.codecStatus == CODECHAL_STATUS_INCOMPLETE) ||
(tempNewReport.codecStatus == CODECHAL_STATUS_RESET))
{
mediaCtx->pSurfaceHeap->lock.lock_shared();
PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;

uint32_t j = 0;
Expand All @@ -502,6 +505,7 @@ VAStatus DdiDecode_StatusReport(PDDI_MEDIA_CONTEXT mediaCtx, DecodePipelineAdapt
break;
}
}
mediaCtx->pSurfaceHeap->lock.unlock_shared();
}
else
{
Expand Down
31 changes: 27 additions & 4 deletions media_driver/linux/common/ddi/media_libva.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,13 @@ static uint32_t DdiMedia_CreateRenderTarget(
return VA_INVALID_ID;
}

surfaceElement->lock.lock();
surfaceElement->pSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE));
if (nullptr == surfaceElement->pSurface)
{
DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID);
//DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
surfaceElement->lock.unlock();
return VA_INVALID_ID;
}

Expand All @@ -332,11 +334,13 @@ static uint32_t DdiMedia_CreateRenderTarget(
MOS_FreeMemory(surfaceElement->pSurface);
DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID);
//DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
surfaceElement->lock.unlock();
return VA_INVALID_ID;
}

mediaDrvCtx->uiNumSurfaces++;
uint32_t surfaceID = surfaceElement->uiVaSurfaceID;
surfaceElement->lock.unlock();
//DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex);
return surfaceID;
}
Expand Down Expand Up @@ -1342,9 +1346,9 @@ VAStatus DdiMedia_MediaMemoryDecompress(PDDI_MEDIA_CONTEXT mediaCtx, DDI_MEDIA_S
//DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
//DdiMediaUtil_LockMutex(&mediaCtx->MemDecompMutex);

//Note: find surfaceElement from pSurface and surfaceElement->lock.lock_shared();
DdiMedia_MediaSurfaceToMosResource(mediaSurface, &surface);
DdiMedia_MediaMemoryDecompressInternal(&mosCtx, &surface);

//DdiMediaUtil_UnLockMutex(&mediaCtx->MemDecompMutex);
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);

Expand Down Expand Up @@ -2520,7 +2524,9 @@ VAStatus DdiMedia_DestroySurfaces (
for(int32_t i = 0; i < num_surfaces; i++)
{
DDI_CHK_LESS((uint32_t)surfaces[i], mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE);
surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaces[i]);
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMedia_GetSurfaceElementFromVASurfaceID (mediaCtx, surfaces[i]);
DDI_CHK_NULL(surfaceElement, "nullptr surfaceElement", VA_STATUS_ERROR_INVALID_SURFACE);
surface = surfaceElement->pSurface;
DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);
if(surface->pCurrentFrameSemaphore)
{
Expand Down Expand Up @@ -2557,10 +2563,12 @@ VAStatus DdiMedia_DestroySurfaces (
}

//DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
surfaceElement->lock.lock();
DdiMediaUtil_FreeSurface(surface);
MOS_FreeMemory(surface);
DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaCtx->pSurfaceHeap, (uint32_t)surfaces[i]);
mediaCtx->uiNumSurfaces--;
surfaceElement->lock.unlock();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
}

Expand Down Expand Up @@ -3960,16 +3968,20 @@ VAStatus DdiMedia_BeginPicture (
uint32_t event[] = {(uint32_t)context, ctxType, (uint32_t)render_target};
MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0);

PDDI_MEDIA_SURFACE surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMedia_GetSurfaceElementFromVASurfaceID (mediaCtx, render_target);
DDI_CHK_NULL(surfaceElement, "nullptr surfaceElement", VA_STATUS_ERROR_INVALID_SURFACE);
PDDI_MEDIA_SURFACE surface = surfaceElement->pSurface;
DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);

//DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
surfaceElement->lock.lock();
surface->curCtxType = ctxType;
surface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING;
if(ctxType == DDI_MEDIA_CONTEXT_TYPE_VP)
{
surface->curStatusReport.vpp.status = VPREP_NOTAVAILABLE;
}
surfaceElement->lock.unlock();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);

switch (ctxType)
Expand Down Expand Up @@ -4078,7 +4090,10 @@ static VAStatus DdiMedia_StatusCheck (
PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx;
if (decCtx && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
{
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMedia_GetSurfaceElementFromVASurfaceID (mediaCtx, surface_id);
DDI_CHK_NULL(surfaceElement , "nullptr surfaceElement", VA_STATUS_ERROR_INVALID_SURFACE);
//DdiMediaUtil_LockGuard guard(&mediaCtx->SurfaceMutex);
DdiMediaUtil_LockGuard2 guard(&surfaceElement->lock);

Codechal *codecHal = decCtx->pCodecHal;
//return success just avoid vaDestroyContext is ahead of vaSyncSurface
Expand Down Expand Up @@ -4407,7 +4422,9 @@ VAStatus DdiMedia_QuerySurfaceError(
PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
DDI_CHK_NULL( mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);

DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target);
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMedia_GetSurfaceElementFromVASurfaceID (mediaCtx, render_target);
DDI_CHK_NULL(surfaceElement, "nullptr surfaceElement", VA_STATUS_ERROR_INVALID_SURFACE);
DDI_MEDIA_SURFACE *surface = surfaceElement->pSurface;
DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE);

PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx;
Expand All @@ -4419,6 +4436,7 @@ VAStatus DdiMedia_QuerySurfaceError(
VAStatus vaStatus = VA_STATUS_SUCCESS;

//DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
surfaceElement->lock.lock_shared();
if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED)
{
if (error_status != -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER)
Expand All @@ -4437,6 +4455,7 @@ VAStatus DdiMedia_QuerySurfaceError(
surfaceErrors[0].decode_error_type = VADecodeMBError;
#endif
*error_info = surfaceErrors;
surfaceElement->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
return VA_STATUS_SUCCESS;
}
Expand All @@ -4449,6 +4468,7 @@ VAStatus DdiMedia_QuerySurfaceError(
surfaceErrors[0].status = 1;
surfaceErrors[0].decode_error_type = VADecodeReset;
*error_info = surfaceErrors;
surfaceElement->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
return VA_STATUS_SUCCESS;
}
Expand Down Expand Up @@ -4477,19 +4497,22 @@ VAStatus DdiMedia_QuerySurfaceError(
}
}

surfaceElement->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
return vaStatus;
}

if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP &&
surface->curStatusReport.vpp.status == CODECHAL_STATUS_ERROR)
{
surfaceElement->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
return VA_STATUS_SUCCESS;
}
}

surfaceErrors[0].status = -1;
surfaceElement->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
return VA_STATUS_SUCCESS;
}
Expand Down
17 changes: 15 additions & 2 deletions media_driver/linux/common/ddi/media_libva_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void* DdiMedia_GetContextFromContextID (VADriverContextP ctx, VAContextID vaCtxI

}

DDI_MEDIA_SURFACE* DdiMedia_GetSurfaceFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID)
PDDI_MEDIA_SURFACE_HEAP_ELEMENT DdiMedia_GetSurfaceElementFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID)
{
uint32_t i = 0;
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = nullptr;
Expand All @@ -147,27 +147,40 @@ DDI_MEDIA_SURFACE* DdiMedia_GetSurfaceFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaC
//DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex);
surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)mediaCtx->pSurfaceHeap->pHeapBase;
surfaceElement += i;
surface = surfaceElement->pSurface;
mediaCtx->pSurfaceHeap->lock.unlock_shared();
//DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex);
}

return surfaceElement;
}

DDI_MEDIA_SURFACE* DdiMedia_GetSurfaceFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID)
{
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = nullptr;
PDDI_MEDIA_SURFACE surface = nullptr;

surfaceElement = DdiMedia_GetSurfaceElementFromVASurfaceID(mediaCtx, surfaceID);
surface = surfaceElement != nullptr ? surfaceElement->pSurface : nullptr;

return surface;
}

VASurfaceID DdiMedia_GetVASurfaceIDFromSurface(PDDI_MEDIA_SURFACE surface)
{
DDI_CHK_NULL(surface, "nullptr surface", VA_INVALID_SURFACE);

surface->pMediaCtx->pSurfaceHeap->lock.lock_shared();
PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surface->pMediaCtx->pSurfaceHeap->pHeapBase;
for(uint32_t i = 0; i < surface->pMediaCtx->pSurfaceHeap->uiAllocatedHeapElements; i ++)
{
if(surface == surfaceElement->pSurface)
{
surface->pMediaCtx->pSurfaceHeap->lock.unlock_shared();
return surfaceElement->uiVaSurfaceID;
}
surfaceElement ++;
}
surface->pMediaCtx->pSurfaceHeap->lock.unlock_shared();
return VA_INVALID_SURFACE;
}

Expand Down
13 changes: 13 additions & 0 deletions media_driver/linux/common/ddi/media_libva_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ void DdiMedia_MediaBufferToMosResource(DDI_MEDIA_BUFFER *mediaBuffer, MOS_RESOUR
//!
void* DdiMedia_GetContextFromContextID (VADriverContextP ctx, VAContextID vaCtxID, uint32_t *ctxType);

//!
//! \brief Get surface element from VA surface ID
//!
//! \param [in] mediaCtx
//! Pointer to ddi media context
//! \param [in] surfaceID
//! VA surface ID
//!
//! \return PDDI_MEDIA_SURFACE_HEAP_ELEMENT
//! Pointer to ddi media surface element
//!
PDDI_MEDIA_SURFACE_HEAP_ELEMENT DdiMedia_GetSurfaceElementFromVASurfaceID (PDDI_MEDIA_CONTEXT mediaCtx, VASurfaceID surfaceID);

//!
//! \brief Get surface from VA surface ID
//!
Expand Down
14 changes: 14 additions & 0 deletions media_driver/linux/common/ddi/media_libva_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@ class DdiMediaUtil_LockGuard {
}
};

class DdiMediaUtil_LockGuard2 {
private:
std::shared_timed_mutex *m_pLock;
public:
DdiMediaUtil_LockGuard2(std::shared_timed_mutex *pLock):m_pLock(pLock)
{
m_pLock->lock();
}
~DdiMediaUtil_LockGuard2()
{
m_pLock->unlock();
}
};

//!
//! \brief Destroy semaphore
//!
Expand Down
2 changes: 2 additions & 0 deletions media_softlet/linux/common/ddi/media_libva_common_next.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ typedef struct _DDI_MEDIA_SURFACE_HEAP_ELEMENT
PDDI_MEDIA_SURFACE pSurface;
uint32_t uiVaSurfaceID;
struct _DDI_MEDIA_SURFACE_HEAP_ELEMENT *pNextFree;
std::shared_timed_mutex lock;
}DDI_MEDIA_SURFACE_HEAP_ELEMENT, *PDDI_MEDIA_SURFACE_HEAP_ELEMENT;

typedef struct _DDI_MEDIA_BUFFER_HEAP_ELEMENT
Expand All @@ -307,6 +308,7 @@ typedef struct _DDI_MEDIA_BUFFER_HEAP_ELEMENT
uint32_t uiCtxType;
uint32_t uiVaBufferID;
struct _DDI_MEDIA_BUFFER_HEAP_ELEMENT *pNextFree;
std::shared_timed_mutex lock;
}DDI_MEDIA_BUFFER_HEAP_ELEMENT, *PDDI_MEDIA_BUFFER_HEAP_ELEMENT;

typedef struct _DDI_MEDIA_IMAGE_HEAP_ELEMENT
Expand Down

0 comments on commit 2d8855b

Please sign in to comment.