From 10db72aa6027f12243092eb417fcff2ef99255a9 Mon Sep 17 00:00:00 2001 From: SeungBeom Kim Date: Fri, 25 Jan 2013 10:15:14 +0900 Subject: [PATCH] exynos_omx: Add secure encode component. Add secure encode component for WFD. Input buffer - Metadata : kMetadataBufferTypeCameraSource with FD(Secure buffer). Output buffer - FD(Secure buffer) : pBuffer of OMX_BUFFERHEADERTYPE is FD. Change-Id: Ie9f70da1101649d553669ad6044d77000eb987d3 Signed-off-by: SeungBeom Kim --- component/video/enc/Exynos_OMX_Venc.c | 15 +++ component/video/enc/Exynos_OMX_Venc.h | 3 + component/video/enc/Exynos_OMX_VencControl.c | 20 ++- component/video/enc/h264/Exynos_OMX_H264enc.c | 118 ++++++++---------- component/video/enc/h264/library_register.c | 7 +- component/video/enc/h264/library_register.h | 3 +- .../video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c | 50 +------- 7 files changed, 96 insertions(+), 120 deletions(-) diff --git a/component/video/enc/Exynos_OMX_Venc.c b/component/video/enc/Exynos_OMX_Venc.c index 4ef3800..8dc6158 100644 --- a/component/video/enc/Exynos_OMX_Venc.c +++ b/component/video/enc/Exynos_OMX_Venc.c @@ -145,6 +145,9 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers( #endif } + if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) + eMemoryType = SECURE_MEMORY; + for (i = 0; i < nBufferCnt; i++) { ppCodecBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); if (ppCodecBuffer[i] == NULL) { @@ -914,6 +917,18 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) break; } Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE); + if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) { + OMX_PTR dataBuffer = NULL; + dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, + dstInputData.buffer.singlePlaneBuffer.dataBuffer); + if (dataBuffer == NULL) { + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Secure buffer", __LINE__); + ret = OMX_ErrorUndefined; + break; + } + + dstInputData.buffer.singlePlaneBuffer.dataBuffer = dataBuffer; + } Exynos_ResetDataBuffer(dstInputUseBuffer); } } diff --git a/component/video/enc/Exynos_OMX_Venc.h b/component/video/enc/Exynos_OMX_Venc.h index af2f423..15c6566 100644 --- a/component/video/enc/Exynos_OMX_Venc.h +++ b/component/video/enc/Exynos_OMX_Venc.h @@ -94,6 +94,9 @@ typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT /* Shared Memory Handle */ OMX_HANDLETYPE hSharedMemory; + /* For DRM Record */ + OMX_BOOL bDRMPlayerMode; + OMX_BOOL configChange; OMX_BOOL IntraRefreshVOP; OMX_VIDEO_CONTROLRATETYPE eControlRate[ALL_PORT_NUM]; diff --git a/component/video/enc/Exynos_OMX_VencControl.c b/component/video/enc/Exynos_OMX_VencControl.c index 73e94cd..36fd766 100644 --- a/component/video/enc/Exynos_OMX_VencControl.c +++ b/component/video/enc/Exynos_OMX_VencControl.c @@ -200,10 +200,13 @@ OMX_ERRORTYPE Exynos_OMX_AllocateBuffer( goto EXIT; } - if (pExynosPort->bNeedContigMem == OMX_TRUE) { + if ((pVideoEnc->bDRMPlayerMode == OMX_TRUE) && + (nPortIndex == OUTPUT_PORT_INDEX)) { + eMemType = SECURE_MEMORY; + } else if (pExynosPort->bNeedContigMem == OMX_TRUE) { eMemType = CONTIG_MEMORY; } else if ((nPortIndex == INPUT_PORT_INDEX) && - (pExynosPort->bufferProcessType & BUFFER_SHARE)) { + (pExynosPort->bufferProcessType & BUFFER_SHARE)) { eMemType = NORMAL_MEMORY; } @@ -228,7 +231,10 @@ OMX_ERRORTYPE Exynos_OMX_AllocateBuffer( pExynosPort->extendBufferHeader[i].buf_fd[0] = fdTempBuffer; pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE); - pTempBufferHdr->pBuffer = pTempBuffer; + if (eMemType == SECURE_MEMORY) + pTempBufferHdr->pBuffer = fdTempBuffer; + else + pTempBufferHdr->pBuffer = pTempBuffer; pTempBufferHdr->nAllocLen = nSizeBytes; pTempBufferHdr->pAppPrivate = pAppPrivate; if (nPortIndex == INPUT_PORT_INDEX) @@ -324,7 +330,13 @@ OMX_ERRORTYPE Exynos_OMX_FreeBuffer( if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) { if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { - Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pOMXBufferHdr->pBuffer); + if ((pVideoEnc->bDRMPlayerMode == OMX_TRUE) && + (nPortIndex == OUTPUT_PORT_INDEX)) { + OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, (int)pOMXBufferHdr->pBuffer); + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, mapBuffer); + } else { + Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pOMXBufferHdr->pBuffer); + } pOMXBufferHdr->pBuffer = NULL; pBufferHdr->pBuffer = NULL; } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { diff --git a/component/video/enc/h264/Exynos_OMX_H264enc.c b/component/video/enc/h264/Exynos_OMX_H264enc.c index a0b10ca..3818e73 100644 --- a/component/video/enc/h264/Exynos_OMX_H264enc.c +++ b/component/video/enc/h264/Exynos_OMX_H264enc.c @@ -993,65 +993,26 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ + /* Register output buffer */ /*************/ /* TBD */ /*************/ - ExynosVideoPlane plane; for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) { - plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + ExynosVideoPlane plane; + if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) { + plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer); + } else { + plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; + } plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; plane.allocSize = OutBufferSize; if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } } - - /* start header encoding */ - 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) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - ExynosVideoBuffer *pVideoBuffer = NULL; - - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Dequeue", __FUNCTION__, __LINE__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dst:0x%x, src:0x%x, dataSize:%d", - OMXBuffer->pBuffer, - pVideoBuffer->planes[0].addr, - pVideoBuffer->planes[0].dataSize); - Exynos_OSAL_Memcpy(OMXBuffer->pBuffer, pVideoBuffer->planes[0].addr, pVideoBuffer->planes[0].dataSize); - OMXBuffer->nFilledLen = pVideoBuffer->planes[0].dataSize; - OMXBuffer->nOffset = 0; - OMXBuffer->nTimeStamp = 0; - OMXBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - OMXBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); - - pVideoEnc->bFirstOutput = OMX_TRUE; - ret = OMX_ErrorNone; - - H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX); - } pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE; ret = OMX_ErrorNone; @@ -1669,7 +1630,13 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) #ifdef USE_CSC_HW csc_method = CSC_METHOD_HW; #endif - pVideoEnc->csc_handle = csc_init(csc_method); + if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) { + pVideoEnc->csc_handle = csc_init(CSC_METHOD_HW); + csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2); + csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoEnc->bDRMPlayerMode); + } else { + pVideoEnc->csc_handle = csc_init(csc_method); + } if (pVideoEnc->csc_handle == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -2008,23 +1975,26 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; if (pVideoEnc->bFirstOutput == OMX_FALSE) { - OMX_U8 *p = NULL; - int iSpsSize = 0; - int iPpsSize = 0; - - /* Calculate sps/pps size if needed */ - p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4), - pDstOutputData->dataLen - 4); - - iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; - pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = - (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; - pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; - - iPpsSize = pDstOutputData->dataLen - iSpsSize; - pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = - (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize; - pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + if (pVideoEnc->bDRMPlayerMode == OMX_FALSE) { + OMX_U8 *p = NULL; + int iSpsSize = 0; + int iPpsSize = 0; + + /* start header return */ + /* Calculate sps/pps size if needed */ + p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4), + pDstOutputData->dataLen - 4); + + iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; + pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = + (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer; + pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; + + iPpsSize = pDstOutputData->dataLen - iSpsSize; + pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = + (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize; + pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + } pDstOutputData->timeStamp = 0; pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; @@ -2220,6 +2190,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( EXYNOS_OMX_BASEPORT *pExynosPort = NULL; EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; EXYNOS_H264ENC_HANDLE *pH264Enc = NULL; + OMX_BOOL bDRMPlayerMode = OMX_FALSE; int i = 0; FunctionIn(); @@ -2229,7 +2200,12 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); goto EXIT; } - if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) { + + if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) == 0) { + bDRMPlayerMode = OMX_FALSE; + } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_ENC, componentName) == 0) { + bDRMPlayerMode = OMX_TRUE; + } else { ret = OMX_ErrorBadParameter; Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); goto EXIT; @@ -2267,7 +2243,13 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( pVideoEnc->quantization.nQpP = 20; pVideoEnc->quantization.nQpB = 20; - Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC); + if (bDRMPlayerMode == OMX_TRUE) + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_ENC); + else + Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC); + + pVideoEnc->bDRMPlayerMode = bDRMPlayerMode; + /* Set componentVersion */ pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; @@ -2305,6 +2287,8 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; pExynosPort->portDefinition.bEnabled = OMX_TRUE; pExynosPort->bufferProcessType = BUFFER_SHARE; + if (bDRMPlayerMode == OMX_TRUE) + pExynosPort->bufferProcessType = BUFFER_SHARE; pExynosPort->portWayType = WAY2_PORT; for(i = 0; i < ALL_PORT_NUM; i++) { diff --git a/component/video/enc/h264/library_register.c b/component/video/enc/h264/library_register.c index c8afbd6..ad65ae0 100644 --- a/component/video/enc/h264/library_register.c +++ b/component/video/enc/h264/library_register.c @@ -42,11 +42,16 @@ OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponen if (exynosComponents == NULL) goto EXIT; - /* component 1 - video decoder H.264 */ + /* component 1 - video Encoder H.264 */ Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_ENC); Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_ENC_ROLE); exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + /* component 2 - video Encoder H.264 for DRM */ + Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_ENC); + Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_H264_ENC_ROLE); + exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + EXIT: FunctionOut(); diff --git a/component/video/enc/h264/library_register.h b/component/video/enc/h264/library_register.h index 1d2022a..0e8d723 100644 --- a/component/video/enc/h264/library_register.h +++ b/component/video/enc/h264/library_register.h @@ -33,11 +33,12 @@ #define OSCL_EXPORT_REF __attribute__((visibility("default"))) -#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_NUM 2 #define MAX_COMPONENT_ROLE_NUM 1 /* H.264 */ #define EXYNOS_OMX_COMPONENT_H264_ENC "OMX.Exynos.AVC.Encoder" +#define EXYNOS_OMX_COMPONENT_H264_DRM_ENC "OMX.Exynos.AVC.Encoder.secure" #define EXYNOS_OMX_COMPONENT_H264_ENC_ROLE "video_encoder.avc" diff --git a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c index 1a1c4f4..0dd2d2a 100644 --- a/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c +++ b/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c @@ -1119,7 +1119,7 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - /* Register input buffer */ + /* Register output buffer */ /*************/ /* TBD */ /*************/ @@ -1129,57 +1129,12 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0]; plane.allocSize = OutBufferSize; if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); + Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); ret = OMX_ErrorInsufficientResources; goto EXIT; } - pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, - (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); } } - - /* start header encoding */ - if (pOutbufOps->Run) { - 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) { - OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; - ExynosVideoBuffer *pVideoBuffer = NULL; - - OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); - if (OMXBuffer == OMX_ErrorNone) { - ret = OMX_ErrorUndefined; - goto EXIT; - } - - if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Dequeue", __FUNCTION__, __LINE__); - ret = OMX_ErrorUndefined; - goto EXIT; - } - - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dst:0x%x, src:0x%x, dataSize:%d", - OMXBuffer->pBuffer, - pVideoBuffer->planes[0].addr, - pVideoBuffer->planes[0].dataSize); - Exynos_OSAL_Memcpy(OMXBuffer->pBuffer, pVideoBuffer->planes[0].addr, pVideoBuffer->planes[0].dataSize); - OMXBuffer->nFilledLen = pVideoBuffer->planes[0].dataSize; - OMXBuffer->nOffset = 0; - OMXBuffer->nTimeStamp = 0; - OMXBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; - OMXBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); - - pVideoEnc->bFirstOutput = OMX_TRUE; - ret = OMX_ErrorNone; - - Mpeg4CodecStop(pOMXComponent, OUTPUT_PORT_INDEX); - } pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE; ret = OMX_ErrorNone; @@ -2202,6 +2157,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM if (pVideoEnc->bFirstOutput == OMX_FALSE) { OMX_U8 *p = NULL; + /* start header return */ pDstOutputData->timeStamp = 0; pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; -- 2.20.1