summaryrefslogtreecommitdiffstats
path: root/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c
diff options
context:
space:
mode:
authorSeungBeom Kim <sbcrux.kim@samsung.com>2011-08-16 14:33:17 +0900
committerJP Abgrall <jpa@google.com>2011-09-29 18:59:52 -0700
commitcf663174a6221ba8b2442bc7d6507e797a3954f9 (patch)
tree965457258524c91895555445fadb19d2cf54af41 /sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c
parent70bfae5cdf49fbed04b9994c307bcf90a45c1a9f (diff)
downloaddevice_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/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c')
-rw-r--r--sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c355
1 files changed, 236 insertions, 119 deletions
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();