diff options
Diffstat (limited to 'sec_mm/sec_omx/sec_omx_component')
10 files changed, 888 insertions, 322 deletions
diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h index d9e265b..52130f0 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h @@ -43,6 +43,7 @@ #define DEFAULT_VIDEO_INPUT_BUFFER_SIZE ((DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2) #define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE ((DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2) +#define MFC_INPUT_BUFFER_NUM_MAX 2 #define DEFAULT_MFC_INPUT_BUFFER_SIZE ((1280 * 720 * 3) / 2) #define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 @@ -58,6 +59,24 @@ typedef struct void *pAddrC; } MFC_DEC_ADDR_INFO; +typedef struct _SEC_MFC_NBDEC_THREAD +{ + OMX_HANDLETYPE hNBDecodeThread; + OMX_HANDLETYPE hDecFrameStart; + OMX_HANDLETYPE hDecFrameEnd; + OMX_BOOL bExitDecodeThread; + OMX_BOOL bDecoderRun; + + OMX_U32 oneFrameSize; +} SEC_MFC_NBDEC_THREAD; + +typedef struct _MFC_DEC_INPUT_BUFFER +{ + void *PhyAddr; // physical address + void *VirAddr; // virtual address + int bufferSize; // input buffer alloc size + int dataSize; // Data length +} MFC_DEC_INPUT_BUFFER; #ifdef __cplusplus extern "C" { 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 f341130..1c72195 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 @@ -743,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) { @@ -760,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; @@ -768,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); @@ -805,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; @@ -824,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(); @@ -840,7 +915,7 @@ 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 */ @@ -852,8 +927,8 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA 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]; @@ -939,25 +1014,19 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA pSECComponent->bUseFlagEOF = OMX_TRUE; #endif - if (Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { - 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)); + pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - 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; - pH264Dec->hMFCH264Handle.indexTimestamp++; - pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + /* 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); @@ -971,100 +1040,14 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA 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)) { - /** Fill Output Buffer **/ - int frameSize = bufWidth * bufHeight; - int imageSize = outputInfo.img_width * outputInfo.img_height; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - void *pOutputBuf[3]; - - 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(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 { - 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, - actualWidth, - actualHeight); - csc_tiled_to_linear_deinterleave( - (unsigned char *)pOutputBuf[1], - (unsigned char *)pOutputBuf[2], - (unsigned char *)outputInfo.CVirAddr, - 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 + 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)) @@ -1079,7 +1062,7 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA } else { ret = OMX_ErrorNone; } - goto EXIT; + outputDataValid = OMX_FALSE; } #ifdef FULL_FRAME_SEARCH @@ -1108,11 +1091,145 @@ OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; pSECComponent->getAllDelayBuffer = OMX_FALSE; } - pOutputData->dataLen = 0; + outputDataValid = OMX_FALSE; /* ret = OMX_ErrorUndefined; */ ret = OMX_ErrorNone; - goto EXIT; + } + + 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; + } + + 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; + pH264Dec->bFirstFrame = OMX_FALSE; + } + + /** 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]; + + 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(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 { + 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, + actualWidth, + actualHeight); + csc_tiled_to_linear_deinterleave( + (unsigned char *)pOutputBuf[1], + (unsigned char *)pOutputBuf[2], + (unsigned char *)outputInfo.CVirAddr, + 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: diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h index b1374fb..d3f8ac8 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h @@ -40,6 +40,7 @@ typedef struct _SEC_MFC_H264DEC_HANDLE OMX_U32 indexTimestamp; OMX_BOOL bConfiguredMFC; OMX_BOOL bThumbnailMode; + OMX_S32 returnCodec; } SEC_MFC_H264DEC_HANDLE; typedef struct _SEC_H264DEC_HANDLE @@ -50,6 +51,12 @@ typedef struct _SEC_H264DEC_HANDLE /* SEC MFC Codec specific */ SEC_MFC_H264DEC_HANDLE hMFCH264Handle; + + /* For Non-Block mode */ + SEC_MFC_NBDEC_THREAD NBDecThread; + OMX_BOOL bFirstFrame; + MFC_DEC_INPUT_BUFFER MFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; } SEC_H264DEC_HANDLE; #ifdef __cplusplus diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c index febb453..cea12c3 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c @@ -903,6 +903,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_MPEG4_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + + while (pMpeg4Dec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pMpeg4Dec->NBDecThread.hDecFrameStart); + + if (pMpeg4Dec->NBDecThread.bExitDecodeThread == OMX_FALSE) { + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecExe(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, pMpeg4Dec->NBDecThread.oneFrameSize); + SEC_OSAL_SemaphorePost(pMpeg4Dec->NBDecThread.hDecFrameEnd); + } + } + +EXIT: + SEC_OSAL_ThreadExit(NULL); + FunctionOut(); + + return ret; +} + /* MFC Init */ OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) { @@ -921,7 +954,8 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->bSaveFlagEOS = OMX_FALSE; /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ - hMFCHandle = SsbSipMfcDecOpen(); + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(&buf_type); if (hMFCHandle == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -934,10 +968,34 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) ret = OMX_ErrorInsufficientResources; goto EXIT; } - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pStreamBuffer; - pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pStreamPhyBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pStreamBuffer; - pSECComponent->processData[INPUT_PORT_INDEX].allocSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + + pMpeg4Dec->MFCDecInputBuffer[0].VirAddr = pStreamBuffer; + pMpeg4Dec->MFCDecInputBuffer[0].PhyAddr = pStreamPhyBuffer; + pMpeg4Dec->MFCDecInputBuffer[0].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pMpeg4Dec->MFCDecInputBuffer[0].dataSize = 0; + pMpeg4Dec->MFCDecInputBuffer[1].VirAddr = (unsigned char *)pStreamBuffer + pMpeg4Dec->MFCDecInputBuffer[0].bufferSize; + pMpeg4Dec->MFCDecInputBuffer[1].PhyAddr = (unsigned char *)pStreamPhyBuffer + pMpeg4Dec->MFCDecInputBuffer[0].bufferSize; + pMpeg4Dec->MFCDecInputBuffer[1].bufferSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + pMpeg4Dec->MFCDecInputBuffer[1].dataSize = 0; + pMpeg4Dec->indexInputBuffer = 0; + + pMpeg4Dec->bFirstFrame = OMX_TRUE; + + pMpeg4Dec->NBDecThread.bExitDecodeThread = OMX_FALSE; + pMpeg4Dec->NBDecThread.bDecoderRun = OMX_FALSE; + pMpeg4Dec->NBDecThread.oneFrameSize = 0; + SEC_OSAL_SemaphoreCreate(&(pMpeg4Dec->NBDecThread.hDecFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pMpeg4Dec->NBDecThread.hDecFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pMpeg4Dec->NBDecThread.hNBDecodeThread, + SEC_MFC_DecodeThread, + pOMXComponent)) { + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + } + + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pMpeg4Dec->MFCDecInputBuffer[0].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pMpeg4Dec->MFCDecInputBuffer[0].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pMpeg4Dec->MFCDecInputBuffer[0].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pMpeg4Dec->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); @@ -968,6 +1026,23 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + if (pMpeg4Dec->NBDecThread.hNBDecodeThread != NULL) { + pMpeg4Dec->NBDecThread.bExitDecodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pMpeg4Dec->NBDecThread.hDecFrameStart); + SEC_OSAL_ThreadTerminate(pMpeg4Dec->NBDecThread.hNBDecodeThread); + pMpeg4Dec->NBDecThread.hNBDecodeThread = NULL; + } + + if(pMpeg4Dec->NBDecThread.hDecFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pMpeg4Dec->NBDecThread.hDecFrameEnd); + pMpeg4Dec->NBDecThread.hDecFrameEnd = NULL; + } + + if(pMpeg4Dec->NBDecThread.hDecFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pMpeg4Dec->NBDecThread.hDecFrameStart); + pMpeg4Dec->NBDecThread.hDecFrameStart = NULL; + } + if (hMFCHandle != NULL) { SsbSipMfcDecClose(hMFCHandle); pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL; @@ -987,10 +1062,10 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; OMX_U32 oneFrameSize = pInputData->dataLen; SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; - OMX_S32 configValue; - OMX_S32 returnCodec; - int bufWidth; - int bufHeight; + OMX_S32 configValue = 0; + int bufWidth = 0; + int bufHeight = 0; + OMX_BOOL outputDataValid = OMX_FALSE; FunctionIn(); @@ -1013,7 +1088,7 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT } /* Set the number of extra buffer to prevent tearing */ - configValue = 5; + configValue = 0; SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); /* Set mpeg4 deblocking filter enable */ @@ -1025,8 +1100,8 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); } - returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); - if (returnCodec == MFC_RET_OK) { + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); + if (pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { SSBSIP_MFC_IMG_RESOLUTION imgResol; SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; @@ -1084,25 +1159,19 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT pSECComponent->bUseFlagEOF = OMX_TRUE; #endif - if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) { - pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); + pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - returnCodec = SsbSipMfcDecExe(hMFCHandle, oneFrameSize); - } else { - pOutputData->timeStamp = pInputData->timeStamp; - pOutputData->nFlags = pInputData->nFlags; - returnCodec = MFC_RET_OK; - goto EXIT; - } - - if (returnCodec == MFC_RET_OK) { + if ((pMpeg4Dec->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && + (pMpeg4Dec->bFirstFrame == OMX_FALSE)) { SSBSIP_MFC_DEC_OUTBUF_STATUS status; OMX_S32 indexTimestamp = 0; - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + /* wait for mfc decode done */ + if (pMpeg4Dec->NBDecThread.bDecoderRun == OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pMpeg4Dec->NBDecThread.hDecFrameEnd); + pMpeg4Dec->NBDecThread.bDecoderRun = OMX_FALSE; + } status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); bufWidth = (outputInfo.img_width + 15) & (~15); @@ -1116,100 +1185,14 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT 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)) { - /** Fill Output Buffer **/ - int frameSize = bufWidth * bufHeight; - int imageSize = outputInfo.img_width * outputInfo.img_height; - SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; - SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; - void *pOutputBuf[3]; - - 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 ((pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode == OMX_FALSE) && - (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) - { - /* if use Post copy address structure */ - 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 { - switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].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, - actualWidth, - actualHeight); - csc_tiled_to_linear_deinterleave( - (unsigned char *)pOutputBuf[1], - (unsigned char *)pOutputBuf[2], - (unsigned char *)outputInfo.CVirAddr, - 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 + 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)) @@ -1224,7 +1207,7 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT } else { ret = OMX_ErrorNone; } - goto EXIT; + outputDataValid = OMX_FALSE; } #ifdef FULL_FRAME_SEARCH @@ -1253,13 +1236,147 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; pSECComponent->getAllDelayBuffer = OMX_FALSE; } - pOutputData->dataLen = 0; + outputDataValid = OMX_FALSE; /* ret = OMX_ErrorUndefined; */ ret = OMX_ErrorNone; - goto EXIT; } + if (ret == OMX_ErrorInputDataDecodeYet) { + pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].dataSize = oneFrameSize; + pMpeg4Dec->indexInputBuffer++; + pMpeg4Dec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].bufferSize; + oneFrameSize = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].dataSize; + //pInputData->dataLen = oneFrameSize; + //pInputData->remainDataLen = oneFrameSize; + } + + if ((Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) && + ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + + SsbSipMfcDecSetInBuf(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer, + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer, + pSECComponent->processData[INPUT_PORT_INDEX].allocSize); + + pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].dataSize = oneFrameSize; + pMpeg4Dec->NBDecThread.oneFrameSize = oneFrameSize; + + /* mfc decode start */ + SEC_OSAL_SemaphorePost(pMpeg4Dec->NBDecThread.hDecFrameStart); + pMpeg4Dec->NBDecThread.bDecoderRun = OMX_TRUE; + pMpeg4Dec->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + + pMpeg4Dec->indexInputBuffer++; + pMpeg4Dec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].VirAddr; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].PhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].VirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = pMpeg4Dec->MFCDecInputBuffer[pMpeg4Dec->indexInputBuffer].bufferSize; + pMpeg4Dec->bFirstFrame = OMX_FALSE; + } + + /** 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]; + + 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 ((pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) + { + /* if use Post copy address structure */ + 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 { + switch (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].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, + actualWidth, + actualHeight); + csc_tiled_to_linear_deinterleave( + (unsigned char *)pOutputBuf[1], + (unsigned char *)pOutputBuf[2], + (unsigned char *)outputInfo.CVirAddr, + 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: FunctionOut(); diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h index 25170b8..9af04e3 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h @@ -64,6 +64,7 @@ typedef struct _SEC_MFC_MPEG4_HANDLE OMX_BOOL bConfiguredMFC; OMX_BOOL bThumbnailMode; CODEC_TYPE codecType; + OMX_S32 returnCodec; } SEC_MFC_MPEG4_HANDLE; typedef struct _SEC_MPEG4_HANDLE @@ -75,6 +76,12 @@ typedef struct _SEC_MPEG4_HANDLE /* SEC MFC Codec specific */ SEC_MFC_MPEG4_HANDLE hMFCMpeg4Handle; + + /* For Non-Block mode */ + SEC_MFC_NBDEC_THREAD NBDecThread; + OMX_BOOL bFirstFrame; + MFC_DEC_INPUT_BUFFER MFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; } SEC_MPEG4_HANDLE; #ifdef __cplusplus diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h index 2c9ad54..ac24e10 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h @@ -44,6 +44,8 @@ /* (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 */ #define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE DEFAULT_VIDEO_INPUT_BUFFER_SIZE +#define MFC_INPUT_BUFFER_NUM_MAX 2 + #ifdef USE_ANDROID_EXTENSION #define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 4 #else @@ -63,6 +65,26 @@ typedef struct void *pAddrC; } MFC_ENC_ADDR_INFO; +typedef struct _SEC_MFC_NBENC_THREAD +{ + OMX_HANDLETYPE hNBEncodeThread; + OMX_HANDLETYPE hEncFrameStart; + OMX_HANDLETYPE hEncFrameEnd; + OMX_BOOL bExitEncodeThread; + OMX_BOOL bEncoderRun; +} SEC_MFC_NBENC_THREAD; + +typedef struct _MFC_ENC_INPUT_BUFFER +{ + void *YPhyAddr; // physical address of Y + void *CPhyAddr; // physical address of CbCr + void *YVirAddr; // virtual address of Y + void *CVirAddr; // virtual address of CbCr + int YBufferSize; // input buffer alloc size of Y + int CBufferSize; // input buffer alloc size of CbCr + int YDataSize; // input size of Y data + int CDataSize; // input size of CbCr data +} MFC_ENC_INPUT_BUFFER; #ifdef __cplusplus extern "C" { diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c index f038e17..a7f7ad5 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c @@ -251,18 +251,30 @@ void Set_H264ENC_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONEN } #endif +/* SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); switch (pSECOutputPort->eControlRate) { - case OMX_Video_ControlRateDisable: - /* TBD */ - break; case OMX_Video_ControlRateVariable: - /* TBD */ + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 100; break; - default: + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 1; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; + pH264Arg->EnableMBRateControl = 0; + pH264Arg->CBRPeriodRf = 100; break; } - +*/ H264PrintParams(*pH264Arg); } @@ -723,11 +735,45 @@ EXIT: return ret; } +OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + + while (pH264Enc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pH264Enc->NBEncThread.hEncFrameStart); + + if (pH264Enc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); + SEC_OSAL_SemaphorePost(pH264Enc->NBEncThread.hEncFrameEnd); + } + } + +EXIT: + FunctionOut(); + SEC_OSAL_ThreadExit(NULL); + + return ret; +} + /* MFC Init */ OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; SEC_H264ENC_HANDLE *pH264Enc = NULL; OMX_PTR hMFCHandle = NULL; @@ -741,7 +787,8 @@ OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->bSaveFlagEOS = OMX_FALSE; /* MFC(Multi Function Codec) encoder and CMM(Codec Memory Management) driver open */ - hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(&buf_type); if (hMFCHandle == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -758,16 +805,52 @@ OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) ret = OMX_ErrorInsufficientResources; goto EXIT; } + pH264Enc->MFCEncInputBuffer[0].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; + pH264Enc->MFCEncInputBuffer[0].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; + pH264Enc->MFCEncInputBuffer[0].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; + pH264Enc->MFCEncInputBuffer[0].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; + pH264Enc->MFCEncInputBuffer[0].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; + pH264Enc->MFCEncInputBuffer[0].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + pH264Enc->MFCEncInputBuffer[0].YDataSize = 0; + pH264Enc->MFCEncInputBuffer[0].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Enc->MFCEncInputBuffer[1].YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; + pH264Enc->MFCEncInputBuffer[1].CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; + pH264Enc->MFCEncInputBuffer[1].YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; + pH264Enc->MFCEncInputBuffer[1].CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; + pH264Enc->MFCEncInputBuffer[1].YBufferSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; + pH264Enc->MFCEncInputBuffer[1].CBufferSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + pH264Enc->MFCEncInputBuffer[1].YDataSize = 0; + pH264Enc->MFCEncInputBuffer[1].CDataSize = 0; SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pH264Enc->MFCEncInputBuffer[0].YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pH264Enc->MFCEncInputBuffer[0].CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pH264Enc->MFCEncInputBuffer[0].YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pH264Enc->MFCEncInputBuffer[0].CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pH264Enc->MFCEncInputBuffer[0].YBufferSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pH264Enc->MFCEncInputBuffer[0].CBufferSize; + + pH264Enc->indexInputBuffer = 0; + pH264Enc->bFirstFrame = OMX_TRUE; + + pH264Enc->NBEncThread.bExitEncodeThread = OMX_FALSE; + pH264Enc->NBEncThread.bEncoderRun = OMX_FALSE; + SEC_OSAL_SemaphoreCreate(&(pH264Enc->NBEncThread.hEncFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pH264Enc->NBEncThread.hEncFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pH264Enc->NBEncThread.hNBEncodeThread, + SEC_MFC_EncodeThread, + pOMXComponent)) { + pH264Enc->hMFCH264Handle.returnCodec = MFC_RET_OK; + } SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); @@ -790,8 +873,25 @@ OMX_ERRORTYPE SEC_MFC_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; - hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + if (pH264Enc->NBEncThread.hNBEncodeThread != NULL) { + pH264Enc->NBEncThread.bExitEncodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pH264Enc->NBEncThread.hEncFrameStart); + SEC_OSAL_ThreadTerminate(pH264Enc->NBEncThread.hNBEncodeThread); + pH264Enc->NBEncThread.hNBEncodeThread = NULL; + } + + if(pH264Enc->NBEncThread.hEncFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pH264Enc->NBEncThread.hEncFrameEnd); + pH264Enc->NBEncThread.hEncFrameEnd = NULL; + } + + if(pH264Enc->NBEncThread.hEncFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pH264Enc->NBEncThread.hEncFrameStart); + pH264Enc->NBEncThread.hEncFrameStart = NULL; + } + + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; if (hMFCHandle != NULL) { SsbSipMfcEncClose(hMFCHandle); hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL; @@ -813,20 +913,19 @@ OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA SEC_OMX_BASEPORT *pSECPort = NULL; MFC_ENC_ADDR_INFO addrInfo; OMX_U32 oneFrameSize = pInputData->dataLen; - OMX_S32 returnCodec = 0; FunctionIn(); if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { Set_H264ENC_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); - returnCodec = SsbSipMfcEncInit(pH264Enc->hMFCH264Handle.hMFCHandle, &(pH264Enc->hMFCH264Handle.mfcVideoAvc)); - if (returnCodec != MFC_RET_OK) { + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncInit(pH264Enc->hMFCH264Handle.hMFCHandle, &(pH264Enc->hMFCH264Handle.mfcVideoAvc)); + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { ret = OMX_ErrorInsufficientResources; goto EXIT; } - returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); - if (returnCodec != MFC_RET_OK) + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); ret = OMX_ErrorUndefined; @@ -866,12 +965,6 @@ OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA pSECComponent->bUseFlagEOF = OMX_TRUE; } - pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); - pH264Enc->hMFCH264Handle.indexTimestamp++; - pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; - if (oneFrameSize <= 0) { pOutputData->timeStamp = pInputData->timeStamp; pOutputData->nFlags = pInputData->nFlags; @@ -898,18 +991,20 @@ OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA pInputInfo->CPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr; } - ret = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); - if (ret != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); - ret = OMX_ErrorUndefined; - goto EXIT; - } + pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; - returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); - if (returnCodec == MFC_RET_OK) { + if ((pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) && + (pH264Enc->bFirstFrame == OMX_FALSE)) { OMX_S32 indexTimestamp = 0; - returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + /* wait for mfc encode done */ + if (pH264Enc->NBEncThread.bEncoderRun != OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pH264Enc->NBEncThread.hEncFrameEnd); + pH264Enc->NBEncThread.bEncoderRun = OMX_FALSE; + } + + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))){ pOutputData->timeStamp = pInputData->timeStamp; @@ -919,7 +1014,7 @@ OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; } - if (returnCodec == MFC_RET_OK) { + if (pH264Enc->hMFCH264Handle.returnCodec == MFC_RET_OK) { /** Fill Output Buffer **/ pOutputData->dataBuffer = outputInfo.StrmVirAddr; pOutputData->allocSize = outputInfo.dataSize; @@ -933,14 +1028,42 @@ OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); ret = OMX_ErrorNone; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pH264Enc->hMFCH264Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; } } + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe Failed!!!\n", __func__); + ret = OMX_ErrorUndefined; + } - if (returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe OR SsbSipMfcEncGetOutBuf Failed!!!\n", __func__); + pH264Enc->hMFCH264Handle.returnCodec = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); + if (pH264Enc->hMFCH264Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pH264Enc->indexInputBuffer++; + pH264Enc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].YBufferSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pH264Enc->MFCEncInputBuffer[pH264Enc->indexInputBuffer].CBufferSize; } + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); + + /* mfc encode start */ + SEC_OSAL_SemaphorePost(pH264Enc->NBEncThread.hEncFrameStart); + pH264Enc->NBEncThread.bEncoderRun = OMX_TRUE; + pH264Enc->hMFCH264Handle.indexTimestamp++; + pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP; + pH264Enc->bFirstFrame = OMX_FALSE; + EXIT: FunctionOut(); diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h index 80f6260..bdd525f 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h @@ -47,9 +47,10 @@ typedef struct _SEC_MFC_H264ENC_HANDLE SSBSIP_MFC_ENC_H264_PARAM mfcVideoAvc; SSBSIP_MFC_ENC_INPUT_INFO inputInfo; /* SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; */ - OMX_U32 indexTimestamp; + OMX_U32 indexTimestamp; OMX_BOOL bConfiguredMFC; EXTRA_DATA headerData; + OMX_S32 returnCodec; } SEC_MFC_H264ENC_HANDLE; typedef struct _SEC_H264ENC_HANDLE @@ -60,6 +61,12 @@ typedef struct _SEC_H264ENC_HANDLE /* SEC MFC Codec specific */ SEC_MFC_H264ENC_HANDLE hMFCH264Handle; + + /* For Non-Block mode */ + SEC_MFC_NBENC_THREAD NBEncThread; + OMX_BOOL bFirstFrame; + MFC_ENC_INPUT_BUFFER MFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; } SEC_H264ENC_HANDLE; #ifdef __cplusplus diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c index 8c29d47..8fdd41e 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c @@ -235,18 +235,30 @@ void Set_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOM } #endif +/* SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); switch (pSECOutputPort->eControlRate) { - case OMX_Video_ControlRateDisable: - /* TBD */ - break; case OMX_Video_ControlRateVariable: - /* TBD */ + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 100; break; - default: + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 1; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; + pH264Arg->EnableMBRateControl = 0; + pH264Arg->CBRPeriodRf = 100; break; } - +*/ Mpeg4PrintParams(*pMpeg4Param); } @@ -300,18 +312,30 @@ void Set_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPON } #endif +/* SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); switch (pSECOutputPort->eControlRate) { - case OMX_Video_ControlRateDisable: - /* TBD */ - break; case OMX_Video_ControlRateVariable: - /* TBD */ + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 100; break; - default: + case OMX_Video_ControlRateConstant: + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode CBR"); + pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH264Arg->EnableMBRateControl = 1; // 0: Disable, 1:MB level RC + pH264Arg->CBRPeriodRf = 10; + break; + case OMX_Video_ControlRateDisable: + default: //Android default + SEC_OSAL_Log(SEC_LOG_TRACE, "Video Encode VBR"); + pH264Arg->EnableFRMRateControl = 0; + pH264Arg->EnableMBRateControl = 0; + pH264Arg->CBRPeriodRf = 100; break; } - +*/ H263PrintParams(*pH263Param); } @@ -880,12 +904,47 @@ EXIT: return ret; } +OMX_ERRORTYPE SEC_MFC_EncodeThread(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + + while (pMpeg4Enc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pMpeg4Enc->NBEncThread.hEncFrameStart); + + if (pMpeg4Enc->NBEncThread.bExitEncodeThread == OMX_FALSE) { + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncExe(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle); + SEC_OSAL_SemaphorePost(pMpeg4Enc->NBEncThread.hEncFrameEnd); + } + } + +EXIT: + FunctionOut(); + SEC_OSAL_ThreadExit(NULL); + + return ret; +} + /* MFC Init */ OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) { OMX_ERRORTYPE ret = OMX_ErrorNone; SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECPort = NULL; SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; OMX_HANDLETYPE hMFCHandle = NULL; OMX_S32 returnCodec = 0; @@ -898,7 +957,8 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) pSECComponent->bSaveFlagEOS = OMX_FALSE; /* MFC(Multi Format Codec) encoder and CMM(Codec Memory Management) driver open */ - hMFCHandle = SsbSipMfcEncOpen(); + SSBIP_MFC_BUFFER_TYPE buf_type = CACHE; + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(&buf_type); if (hMFCHandle == NULL) { ret = OMX_ErrorInsufficientResources; goto EXIT; @@ -922,13 +982,53 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) ret = OMX_ErrorInsufficientResources; goto EXIT; } + pMpeg4Enc->MFCEncInputBuffer[0].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; + pMpeg4Enc->MFCEncInputBuffer[0].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; + pMpeg4Enc->MFCEncInputBuffer[0].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; + pMpeg4Enc->MFCEncInputBuffer[0].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; + pMpeg4Enc->MFCEncInputBuffer[0].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; + pMpeg4Enc->MFCEncInputBuffer[0].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + pMpeg4Enc->MFCEncInputBuffer[0].YDataSize = 0; + pMpeg4Enc->MFCEncInputBuffer[0].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; - pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + /* allocate encoder's input buffer */ + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pMpeg4Enc->MFCEncInputBuffer[1].YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; + pMpeg4Enc->MFCEncInputBuffer[1].CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; + pMpeg4Enc->MFCEncInputBuffer[1].YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; + pMpeg4Enc->MFCEncInputBuffer[1].CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; + pMpeg4Enc->MFCEncInputBuffer[1].YBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; + pMpeg4Enc->MFCEncInputBuffer[1].CBufferSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + pMpeg4Enc->MFCEncInputBuffer[1].YDataSize = 0; + pMpeg4Enc->MFCEncInputBuffer[1].CDataSize = 0; + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr : 0x%x", pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr); + + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pMpeg4Enc->MFCEncInputBuffer[0].YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pMpeg4Enc->MFCEncInputBuffer[0].CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pMpeg4Enc->MFCEncInputBuffer[0].YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pMpeg4Enc->MFCEncInputBuffer[0].CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pMpeg4Enc->MFCEncInputBuffer[0].YBufferSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pMpeg4Enc->MFCEncInputBuffer[0].CBufferSize; + + pMpeg4Enc->indexInputBuffer = 0; + pMpeg4Enc->bFirstFrame = OMX_TRUE; + + pMpeg4Enc->NBEncThread.bExitEncodeThread = OMX_FALSE; + pMpeg4Enc->NBEncThread.bEncoderRun = OMX_FALSE; + SEC_OSAL_SemaphoreCreate(&(pMpeg4Enc->NBEncThread.hEncFrameStart)); + SEC_OSAL_SemaphoreCreate(&(pMpeg4Enc->NBEncThread.hEncFrameEnd)); + if (OMX_ErrorNone == SEC_OSAL_ThreadCreate(&pMpeg4Enc->NBEncThread.hNBEncodeThread, + SEC_MFC_EncodeThread, + pOMXComponent)) { + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = MFC_RET_OK; + } SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); @@ -951,8 +1051,25 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) FunctionIn(); pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; - hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + if (pMpeg4Enc->NBEncThread.hNBEncodeThread != NULL) { + pMpeg4Enc->NBEncThread.bExitEncodeThread = OMX_TRUE; + SEC_OSAL_SemaphorePost(pMpeg4Enc->NBEncThread.hEncFrameStart); + SEC_OSAL_ThreadTerminate(pMpeg4Enc->NBEncThread.hNBEncodeThread); + pMpeg4Enc->NBEncThread.hNBEncodeThread = NULL; + } + + if(pMpeg4Enc->NBEncThread.hEncFrameEnd != NULL) { + SEC_OSAL_SemaphoreTerminate(pMpeg4Enc->NBEncThread.hEncFrameEnd); + pMpeg4Enc->NBEncThread.hEncFrameEnd = NULL; + } + + if(pMpeg4Enc->NBEncThread.hEncFrameStart != NULL) { + SEC_OSAL_SemaphoreTerminate(pMpeg4Enc->NBEncThread.hEncFrameStart); + pMpeg4Enc->NBEncThread.hEncFrameStart = NULL; + } + + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; if (hMFCHandle != NULL) { SsbSipMfcEncClose(hMFCHandle); pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL; @@ -975,7 +1092,6 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT SEC_OMX_BASEPORT *pSECPort = NULL; MFC_ENC_ADDR_INFO addrInfo; OMX_U32 oneFrameSize = pInputData->dataLen; - OMX_S32 returnCodec = 0; FunctionIn(); @@ -983,20 +1099,20 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT /* set MFC ENC VIDEO PARAM and initialize MFC encoder instance */ if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { Set_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); - returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam)); + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam)); } else { Set_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); - returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam)); + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam)); } - if (returnCodec != MFC_RET_OK) { + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { ret = OMX_ErrorInsufficientResources; goto EXIT; } - returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); - if (returnCodec != MFC_RET_OK) + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); ret = OMX_ErrorUndefined; goto EXIT; } @@ -1019,12 +1135,6 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT pSECComponent->bUseFlagEOF = OMX_TRUE; } - pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; - pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; - pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; - if (oneFrameSize <= 0) { pOutputData->timeStamp = pInputData->timeStamp; pOutputData->nFlags = pInputData->nFlags; @@ -1051,19 +1161,20 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT pInputInfo->CPhyAddr = pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr; } - returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); - if (returnCodec != MFC_RET_OK) { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, returnCodec); - ret = OMX_ErrorUndefined; - goto EXIT; - } + pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; - returnCodec = SsbSipMfcEncExe(hMFCHandle); - if (returnCodec == MFC_RET_OK) { + if ((pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) && + (pMpeg4Enc->bFirstFrame == OMX_FALSE)) { OMX_S32 indexTimestamp = 0; - returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + /* wait for mfc encode done */ + if (pMpeg4Enc->NBEncThread.bEncoderRun != OMX_FALSE) { + SEC_OSAL_SemaphoreWait(pMpeg4Enc->NBEncThread.hEncFrameEnd); + pMpeg4Enc->NBEncThread.bEncoderRun = OMX_FALSE; + } + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); if ((SsbSipMfcEncGetConfig(hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || (((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)))) { pOutputData->timeStamp = pInputData->timeStamp; @@ -1073,25 +1184,54 @@ OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DAT pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; } - if (returnCodec == MFC_RET_OK) { + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec == MFC_RET_OK) { /** Fill Output Buffer **/ pOutputData->dataBuffer = outputInfo.StrmVirAddr; pOutputData->allocSize = outputInfo.dataSize; pOutputData->dataLen = outputInfo.dataSize; + pOutputData->usedDataLen = 0; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; ret = OMX_ErrorNone; } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); ret = OMX_ErrorUndefined; + goto EXIT; } - } else { - SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, returnCodec); + } + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); ret = OMX_ErrorUndefined; } + pMpeg4Enc->hMFCMpeg4Handle.returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); + if (pMpeg4Enc->hMFCMpeg4Handle.returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, pMpeg4Enc->hMFCMpeg4Handle.returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + pMpeg4Enc->indexInputBuffer++; + pMpeg4Enc->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].YBufferSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pMpeg4Enc->MFCEncInputBuffer[pMpeg4Enc->indexInputBuffer].CBufferSize; + } + + SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); + + /* mfc encode start */ + SEC_OSAL_SemaphorePost(pMpeg4Enc->NBEncThread.hEncFrameStart); + pMpeg4Enc->NBEncThread.bEncoderRun = OMX_TRUE; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP; + pMpeg4Enc->bFirstFrame = OMX_FALSE; + EXIT: FunctionOut(); diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h index d4f9038..36e02d8 100644 --- a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h @@ -47,6 +47,7 @@ typedef struct _SEC_MFC_MPEG4ENC_HANDLE OMX_U32 indexTimestamp; OMX_BOOL bConfiguredMFC; CODEC_TYPE codecType; + OMX_S32 returnCodec; } SEC_MFC_MPEG4ENC_HANDLE; typedef struct _SEC_MPEG4ENC_HANDLE @@ -58,6 +59,12 @@ typedef struct _SEC_MPEG4ENC_HANDLE /* SEC MFC Codec specific */ SEC_MFC_MPEG4ENC_HANDLE hMFCMpeg4Handle; + + /* For Non-Block mode */ + SEC_MFC_NBENC_THREAD NBEncThread; + OMX_BOOL bFirstFrame; + MFC_ENC_INPUT_BUFFER MFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX]; + OMX_U32 indexInputBuffer; } SEC_MPEG4ENC_HANDLE; |