From 3b1c2e30b8c73bb51c3e2c93504e3571ab851268 Mon Sep 17 00:00:00 2001 From: SeungBeom Kim Date: Wed, 31 Jul 2013 13:46:35 +0900 Subject: [PATCH] exynos_omx: multi_thread: Add dynamic DPB change scheme. - Decode output port supported StoreMetaDataBuffer. - Dynamic DPB change supported. Change-Id: If23a5eb5cc6fef3781c4a45fb06fe7eab41b1b5b Signed-off-by: SeungBeom Kim Bug: 10192533 --- .../mfc_v4l2/dec/src/ExynosVideoDecoder.c | 366 +++++++++++++++++- .../mfc_v4l2/enc/src/ExynosVideoEncoder.c | 46 ++- .../exynos5/mfc_v4l2/include/ExynosVideoApi.h | 18 + .../exynos5/mfc_v4l2/include/ExynosVideoDec.h | 4 + .../component/common/Exynos_OMX_Baseport.h | 2 +- .../exynos_omx/component/video/dec/Android.mk | 4 + .../component/video/dec/Exynos_OMX_Vdec.c | 67 +++- .../component/video/dec/Exynos_OMX_Vdec.h | 4 + .../video/dec/Exynos_OMX_VdecControl.c | 54 ++- .../component/video/dec/h264/Android.mk | 3 +- .../video/dec/h264/Exynos_OMX_H264dec.c | 108 +++--- .../component/video/dec/mpeg4/Android.mk | 3 +- .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 110 +++--- .../component/video/dec/vp8/Android.mk | 3 +- .../video/dec/vp8/Exynos_OMX_Vp8dec.c | 112 +++--- .../component/video/enc/Exynos_OMX_Venc.c | 6 +- .../component/video/enc/h264/Android.mk | 3 +- .../component/video/enc/mpeg4/Android.mk | 3 +- .../include/exynos/Exynos_OMX_Def.h | 1 + exynos_omx/openmax/exynos_omx/osal/Android.mk | 1 + .../exynos_omx/osal/Exynos_OSAL_Android.cpp | 302 ++++++++++++++- .../exynos_omx/osal/Exynos_OSAL_Android.h | 27 ++ 22 files changed, 1042 insertions(+), 205 deletions(-) diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c index abf7ae7..12275ee 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/dec/src/ExynosVideoDecoder.c @@ -38,6 +38,7 @@ #include +#include "ion.h" #include "ExynosVideoApi.h" #include "ExynosVideoDec.h" #include "OMX_Core.h" @@ -46,6 +47,8 @@ #define LOG_TAG "ExynosVideoDecoder" #include +#define MAX_OUTPUTBUFFER_COUNT 32 + /* * [Common] __CodingType_To_V4L2PixelFormat */ @@ -161,6 +164,13 @@ static void *MFC_Decoder_Init(int nMemoryType) } pCtx->pOutMutex = (void*)pMutex; + pCtx->hIONHandle = (void*)ion_client_create(); + pCtx->nPrivateDataShareFD = ion_alloc((ion_client)pCtx->hIONHandle, + sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED); + pCtx->nPrivateDataShareAddress = + ion_map(pCtx->nPrivateDataShareFD, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM, 0); + memset(pCtx->nPrivateDataShareAddress, -1, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM); + return (void *)pCtx; EXIT_QUERYCAP_FAIL: @@ -200,6 +210,10 @@ static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle) goto EXIT; } + ion_unmap(pCtx->nPrivateDataShareAddress, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM); + ion_free(pCtx->nPrivateDataShareFD); + ion_client_destroy((ion_client)pCtx->hIONHandle); + if (pCtx->pOutMutex != NULL) { pMutex = (pthread_mutex_t*)pCtx->pOutMutex; pthread_mutex_destroy(pMutex); @@ -955,9 +969,8 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( } if (nBufferCount == 0) { - ALOGE("%s: Buffer count must be greater than 0", __func__); - ret = VIDEO_ERROR_BADPARAM; - goto EXIT; + nBufferCount = MAX_OUTPUTBUFFER_COUNT; + ALOGV("%s: Change buffer count %d", __func__, nBufferCount); } ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount, @@ -1025,8 +1038,10 @@ static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( } pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry; - pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; - pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bSlotUsed = VIDEO_FALSE; + pCtx->pOutbuf[i].nIndexUseCnt = 0; + pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE; } } @@ -1165,7 +1180,9 @@ static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle) } for (i = 0; i < pCtx->nOutbufs; i++) { - pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; + pCtx->pOutbuf[i].bSlotUsed = VIDEO_FALSE; + pCtx->pOutbuf[i].nIndexUseCnt = 0; } EXIT: @@ -1442,7 +1459,6 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( buf.index = index; pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; - pthread_mutex_unlock(pMutex); if (pCtx->bShareInbuf == VIDEO_TRUE) { buf.memory = pCtx->nMemoryType; @@ -1472,15 +1488,20 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( !!(buf.flags & V4L2_BUF_FLAG_LAST_FRAME)); } + pCtx->pInbuf[buf.index].pPrivate = pPrivate; + + pthread_mutex_unlock(pMutex); + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); - pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_lock(pMutex); + pCtx->pInbuf[buf.index].pPrivate = NULL; + pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - pCtx->pInbuf[buf.index].pPrivate = pPrivate; - EXIT: return ret; } @@ -1532,7 +1553,6 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf( } buf.index = index; pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; - pthread_mutex_unlock(pMutex); if (pCtx->bShareOutbuf == VIDEO_TRUE) { buf.memory = pCtx->nMemoryType; @@ -1555,15 +1575,20 @@ static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf( buf.memory = V4L2_MEMORY_MMAP; } + pCtx->pOutbuf[buf.index].pPrivate = pPrivate; + + pthread_mutex_unlock(pMutex); + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { ALOGE("%s: Failed to enqueue output buffer", __func__); - pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_lock(pMutex); + pCtx->pOutbuf[buf.index].pPrivate = NULL; + pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - pCtx->pOutbuf[buf.index].pPrivate = pPrivate; - EXIT: return ret; } @@ -1575,6 +1600,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle) { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoBuffer *pInbuf = NULL; + pthread_mutex_t *pMutex = NULL; struct v4l2_buffer buf; @@ -1602,12 +1628,17 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle) goto EXIT; } + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_lock(pMutex); + pInbuf = &pCtx->pInbuf[buf.index]; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; if (pCtx->bStreamonInbuf == VIDEO_FALSE) pInbuf = NULL; + pthread_mutex_unlock(pMutex); + EXIT: return pInbuf; } @@ -1619,6 +1650,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) { ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; ExynosVideoBuffer *pOutbuf = NULL; + pthread_mutex_t *pMutex = NULL; struct v4l2_buffer buf; int value; @@ -1652,6 +1684,9 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) goto EXIT; } + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + pOutbuf = &pCtx->pOutbuf[buf.index]; exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); @@ -1665,7 +1700,7 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) break; case 2: pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; - break; + break; case 3: pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; break; @@ -1691,6 +1726,8 @@ static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) pOutbuf->bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); + EXIT: return pOutbuf; } @@ -1735,6 +1772,302 @@ EXIT: return ret; } +/* + * [Decoder Buffer OPS] FindIndex (Output) + */ +static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int nIndex = -1; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + goto EXIT; + } + + for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { + if ((pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) && + (pCtx->pOutbuf[nIndex].bSlotUsed == VIDEO_FALSE)) + break; + } + + if (nIndex == pCtx->nOutbufs) + nIndex = -1; + +EXIT: + return nIndex; +} + +/* + * [Decoder Buffer OPS] BufferIndexFree (Output) + */ +void MFC_Decoder_BufferIndexFree_Outbuf(void *pHandle, PrivateDataShareBuffer *pPDSB, int index) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + int i, j; + + ALOGV("De-queue buf.index:%d", index); + ALOGV("pOutbuf fd:%d", pCtx->pOutbuf[index].planes[0].fd); + + if (pCtx->pOutbuf[index].nIndexUseCnt == 0) { + pCtx->pOutbuf[index].bSlotUsed = VIDEO_FALSE; + } + + for (i = 0; pPDSB->dpbFD[i].fd > -1; i++) { + ALOGV("pPDSB->dpbFD[%d].fd:%d", i, pPDSB->dpbFD[i].fd); + for (j = 0; pCtx->nOutbufs > j; j++) + if (pPDSB->dpbFD[i].fd == pCtx->pOutbuf[j].planes[0].fd) { + if (pCtx->pOutbuf[j].bQueued == VIDEO_FALSE) { + if (pCtx->pOutbuf[j].nIndexUseCnt > 0) + pCtx->pOutbuf[j].nIndexUseCnt--; + } else if(pCtx->pOutbuf[j].bQueued == VIDEO_TRUE) { + if (pCtx->pOutbuf[j].nIndexUseCnt > 1) { + /* The buffer being used as the reference buffer came again. */ + pCtx->pOutbuf[j].nIndexUseCnt--; + } else { + /* Reference DPB buffer is internally reused. */ + } + } + ALOGV("dec FD:%d, pCtx->pOutbuf[%d].nIndexUseCnt:%d", pPDSB->dpbFD[i].fd, j, pCtx->pOutbuf[j].nIndexUseCnt); + if ((pCtx->pOutbuf[j].nIndexUseCnt == 0) && + (pCtx->pOutbuf[j].bQueued == VIDEO_FALSE)) { + pCtx->pOutbuf[j].bSlotUsed = VIDEO_FALSE; + } + } + } + memset((char *)pPDSB, -1, sizeof(PrivateDataShareBuffer)); + + return; +} + +/* + * [Decoder Buffer OPS] ExtensionEnqueue (Output) + */ +static ExynosVideoErrorType MFC_Decoder_ExtensionEnqueue_Outbuf( + void *pHandle, + unsigned char *pBuffer[], + unsigned int *pFd[], + unsigned int allocLen[], + unsigned int dataSize[], + int nPlanes, + void *pPrivate) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + + struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; + struct v4l2_buffer buf; + int index, i; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) { + ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, + VIDEO_DECODER_OUTBUF_PLANES, nPlanes); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.m.planes = planes; + buf.length = VIDEO_DECODER_OUTBUF_PLANES; + + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + + index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]); + if (index == -1) { + ALOGV("%s: Failed to find index", __func__); + index = MFC_Decoder_FindEmpty_Outbuf(pCtx); + if (index == -1) { + pthread_mutex_unlock(pMutex); + ALOGE("%s: Failed to get index", __func__); + ret = VIDEO_ERROR_NOBUFFERS; + goto EXIT; + } + } + + buf.index = index; + ALOGV("En-queue index:%d pCtx->pOutbuf[buf.index].bQueued:%d, pFd[0]:%d", + index, pCtx->pOutbuf[buf.index].bQueued, pFd[0]); + pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; + pCtx->pOutbuf[buf.index].bSlotUsed = VIDEO_TRUE; + + buf.memory = pCtx->nMemoryType; + for (i = 0; i < nPlanes; i++) { + /* V4L2_MEMORY_USERPTR */ + buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; + /* V4L2_MEMORY_DMABUF */ + buf.m.planes[i].m.fd = pFd[i]; + buf.m.planes[i].length = allocLen[i]; + buf.m.planes[i].bytesused = dataSize[i]; + + /* Temporary storage for Dequeue */ + pCtx->pOutbuf[buf.index].planes[i].addr = (unsigned long)pBuffer[i]; + pCtx->pOutbuf[buf.index].planes[i].fd = (unsigned int)pFd[i]; + pCtx->pOutbuf[buf.index].planes[i].allocSize = allocLen[i]; + + ALOGV("%s: shared outbuf(%d) plane=%d addr=0x%x fd=%d len=%d used=%d\n", + __func__, index, i, + (void*)buf.m.planes[i].m.userptr, buf.m.planes[i].m.fd, + buf.m.planes[i].length, buf.m.planes[i].bytesused); + } + + pCtx->pOutbuf[buf.index].pPrivate = pPrivate; + pCtx->pOutbuf[buf.index].nIndexUseCnt++; + + pthread_mutex_unlock(pMutex); + + if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { + ALOGE("%s: Failed to enqueue output buffer", __func__); + pthread_mutex_lock(pMutex); + pCtx->pOutbuf[buf.index].nIndexUseCnt--; + pCtx->pOutbuf[buf.index].pPrivate = NULL; + pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + if (pCtx->pOutbuf[buf.index].nIndexUseCnt == 0) + pCtx->pOutbuf[buf.index].bSlotUsed = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] ExtensionDequeue (Output) + */ +static ExynosVideoErrorType MFC_Decoder_ExtensionDequeue_Outbuf( + void *pHandle, + ExynosVideoBuffer *pVideoBuffer) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + pthread_mutex_t *pMutex = NULL; + ExynosVideoBuffer *pOutbuf = NULL; + PrivateDataShareBuffer *pPDSB = NULL; + struct v4l2_buffer buf; + int value, i, j; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { + pOutbuf = NULL; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + if (pCtx->bShareOutbuf == VIDEO_TRUE) + buf.memory = pCtx->nMemoryType; + else + buf.memory = V4L2_MEMORY_MMAP; + + /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */ + if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { + pOutbuf = NULL; + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + + pOutbuf = &pCtx->pOutbuf[buf.index]; + exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); + + switch (value) { + case 0: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY; + break; + case 1: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING; + break; + case 2: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; + break; + case 3: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; + break; + default: + pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; + break; + } + + switch (buf.flags & (0x7 << 3)) { + case V4L2_BUF_FLAG_KEYFRAME: + pOutbuf->frameType = VIDEO_FRAME_I; + break; + case V4L2_BUF_FLAG_PFRAME: + pOutbuf->frameType = VIDEO_FRAME_P; + break; + case V4L2_BUF_FLAG_BFRAME: + pOutbuf->frameType = VIDEO_FRAME_B; + break; + default: + pOutbuf->frameType = VIDEO_FRAME_OTHERS; + break; + }; + + pPDSB = ((PrivateDataShareBuffer *)pCtx->nPrivateDataShareAddress) + buf.index; + if (pCtx->pOutbuf[buf.index].bQueued == VIDEO_TRUE) { + memcpy(pVideoBuffer, pOutbuf, sizeof(ExynosVideoBuffer)); + memcpy((char *)(&(pVideoBuffer->PDSB)), (char *)pPDSB, sizeof(PrivateDataShareBuffer)); + } else { + ret = VIDEO_ERROR_NOBUFFERS; + ALOGV("%s :: %d", __FUNCTION__, __LINE__); + } + + pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + MFC_Decoder_BufferIndexFree_Outbuf(pHandle, pPDSB, buf.index); + + pthread_mutex_unlock(pMutex); + +EXIT: + return ret; +} + +/* + * [Decoder Buffer OPS] Enable Dynamic DPB + */ +static ExynosVideoErrorType MFC_Decoder_Enable_DynamicDPB(void *pHandle) +{ + ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; + ExynosVideoErrorType ret = VIDEO_ERROR_NONE; + + if (pCtx == NULL) { + ALOGE("%s: Video context info must be supplied", __func__); + ret = VIDEO_ERROR_BADPARAM; + goto EXIT; + } + + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE, 1) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + + if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE, pCtx->nPrivateDataShareFD) != 0) { + ret = VIDEO_ERROR_APIFAIL; + goto EXIT; + } + +EXIT: + return ret; +} + /* * [Decoder OPS] Common */ @@ -1794,6 +2127,9 @@ static ExynosVideoDecBufferOps defOutbufOps = { .Register = MFC_Decoder_Register_Outbuf, .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf, .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf, + .ExtensionEnqueue = MFC_Decoder_ExtensionEnqueue_Outbuf, + .ExtensionDequeue = MFC_Decoder_ExtensionDequeue_Outbuf, + .Enable_DynamicDPB = MFC_Decoder_Enable_DynamicDPB, }; int Exynos_Video_Register_Decoder( diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/enc/src/ExynosVideoEncoder.c b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/enc/src/ExynosVideoEncoder.c index 8d646db..0d3d686 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/enc/src/ExynosVideoEncoder.c +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/enc/src/ExynosVideoEncoder.c @@ -1835,7 +1835,6 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf( buf.index = index; pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; - pthread_mutex_unlock(pMutex); if (pCtx->bShareInbuf == VIDEO_TRUE) { buf.memory = pCtx->nMemoryType; @@ -1853,15 +1852,20 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf( buf.m.planes[i].bytesused = dataSize[i]; } + pCtx->pInbuf[buf.index].pPrivate = pPrivate; + + pthread_mutex_unlock(pMutex); + if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); + pthread_mutex_lock(pMutex); + pCtx->pInbuf[buf.index].pPrivate = NULL; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - pCtx->pInbuf[buf.index].pPrivate = pPrivate; - EXIT: return ret; } @@ -1913,7 +1917,6 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf( } buf.index = index; pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; - pthread_mutex_unlock(pMutex); if (pCtx->bShareOutbuf == VIDEO_TRUE) { buf.memory = pCtx->nMemoryType; @@ -1929,15 +1932,20 @@ static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf( buf.memory = V4L2_MEMORY_MMAP; } + pCtx->pOutbuf[buf.index].pPrivate = pPrivate; + + pthread_mutex_unlock(pMutex); + if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to enqueue output buffer", __func__); + pthread_mutex_lock(pMutex); + pCtx->pOutbuf[buf.index].pPrivate = NULL; pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - pCtx->pOutbuf[buf.index].pPrivate = pPrivate; - EXIT: return ret; } @@ -1978,6 +1986,7 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle) { ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; ExynosVideoBuffer *pInbuf = NULL; + pthread_mutex_t *pMutex = NULL; struct v4l2_buffer buf; @@ -2005,9 +2014,14 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle) goto EXIT; } + pMutex = (pthread_mutex_t*)pCtx->pInMutex; + pthread_mutex_lock(pMutex); + pInbuf = &pCtx->pInbuf[buf.index]; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); + EXIT: return pInbuf; } @@ -2019,6 +2033,7 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle) { ExynosVideoEncContext *pCtx = (ExynosVideoEncContext *)pHandle; ExynosVideoBuffer *pOutbuf = NULL; + pthread_mutex_t *pMutex = NULL; struct v4l2_buffer buf; struct v4l2_plane planes[VIDEO_ENCODER_OUTBUF_PLANES]; @@ -2049,6 +2064,9 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle) goto EXIT; } + pMutex = (pthread_mutex_t*)pCtx->pOutMutex; + pthread_mutex_lock(pMutex); + pOutbuf = &pCtx->pOutbuf[buf.index]; pOutbuf->planes[0].dataSize = buf.m.planes[0].bytesused; @@ -2070,6 +2088,8 @@ static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle) pOutbuf->bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); + EXIT: return pOutbuf; } @@ -2191,9 +2211,7 @@ static ExynosVideoErrorType MFC_Encoder_ExtensionEnqueue_Inbuf( } buf.index = index; - pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; - pthread_mutex_unlock(pMutex); buf.memory = pCtx->nMemoryType; for (i = 0; i < nPlanes; i++) { @@ -2208,17 +2226,20 @@ static ExynosVideoErrorType MFC_Encoder_ExtensionEnqueue_Inbuf( pCtx->pInbuf[buf.index].planes[i].allocSize = allocLen[i]; } + pCtx->pInbuf[buf.index].pPrivate = pPrivate; + + pthread_mutex_unlock(pMutex); + if (exynos_v4l2_qbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to enqueue input buffer", __func__); pthread_mutex_lock(pMutex); + pCtx->pInbuf[buf.index].pPrivate = NULL; pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; pthread_mutex_unlock(pMutex); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - pCtx->pInbuf[buf.index].pPrivate = pPrivate; - EXIT: return ret; } @@ -2248,16 +2269,19 @@ static ExynosVideoErrorType MFC_Encoder_ExtensionDequeue_Inbuf(void *pHandle, Ex memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf.memory = pCtx->nMemoryType; + if (exynos_v4l2_dqbuf(pCtx->hEnc, &buf) != 0) { ALOGE("%s: Failed to dequeue input buffer", __func__); ret = VIDEO_ERROR_APIFAIL; goto EXIT; } - memcpy(pVideoBuffer, &pCtx->pInbuf[buf.index], sizeof(ExynosVideoBuffer)); pMutex = (pthread_mutex_t*)pCtx->pInMutex; pthread_mutex_lock(pMutex); + + memcpy(pVideoBuffer, &pCtx->pInbuf[buf.index], sizeof(ExynosVideoBuffer)); pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; + pthread_mutex_unlock(pMutex); EXIT: diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoApi.h b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoApi.h index 35c0b47..2b9db97 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoApi.h +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoApi.h @@ -22,6 +22,7 @@ /* Fixed */ #define VIDEO_BUFFER_MAX_PLANES 3 +#define VIDEO_BUFFER_MAX_NUM 32 typedef enum _ExynosVideoBoolType { VIDEO_FALSE = 0, @@ -107,14 +108,28 @@ typedef struct _ExynosVideoPlane { int fd; } ExynosVideoPlane; +typedef struct _ReleaseDPB { + int fd; + int fd1; + int fd2; +} ReleaseDPB; + +typedef struct _PrivateDataShareBuffer { + int index; + ReleaseDPB dpbFD[VIDEO_BUFFER_MAX_NUM]; +}PrivateDataShareBuffer; + typedef struct _ExynosVideoBuffer { ExynosVideoPlane planes[VIDEO_BUFFER_MAX_PLANES]; ExynosVideoGeometry *pGeometry; ExynosVideoFrameStatusType displayStatus; ExynosVideoFrameType frameType; ExynosVideoBoolType bQueued; + ExynosVideoBoolType bSlotUsed; ExynosVideoBoolType bRegistered; void *pPrivate; + PrivateDataShareBuffer PDSB; + int nIndexUseCnt; } ExynosVideoBuffer; typedef struct _ExynosVideoFramePacking{ @@ -269,6 +284,9 @@ typedef struct _ExynosVideoDecBufferOps { ExynosVideoErrorType (*Register)(void *pHandle, ExynosVideoPlane *planes, int nPlanes); ExynosVideoErrorType (*Clear_RegisteredBuffer)(void *pHandle); ExynosVideoErrorType (*Clear_Queue)(void *pHandle); + ExynosVideoErrorType (*ExtensionEnqueue)(void *pHandle, unsigned char *pBuffer[], unsigned int *pFd[], unsigned int allocLen[], unsigned int dataSize[], int nPlanes, void *pPrivate); + ExynosVideoErrorType (*ExtensionDequeue)(void *pHandle, ExynosVideoBuffer *pVideoBuffer); + ExynosVideoErrorType (*Enable_DynamicDPB)(void *pHandle); } ExynosVideoDecBufferOps; typedef struct _ExynosVideoEncBufferOps { diff --git a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoDec.h b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoDec.h index 45287b0..8b56a82 100644 --- a/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoDec.h +++ b/exynos_omx/codecs/exynos_codecs/video/exynos5/mfc_v4l2/include/ExynosVideoDec.h @@ -45,6 +45,10 @@ typedef struct _ExynosVideoDecContext { void *pInMutex; void *pOutMutex; int nMemoryType; + + void *hIONHandle; + int nPrivateDataShareFD; + void *nPrivateDataShareAddress; } ExynosVideoDecContext; #endif /* _EXYNOS_VIDEO_DEC_H_ */ diff --git a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Baseport.h b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Baseport.h index 165bbf2..e486555 100644 --- a/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Baseport.h +++ b/exynos_omx/openmax/exynos_omx/component/common/Exynos_OMX_Baseport.h @@ -100,7 +100,7 @@ typedef struct _EXYNOS_OMX_DATA OMX_TICKS timeStamp; OMX_PTR pPrivate; CODEC_EXTRA_BUFFERINFO extInfo; - + /* For Share Buffer */ OMX_BUFFERHEADERTYPE* bufferHeader; } EXYNOS_OMX_DATA; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/Android.mk index 0d79ec4..816f044 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Android.mk @@ -24,4 +24,8 @@ LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL libcsc_helper LOCAL_CFLAGS += -DUSE_ANB endif +ifeq ($(BOARD_USE_STOREMETADATA), true) +LOCAL_CFLAGS += -DUSE_STOREMETADATA +endif + include $(BUILD_STATIC_LIBRARY) diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c index c40221b..1179b1b 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.c @@ -192,14 +192,14 @@ OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosC { OMX_ERRORTYPE ret = OMX_ErrorNone; EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; - OMX_PTR pSrcBuf[MAX_BUFFER_PLANE]; - OMX_U32 allocSize[MAX_BUFFER_PLANE]; - - pVideoDec->exynos_codec_getCodecOutputPrivateData(codecBuffer, pSrcBuf, allocSize); - pData->buffer.multiPlaneBuffer.dataBuffer[0] = pSrcBuf[0]; - pData->buffer.multiPlaneBuffer.dataBuffer[1] = pSrcBuf[1]; - pData->buffer.multiPlaneBuffer.dataBuffer[2] = pSrcBuf[2]; - pData->allocSize = allocSize[0] + allocSize[1] + allocSize[2]; + CODEC_DEC_BUFFER *pCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer; + int i = 0; + + for (i = 0; i < MAX_BUFFER_PLANE; i++) { + pData->buffer.multiPlaneBuffer.dataBuffer[i] = pCodecBuffer->pVirAddr[i]; + pData->buffer.multiPlaneBuffer.fd[i] = pCodecBuffer->fd[i]; + pData->allocSize += pCodecBuffer->bufferSize[i]; + } pData->dataLen = 0; pData->usedDataLen = 0; pData->remainDataLen = 0; @@ -284,10 +284,15 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA } #ifdef USE_ANB - if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) { + if ((exynosOutputPort->bIsANBEnabled == OMX_TRUE) || + (exynosOutputPort->bStoreMetaData == OMX_TRUE)) { ExynosVideoPlane planes[MAX_BUFFER_PLANE]; OMX_U32 stride; - Exynos_OSAL_LockANB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes); + if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) { + Exynos_OSAL_LockANB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes); + } else if (exynosOutputPort->bStoreMetaData == OMX_TRUE) { + Exynos_OSAL_LockMetaData(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes); + } width = stride; outputUseBuffer->dataLen = sizeof(void *); @@ -303,6 +308,7 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA } #endif if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (exynosOutputPort->bStoreMetaData == OMX_FALSE) && (csc_method == CSC_METHOD_HW)) { pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf); pYUVBuf[1] = NULL; @@ -347,6 +353,8 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA #ifdef USE_ANB if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) { Exynos_OSAL_UnlockANB(pOutputBuf); + } else if (exynosOutputPort->bStoreMetaData == OMX_TRUE) { + Exynos_OSAL_UnlockMetaData(pOutputBuf); } #endif @@ -471,7 +479,8 @@ OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ FunctionIn(); if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { - if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) { + if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (exynosOutputPort->bStoreMetaData == OMX_FALSE)) { if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone) outputUseBuffer->dataValid = OMX_TRUE; } else { @@ -753,7 +762,8 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); break; } - if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) { + if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (exynosOutputPort->bStoreMetaData == OMX_FALSE)) { Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE); } else { ret = Exynos_Shared_ANBBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE); @@ -763,6 +773,7 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) break; } } + Exynos_OSAL_RefANB_Increase(pVideoDec->hRefHandle, dstInputData.bufferHeader->pBuffer); Exynos_ResetDataBuffer(dstInputUseBuffer); } } @@ -829,12 +840,24 @@ OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent) if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) || (exynosOutputPort->bufferProcessType == BUFFER_SHARE)) { + if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + int i; + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; + for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) { + if (pBufferInfo->PDSB.dpbFD[i].fd > -1) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "decRefCnt-FD:%d", pBufferInfo->PDSB.dpbFD[i].fd); + Exynos_OSAL_RefANB_Decrease(pVideoDec->hRefHandle, pBufferInfo->PDSB.dpbFD[i].fd); + } else { + break; + } + } + } Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData); } if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { - OMX_PTR codecBuffer; - codecBuffer = pDstOutputData->pPrivate; + OMX_PTR codecBuffer = pDstOutputData->pPrivate; if (codecBuffer != NULL) { Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer); pDstOutputData->pPrivate = NULL; @@ -1153,7 +1176,17 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pExynosPort->portDefinition.format.video.pNativeWindow = NULL; pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO)); - + Exynos_OSAL_Memset(((char *)pExynosPort->processData.extInfo), 0, sizeof(DECODE_CODEC_EXTRA_BUFFERINFO)); +{ + int i = 0; + DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; + pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo); + for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) { + pBufferInfo->PDSB.dpbFD[i].fd = -1; + pBufferInfo->PDSB.dpbFD[i].fd1 = -1; + pBufferInfo->PDSB.dpbFD[i].fd2 = -1; + } +} pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; @@ -1165,6 +1198,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; + pVideoDec->hRefHandle = Exynos_OSAL_RefANB_Create(); + EXIT: FunctionOut(); @@ -1200,6 +1235,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hCompo pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + Exynos_OSAL_RefANB_Terminate(pVideoDec->hRefHandle); + Exynos_OSAL_Free(pVideoDec); pExynosComponent->hComponentHandle = pVideoDec = NULL; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.h b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.h index 7f1be9b..e7bee2d 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.h +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_Vdec.h @@ -60,6 +60,7 @@ #define MFC_INPUT_BUFFER_PLANE 1 #define MFC_OUTPUT_BUFFER_PLANE 2 +#define MAX_OUTPUTBUFFER_NUM_DYNAMIC 0 /* Dynamic number of metadata buffer */ #define PLATFORM_DISPLAY_BUFFER 1 typedef struct @@ -82,6 +83,7 @@ typedef struct _DECODE_CODEC_EXTRA_BUFFERINFO OMX_U32 imageWidth; OMX_U32 imageHeight; OMX_COLOR_FORMATTYPE ColorFormat; + PrivateDataShareBuffer PDSB; } DECODE_CODEC_EXTRA_BUFFERINFO; typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT @@ -109,6 +111,8 @@ typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT OMX_PTR csc_handle; OMX_U32 csc_set_format; + OMX_HANDLETYPE hRefHandle; + OMX_ERRORTYPE (*exynos_codec_srcInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); OMX_ERRORTYPE (*exynos_codec_srcOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData); OMX_ERRORTYPE (*exynos_codec_dstInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData); diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c index ca1ae4d..17c05f2 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/Exynos_OMX_VdecControl.c @@ -484,6 +484,20 @@ OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 por Exynos_ResetCodecData(&pExynosPort->processData); } + if ((pExynosPort->bufferProcessType == BUFFER_SHARE) && + (portIndex == OUTPUT_PORT_INDEX)){ + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; + + Exynos_OSAL_RefANB_Reset(pVideoDec->hRefHandle); + } + while(1) { OMX_S32 cnt = 0; Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt); @@ -756,6 +770,9 @@ OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) bufferHeader->nFlags = dataBuffer->nFlags; bufferHeader->nTimeStamp = dataBuffer->timeStamp; + if (exynosOMXOutputPort->bStoreMetaData == OMX_TRUE) + bufferHeader->nFilledLen = bufferHeader->nAllocLen; + if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) { bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent; bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData; @@ -1099,7 +1116,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter( pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; portDefinition = &pExynosPort->portDefinition; - if (pExynosPort->bIsANBEnabled == OMX_FALSE) { + if ((pExynosPort->bIsANBEnabled == OMX_FALSE) && + (pExynosPort->bStoreMetaData == OMX_FALSE)) { switch (index) { case supportFormat_0: portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; @@ -1168,9 +1186,11 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter( * just dereference things directly here */ pExynosPort = &pExynosComponent->pExynosPort[portIndex]; - if (pExynosPort->bIsANBEnabled == OMX_TRUE) { + if ((pExynosPort->bIsANBEnabled == OMX_TRUE) || + (pExynosPort->bStoreMetaData == OMX_TRUE)){ portDefinition->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HalPixelFormat(portDefinition->format.video.eColorFormat); + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat:0x%x", portDefinition->format.video.eColorFormat); } } break; @@ -1250,6 +1270,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter( portDefinition->format.video.eColorFormat = portFormat->eColorFormat; portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; portDefinition->format.video.xFramerate = portFormat->xFramerate; + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portIndex:%d, portFormat->eColorFormat:0x%x", portIndex, portFormat->eColorFormat); } } break; @@ -1288,7 +1310,8 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter( #ifdef USE_ANB // Modified by Google engineer /* should not affect the format since in ANB case, the caller * is providing us a HAL format */ - if (pExynosPort->bIsANBEnabled == OMX_TRUE) { + if ((pExynosPort->bIsANBEnabled == OMX_TRUE) || + (pExynosPort->bStoreMetaData == OMX_TRUE)) { pExynosPort->portDefinition.format.video.eColorFormat = Exynos_OSAL_Hal2OMXPixelFormat(pExynosPort->portDefinition.format.video.eColorFormat); } @@ -1338,6 +1361,7 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter( #ifdef USE_ANB case OMX_IndexParamEnableAndroidBuffers: case OMX_IndexParamUseAndroidNativeBuffer: + case OMX_IndexParamStoreMetaDataBuffer: { ret = Exynos_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure); } @@ -1522,6 +1546,12 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex( *pIndexType = OMX_IndexParamEnableThumbnailMode; goto EXIT; } +#ifdef USE_STOREMETADATA + if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) { + *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer; + goto EXIT; + } +#endif ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); @@ -1536,18 +1566,22 @@ OMX_ERRORTYPE Exynos_Shared_ANBBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, E { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_U32 width, height; -// void *pPhys[MAX_BUFFER_PLANE]; ExynosVideoPlane planes[MAX_BUFFER_PLANE]; memset(planes, 0, sizeof(planes)); - if (pExynosPort->bIsANBEnabled == OMX_TRUE) { - OMX_U32 stride; + width = pExynosPort->portDefinition.format.video.nFrameWidth; + height = pExynosPort->portDefinition.format.video.nFrameHeight; - width = pExynosPort->portDefinition.format.video.nFrameWidth; - height = pExynosPort->portDefinition.format.video.nFrameHeight; + if ((pExynosPort->bIsANBEnabled == OMX_TRUE) || + (pExynosPort->bStoreMetaData == OMX_TRUE)) { + OMX_U32 stride; if ((pUseBuffer->bufferHeader != NULL) && (pUseBuffer->bufferHeader->pBuffer != NULL)) { - Exynos_OSAL_LockANB(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes); + if (pExynosPort->bIsANBEnabled == OMX_TRUE) { + Exynos_OSAL_LockANB(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes); + } else if (pExynosPort->bStoreMetaData == OMX_TRUE) { + Exynos_OSAL_LockMetaData(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes); + } pUseBuffer->dataLen = sizeof(void *); } else { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); @@ -1606,6 +1640,8 @@ OMX_ERRORTYPE Exynos_Shared_DataToANBBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_D if (pExynosPort->bIsANBEnabled == OMX_TRUE) { Exynos_OSAL_UnlockANB(pUseBuffer->bufferHeader->pBuffer); + } else if (pExynosPort->bStoreMetaData == OMX_TRUE) { + Exynos_OSAL_UnlockMetaData(pUseBuffer->bufferHeader->pBuffer); } else { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); ret = OMX_ErrorBadParameter; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk index 94ced6a..984bd9d 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Android.mk @@ -30,7 +30,8 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ - libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler \ + libhardware ifeq ($(BOARD_USES_MFC_FPS),true) LOCAL_CFLAGS += -DCONFIG_MFC_FPS diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c index 52d17d7..c88bf70 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/h264/Exynos_OMX_H264dec.c @@ -568,8 +568,7 @@ OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U3 nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); nOutbufs += EXTRA_DPB_NUM; for (i = 0; i < nOutbufs; i++) { - pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); - Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]); } pOutbufOps->Clear_Queue(hMFCHandle); } else { @@ -839,9 +838,13 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } + if (pOutbufOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorUndefined; + goto EXIT; + } pOutbufOps->Set_Shareable(hMFCHandle); - if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -881,43 +884,27 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane]; - - planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]; - planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane]; - planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + /* Enqueue output buffer */ + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->fd, + (unsigned int *)pVideoDec->pMFCDecOutputBuffer[i]->bufferSize, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - /* Register output buffer */ /*************/ /* TBD */ /*************/ #ifdef USE_ANB - if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { - for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { - planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; - planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; - planes[plane].allocSize = nAllocLen[plane]; - } - - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); - } - } else { + if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) { ret = OMX_ErrorNotImplemented; goto EXIT; } @@ -927,15 +914,6 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #endif } - if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX); - } pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE; ret = OMX_ErrorNone; @@ -1767,13 +1745,21 @@ OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); - - codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); - + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1], + pDstInputData->buffer.multiPlaneBuffer.fd[0], + pDstInputData->buffer.multiPlaneBuffer.fd[1]); + + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight; + nAllocLen[1] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight / 2; + + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int **)pDstInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)dataLen, + MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; @@ -1801,6 +1787,7 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps; ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; ExynosVideoGeometry *bufferGeometry; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; @@ -1815,7 +1802,11 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } while (1) { - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer)); + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; ret = OMX_ErrorNone; goto EXIT; } @@ -1851,6 +1842,28 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX } pDstOutputData->usedDataLen = 0; pDstOutputData->pPrivate = pVideoBuffer; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + pDstOutputData->pPrivate = NULL; + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] == + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) { + pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0], + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[1], + pVideoDec->pMFCDecOutputBuffer[i]->fd[0], + pVideoDec->pMFCDecOutputBuffer[i]->fd[1]); + break; + } + } + + if (pDstOutputData->pPrivate == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + } /* For Share Buffer */ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; @@ -1858,6 +1871,7 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf; pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer)); switch (bufferGeometry->eColorFormat) { case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk index 5f2f98e..d3dec8e 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Android.mk @@ -26,7 +26,8 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ - libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler \ + libhardware ifeq ($(BOARD_USES_MFC_FPS),true) LOCAL_CFLAGS += -DCONFIG_MFC_FPS diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index 0bc6bae..95aa02a 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -672,8 +672,7 @@ OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); nOutbufs += EXTRA_DPB_NUM; for (i = 0; i < nOutbufs; i++) { - pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); - Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]); } pOutbufOps->Clear_Queue(hMFCHandle); } else { @@ -918,8 +917,13 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } + if (pOutbufOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + pOutbufOps->Set_Shareable(hMFCHandle); - if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -953,43 +957,27 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane]; - - planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]; - planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane]; - planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + /* Enqueue output buffer */ + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->fd, + (unsigned int *)pVideoDec->pMFCDecOutputBuffer[i]->bufferSize, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - /* Register output buffer */ /*************/ /* TBD */ /*************/ #ifdef USE_ANB - if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { - for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { - planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; - planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; - planes[plane].allocSize = nAllocLen[plane]; - } - - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); - } - } else { + if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) { ret = OMX_ErrorNotImplemented; goto EXIT; } @@ -999,15 +987,6 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #endif } - if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - Mpeg4CodecStop(pOMXComponent, OUTPUT_PORT_INDEX); - } pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE; ret = OMX_ErrorNone; @@ -1727,7 +1706,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); } - Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); pVideoDec->pMFCDecInputBuffer[i] = NULL; } @@ -1895,13 +1873,21 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); - - codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); - + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1], + pDstInputData->buffer.multiPlaneBuffer.fd[0], + pDstInputData->buffer.multiPlaneBuffer.fd[1]); + + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight; + nAllocLen[1] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight / 2; + + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int **)pDstInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)dataLen, + MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; @@ -1929,6 +1915,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; ExynosVideoGeometry *bufferGeometry; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; @@ -1943,7 +1930,11 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } while (1) { - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer)); + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; ret = OMX_ErrorNone; goto EXIT; } @@ -1979,6 +1970,28 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } pDstOutputData->usedDataLen = 0; pDstOutputData->pPrivate = pVideoBuffer; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + pDstOutputData->pPrivate = NULL; + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] == + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) { + pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0], + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[1], + pVideoDec->pMFCDecOutputBuffer[i]->fd[0], + pVideoDec->pMFCDecOutputBuffer[i]->fd[1]); + break; + } + } + + if (pDstOutputData->pPrivate == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + } /* For Share Buffer */ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; @@ -1986,6 +1999,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM bufferGeometry = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf; pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer)); switch (bufferGeometry->eColorFormat) { case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk index 54caa40..a6f5628 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Android.mk @@ -26,7 +26,8 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ - libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos libexynosgscaler \ + libhardware ifeq ($(BOARD_USES_MFC_FPS),true) LOCAL_CFLAGS += -DCONFIG_MFC_FPS diff --git a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c index 8a18f15..bb8310d 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c +++ b/exynos_omx/openmax/exynos_omx/component/video/dec/vp8/Exynos_OMX_Vp8dec.c @@ -487,8 +487,7 @@ OMX_ERRORTYPE VP8CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); nOutbufs += EXTRA_DPB_NUM; for (i = 0; i < nOutbufs; i++) { - pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); - Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); + Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]); } pOutbufOps->Clear_Queue(hMFCHandle); } else { @@ -729,9 +728,13 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) goto EXIT; } } + if (pOutbufOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) { + ret = OMX_ErrorUndefined; + goto EXIT; + } pOutbufOps->Set_Shareable(hMFCHandle); - if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { + if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -765,43 +768,27 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane]; - - planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]; - planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane]; - planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane]; } - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + /* Enqueue output buffer */ + pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, + (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->fd, + (unsigned int *)pVideoDec->pMFCDecOutputBuffer[i]->bufferSize, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } + if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - /* Register output buffer */ /*************/ /* TBD */ /*************/ #ifdef USE_ANB - if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { - for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { - for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { - planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; - planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; - planes[plane].allocSize = nAllocLen[plane]; - } - - if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); - } - } else { + if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) && + (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) { ret = OMX_ErrorNotImplemented; goto EXIT; } @@ -811,15 +798,6 @@ OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) #endif } - if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { - VP8CodecStop (pOMXComponent, OUTPUT_PORT_INDEX); - } pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE; ret = OMX_ErrorNone; @@ -1319,7 +1297,6 @@ OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); } - Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); pVideoDec->pMFCDecInputBuffer[i] = NULL; } @@ -1487,13 +1464,21 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_D goto EXIT; } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], - pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); - - codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); - + pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1], + pDstInputData->buffer.multiPlaneBuffer.fd[0], + pDstInputData->buffer.multiPlaneBuffer.fd[1]); + + OMX_U32 nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0}; + nAllocLen[0] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight; + nAllocLen[1] = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight / 2; + + codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle, + (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, + (unsigned int **)pDstInputData->buffer.multiPlaneBuffer.fd, + (unsigned int *)nAllocLen, (unsigned int *)dataLen, + MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); if (codecReturn != VIDEO_ERROR_NONE) { Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; @@ -1521,6 +1506,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; ExynosVideoBuffer *pVideoBuffer; + ExynosVideoBuffer videoBuffer; ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; ExynosVideoGeometry *bufferGeometry; DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; @@ -1535,7 +1521,11 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } while (1) { - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { + Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer)); + if (pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE) { + pVideoBuffer = &videoBuffer; + } else { + pVideoBuffer = NULL; ret = OMX_ErrorNone; goto EXIT; } @@ -1571,6 +1561,31 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } pDstOutputData->usedDataLen = 0; pDstOutputData->pPrivate = pVideoBuffer; + if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { + int i = 0; + pDstOutputData->pPrivate = NULL; + + for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]:0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]); + if ((pVideoDec->pMFCDecOutputBuffer[i] != NULL) && + (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] == + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0])) { + pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i]; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x, FD[0]:%d, FD[1]:%d", __FUNCTION__, __LINE__, + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0], + pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[1], + pVideoDec->pMFCDecOutputBuffer[i]->fd[0], + pVideoDec->pMFCDecOutputBuffer[i]->fd[1]); + break; + } + } + + if (pDstOutputData->pPrivate == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); + ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; + goto EXIT; + } + } /* For Share Buffer */ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; @@ -1578,6 +1593,7 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ bufferGeometry = &pVp8Dec->hMFCVp8Handle.codecOutbufConf; pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; + Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer)); switch (bufferGeometry->eColorFormat) { case VIDEO_COLORFORMAT_NV12: pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c index e59a555..68ceaaf 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c @@ -339,7 +339,7 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ #ifdef USE_METADATABUFFERTYPE if (exynosInputPort->bStoreMetaData == OMX_TRUE) { OMX_PTR ppBuf[MAX_BUFFER_PLANE]; - OMX_PTR allocSize[MAX_BUFFER_PLANE]; + OMX_U32 allocSize[MAX_BUFFER_PLANE]; int plane = 0; if (inputUseBuffer->dataLen <= 0) { @@ -352,11 +352,11 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_ /* Make EOS Buffer for MFC Processing scheme */ /* Use ION Allocator */ /*Alloc Y-Buffer */ - allocSize[0] = nFrameWidth * nFrameHeight; + allocSize[0] = ALIGN(nFrameWidth, 16) * ALIGN(nFrameHeight, 16); srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[0], NORMAL_MEMORY); srcInputData->buffer.multiPlaneBuffer.fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]); /*Alloc C-Buffer */ - allocSize[1] = nFrameWidth * nFrameHeight >> 1; + allocSize[1] = ALIGN(allocSize[0] / 2, 256); srcInputData->buffer.multiPlaneBuffer.dataBuffer[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[1], NORMAL_MEMORY); srcInputData->buffer.multiPlaneBuffer.fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]); /* input buffers are 2 plane. */ diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk index 074d506..716fcd8 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/h264/Android.mk @@ -23,7 +23,8 @@ LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basec libswconverter libExynosVideoApi LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ - libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos \ + libhardware LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ $(EXYNOS_OMX_INC)/exynos \ diff --git a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk index e1c5af6..c7bdebf 100644 --- a/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk +++ b/exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Android.mk @@ -22,7 +22,8 @@ LOCAL_ARM_MODE := arm LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \ libswconverter libExynosVideoApi LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils liblog libui \ - libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos + libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion_exynos \ + libhardware LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ $(EXYNOS_OMX_INC)/exynos \ diff --git a/exynos_omx/openmax/exynos_omx/include/exynos/Exynos_OMX_Def.h b/exynos_omx/openmax/exynos_omx/include/exynos/Exynos_OMX_Def.h index 1980735..5c8f230 100644 --- a/exynos_omx/openmax/exynos_omx/include/exynos/Exynos_OMX_Def.h +++ b/exynos_omx/openmax/exynos_omx/include/exynos/Exynos_OMX_Def.h @@ -45,6 +45,7 @@ #define MAX_TIMESTAMP 40 #define MAX_FLAGS 40 +#define MAX_BUFFER_REF 40 #define MAX_BUFFER_PLANE 3 diff --git a/exynos_omx/openmax/exynos_omx/osal/Android.mk b/exynos_omx/openmax/exynos_omx/osal/Android.mk index c58f5e0..ec9127a 100644 --- a/exynos_omx/openmax/exynos_omx/osal/Android.mk +++ b/exynos_omx/openmax/exynos_omx/osal/Android.mk @@ -25,6 +25,7 @@ ifeq ($(BOARD_USE_S3D_SUPPORT), true) LOCAL_CFLAGS += -DS3D_SUPPORT endif +LOCAL_SHARED_LIBRARIES := libhardware LOCAL_STATIC_LIBRARIES := liblog libcutils LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \ diff --git a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp index 3220345..7f10331 100644 --- a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp +++ b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.cpp @@ -39,6 +39,7 @@ #include #include +#include "Exynos_OSAL_Mutex.h" #include "Exynos_OSAL_Semaphore.h" #include "Exynos_OMX_Baseport.h" #include "Exynos_OMX_Basecomponent.h" @@ -47,6 +48,7 @@ #include "Exynos_OMX_Venc.h" #include "Exynos_OSAL_Android.h" #include "exynos_format.h" +#include "ion.h" #undef EXYNOS_LOG_TAG #define EXYNOS_LOG_TAG "Exynos_OSAL_Android" @@ -59,6 +61,11 @@ using namespace android; extern "C" { #endif +int getIonFd(gralloc_module_t const *module) +{ + private_module_t* m = const_cast(reinterpret_cast(module)); + return m->ionfd; +} OMX_ERRORTYPE Exynos_OSAL_LockANBHandle( OMX_IN OMX_U32 handle, @@ -156,6 +163,21 @@ EXIT: return ret; } +OMX_U32 Exynos_OSAL_GetANBStride(OMX_IN OMX_U32 handle) +{ + FunctionIn(); + + OMX_U32 nStride = 0; + private_handle_t *priv_hnd = (private_handle_t *) handle; + + nStride = priv_hnd->stride; + +EXIT: + FunctionOut(); + + return nStride; +} + OMX_ERRORTYPE Exynos_OSAL_LockANB( OMX_IN OMX_PTR pBuffer, OMX_IN OMX_U32 width, @@ -193,6 +215,267 @@ EXIT: return ret; } +OMX_ERRORTYPE Exynos_OSAL_LockMetaData( + OMX_IN OMX_PTR pBuffer, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_U32 *pStride, + OMX_OUT OMX_PTR planes) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_PTR pBuf; + + ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf); + if (ret == OMX_ErrorNone) { + ret = Exynos_OSAL_LockANBHandle((OMX_U32)pBuf, width, height, format, planes); + *pStride = Exynos_OSAL_GetANBStride((OMX_U32)pBuf); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_PTR pBuf; + + ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf); + if (ret == OMX_ErrorNone) + ret = Exynos_OSAL_UnlockANBHandle((OMX_U32)pBuf); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_HANDLETYPE Exynos_OSAL_RefANB_Create() +{ + int i = 0; + EXYNOS_OMX_REF_HANDLE *phREF = NULL; + OMX_ERRORTYPE err = OMX_ErrorNone; + + FunctionIn(); + + phREF = (EXYNOS_OMX_REF_HANDLE *) Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_REF_HANDLE)); + if (phREF == NULL) + goto EXIT; + + Exynos_OSAL_Memset(phREF, 0, sizeof(EXYNOS_OMX_REF_HANDLE)); + for (i = 0; i < MAX_BUFFER_REF; i++) { + phREF->SharedBuffer[i].BufferFd = -1; + phREF->SharedBuffer[i].BufferFd1 = -1; + phREF->SharedBuffer[i].BufferFd2 = -1; + } + + err = Exynos_OSAL_MutexCreate(&phREF->hMutex); + if (err != OMX_ErrorNone) { + Exynos_OSAL_Free(phREF); + phREF = NULL; + } + +EXIT: + FunctionOut(); + + return ((OMX_HANDLETYPE)phREF); +} + +OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF) +{ + int i = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; + gralloc_module_t* module = NULL; + + FunctionIn(); + + if (phREF == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); + + Exynos_OSAL_MutexLock(phREF->hMutex); + for (i = 0; i < MAX_BUFFER_REF; i++) { + if (phREF->SharedBuffer[i].BufferFd > -1) { + while(phREF->SharedBuffer[i].cnt > 0) { + if (phREF->SharedBuffer[i].BufferFd > -1) + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle); + if (phREF->SharedBuffer[i].BufferFd1 > -1) + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1); + if (phREF->SharedBuffer[i].BufferFd2 > -1) + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2); + phREF->SharedBuffer[i].cnt--; + } + phREF->SharedBuffer[i].BufferFd = -1; + phREF->SharedBuffer[i].BufferFd1 = -1; + phREF->SharedBuffer[i].BufferFd2 = -1; + phREF->SharedBuffer[i].pIonHandle = NULL; + phREF->SharedBuffer[i].pIonHandle1 = NULL; + phREF->SharedBuffer[i].pIonHandle2 = NULL; + } + } + Exynos_OSAL_MutexUnlock(phREF->hMutex); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; + FunctionIn(); + + if (phREF == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_RefANB_Reset(phREF); + + ret = Exynos_OSAL_MutexTerminate(phREF->hMutex); + if (ret != OMX_ErrorNone) + goto EXIT; + + Exynos_OSAL_Free(phREF); + phREF = NULL; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(OMX_HANDLETYPE hREF, OMX_PTR pBuffer) +{ + int i; + OMX_ERRORTYPE ret = OMX_ErrorNone; + buffer_handle_t bufferHandle = (buffer_handle_t) pBuffer;//pANB->handle; + private_handle_t *priv_hnd = (private_handle_t *) bufferHandle; + EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; + gralloc_module_t* module = NULL; + + unsigned long *pIonHandle; + unsigned long *pIonHandle1; + unsigned long *pIonHandle2; + + FunctionIn(); + + if (phREF == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); + + Exynos_OSAL_MutexLock(phREF->hMutex); + + if (priv_hnd->fd >= 0) { + ion_incRef(getIonFd(module), priv_hnd->fd, &pIonHandle); + } + if (priv_hnd->fd1 >= 0) { + ion_incRef(getIonFd(module), priv_hnd->fd1, &pIonHandle1); + } + if (priv_hnd->fd2 >= 0) { + ion_incRef(getIonFd(module), priv_hnd->fd2, &pIonHandle2); + } + + for (i = 0; i < MAX_BUFFER_REF; i++) { + if (phREF->SharedBuffer[i].BufferFd == priv_hnd->fd) { + phREF->SharedBuffer[i].cnt++; + break; + } + } + + if (i >= MAX_BUFFER_REF) { + for (i = 0; i < MAX_BUFFER_REF; i++) { + if (phREF->SharedBuffer[i].BufferFd == -1) { + phREF->SharedBuffer[i].BufferFd = priv_hnd->fd; + phREF->SharedBuffer[i].BufferFd1 = priv_hnd->fd1; + phREF->SharedBuffer[i].BufferFd2 = priv_hnd->fd2; + phREF->SharedBuffer[i].pIonHandle = pIonHandle; + phREF->SharedBuffer[i].pIonHandle1 = pIonHandle1; + phREF->SharedBuffer[i].pIonHandle2 = pIonHandle2; + phREF->SharedBuffer[i].cnt++; + break; + } + } + } + + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "inc fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt); + + Exynos_OSAL_MutexUnlock(phREF->hMutex); + + if (i >= MAX_BUFFER_REF) { + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_U32 BufferFd) +{ + int i; + OMX_ERRORTYPE ret = OMX_ErrorNone; + EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF; + gralloc_module_t* module = NULL; + + FunctionIn(); + + if ((phREF == NULL) || (BufferFd < 0)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + Exynos_OSAL_MutexLock(phREF->hMutex); + hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module); + for (i = 0; i < MAX_BUFFER_REF; i++) { + if (phREF->SharedBuffer[i].BufferFd == BufferFd) { + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle); + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle1); + ion_decRef(getIonFd(module), phREF->SharedBuffer[i].pIonHandle2); + phREF->SharedBuffer[i].cnt--; + if (phREF->SharedBuffer[i].cnt == 0) { + phREF->SharedBuffer[i].BufferFd = -1; + phREF->SharedBuffer[i].BufferFd1 = -1; + phREF->SharedBuffer[i].BufferFd2 = -1; + phREF->SharedBuffer[i].pIonHandle = NULL; + phREF->SharedBuffer[i].pIonHandle1 = NULL; + phREF->SharedBuffer[i].pIonHandle2 = NULL; + } + break; + } + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dec fd:%d cnt:%d", phREF->SharedBuffer[i].BufferFd, phREF->SharedBuffer[i].cnt); + + Exynos_OSAL_MutexUnlock(phREF->hMutex); + + if (i >= MAX_BUFFER_REF) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + OMX_ERRORTYPE useAndroidNativeBuffer( EXYNOS_OMX_BASEPORT *pExynosPort, OMX_BUFFERHEADERTYPE **ppBufferHdr, @@ -428,7 +711,8 @@ OMX_ERRORTYPE Exynos_OSAL_SetANBParameter( } /* ANB and DPB Buffer Sharing */ - pExynosPort->bIsANBEnabled = pANBParams->enable; + if (pExynosPort->bStoreMetaData != OMX_TRUE) + pExynosPort->bIsANBEnabled = pANBParams->enable; if ((portIndex == OUTPUT_PORT_INDEX) && (pExynosPort->bIsANBEnabled == OMX_TRUE) && ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) { @@ -494,7 +778,6 @@ OMX_ERRORTYPE Exynos_OSAL_SetANBParameter( case OMX_IndexParamStoreMetaDataBuffer: { - EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;; StoreMetaDataInBuffersParams *pANBParams = (StoreMetaDataInBuffersParams *) ComponentParameterStructure; OMX_U32 portIndex = pANBParams->nPortIndex; EXYNOS_OMX_BASEPORT *pExynosPort = NULL; @@ -525,7 +808,20 @@ OMX_ERRORTYPE Exynos_OSAL_SetANBParameter( } pExynosPort->bStoreMetaData = pANBParams->bStoreMetaData; - pVideoEnc->bFirstInput = OMX_TRUE; + if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) { + EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;; + pVideoEnc->bFirstInput = OMX_TRUE; + } else if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) { + EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;; + if ((portIndex == OUTPUT_PORT_INDEX) && + (pExynosPort->bStoreMetaData == OMX_TRUE) && + ((pExynosPort->bufferProcessType & BUFFER_ANBSHARE) == BUFFER_ANBSHARE)) { + pExynosPort->bufferProcessType = BUFFER_SHARE; + pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexParamStoreMetaDataBuffer & bufferProcessType change to BUFFER_SHARE"); + } + + } } break; diff --git a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h index 381b9f9..2996976 100644 --- a/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h +++ b/exynos_omx/openmax/exynos_omx/osal/Exynos_OSAL_Android.h @@ -33,12 +33,30 @@ #include "OMX_Core.h" #include "OMX_Index.h" +typedef struct _EXYNOS_OMX_SHARED_BUFFER { + OMX_S32 BufferFd; + OMX_S32 BufferFd1; + OMX_S32 BufferFd2; + unsigned long *pIonHandle; + unsigned long *pIonHandle1; + unsigned long *pIonHandle2; + OMX_U32 cnt; +} EXYNOS_OMX_SHARED_BUFFER; + +typedef struct _EXYNOS_OMX_REF_HANDLE { + OMX_HANDLETYPE hMutex; + EXYNOS_OMX_SHARED_BUFFER SharedBuffer[MAX_BUFFER_REF]; +} EXYNOS_OMX_REF_HANDLE; + + #ifdef __cplusplus extern "C" { #endif OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_U32 handle); +OMX_U32 Exynos_OSAL_GetANBStride(OMX_IN OMX_U32 handle); + OMX_ERRORTYPE Exynos_OSAL_GetANBParameter(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nIndex, OMX_INOUT OMX_PTR ComponentParameterStructure); @@ -56,6 +74,15 @@ OMX_ERRORTYPE Exynos_OSAL_LockANB(OMX_IN OMX_PTR pBuffer, OMX_ERRORTYPE Exynos_OSAL_UnlockANB(OMX_IN OMX_PTR pBuffer); +OMX_ERRORTYPE Exynos_OSAL_LockMetaData(OMX_IN OMX_PTR pBuffer, + OMX_IN OMX_U32 width, + OMX_IN OMX_U32 height, + OMX_IN OMX_COLOR_FORMATTYPE format, + OMX_OUT OMX_U32 *pStride, + OMX_OUT OMX_PTR planes); + +OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer); + OMX_ERRORTYPE Exynos_OSAL_LockANBHandle(OMX_IN OMX_U32 pBuffer, OMX_IN OMX_U32 width, OMX_IN OMX_U32 height, -- 2.20.1