diff options
author | SeungBeom Kim <sbcrux.kim@samsung.com> | 2011-08-16 14:33:17 +0900 |
---|---|---|
committer | JP Abgrall <jpa@google.com> | 2011-09-29 18:59:52 -0700 |
commit | cf663174a6221ba8b2442bc7d6507e797a3954f9 (patch) | |
tree | 965457258524c91895555445fadb19d2cf54af41 /sec_mm | |
parent | 70bfae5cdf49fbed04b9994c307bcf90a45c1a9f (diff) | |
download | device_samsung_crespo-cf663174a6221ba8b2442bc7d6507e797a3954f9.zip device_samsung_crespo-cf663174a6221ba8b2442bc7d6507e797a3954f9.tar.gz device_samsung_crespo-cf663174a6221ba8b2442bc7d6507e797a3954f9.tar.bz2 |
Changed SEC-OMX for decoding and encoding speed improvements.
1. I separate thread for decode and other(CSC) in OMX component.
OMX is processing color converting when one frame decoding. (parallel processing.)
(n-1)frame CSC with (n)frame decode are process At the same time.
Encoding scheme is the same as decoding scheme.
2. MFC use cacheable input and ouput buffer.
Because, ICS framework can not use '0'copy. use real data.
Therefore, should be used Cacheable buffer at CSC for performance.
Dependencies
- Change Ia0191181: S5PC11X: MFC: MFC use cacheable buffer for improve performance.
Change-Id: Ib07a00f2569dd80b9def015d4b1fdcfbb9d36c67
Signed-off-by: SeungBeom Kim <sbcrux.kim@samsung.com>
Diffstat (limited to 'sec_mm')
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; |