diff options
14 files changed, 951 insertions, 328 deletions
diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c index 19b63b0..8e47683 100644 --- a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c @@ -84,11 +84,13 @@ out: return MFC_UNPACKED_PB; } -void *SsbSipMfcDecOpen(void) +void *SsbSipMfcDecOpen(void *value) { int hMFCOpen; unsigned int mapped_addr; _MFCLIB *pCTX; + mfc_common_args DecArg; + int ret_code; pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); if (pCTX == NULL) { @@ -103,6 +105,17 @@ void *SsbSipMfcDecOpen(void) return NULL; } + if (*(unsigned int *)value == NO_CACHE || + *(unsigned int *)value == CACHE) { + DecArg.args.buf_type = *(unsigned int *)value; + ret_code = ioctl(hMFCOpen, IOCTL_MFC_BUF_CACHE, &DecArg); + if (DecArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecOpenExt: IOCTL_MFC_BUF_CACHE (%d) failed\n", DecArg.ret_code); + } + } else { + LOGE("SsbSipMfcDecOpenExt: value is invalid, value: %d\n", *(int *)value); + } + mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); if (!mapped_addr) { LOGE("SsbSipMfcDecOpen: FIMV5.0 driver address mapping failed\n"); diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c index 9216c7b..b51a55f 100644 --- a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c @@ -30,11 +30,13 @@ #define _MFCLIB_MAGIC_NUMBER 0x92241001 -void *SsbSipMfcEncOpen(void) +void *SsbSipMfcEncOpen(void *value) { int hMFCOpen; _MFCLIB *pCTX; unsigned int mapped_addr; + mfc_common_args EncArg; + int ret_code; hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY); if (hMFCOpen < 0) { @@ -49,6 +51,17 @@ void *SsbSipMfcEncOpen(void) return NULL; } + if (*(unsigned int *)value == NO_CACHE || + *(unsigned int *)value == CACHE) { + EncArg.args.buf_type = *(unsigned int *)value; + ret_code = ioctl(hMFCOpen, IOCTL_MFC_BUF_CACHE, &EncArg); + if (EncArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecOpenExt: IOCTL_MFC_BUF_CACHE (%d) failed\n", EncArg.ret_code); + } + } else { + LOGE("SsbSipMfcDecOpenExt: value is invalid, value: %d\n", *(int *)value); + } + mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); if (!mapped_addr) { LOGE("SsbSipMfcEncOpen: FIMV5.0 driver address mapping failed\n"); @@ -374,6 +387,13 @@ SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; EncArg.args.enc_exe.in_frametag = pCTX->in_frametag; + if (pCTX->encode_cnt == 0) { + EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; + EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; + } else { + EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2); + EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2) + pCTX->sizeStrmBuf; + } ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg); if (EncArg.ret_code != MFC_RET_OK) { @@ -534,8 +554,17 @@ SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUT output_info->headerSize = pCTX->encodedHeaderSize; output_info->dataSize = pCTX->encodedDataSize; - output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; - output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; + + if (pCTX->encode_cnt == 0) { + output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; + output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; + } else { + output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2); + output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2); + } + + pCTX->encode_cnt ++; + pCTX->encode_cnt %= 2; if (pCTX->encodedframeType == 0) output_info->frameType = MFC_FRAME_TYPE_NOT_CODED; diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h index a07739a..3c10390 100644 --- a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h @@ -61,6 +61,11 @@ typedef enum { } SSBSIP_MFC_INSTRM_MODE_TYPE; typedef enum { + NO_CACHE = 0, + CACHE = 1 +} SSBIP_MFC_BUFFER_TYPE; + +typedef enum { MFC_DEC_SETCONF_POST_ENABLE = 1, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, MFC_DEC_SETCONF_DISPLAY_DELAY, @@ -289,7 +294,7 @@ extern "C" { /*--------------------------------------------------------------------------------*/ /* Decoding APIs */ /*--------------------------------------------------------------------------------*/ -void *SsbSipMfcDecOpen(void); +void *SsbSipMfcDecOpen(void *value); SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); @@ -305,7 +310,7 @@ SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CON /*--------------------------------------------------------------------------------*/ /* Encoding APIs */ /*--------------------------------------------------------------------------------*/ -void *SsbSipMfcEncOpen(void); +void *SsbSipMfcEncOpen(void *value); SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h index f4a1f42..466860d 100644 --- a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h @@ -31,6 +31,8 @@ #define IOCTL_MFC_SET_CONFIG 0x00800101 #define IOCTL_MFC_GET_CONFIG 0x00800102 +#define IOCTL_MFC_BUF_CACHE 0x00801000 + /* MFC H/W support maximum 32 extra DPB */ #define MFC_MAX_EXTRA_DPB 5 @@ -283,6 +285,11 @@ typedef struct tag_mem_free_arg_t unsigned int u_addr; } mfc_mem_free_arg_t; +typedef enum { + MFC_BUFFER_NO_CACHE = 0, + MFC_BUFFER_CACHE = 1 +} mfc_buffer_type; + typedef union { mfc_enc_init_mpeg4_arg_t enc_init_mpeg4; mfc_enc_init_h263_arg_t enc_init_h263; @@ -298,6 +305,8 @@ typedef union { mfc_mem_alloc_arg_t mem_alloc; mfc_mem_free_arg_t mem_free; mfc_get_phys_addr_arg_t get_phys_addr; + + mfc_buffer_type buf_type; } mfc_args; typedef struct tag_mfc_args { @@ -332,6 +341,7 @@ typedef struct { int out_frametag_bottom; unsigned int encoded_Y_paddr; unsigned int encoded_C_paddr; + unsigned int encode_cnt; } _MFCLIB; #endif /* _MFC_INTERFACE_H_ */ 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; |