summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Wong <Benny.Wong@motorola.com>2009-11-20 09:50:54 -0600
committerJames Dong <jdong@google.com>2009-12-08 17:39:14 -0800
commite074e61deca17dd3ffc4e431f30464943d225fe0 (patch)
tree4b2495987f5749fad17450a73a61dc71c0841cf4
parentc5b21bfb410626a503e479a5afa2095902783427 (diff)
downloadomap3-e074e61deca17dd3ffc4e431f30464943d225fe0.tar.gz
WMV Video decoder byte alignment fix
- rebased ... Originally from: https://partner.source.android.com/g/#change,1497
-rw-r--r--omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h146
-rw-r--r--omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c44
-rw-r--r--omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c63
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);