diff options
author | Benny Wong <Benny.Wong@motorola.com> | 2009-11-20 09:50:54 -0600 |
---|---|---|
committer | James Dong <jdong@google.com> | 2009-12-08 17:39:14 -0800 |
commit | e074e61deca17dd3ffc4e431f30464943d225fe0 (patch) | |
tree | 4b2495987f5749fad17450a73a61dc71c0841cf4 | |
parent | c5b21bfb410626a503e479a5afa2095902783427 (diff) | |
download | omap3-e074e61deca17dd3ffc4e431f30464943d225fe0.tar.gz |
WMV Video decoder byte alignment fix
- rebased ...
Originally from: https://partner.source.android.com/g/#change,1497
3 files changed, 168 insertions, 85 deletions
diff --git a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h index 4fa2e74..be41808 100644 --- a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h +++ b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h @@ -162,6 +162,13 @@ typedef enum VIDDEC_ENUM_MEMLEVELS{ #endif #define __STD_COMPONENT__ + +/* + * MAX_PRIVATE_IN_BUFFERS and MAX_PRIVATE_OUT_BUFFERS must NOT be + * greater than MAX_PRIVATE_BUFFERS. MAX_PRIVATE_BUFFERS is set + * to 6 because 6 overlay buffers are currently being used for + * playback + */ #define MAX_PRIVATE_IN_BUFFERS 6 #define MAX_PRIVATE_OUT_BUFFERS 6 #define MAX_PRIVATE_BUFFERS 6 @@ -308,6 +315,7 @@ typedef enum VIDDEC_ENUM_MEMLEVELS{ #define VIDDEC_PADDING_FULL 256 #define VIDDEC_PADDING_HALF VIDDEC_PADDING_FULL / 2 +#define VIDDEC_ALIGNMENT 4 #define VIDDEC_CLEARFLAGS 0 #define H264VDEC_SN_MAX_NALUNITS 1200 @@ -367,7 +375,7 @@ typedef enum VIDDEC_ENUM_MEMLEVELS{ #define VIDDEC_WMV_PROFILE_ID8 8 #define VIDDEC_MAX_QUEUE_SIZE 256 -#define VIDDEC_WMV_BUFFER_OFFSET 255 - 4 +#define VIDDEC_WMV_BUFFER_OFFSET (255 - 4) #define VIDDEC_WMV_ELEMSTREAM 0 #define VIDDEC_WMV_RCVSTREAM 1 @@ -543,6 +551,7 @@ typedef struct VIDDEC_BUFFER_PRIVATE VIDDEC_BUFFER_OWNER eBufferOwner; VIDDEC_TYPE_ALLOCATE bAllocByComponent; OMX_U32 nNumber; + OMX_U8* pOriginalBuffer; #ifdef VIDDEC_WMVPOINTERFIXED OMX_U8* pTempBuffer; #endif @@ -1026,6 +1035,141 @@ typedef struct VIDDEC_COMPONENT_PRIVATE pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel4]*/ + +/*----------------------------------------------------------------------------*/ +/** + * OMX_ALIGN_BUFFER() Align the buffer to the desire number of bytes. + * + * This method will update the component function pointer to the handle + * + * @param _pBuffer_ Pointer to align + * @param _nBytes_ # of byte to alignment desire + * + **/ +/*----------------------------------------------------------------------------*/ + +#define OMX_ALIGN_BUFFER(_pBuffer_, _nBytes_) \ + _pBuffer_ = (OMX_U8*) ((((OMX_U32) _pBuffer_) + (_nBytes_ - 1)) & (~(_nBytes_ - 1))); + +/*----------------------------------------------------------------------------*/ +/** + * OMX_MALLOC_BUFFER_VIDDEC() Allocate buffer for video decoder component + * + * This method will allocate memory for the _pBuffer_. Taking care of cache + * coherency requirement and include configuration data if require. + * + * @param _pBuffer_ Pointer to buffer to be use + * @param _nSize_ # of byte to allocate + * @param _pOriginalBuffer_ Pointer to the original allocate address + * + **/ +/*----------------------------------------------------------------------------*/ + +#define OMX_MALLOC_BUFFER_VIDDEC(_pBuffer_, _nSize_, _pOriginalBuffer_) \ + _pBuffer_ = OMX_MALLOC_STRUCT_SIZED(_pBuffer_, OMX_U8, _nSize_ + VIDDEC_PADDING_FULL + VIDDEC_WMV_BUFFER_OFFSET + VIDDEC_ALIGNMENT, pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel1]); \ + _pOriginalBuffer_ = _pBuffer_; \ + _pBuffer_ += VIDDEC_PADDING_HALF; \ + OMX_ALIGN_BUFFER(_pBuffer_, VIDDEC_ALIGNMENT); + + +/*----------------------------------------------------------------------------*/ +/** + * OMX_FREE_VIDDEC() Free memory + * + * This method will free memory and set pointer to NULL + * + * @param _pBuffer_ Pointer to free + * + **/ +/*----------------------------------------------------------------------------*/ + +#define OMX_FREE_VIDDEC(_pBuffer_) \ + if(_pBuffer_ != NULL){ \ + free(_pBuffer_); \ + _pBuffer_ = NULL; \ + } + + + +/*----------------------------------------------------------------------------*/ +/** + * OMX_FREE_BUFFER_VIDDEC() Free video decoder buffer + * + * This method will free video decoder buffer + * + * @param _pBuffHead_ Buffer header pointer + * @param _pCompPort_ Component port will give us the reference to the + * desire buffer to free + * + **/ +/*----------------------------------------------------------------------------*/ + +#define OMX_FREE_BUFFER_VIDDEC(_pBuffHead_, _pCompPort_) \ + { \ + int _nBufferCount_ = 0; \ + OMX_U8* _pTemp_ = NULL; \ + \ + for(_nBufferCount_ = 0; _nBufferCount_ < MAX_PRIVATE_BUFFERS; _nBufferCount_++){ \ + if(_pCompPort_->pBufferPrivate[_nBufferCount_]->pBufferHdr != NULL){ \ + _pTemp_ = (OMX_U8*)_pCompPort_->pBufferPrivate[_nBufferCount_]->pBufferHdr->pBuffer; \ + if(_pBuffHead_->pBuffer == _pTemp_){ \ + break; \ + } \ + } \ + } \ + \ + if(_nBufferCount_ == MAX_PRIVATE_BUFFERS){ \ + OMX_ERROR4(pComponentPrivate->dbg, "Error: Buffer NOT found to free: %p \n", _pBuffHead_->pBuffer); \ + goto EXIT; \ + } \ + \ + _pBuffHead_->pBuffer = _pCompPort_->pBufferPrivate[_nBufferCount_]->pOriginalBuffer; \ + OMX_PRBUFFER1(pComponentPrivate->dbg, "Free original allocated buffer: %p\n", _pBuffHead_->pBuffer); \ + OMX_FREE_VIDDEC(_pBuffHead_->pBuffer); \ + } + + + +/*----------------------------------------------------------------------------*/ +/** + * OMX_WMV_INSERT_CODEC_DATA() + * + * This method will insert the codec data to the first frame to be sent to + * queue in LCML + * + * @param _pBuffHead_ Buffer header pointer + * @param _pComponentPrivate_ Component private structure to provide needed + * references + * + **/ +/*----------------------------------------------------------------------------*/ + +#define OMX_WMV_INSERT_CODEC_DATA(_pBuffHead_, _pComponentPrivate_) \ + { \ + OMX_U8* _pTempBuffer_ = NULL; \ + /* Copy frame data in a temporary buffer*/ \ + OMX_MALLOC_STRUCT_SIZED(_pTempBuffer_, OMX_U8, _pBuffHead_->nFilledLen, NULL); \ + memcpy (_pTempBuffer_, _pBuffHead_->pBuffer, _pBuffHead_->nFilledLen); \ + \ + /*Copy configuration data at the begining of the buffer*/ \ + memcpy (_pBuffHead_->pBuffer, _pComponentPrivate_->pCodecData, _pComponentPrivate_->nCodecDataSize); \ + _pBuffHead_->pBuffer += _pComponentPrivate_->nCodecDataSize; \ + /* Add frame start code */ \ + (*(_pBuffHead_->pBuffer++)) = 0x00; \ + (*(_pBuffHead_->pBuffer++)) = 0x00; \ + (*(_pBuffHead_->pBuffer++)) = 0x01; \ + (*(_pBuffHead_->pBuffer++)) = 0x0d; \ + \ + /* Insert again the frame buffer */ \ + memcpy (_pBuffHead_->pBuffer, _pTempBuffer_, _pBuffHead_->nFilledLen); \ + /* pTempBuffer no longer need*/ \ + OMX_FREE_VIDDEC(_pTempBuffer_); \ + \ + _pBuffHead_->pBuffer -= (pComponentPrivate->nCodecDataSize + 4); \ + _pBuffHead_->nFilledLen += pComponentPrivate->nCodecDataSize + 4; \ + } + + #define OMX_CONF_INIT_STRUCT(_s_, _name_, dbg) \ memset((_s_), 0x0, sizeof(_name_)); \ (_s_)->nSize = sizeof(_name_); \ diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c index e65fa00..ece2bf7 100644 --- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c +++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c @@ -1821,6 +1821,7 @@ OMX_ERRORTYPE VIDDEC_DisablePort (VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, O pComponentPrivate->sInSemaphore.bSignaled) { VIDDEC_PTHREAD_SEMAPHORE_WAIT(pComponentPrivate->sInSemaphore); } + OMX_PRBUFFER2(pComponentPrivate->dbg, "Populated VIDDEC_INPUT_PORT IN 0x%x\n",pComponentPrivate->pInPortDef->bPopulated); pComponentPrivate->bInPortSettingsChanged = OMX_FALSE; pComponentPrivate->cbInfo.EventHandler (pComponentPrivate->pHandle, @@ -5354,6 +5355,12 @@ OMX_ERRORTYPE VIDDEC_HandleDataBuf_FromApp(VIDDEC_COMPONENT_PRIVATE *pComponentP memcpy (pComponentPrivate->pCodecData, pBuffHead->pBuffer + pBuffHead->nOffset, pBuffHead->nFilledLen); #endif pComponentPrivate->nCodecDataSize = pBuffHead->nFilledLen; + if(pComponentPrivate->nCodecDataSize > VIDDEC_WMV_BUFFER_OFFSET){ + OMX_ERROR4(pComponentPrivate->dbg, "Insufficient space in buffer pbuffer %p - nCodecDataSize %u\n", + (void *)pBuffHead->pBuffer,pComponentPrivate->nCodecDataSize); + eError = OMX_ErrorStreamCorrupt; + goto EXIT; + } #ifdef VIDDEC_ACTIVATEPARSER eError = VIDDEC_ParseHeader( pComponentPrivate, pBuffHead); #endif @@ -5375,40 +5382,9 @@ OMX_ERRORTYPE VIDDEC_HandleDataBuf_FromApp(VIDDEC_COMPONENT_PRIVATE *pComponentP return OMX_ErrorNone; } else { - OMX_S32 nDifference = 0; - OMX_U8* pTempBuffer = NULL; + /* VC-1: First data buffer received, add configuration data to it*/ pComponentPrivate->bFirstHeader = OMX_TRUE; -#ifdef VIDDEC_WMVPOINTERFIXED - pTempBuffer = pBuffHead->pBuffer; -#else - pTempBuffer = pBuffHead->pBuffer + pBuffHead->nOffset; -#endif - (*(--pTempBuffer)) = 0x0d; - (*(--pTempBuffer)) = 0x01; - (*(--pTempBuffer)) = 0x00; - (*(--pTempBuffer)) = 0x00; - pTempBuffer -= pComponentPrivate->nCodecDataSize; -#ifdef VIDDEC_WMVPOINTERFIXED - nDifference = pBuffHead->pBuffer - pTempBuffer; -#else - nDifference = pTempBuffer - pBuffHead->pBuffer; -#endif - if (nDifference < 0) { - OMX_ERROR4(pComponentPrivate->dbg, "Insufficient space in buffer pbuffer %p - nOffset %p\n", - (void *)pBuffHead->pBuffer,(void *)pBuffHead->nOffset); - eError = OMX_ErrorStreamCorrupt; - goto EXIT; - } - memcpy (pTempBuffer, pComponentPrivate->pCodecData, pComponentPrivate->nCodecDataSize); - pBuffHead->nFilledLen += pComponentPrivate->nCodecDataSize + 4; -#ifdef VIDDEC_WMVPOINTERFIXED - pBuffHead->pBuffer = pTempBuffer; - pBuffHead->nOffset = 0; -#else - pBuffHead->nOffset = pTempBuffer - pBuffHead->pBuffer; -#endif - OMX_PRBUFFER1(pComponentPrivate->dbg, "pTempBuffer %p - pBuffHead->pBuffer %p - pBuffHead->nOffset %lx\n", - pTempBuffer,pBuffHead->pBuffer,pBuffHead->nOffset); + OMX_WMV_INSERT_CODEC_DATA(pBuffHead, pComponentPrivate); eError = OMX_ErrorNone; } } @@ -8970,7 +8946,7 @@ OMX_ERRORTYPE VIDDEC_Set_Debocking(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate) /* Disable if resolution higher than D1 NTSC (720x480) */ if(pComponentPrivate->pOutPortDef->format.video.nFrameWidth > 480 || pComponentPrivate->pOutPortDef->format.video.nFrameHeight > 480){ - bDisDeblocking = OMX_TRUE; + bDisDeblocking = OMX_TRUE; LOGD("D1 or higher resolution: Disable Deblocking!!"); } } diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c index 5e4fda9..166c1ea 100644 --- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c +++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c @@ -1446,7 +1446,7 @@ static OMX_ERRORTYPE VIDDEC_SetParameter (OMX_HANDLETYPE hComp, pComponentPrivate->pInPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingH263){ pComponentPrivate->pDeblockingParamType->bDeblocking = ((OMX_PARAM_DEBLOCKINGTYPE*)pCompParam)->bDeblocking; - LOGD("Deblocking Enable"); + LOGD("Deblocking Enable"); break; } } @@ -3075,20 +3075,8 @@ static OMX_ERRORTYPE VIDDEC_FreeBuffer (OMX_IN OMX_HANDLETYPE hComponent, PERF_ModuleMemory); #endif - pTemp = (OMX_U8*)(pBuffHead->pBuffer); -#ifdef VIDDEC_WMVPOINTERFIXED - if (pComponentPrivate->pInPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingWMV && - nPortIndex == VIDDEC_INPUT_PORT && - pComponentPrivate->ProcessMode == 0) { - pTemp -= VIDDEC_WMV_BUFFER_OFFSET; - OMX_PRBUFFER1(pComponentPrivate->dbg, "Removing extra wmv padding %d pBuffer 0x%p\n", VIDDEC_WMV_BUFFER_OFFSET, - pTemp); - } -#endif - pTemp -= VIDDEC_PADDING_HALF; - pBuffHead->pBuffer = (OMX_U8*)pTemp; - free(pBuffHead->pBuffer); - pBuffHead->pBuffer = NULL; + OMX_FREE_BUFFER_VIDDEC(pBuffHead, pCompPort); + } } @@ -3218,10 +3206,7 @@ static OMX_ERRORTYPE VIDDEC_AllocateBuffer (OMX_IN OMX_HANDLETYPE hComponent, VIDDEC_COMPONENT_PRIVATE* pComponentPrivate = NULL; OMX_PARAM_PORTDEFINITIONTYPE* pPortDef = NULL; VIDDEC_PORT_TYPE* pCompPort = NULL; - OMX_U8* pTemp = NULL; OMX_U8 pBufferCnt = 0; - OMX_U32 nTempSizeBytes = 0; - nTempSizeBytes = nSizeBytes; OMX_CONF_CHECK_CMD(hComponent, OMX_TRUE, OMX_TRUE); @@ -3231,14 +3216,6 @@ static OMX_ERRORTYPE VIDDEC_AllocateBuffer (OMX_IN OMX_HANDLETYPE hComponent, OMX_PRBUFFER1(pComponentPrivate->dbg, "+++Entering pHandle 0x%p pBuffHead 0x%p nPortIndex 0x%lx nSizeBytes 0x%lx\n", hComponent, *pBuffHead, nPortIndex, nSizeBytes); -#ifdef VIDDEC_WMVPOINTERFIXED - if (pComponentPrivate->pInPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingWMV && - nPortIndex == VIDDEC_INPUT_PORT && - pComponentPrivate->ProcessMode == 0) { - nTempSizeBytes += VIDDEC_WMV_BUFFER_OFFSET; - OMX_PRBUFFER1(pComponentPrivate->dbg, "Adding extra wmv buffer add %d size %lu\n", VIDDEC_WMV_BUFFER_OFFSET, nTempSizeBytes); - } -#endif if (nPortIndex == pComponentPrivate->pInPortFormat->nPortIndex) { pCompPort = pComponentPrivate->pCompPort[VIDDEC_INPUT_PORT]; pBufferCnt = pCompPort->nBufferCnt; @@ -3269,7 +3246,10 @@ static OMX_ERRORTYPE VIDDEC_AllocateBuffer (OMX_IN OMX_HANDLETYPE hComponent, *pBuffHead = pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr; memset(*pBuffHead, 0, sizeof(OMX_BUFFERHEADERTYPE)); OMX_CONF_INIT_STRUCT(pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr, OMX_BUFFERHEADERTYPE, pComponentPrivate->dbg); - OMX_MALLOC_STRUCT_SIZED(pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer, OMX_U8, nSizeBytes + VIDDEC_PADDING_FULL,pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel1]); + /* Allocate Video Decoder buffer */ + OMX_MALLOC_BUFFER_VIDDEC(pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer, + nSizeBytes, + pCompPort->pBufferPrivate[pBufferCnt]->pOriginalBuffer); if (!pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer) { eError = OMX_ErrorInsufficientResources; pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, @@ -3280,37 +3260,20 @@ static OMX_ERRORTYPE VIDDEC_AllocateBuffer (OMX_IN OMX_HANDLETYPE hComponent, NULL); goto EXIT; } - pTemp = (OMX_U8*)pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer; - pTemp += VIDDEC_PADDING_HALF; #ifdef VIDDEC_WMVPOINTERFIXED - if (pComponentPrivate->pInPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingWMV && - nPortIndex == VIDDEC_INPUT_PORT && - pComponentPrivate->ProcessMode == 0) { - pTemp += VIDDEC_WMV_BUFFER_OFFSET; - pCompPort->pBufferPrivate[pBufferCnt]->pTempBuffer = (OMX_U8*)pTemp; - (*pBuffHead)->nOffset = 0; - OMX_PRBUFFER1(pComponentPrivate->dbg, "Adding extra wmv padding %d pBuffer 0x%p\n", VIDDEC_WMV_BUFFER_OFFSET, - pTemp); - } + pCompPort->pBufferPrivate[pBufferCnt]->pTempBuffer = (pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer); + (*pBuffHead)->nOffset = 0; #endif - pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer = (OMX_U8*)pTemp; + (*pBuffHead)->pBuffer = (pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer); - (*pBuffHead)->nAllocLen = nTempSizeBytes; + (*pBuffHead)->nAllocLen = nSizeBytes; (*pBuffHead)->pAppPrivate = pAppPrivate; (*pBuffHead)->pPlatformPrivate = NULL; (*pBuffHead)->pInputPortPrivate = NULL; (*pBuffHead)->pOutputPortPrivate = NULL; (*pBuffHead)->nFlags = VIDDEC_CLEARFLAGS; (*pBuffHead)->pMarkData = NULL; -#ifndef VIDDEC_WMVPOINTERFIXED - if (pComponentPrivate->nWMVFileType == VIDDEC_WMV_ELEMSTREAM && - pComponentPrivate->pInPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingWMV && - pComponentPrivate->ProcessMode == 0 && - nPortIndex == VIDDEC_INPUT_PORT) { - /* vc-1 fix */ - (*pBuffHead)->nOffset = VIDDEC_WMV_BUFFER_OFFSET; - } -#endif + #ifdef __PERF_INSTRUMENTATION__ PERF_ReceivedFrame(pComponentPrivate->pPERFcomp, (*pBuffHead)->pBuffer, @@ -3357,7 +3320,7 @@ static OMX_ERRORTYPE VIDDEC_AllocateBuffer (OMX_IN OMX_HANDLETYPE hComponent, pCompPort->pBufferPrivate[pBufferCnt]->eBufferOwner = VIDDEC_BUFFER_WITH_CLIENT; } - pPortDef->nBufferSize = nTempSizeBytes; + pPortDef->nBufferSize = nSizeBytes; OMX_PRBUFFER1(pComponentPrivate->dbg, "pBuffHead 0x%p nAllocLen 0x%lx pBuffer %p eBufferOwner %d\n", *pBuffHead, (*pBuffHead)->nAllocLen, pCompPort->pBufferPrivate[pBufferCnt]->pBufferHdr->pBuffer, pCompPort->pBufferPrivate[pBufferCnt]->eBufferOwner); |