diff options
Diffstat (limited to 'sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c')
-rw-r--r-- | sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c | 497 |
1 files changed, 387 insertions, 110 deletions
diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c index 5e73b7f..07e1a89 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c @@ -35,6 +35,7 @@ #include "library_register.h" #include "SEC_OMX_H264dec.h" #include "SsbSipMfcApi.h" +#include "color_space_convertor.h" #undef SEC_LOG_TAG #define SEC_LOG_TAG "SEC_H264_DEC" @@ -56,8 +57,6 @@ SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, @@ -69,8 +68,6 @@ SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, @@ -81,9 +78,7 @@ SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, - {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}}; static int Check_H264_Frame(OMX_U8 *pInputStream, int buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) @@ -242,7 +237,7 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_GetParameter( goto EXIT; } - SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE); + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); } break; case OMX_IndexParamVideoProfileLevelQuerySupported: @@ -401,7 +396,7 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_SetParameter( goto EXIT; } - if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE)) { + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE)) { pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; } else { ret = OMX_ErrorBadParameter; @@ -453,10 +448,18 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_SetParameter( pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; pSECOutputPort->portDefinition.format.video.nStride = width; pSECOutputPort->portDefinition.format.video.nSliceHeight = height; - if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) { + + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; - } else if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV422Planar) { - pSECOutputPort->portDefinition.nBufferSize = width * height * 2; + break; + default: + SEC_OSAL_Log(SEC_LOG_ERROR, "Color format is not support!! use default YUV size!!"); + ret = OMX_ErrorUnsupportedSetting; + break; } } } @@ -519,6 +522,84 @@ EXIT: return ret; } +OMX_ERRORTYPE SEC_MFC_H264Dec_GetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexConfigCommonOutputCrop: + { + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_CONFIG_RECTTYPE *pSrcRectType = NULL; + OMX_CONFIG_RECTTYPE *pDstRectType = NULL; + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + + if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + ret = OMX_ErrorNotReady; + break; + } + + pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure; + + if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) && + (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[pDstRectType->nPortIndex]; + + pSrcRectType = &(pSECPort->cropRectangle); + + pDstRectType->nTop = pSrcRectType->nTop; + pDstRectType->nLeft = pSrcRectType->nLeft; + pDstRectType->nHeight = pSrcRectType->nHeight; + pDstRectType->nWidth = pSrcRectType->nWidth; + } + break; + default: + ret = SEC_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + OMX_ERRORTYPE SEC_MFC_H264Dec_SetConfig( OMX_HANDLETYPE hComponent, OMX_INDEXTYPE nIndex, @@ -612,12 +693,21 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_GetExtensionIndex( goto EXIT; } - if (SEC_OSAL_Strcmp(cParameterName, "OMX.SEC.index.ThumbnailMode") == 0) { + if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; - *pIndexType = OMX_IndexVendorThumbnailMode; - ret = OMX_ErrorNone; +#ifdef USE_ANDROID_EXTENSION + } else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_ENABLE_ANB) == 0) { + *pIndexType = OMX_IndexParamEnableAndroidBuffers; + ret = OMX_ErrorNone; + } else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_GET_ANB) == 0) { + *pIndexType = OMX_IndexParamGetAndroidNativeBuffer; + ret = OMX_ErrorNone; + } else if (SEC_OSAL_Strcmp(cParameterName, SEC_INDEX_PARAM_USE_ANB) == 0) { + *pIndexType = OMX_IndexParamUseAndroidNativeBuffer; + ret = OMX_ErrorNone; +#endif } else { ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); } @@ -628,7 +718,6 @@ EXIT: return ret; } - OMX_ERRORTYPE SEC_MFC_H264Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -642,7 +731,7 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U goto EXIT; } if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { - SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE); + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPONENT_H264_DEC_ROLE); ret = OMX_ErrorNone; } else { ret = OMX_ErrorNoMore; @@ -654,6 +743,39 @@ EXIT: return ret; } +OMX_ERRORTYPE SEC_MFC_DecodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + + while (pH264Dec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pH264Dec->NBDecThread.hDecFrameStart); + + if (pH264Dec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, pH264Dec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pH264Dec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + /* MFC Init */ OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) { @@ -671,7 +793,8 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->bSaveFlagEOS = OMX_FALSE; /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ - hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(&buf_type); if (hMFCHandle == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -679,15 +802,39 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pH264Dec->hMFCH264Handle.hMFCHandle = hMFCHandle; /* Allocate decoder's input buffer */ - pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE); + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE * MFC_INPUT_BUFFER_NUM_MAX); if (pStreamBuffer == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; } - pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pStreamBuffer; - pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pStreamPhyBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pStreamBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + + pH264Dec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pH264Dec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pH264Dec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pH264Dec->MFCDecInputBuffer[0].dataSize = 0; + pH264Dec->MFCDecInputBuffer[1].VirAddr = (unsigned char *)pStreamBuffer + pH264Dec->MFCDecInputBuffer[0].bufferSize; + pH264Dec->MFCDecInputBuffer[1].PhyAddr = (unsigned char *)pStreamPhyBuffer + pH264Dec->MFCDecInputBuffer[0].bufferSize; + pH264Dec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pH264Dec->MFCDecInputBuffer[1].dataSize = 0; + pH264Dec->indexInputBuffer = 0; + + pH264Dec->bFirstFrame = OMX_TRUE; + + pH264Dec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pH264Dec->NBDecThread.bDecoderRun = OMX_FALSE; + pH264Dec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pH264Dec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pH264Dec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pH264Dec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; + } + + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pH264Dec->MFCDecInputBuffer[0].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pH264Dec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pH264Dec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pH264Dec->MFCDecInputBuffer[0].bufferSize; SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); @@ -716,6 +863,23 @@ OMX_ERRORTYPE SEC_MFC_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + if (pH264Dec->NBDecThread.hNBDecodeThread != NULL) { + pH264Dec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pH264Dec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pH264Dec->NBDecThread.hNBDecodeThread); + pH264Dec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pH264Dec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pH264Dec->NBDecThread.hDecFrameEnd); + pH264Dec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pH264Dec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pH264Dec->NBDecThread.hDecFrameStart); + pH264Dec->NBDecThread.hDecFrameStart = NULL; + } + if (hMFCHandle != NULL) { SsbSipMfcDecClose(hMFCHandle); hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle = NULL; @@ -735,9 +899,9 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA OMX_U32 oneFrameSize = pInputData->dataLen; SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; OMX_S32 setConfVal = 0; - OMX_S32 returnCodec = 0; - int bufWidth; - int bufHeight; + int bufWidth = 0; + int bufHeight = 0; + OMX_BOOL outputDataValid = OMX_FALSE; FunctionIn(); @@ -751,23 +915,24 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA goto EXIT; } - setConfVal = 5; + setConfVal = 0; SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); /* Default number in the driver is optimized */ if (pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_TRUE) { - setConfVal = 0; + setConfVal = 1; SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); } else { setConfVal = 8; SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); } - returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { + pH264Dec->hMFCH264Handle.returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); + if (pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) { SSBSIP_MFC_IMG_RESOLUTION imgResol; SSBSIP_MFC_CROP_INFORMATION cropInfo; SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", @@ -781,16 +946,38 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , cropInfo.crop_left_offset , cropInfo.crop_right_offset); - int actualWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; - int actualHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; + secOutputPort->cropRectangle.nTop = cropInfo.crop_top_offset; + secOutputPort->cropRectangle.nLeft = cropInfo.crop_left_offset; + secOutputPort->cropRectangle.nWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; + secOutputPort->cropRectangle.nHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; + + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; /** Update Frame Size **/ - if((secInputPort->portDefinition.format.video.nFrameWidth != actualWidth) || - (secInputPort->portDefinition.format.video.nFrameHeight != actualHeight)) { + if ((cropInfo.crop_left_offset != 0) || (cropInfo.crop_right_offset != 0) || + (cropInfo.crop_top_offset != 0) || (cropInfo.crop_bottom_offset != 0)) { + /* change width and height information */ + secInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + secInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + secInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + secInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send crop info call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + OMX_IndexConfigCommonOutputCrop, + NULL); + } else if((secInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || + (secInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); /* change width and height information */ - secInputPort->portDefinition.format.video.nFrameWidth = actualWidth; - secInputPort->portDefinition.format.video.nFrameHeight = actualHeight; + secInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + secInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; secInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); secInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); @@ -806,7 +993,6 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA NULL); } - pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; #ifdef ADD_SPS_PPS_I_FRAME ret = OMX_ErrorInputDataDecodeYet; #else @@ -824,68 +1010,59 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA #ifndef FULL_FRAME_SEARCH if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && - (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + (pSECComponent->bUseFlagEOF == OMX_FALSE)) pSECComponent->bUseFlagEOF = OMX_TRUE; - } #endif pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); - pH264Dec->hMFCH264Handle.indexTimestamp++; - if (pH264Dec->hMFCH264Handle.indexTimestamp >= MAX_TIMESTAMP) - pH264Dec->hMFCH264Handle.indexTimestamp = 0; - - if (Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { - returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, oneFrameSize); - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - if (returnCodec == MFC_RET_OK) { + if ((pH264Dec->hMFCH264Handle.returnCodec == MFC_RET_OK) && + (pH264Dec->bFirstFrame == OMX_FALSE)) { SSBSIP_MFC_DEC_OUTBUF_STATUS status; OMX_S32 indexTimestamp = 0; + /* wait for mfc decode done */ + if (pH264Dec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pH264Dec->NBDecThread.hDecFrameEnd); + pH264Dec->NBDecThread.bDecoderRun = OMX_FALSE; + } + status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); - bufWidth = (outputInfo.img_width + 15) & (~15); - bufHeight = (outputInfo.img_height + 15) & (~15); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || - (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))) { + (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { pOutputData->timeStamp = pInputData->timeStamp; pOutputData->nFlags = pInputData->nFlags; } else { pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; } + SEC_OSAL_Log(SEC_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { - switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; - break; - default: - pOutputData->dataLen = bufWidth * bufHeight * 2; - break; - } + outputDataValid = OMX_TRUE; } if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) - pOutputData->dataLen = 0; + outputDataValid = OMX_FALSE; if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || - (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) ret = OMX_ErrorInputDataDecodeYet; - } if(status == MFC_GETOUTBUF_DECODING_ONLY) { - /* ret = OMX_ErrorInputDataDecodeYet; */ - ret = OMX_ErrorNone; - goto EXIT; + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else { + ret = OMX_ErrorNone; + } + outputDataValid = OMX_FALSE; } #ifdef FULL_FRAME_SEARCH @@ -896,7 +1073,6 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA ret = OMX_ErrorInputDataDecodeYet; } else #endif - if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); pSECComponent->getAllDelayBuffer = OMX_TRUE; @@ -908,62 +1084,162 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA } else { pOutputData->timeStamp = pInputData->timeStamp; pOutputData->nFlags = pInputData->nFlags; - switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { - case OMX_COLOR_FormatYUV420Planar: - case OMX_COLOR_FormatYUV420SemiPlanar: - pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; - break; - default: - pOutputData->dataLen = bufWidth * bufHeight * 2; - break; - } if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || (pSECComponent->getAllDelayBuffer == OMX_TRUE) || (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; pSECComponent->getAllDelayBuffer = OMX_FALSE; - pOutputData->dataLen = 0; } + if ((pH264Dec->bFirstFrame == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + + outputDataValid = OMX_FALSE; - /* ret = OMX_ErrorUndefined; */ /* ????? */ + /* ret = OMX_ErrorUndefined; */ ret = OMX_ErrorNone; - goto EXIT; } - /** Fill Output Buffer **/ - if (pOutputData->dataLen > 0) - { - int frameSize = bufWidth * bufHeight; - void *pOutBuf = (void *)pOutputData->dataBuffer; + if (ret == OMX_ErrorInputDataDecodeYet) { + pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].dataSize = oneFrameSize; + pH264Dec->indexInputBuffer++; + pH264Dec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].bufferSize; + oneFrameSize = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } -#ifdef USE_SAMSUNG_COLORFORMAT - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + if ((Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); + pH264Dec->hMFCH264Handle.indexTimestamp++; + pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + + SsbSipMfcDecSetInBuf(pH264Dec->hMFCH264Handle.hMFCHandle, + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer, + pH264Dec->hMFCH264Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].dataSize = oneFrameSize; + pH264Dec->NBDecThread.oneFrameSize = oneFrameSize; + + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pH264Dec->NBDecThread.hDecFrameStart); + pH264Dec->NBDecThread.bDecoderRun = OMX_TRUE; + pH264Dec->hMFCH264Handle.returnCodec = MFC_RET_OK; + + pH264Dec->indexInputBuffer++; + pH264Dec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].VirAddr; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pH264Dec->MFCDecInputBuffer[pH264Dec->indexInputBuffer].bufferSize; + if (((pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_TRUE) || (pSECComponent->bSaveFlagEOS == OMX_TRUE)) && + (pH264Dec->bFirstFrame == OMX_TRUE) && + (outputDataValid == OMX_FALSE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + pH264Dec->bFirstFrame = OMX_FALSE; + } - if ((pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress)) + /** Fill Output Buffer **/ + if (outputDataValid == OMX_TRUE) { + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + void *pOutputBuf[3]; -#else - if (pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_FALSE) + int frameSize = bufWidth * bufHeight; + int imageSize = outputInfo.img_width * outputInfo.img_height; + + int actualWidth = outputInfo.img_width; + int actualHeight = outputInfo.img_height; + int actualImageSize = imageSize; + + pOutputBuf[0] = (void *)pOutputData->dataBuffer; + pOutputBuf[1] = (void *)pOutputData->dataBuffer + actualImageSize; + pOutputBuf[2] = (void *)pOutputData->dataBuffer + ((actualImageSize * 5) / 4); + +#ifdef USE_ANDROID_EXTENSION + if (pSECOutputPort->bUseAndroidNativeBuffer == OMX_TRUE) { + OMX_U32 retANB = 0; + void *pVirAddrs[2]; + actualWidth = (outputInfo.img_width + 15) & (~15); + actualImageSize = actualWidth * actualHeight; + + retANB = getVADDRfromANB (pOutputData->dataBuffer, + (OMX_U32)pSECInputPort->portDefinition.format.video.nFrameWidth, + (OMX_U32)pSECInputPort->portDefinition.format.video.nFrameHeight, + pVirAddrs); + if (retANB != 0) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Error getVADDRfromANB, Error code:%d", retANB); + ret = OMX_ErrorOverflow; + goto EXIT; + } + pOutputBuf[0] = pVirAddrs[0]; + pOutputBuf[1] = pVirAddrs[1]; + } #endif + if ((pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { /* if use Post copy address structure */ - SEC_OSAL_Memcpy(pOutBuf, &frameSize, sizeof(frameSize)); - SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize), &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); - SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); - SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); - SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + SEC_OSAL_Memcpy(pOutputBuf[0], &frameSize, sizeof(frameSize)); + SEC_OSAL_Memcpy(pOutputBuf[0] + sizeof(frameSize), &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy(pOutputBuf[0] + sizeof(frameSize) + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy(pOutputBuf[0] + sizeof(frameSize) + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy(pOutputBuf[0] + sizeof(frameSize) + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; } else { - SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); - Y_tile_to_linear_4x2( - (unsigned char *)pOutBuf, + switch (pSECOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420P out"); + csc_tiled_to_linear( + (unsigned char *)pOutputBuf[0], (unsigned char *)outputInfo.YVirAddr, - bufWidth, bufHeight); - CbCr_tile_to_linear_4x2( - ((unsigned char *)pOutBuf) + frameSize, + actualWidth, + actualHeight); + csc_tiled_to_linear_deinterleave( + (unsigned char *)pOutputBuf[1], + (unsigned char *)pOutputBuf[2], (unsigned char *)outputInfo.CVirAddr, - bufWidth, bufHeight); + actualWidth, + actualHeight >> 1); + pOutputData->dataLen = actualImageSize * 3 / 2; + } + break; + case OMX_COLOR_FormatYUV420SemiPlanar: + case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: + default: + { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420SP out"); + csc_tiled_to_linear( + (unsigned char *)pOutputBuf[0], + (unsigned char *)outputInfo.YVirAddr, + actualWidth, + actualHeight); + csc_tiled_to_linear( + (unsigned char *)pOutputBuf[1], + (unsigned char *)outputInfo.CVirAddr, + actualWidth, + actualHeight >> 1); + pOutputData->dataLen = actualImageSize * 3 / 2; + } + break; + } } +#ifdef USE_ANDROID_EXTENSION + if (pSECOutputPort->bUseAndroidNativeBuffer == OMX_TRUE) + putVADDRtoANB(pOutputData->dataBuffer); +#endif + } else { + pOutputData->dataLen = 0; } EXIT: @@ -1037,7 +1313,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, O SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); goto EXIT; } - if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_H264_DEC, componentName) != 0) { + if (SEC_OSAL_Strcmp(SEC_OMX_COMPONENT_H264_DEC, componentName) != 0) { ret = OMX_ErrorBadParameter; SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); goto EXIT; @@ -1071,7 +1347,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, O SEC_OSAL_Memset(pH264Dec, 0, sizeof(SEC_H264DEC_HANDLE)); pSECComponent->hCodecHandle = (OMX_HANDLETYPE)pH264Dec; - SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_H264_DEC); + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPONENT_H264_DEC); /* Set componentVersion */ pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; @@ -1120,7 +1396,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, O SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); pSECPort->portDefinition.format.video.pNativeRender = 0; pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; - pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; pSECPort->portDefinition.bEnabled = OMX_TRUE; for(i = 0; i < ALL_PORT_NUM; i++) { @@ -1132,6 +1408,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, O pOMXComponent->GetParameter = &SEC_MFC_H264Dec_GetParameter; pOMXComponent->SetParameter = &SEC_MFC_H264Dec_SetParameter; + pOMXComponent->GetConfig = &SEC_MFC_H264Dec_GetConfig; pOMXComponent->SetConfig = &SEC_MFC_H264Dec_SetConfig; pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Dec_GetExtensionIndex; pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Dec_ComponentRoleEnum; |