summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c')
-rw-r--r--libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c945
1 files changed, 945 insertions, 0 deletions
diff --git a/libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c b/libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c
new file mode 100644
index 0000000..0589c78
--- /dev/null
+++ b/libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c
@@ -0,0 +1,945 @@
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "OMX_VIDDEC_INTERNAL"
18
19#include <omx_video_decoder_internal.h>
20#include <libdce.h>
21
22#define OMX_VIDDEC_DEFAULT_INBUF_WIDTH 1024
23#define OMX_VIDDEC_DEFAULT_INBUF_HEIGHT 1024
24
25OMX_ERRORTYPE OMXVidDec_InitFields(OMXVidDecComp *pVidDecComp)
26{
27 OMX_ERRORTYPE eError = OMX_ErrorNone;
28 hw_module_t const* module;
29 OMX_U32 i = 0;
30
31 pVidDecComp->sBase.cComponentName = (OMX_STRING )OSAL_Malloc(sizeof(OMX_U8) * OMX_MAX_STRINGNAME_SIZE);
32 OMX_CHECK(pVidDecComp->sBase.cComponentName != NULL, OMX_ErrorInsufficientResources);
33
34 /* Initialize Video Port parameters */
35 pVidDecComp->sBase.pVideoPortParams = (OMX_PORT_PARAM_TYPE*)OSAL_Malloc(sizeof(OMX_PORT_PARAM_TYPE));
36
37 OMX_BASE_INIT_STRUCT_PTR(pVidDecComp->sBase.pVideoPortParams, OMX_PORT_PARAM_TYPE);
38 pVidDecComp->sBase.pVideoPortParams->nPorts = OMX_VIDDEC_NUM_OF_PORTS;
39 pVidDecComp->sBase.pVideoPortParams->nStartPortNumber = OMX_VIDDEC_DEFAULT_START_PORT_NUM;
40 pVidDecComp->sBase.nNumPorts = OMX_VIDDEC_NUM_OF_PORTS;
41 pVidDecComp->sBase.nMinStartPortIndex = OMX_VIDDEC_DEFAULT_START_PORT_NUM;
42
43 pVidDecComp->sBase.nComponentVersion.s.nVersionMajor = OMX_VIDDEC_COMP_VERSION_MAJOR;
44 pVidDecComp->sBase.nComponentVersion.s.nVersionMinor = OMX_VIDDEC_COMP_VERSION_MINOR;
45 pVidDecComp->sBase.nComponentVersion.s.nRevision = OMX_VIDDEC_COMP_VERSION_REVISION;
46 pVidDecComp->sBase.nComponentVersion.s.nStep = OMX_VIDDEC_COMP_VERSION_STEP;
47
48 eError = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
49 if (eError == 0) {
50 pVidDecComp->grallocModule = (gralloc_module_t const *)module;
51 } else {
52 eError = OMX_ErrorInsufficientResources;
53 }
54
55EXIT:
56 return (eError);
57}
58
59/*
60*/
61void OMXVidDec_InitPortDefs(OMX_HANDLETYPE hComponent, OMXVidDecComp *pVidDecComp)
62{
63 OMXBaseComp *pBaseComp = &(pVidDecComp->sBase);
64
65 OMX_PARAM_PORTDEFINITIONTYPE *inPortDefs = &(pBaseComp->pPorts[OMX_VIDDEC_INPUT_PORT]->sPortDef);
66 OMX_PARAM_PORTDEFINITIONTYPE *outPortDefs= &(pBaseComp->pPorts[OMX_VIDDEC_OUTPUT_PORT]->sPortDef);
67
68 /* set the default/Actual values of an Input port */
69 inPortDefs->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
70 inPortDefs->nVersion = pBaseComp->nComponentVersion;
71 inPortDefs->bEnabled = OMX_TRUE;
72 inPortDefs->bPopulated = OMX_FALSE;
73 inPortDefs->eDir = OMX_DirInput;
74 inPortDefs->nPortIndex = OMX_VIDDEC_INPUT_PORT;
75 inPortDefs->nBufferCountMin = OMX_VIDDEC_MIN_IN_BUF_COUNT;
76 inPortDefs->nBufferCountActual = OMX_VIDDEC_DEFAULT_IN_BUF_COUNT;
77 inPortDefs->nBufferSize = Calc_InbufSize(OMX_VIDDEC_DEFAULT_INBUF_WIDTH,
78 OMX_VIDDEC_DEFAULT_INBUF_HEIGHT);
79
80 inPortDefs->eDomain = OMX_PortDomainVideo;
81 inPortDefs->bBuffersContiguous = OMX_TRUE;
82 inPortDefs->nBufferAlignment = OMX_VIDDEC_DEFAULT_1D_INPUT_BUFFER_ALIGNMENT;
83 inPortDefs->format.video.cMIMEType= NULL;
84 inPortDefs->format.video.pNativeRender = NULL;
85 inPortDefs->format.video.nFrameWidth = OMX_VIDDEC_DEFAULT_FRAME_WIDTH;
86 inPortDefs->format.video.nFrameHeight = OMX_VIDDEC_DEFAULT_FRAME_HEIGHT;
87 inPortDefs->format.video.nStride = 0;
88 inPortDefs->format.video.nSliceHeight = 0;
89 inPortDefs->format.video.nBitrate = 0;
90 inPortDefs->format.video.xFramerate = OMX_VIDEODECODER_DEFAULT_FRAMERATE << 16;
91 inPortDefs->format.video.bFlagErrorConcealment = OMX_TRUE;
92 inPortDefs->format.video.eCompressionFormat = pVidDecComp->tVideoParams[OMX_VIDDEC_INPUT_PORT].eCompressionFormat;
93 inPortDefs->format.video.eColorFormat = OMX_COLOR_FormatUnused;
94
95 /* set the default/Actual values of an output port */
96 outPortDefs->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
97 outPortDefs->nVersion = pVidDecComp->sBase.nComponentVersion;
98 outPortDefs->bEnabled = OMX_TRUE;
99 outPortDefs->bPopulated = OMX_FALSE;
100 outPortDefs->eDir = OMX_DirOutput;
101 outPortDefs->nPortIndex = OMX_VIDDEC_OUTPUT_PORT;
102 outPortDefs->nBufferCountMin = pVidDecComp->fpCalc_OubuffDetails(hComponent,
103 OMX_VIDDEC_DEFAULT_FRAME_WIDTH,
104 OMX_VIDDEC_DEFAULT_FRAME_HEIGHT).nBufferCountMin;
105 outPortDefs->nBufferCountActual = pVidDecComp->fpCalc_OubuffDetails(hComponent,
106 OMX_VIDDEC_DEFAULT_FRAME_WIDTH,
107 OMX_VIDDEC_DEFAULT_FRAME_HEIGHT).nBufferCountActual;
108
109 outPortDefs->nBufferSize = pVidDecComp->fpCalc_OubuffDetails(hComponent,
110 OMX_VIDDEC_DEFAULT_FRAME_WIDTH,
111 OMX_VIDDEC_DEFAULT_FRAME_HEIGHT).nBufferSize;
112 outPortDefs->eDomain = OMX_PortDomainVideo;
113 outPortDefs->bBuffersContiguous = OMX_TRUE;
114 outPortDefs->nBufferAlignment = pVidDecComp->fpCalc_OubuffDetails(hComponent,
115 OMX_VIDDEC_DEFAULT_FRAME_WIDTH,
116 OMX_VIDDEC_DEFAULT_FRAME_HEIGHT).n1DBufferAlignment;
117 outPortDefs->format.video.cMIMEType = NULL;
118 outPortDefs->format.video.pNativeRender = NULL;
119 outPortDefs->format.video.nFrameWidth = OMX_VIDDEC_DEFAULT_FRAME_WIDTH;
120 outPortDefs->format.video.nFrameHeight = OMX_VIDDEC_DEFAULT_FRAME_HEIGHT;
121 outPortDefs->format.video.nStride = OMX_VIDDEC_DEFAULT_STRIDE;
122 outPortDefs->format.video.nSliceHeight = OMX_VIDDEC_DEFAULT_FRAME_HEIGHT;
123 outPortDefs->format.video.nBitrate = 0;
124 outPortDefs->format.video.xFramerate = OMX_VIDEODECODER_DEFAULT_FRAMERATE << 16;
125 outPortDefs->format.video.bFlagErrorConcealment = OMX_TRUE;
126 outPortDefs->format.video.eCompressionFormat = pVidDecComp->tVideoParams[OMX_VIDDEC_OUTPUT_PORT].eCompressionFormat;
127 outPortDefs->format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar;
128}
129
130
131void OMXVidDec_InitPortParams(OMXVidDecComp *pVidDecComp)
132{
133 OMX_VIDEO_PARAM_PORTFORMATTYPE *tInPortVideoParam
134 = &(pVidDecComp->tVideoParams[OMX_VIDDEC_INPUT_PORT]);
135 OMX_VIDEO_PARAM_PORTFORMATTYPE *tOutPortVideoParam
136 = &(pVidDecComp->tVideoParams[OMX_VIDDEC_OUTPUT_PORT]);
137
138 // Initialize Input Video Port Param
139 tInPortVideoParam->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
140 tInPortVideoParam->nVersion = pVidDecComp->sBase.nComponentVersion;
141 tInPortVideoParam->nPortIndex = OMX_VIDDEC_INPUT_PORT;
142 tInPortVideoParam->nIndex = 0;
143 tInPortVideoParam->eCompressionFormat = pVidDecComp->tVideoParams[OMX_VIDDEC_INPUT_PORT].eCompressionFormat;
144 tInPortVideoParam->eColorFormat = OMX_COLOR_FormatUnused;
145 tInPortVideoParam->xFramerate = OMX_VIDEODECODER_DEFAULT_FRAMERATE;
146
147 // Initialize Output Video Port Param
148 tOutPortVideoParam->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
149 tOutPortVideoParam->nVersion = pVidDecComp->sBase.nComponentVersion;
150 tOutPortVideoParam->nPortIndex = OMX_VIDDEC_OUTPUT_PORT;
151 tOutPortVideoParam->nIndex = 1;
152 tOutPortVideoParam->eCompressionFormat = pVidDecComp->tVideoParams[OMX_VIDDEC_OUTPUT_PORT].eCompressionFormat;
153 tOutPortVideoParam->eColorFormat = OMX_COLOR_FormatYUV420PackedSemiPlanar;
154 tOutPortVideoParam->xFramerate = OMX_VIDEODECODER_DEFAULT_FRAMERATE;
155}
156
157void OMXVidDec_InitDecoderParams(OMX_HANDLETYPE hComponent,
158 OMXVidDecComp *pVidDecComp)
159{
160 OMX_U32 outPort = (OMX_U32)OMX_VIDDEC_OUTPUT_PORT;
161 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = &(pVidDecComp->sBase.pPorts[outPort]->sPortDef);
162 OMX_CONFIG_RECTTYPE *p2DOutBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[outPort]);
163
164 OMXVidDec_InitPortDefs(hComponent, pVidDecComp);
165 OMXVidDec_InitPortParams(pVidDecComp);
166 OMXVidDec_Set2DBuffParams(hComponent, pVidDecComp);
167 pOutputPortDef->format.video.nStride = p2DOutBufAllocParam->nWidth;
168
169 pVidDecComp->pDecStaticParams->maxHeight = OMX_VIDDEC_DEFAULT_FRAME_HEIGHT;
170 pVidDecComp->pDecStaticParams->maxWidth = OMX_VIDDEC_DEFAULT_FRAME_WIDTH;
171
172 /* Call Decoder Specific function to set Static Params */
173 pVidDecComp->fpSet_StaticParams(hComponent, pVidDecComp->pDecStaticParams);
174 return;
175}
176
177
178void OMXVidDec_Set2DBuffParams(OMX_HANDLETYPE hComponent, OMXVidDecComp *pVidDecComp)
179{
180 OMX_U32 outPort = (OMX_U32)OMX_VIDDEC_OUTPUT_PORT;
181 OMX_U32 inPort = (OMX_U32)OMX_VIDDEC_INPUT_PORT;
182 OMX_CONFIG_RECTTYPE *p2DOutBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[outPort]);
183 OMX_CONFIG_RECTTYPE *p2DInBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[inPort]);
184
185 PaddedBuffParams outBuffParams;
186 OMX_U32 nFrameWidth, nFrameHeight;
187
188 p2DOutBufAllocParam->nSize = sizeof(OMX_CONFIG_RECTTYPE);
189 p2DOutBufAllocParam->nVersion = pVidDecComp->sBase.nComponentVersion;
190 p2DOutBufAllocParam->nPortIndex = outPort;
191
192 nFrameWidth = pVidDecComp->sBase.pPorts[inPort]->sPortDef.format.video.nFrameWidth;
193 nFrameHeight = pVidDecComp->sBase.pPorts[inPort]->sPortDef.format.video.nFrameHeight;
194 if( nFrameWidth & 0x0F ) {
195 nFrameWidth = nFrameWidth + 16 - (nFrameWidth & 0x0F);
196 }
197 if( nFrameHeight & 0x1F ) {
198 nFrameHeight = nFrameHeight + 32 - (nFrameHeight & 0x1F);
199 }
200 outBuffParams = pVidDecComp->fpCalc_OubuffDetails(hComponent, nFrameWidth, nFrameHeight);
201
202 p2DOutBufAllocParam->nWidth = outBuffParams.nPaddedWidth;
203 p2DOutBufAllocParam->nHeight = outBuffParams.nPaddedHeight;
204 p2DOutBufAllocParam->nLeft = outBuffParams.n2DBufferXAlignment;
205 p2DOutBufAllocParam->nTop = outBuffParams.n2DBufferYAlignment;
206
207 p2DInBufAllocParam->nSize = sizeof(OMX_CONFIG_RECTTYPE);
208 p2DInBufAllocParam->nVersion = pVidDecComp->sBase.nComponentVersion;
209 p2DInBufAllocParam->nPortIndex = OMX_VIDDEC_INPUT_PORT;
210 p2DInBufAllocParam->nWidth = pVidDecComp->sBase.pPorts[inPort]->sPortDef.nBufferSize;
211 p2DInBufAllocParam->nHeight = 1; //On input port only 1D buffers supported.
212 p2DInBufAllocParam->nLeft = pVidDecComp->sBase.pPorts[inPort]->sPortDef.nBufferAlignment;
213 p2DInBufAllocParam->nTop = 1;
214}
215
216
217OMX_ERRORTYPE OMXVidDec_HandleFLUSH_EOS(OMX_HANDLETYPE hComponent,
218 OMX_BUFFERHEADERTYPE *pLastOutBufHeader,
219 OMX_BUFFERHEADERTYPE *pInBufHeader)
220{
221 OMX_ERRORTYPE eError = OMX_ErrorNone, eRMError = OMX_ErrorNone;
222 OMX_COMPONENTTYPE *pHandle = NULL;
223 OMX_BUFFERHEADERTYPE *pDupBufHeader = NULL;
224 OMXVidDecComp *pVidDecComp = NULL;
225 OMX_U32 i = 0;
226 OMX_U32 nStride;
227 IVIDDEC3_OutArgs *pDecOutArgs = NULL;
228 OMX_U32 outPort = (OMX_U32)OMX_VIDDEC_OUTPUT_PORT;
229 OMX_CONFIG_RECTTYPE *p2DOutBufAllocParam = NULL;
230 XDAS_Int32 status;
231 uint32_t nActualSize;
232 IMG_native_handle_t* grallocHandle;
233 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = NULL;
234 XDM_Rect activeFrameRegion[2];
235
236 pHandle = (OMX_COMPONENTTYPE *)hComponent;
237 pVidDecComp = (OMXVidDecComp *)pHandle->pComponentPrivate;
238 pDecOutArgs = pVidDecComp->pDecOutArgs;
239 p2DOutBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[outPort]);
240
241 pOutputPortDef = &(pVidDecComp->sBase.pPorts[outPort]->sPortDef);
242 /*! Ensure that the stride on output portdef structure is more than
243 the padded width. This is needed in the case where application
244 sets the Stride less than padded width */
245 if( (OMX_U32)pOutputPortDef->format.video.nStride >=
246 p2DOutBufAllocParam->nWidth ) {
247 nStride = pOutputPortDef->format.video.nStride;
248 } else {
249 nStride = p2DOutBufAllocParam->nWidth;
250 }
251
252 if( pVidDecComp->nFrameCounter > 0 ) {
253 /* Call codec flush and call process call until error */
254 OMX_CHECK(((pVidDecComp->pDecDynParams != NULL) && (pVidDecComp->pDecStatus != NULL)), OMX_ErrorBadParameter);
255 status = VIDDEC3_control(pVidDecComp->pDecHandle, XDM_FLUSH, pVidDecComp->pDecDynParams, pVidDecComp->pDecStatus);
256 if( status != VIDDEC3_EOK ) {
257 OSAL_ErrorTrace("VIDDEC3_control XDM_FLUSH failed ....! \n");
258 eError = OMX_ErrorInsufficientResources;
259 goto EXIT;
260 }
261 OMX_CHECK(eError == OMX_ErrorNone, eError);
262 do {
263 pVidDecComp->tOutBufDesc->numBufs = 0;
264 pVidDecComp->tInBufDesc->numBufs = 0;
265 status = VIDDEC3_process(pVidDecComp->pDecHandle, (XDM2_BufDesc *)pVidDecComp->tInBufDesc,
266 (XDM2_BufDesc *)pVidDecComp->tOutBufDesc,
267 (VIDDEC3_InArgs *)pVidDecComp->pDecInArgs,
268 (VIDDEC3_OutArgs *)pVidDecComp->pDecOutArgs);
269
270 /*! In case this is an IPC failure */
271 if(status == DCE_EIPC_CALL_FAIL) {
272 ALOGE("\n Remote Core Communication Failure... \n");
273 eError = OMX_ErrorHardware;
274 pVidDecComp->bIPCRecoveryNeeded = OMX_TRUE;
275 goto EXIT;
276 }
277
278 if( status != XDM_EFAIL ) {
279 /* Send the buffers out */
280 i = 0;
281 while( pDecOutArgs->outputID[i] ) {
282 pDupBufHeader = (OMX_BUFFERHEADERTYPE *)pDecOutArgs->outputID[i];
283 if( pVidDecComp->bSupportDecodeOrderTimeStamp == OMX_TRUE ) {
284 OSAL_ReadFromPipe(pVidDecComp->pTimeStampStoragePipe, &(pDupBufHeader->nTimeStamp),
285 sizeof(OMX_TICKS), &(nActualSize), OSAL_NO_SUSPEND);
286 }
287
288 activeFrameRegion[0] = pDecOutArgs->displayBufs.bufDesc[0].activeFrameRegion;
289 activeFrameRegion[1].bottomRight.y = (activeFrameRegion[0].bottomRight.y) / 2;
290 activeFrameRegion[1].bottomRight.x = activeFrameRegion[0].bottomRight.x;
291
292 // Crop rectangle handles the Y and UV buffer offsets
293 pDupBufHeader->nOffset = 0;
294 pDupBufHeader->nFilledLen = (nStride * pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3 ) / 2;
295
296 if((pVidDecComp->tCropDimension.nTop != activeFrameRegion[0].topLeft.y
297 || pVidDecComp->tCropDimension.nLeft != activeFrameRegion[0].topLeft.x)
298 || (pVidDecComp->tCropDimension.nWidth != (OMX_U32)(activeFrameRegion[0].bottomRight.x - activeFrameRegion[0].topLeft.x)
299 || pVidDecComp->tCropDimension.nHeight != (OMX_U32)(activeFrameRegion[0].bottomRight.y - activeFrameRegion[0].topLeft.y))) {
300 pVidDecComp->tCropDimension.nTop = activeFrameRegion[0].topLeft.y;
301 pVidDecComp->tCropDimension.nLeft = activeFrameRegion[0].topLeft.x;
302 pVidDecComp->tCropDimension.nWidth = activeFrameRegion[0].bottomRight.x - activeFrameRegion[0].topLeft.x;
303 pVidDecComp->tCropDimension.nHeight = activeFrameRegion[0].bottomRight.y - activeFrameRegion[0].topLeft.y;
304 if( pVidDecComp->bUsePortReconfigForCrop == OMX_TRUE ) {
305 eError = pVidDecComp->sBase.fpReturnEventNotify(hComponent, OMX_EventPortSettingsChanged,
306 OMX_VIDDEC_OUTPUT_PORT, OMX_IndexConfigCommonOutputCrop, NULL);
307 if( eError != OMX_ErrorNone ) {
308 OSAL_ErrorTrace("Port reconfig callback returned error, trying to continue");
309 }
310 }
311 }
312
313 if( pVidDecComp->bSupportSkipGreyOutputFrames ) {
314 if( pDecOutArgs->displayBufs.bufDesc[0].frameType == IVIDEO_I_FRAME ||
315 pDecOutArgs->displayBufs.bufDesc[0].frameType == IVIDEO_IDR_FRAME ||
316 pDecOutArgs->displayBufs.bufDesc[0].frameType == IVIDEO_IP_FRAME ||
317 pDecOutArgs->displayBufs.bufDesc[0].frameType == IVIDEO_IB_FRAME ) {
318 pVidDecComp->bSyncFrameReady = OMX_TRUE;
319 }
320 }
321 grallocHandle = (IMG_native_handle_t*)(pDupBufHeader->pBuffer);
322 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule, (buffer_handle_t)grallocHandle);
323
324 if( pVidDecComp->bSyncFrameReady == OMX_TRUE ) {
325 // Send the Output buffer to Base component
326 pVidDecComp->sBase.pPvtData->fpDioSend(hComponent,
327 OMX_VIDDEC_OUTPUT_PORT, pDupBufHeader);
328 }
329 pDecOutArgs->outputID[i] = 0;
330 i++;
331 }
332 i = 0;
333 while( pDecOutArgs->freeBufID[i] != 0 ) {
334 pDupBufHeader = (OMX_BUFFERHEADERTYPE *)pDecOutArgs->freeBufID[i];
335 ((OMXBase_BufHdrPvtData *)(pDupBufHeader->pPlatformPrivate))->bIsLocked = OMX_FALSE;
336 if( pDupBufHeader ) {
337 grallocHandle = (IMG_native_handle_t*)(pDupBufHeader->pBuffer);
338 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
339 (buffer_handle_t)grallocHandle);
340 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
341 OMX_VIDDEC_OUTPUT_PORT, pDupBufHeader);
342 }
343 i++;
344 }
345 }
346 } while( status != XDM_EFAIL );
347 }
348 if( pVidDecComp->bSupportDecodeOrderTimeStamp == OMX_TRUE ) {
349 OSAL_ClearPipe(pVidDecComp->pTimeStampStoragePipe);
350 }
351 if( pLastOutBufHeader != NULL ) {
352 pLastOutBufHeader->nFlags |= OMX_BUFFERFLAG_EOS;
353 grallocHandle = (IMG_native_handle_t*)(pLastOutBufHeader->pBuffer);
354 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
355 (buffer_handle_t)grallocHandle);
356 pVidDecComp->sBase.pPvtData->fpDioSend(hComponent, OMX_VIDDEC_OUTPUT_PORT, pLastOutBufHeader);
357 }
358 if( pInBufHeader != NULL ) {
359 pVidDecComp->sBase.pPvtData->fpDioSend(hComponent, OMX_VIDDEC_INPUT_PORT, pInBufHeader);
360 /* Send the EOS event to client */
361 pVidDecComp->sBase.fpReturnEventNotify(hComponent, OMX_EventBufferFlag,
362 OMX_VIDDEC_OUTPUT_PORT, OMX_BUFFERFLAG_EOS, NULL);
363 }
364 pVidDecComp->nFrameCounter = 0;
365 if( pVidDecComp->bSupportSkipGreyOutputFrames ) {
366 pVidDecComp->bSyncFrameReady = OMX_FALSE;
367 }
368 pVidDecComp->nOutbufInUseFlag = 0;
369 pVidDecComp->nFatalErrorGiven = 0;
370
371EXIT:
372 if( pVidDecComp->bSupportDecodeOrderTimeStamp == OMX_TRUE ) {
373 //Clear the pipe, to discard the stale messages
374 OSAL_ERROR err = OSAL_ClearPipe(pVidDecComp->pTimeStampStoragePipe);
375 if( err != OSAL_ErrNone ) {
376 /* if pipe clear fails, nothing can be done, just put error trace */
377 OSAL_ErrorTrace("\npipe clear failed");
378 }
379 }
380 return (eError);
381}
382
383/* ==========================================================================*/
384/**
385 * @fn Calc_InbufSize()
386 * This method Calcullates Buffer size given width and
387 * height of buffer
388 *
389 * @param [in] width : Width of the buffer
390 * @param [in] height : Height of the buffer
391 *
392 */
393/* ==========================================================================*/
394OMX_U32 Calc_InbufSize(OMX_U32 width, OMX_U32 height)
395{
396 return ((width * height * 3) / 2);
397}
398
399OMX_ERRORTYPE OMXVidDec_SetInPortDef(OMX_HANDLETYPE hComponent,
400 OMX_PARAM_PORTDEFINITIONTYPE *pPortDefs)
401{
402 OMX_ERRORTYPE eError = OMX_ErrorNone;
403 OMX_VIDEO_CODINGTYPE currentCompressionType, desiredCompressionType;
404 OMX_U32 nFrameWidth, nFrameHeight;
405 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDef = NULL;
406 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = NULL;
407 PaddedBuffParams tOutBufParams;
408 OMX_U32 i=0;
409 OMX_U32 bFound = 0;
410 OMX_COMPONENTTYPE *pHandle = NULL;
411 OMXVidDecComp *pVidDecComp = NULL;
412
413 /*! Initialize pointers and variables */
414 pHandle = (OMX_COMPONENTTYPE *)hComponent;
415 pVidDecComp = (OMXVidDecComp *)pHandle->pComponentPrivate;
416 pInputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_INPUT_PORT]->sPortDef);
417 pOutputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_OUTPUT_PORT]->sPortDef);
418 nFrameWidth = pPortDefs->format.video.nFrameWidth;
419 nFrameHeight = pPortDefs->format.video.nFrameHeight;
420 if( nFrameWidth & 0x0F ) {
421 nFrameWidth = nFrameWidth + 16 - (nFrameWidth & 0x0F);
422 }
423 if( nFrameHeight & 0x1F ) {
424 nFrameHeight = nFrameHeight + 32 - (nFrameHeight & 0x1F);
425 }
426 currentCompressionType = pInputPortDef->format.video.eCompressionFormat;
427 desiredCompressionType = pPortDefs->format.video.eCompressionFormat;
428 /*! In case there is change in Compression type */
429 if( currentCompressionType != desiredCompressionType ) {
430 /* De-initialize the current codec */
431 pVidDecComp->fpDeinit_Codec(hComponent);
432 /* Call specific component init depending upon the
433 eCompressionFormat set. */
434 i=0;
435 while( NULL != DecoderList[i].eCompressionFormat ) {
436 if( DecoderList[i].eCompressionFormat
437 == desiredCompressionType ) {
438 /* Component found */
439 bFound = 1;
440 break;
441 }
442 i++;
443 }
444 if( bFound == 0 ) {
445 OSAL_ErrorTrace("Unsupported Compression format given in port definition");
446 eError = OMX_ErrorUnsupportedSetting;
447 goto EXIT;
448 }
449 /* Call the Specific Decoder Init function and Initialize Params */
450 eError = DecoderList[i].fpDecoderComponentInit(hComponent);
451 OMX_CHECK(eError == OMX_ErrorNone, eError);
452 OMXVidDec_InitDecoderParams(hComponent, pHandle->pComponentPrivate);
453 strcpy((char *)pVidDecComp->tComponentRole.cRole,
454 (char *)DecoderList[i].cRole);
455 } /* End of if condition for change in codec type */
456
457 /*! set the Actual values of an Input port */
458 pInputPortDef->nBufferCountActual = pPortDefs->nBufferCountActual;
459 pInputPortDef->format = pPortDefs->format;
460 pInputPortDef->nBufferSize = Calc_InbufSize(nFrameWidth, nFrameHeight);
461 pVidDecComp->tCropDimension.nTop = 0;
462 pVidDecComp->tCropDimension.nLeft = 0;
463 pVidDecComp->tCropDimension.nWidth = pInputPortDef->format.video.nFrameWidth;
464 pVidDecComp->tCropDimension.nHeight = pInputPortDef->format.video.nFrameHeight;
465
466 /*! Set o/p port details according to width/height set at i/p Port. */
467 pOutputPortDef->format.video.nFrameWidth = pInputPortDef->format.video.nFrameWidth;
468 pOutputPortDef->format.video.nFrameHeight = pInputPortDef->format.video.nFrameHeight;
469 pOutputPortDef->format.video.nStride = pInputPortDef->format.video.nFrameWidth;
470 OMXVidDec_Set2DBuffParams(hComponent, pHandle->pComponentPrivate);
471 pOutputPortDef->nBufferSize = pOutputPortDef->format.video.nStride *
472 ((pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3) >> 1);
473
474 tOutBufParams = pVidDecComp->fpCalc_OubuffDetails(hComponent, nFrameWidth, nFrameHeight);
475 pOutputPortDef->nBufferCountMin = tOutBufParams.nBufferCountMin;
476 pOutputPortDef->nBufferCountActual = tOutBufParams.nBufferCountActual;
477
478 /*! Set the Static Params (Decoder Specific) */
479 pVidDecComp->fpSet_StaticParams(hComponent, pVidDecComp->pDecStaticParams);
480 pVidDecComp->pDecStaticParams->maxHeight = nFrameHeight;
481 pVidDecComp->pDecStaticParams->maxWidth = nFrameWidth;
482 if (pVidDecComp->tVideoParams[OMX_VIDDEC_INPUT_PORT].eCompressionFormat == OMX_VIDEO_CodingMPEG2) {
483 pVidDecComp->pDecStaticParams->maxWidth = pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nWidth;
484 }
485 if( pOutputPortDef->nBufferCountActual < pOutputPortDef->nBufferCountMin ) {
486 pOutputPortDef->nBufferCountActual = pOutputPortDef->nBufferCountMin;
487 }
488
489EXIT:
490 return (eError);
491
492}
493
494OMX_ERRORTYPE OMXVidDec_SetOutPortDef(OMXVidDecComp *pVidDecComp,
495 OMX_PARAM_PORTDEFINITIONTYPE *pPortDefs)
496{
497 OMX_ERRORTYPE eError = OMX_ErrorNone;
498 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = NULL;
499 OMX_PTR *pBufParams = NULL;
500 OMX_U32 nOutPort = OMX_VIDDEC_OUTPUT_PORT;
501 OMX_U32 nNumBuffers = 0;
502
503 pOutputPortDef = &(pVidDecComp->sBase.pPorts[nOutPort]->sPortDef);
504
505 /*! Set Values to output port based on input parameter */
506 pOutputPortDef->nBufferCountActual = pPortDefs->nBufferCountActual;
507 pOutputPortDef->format = pPortDefs->format;
508 pOutputPortDef->format.video.nSliceHeight
509 = pOutputPortDef->format.video.nFrameHeight;
510 pOutputPortDef->nBufferSize = pOutputPortDef->format.video.nStride *
511 ((pVidDecComp->t2DBufferAllocParams[nOutPort].nHeight * 3) >> 1);
512
513 return (eError);
514}
515
516
517OMX_ERRORTYPE OMXVidDec_HandleFirstFrame(OMX_HANDLETYPE hComponent,
518 OMX_BUFFERHEADERTYPE * *ppInBufHeader)
519{
520 OMX_ERRORTYPE eError = OMX_ErrorNone;
521 OMX_COMPONENTTYPE *pHandle = NULL;
522 OMX_U32 nFrameWidth, nFrameHeight, nFrameWidthNew, nFrameHeightNew, nFrameRate, nFrameRateNew;
523 OMXVidDecComp *pVidDecComp = NULL;
524 XDAS_Int32 status = 0;
525 IVIDDEC3_Status *pDecStatus = NULL;
526 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = NULL;
527 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDef = NULL;
528 PaddedBuffParams tOutBufParams;
529 OMX_BUFFERHEADERTYPE *pInBufHeader;
530 OMX_BOOL bPortReconfigRequiredForPadding = OMX_FALSE;
531 OMX_CONFIG_RECTTYPE *p2DOutBufAllocParam = NULL;
532
533 OMX_BOOL bSendPortReconfigForScale = OMX_FALSE;
534 OMX_U32 nScale, nScaleRem, nScaleQ16Low, nScaleWidth, nScaleHeight;
535 OMX_U64 nScaleQ16 = 0;
536
537 pHandle = (OMX_COMPONENTTYPE *)hComponent;
538 pVidDecComp = (OMXVidDecComp *)pHandle->pComponentPrivate;
539 pOutputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_OUTPUT_PORT]->sPortDef);
540 pInputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_INPUT_PORT]->sPortDef);
541 pVidDecComp->nOutPortReconfigRequired = 0;
542 p2DOutBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT]);
543
544 /*! Call the Codec Control call to get Status from Codec */
545 OMX_CHECK(((pVidDecComp->pDecDynParams != NULL) && (pVidDecComp->pDecStatus != NULL)), OMX_ErrorBadParameter);
546 status = VIDDEC3_control(pVidDecComp->pDecHandle, XDM_GETSTATUS, pVidDecComp->pDecDynParams, pVidDecComp->pDecStatus);
547 if( status != VIDDEC3_EOK ) {
548 OSAL_ErrorTrace("Error in Codec Control Call for GETSTATUS");
549 eError = OMX_ErrorInsufficientResources;
550 goto EXIT;
551 }
552 OMX_CHECK(eError == OMX_ErrorNone, eError);
553 if( pVidDecComp->fpHandle_CodecGetStatus != NULL ) {
554 eError = pVidDecComp->fpHandle_CodecGetStatus(hComponent);
555 }
556 pDecStatus = (IVIDDEC3_Status *)(pVidDecComp->pDecStatus);
557 nFrameWidth = pOutputPortDef->format.video.nFrameWidth;
558 nFrameHeight = pOutputPortDef->format.video.nFrameHeight;
559 nFrameWidthNew = (OMX_U32)pDecStatus->outputWidth;
560 nFrameHeightNew = (OMX_U32)pDecStatus->outputHeight;
561 nFrameRate = pOutputPortDef->format.video.xFramerate >> 16;
562
563 OMX_CHECK(pVidDecComp->nFrameRateDivisor != 0, OMX_ErrorBadParameter);
564 nFrameRateNew = (OMX_U32)(pDecStatus->frameRate / pVidDecComp->nFrameRateDivisor);
565 /*Set 200 as max cap, as if clip with incorrect setting is present in sdcard
566 it breaks havoc on thumbnail generation */
567 if((nFrameRateNew == 0) || (nFrameRateNew > 200)) {
568 OSAL_ErrorTrace("Codec Returned spurious FrameRate Value - %d Setting Back to - %d",
569 nFrameRateNew, nFrameRate);
570 nFrameRateNew = nFrameRate;
571 }
572
573 if( nFrameWidth & 0x0F ) {
574 nFrameWidth = nFrameWidth + 16 - (nFrameWidth & 0x0F);
575 }
576 if( nFrameHeight & 0x1F ) {
577 nFrameHeight = nFrameHeight + 32 - (nFrameHeight & 0x1F);
578 }
579 if( nFrameWidthNew & 0x0F ) {
580 nFrameWidthNew = nFrameWidthNew + 16 - (nFrameWidthNew & 0x0F);
581 }
582 if( nFrameHeightNew & 0x1F ) {
583 nFrameHeightNew = nFrameHeightNew + 32 - (nFrameHeightNew & 0x1F);
584 }
585 if( pVidDecComp->bUsePortReconfigForPadding == OMX_TRUE ) {
586 if( pOutputPortDef->format.video.nFrameWidth != p2DOutBufAllocParam->nWidth
587 || pOutputPortDef->format.video.nFrameHeight != p2DOutBufAllocParam->nHeight ) {
588 bPortReconfigRequiredForPadding = OMX_TRUE;
589 }
590 nFrameWidth = pVidDecComp->pDecStaticParams->maxWidth;
591 nFrameHeight = pVidDecComp->pDecStaticParams->maxHeight;
592 }
593
594 /*! Check whether the displayWidth already accounts for any
595 * difference between the current and new frame width */
596 if ( nFrameWidth != nFrameWidthNew &&
597 nFrameWidth == (OMX_U32)pVidDecComp->pDecDynParams->displayWidth ) {
598 nFrameWidthNew = nFrameWidth;
599 }
600
601 tOutBufParams = pVidDecComp->fpCalc_OubuffDetails(hComponent,
602 (OMX_U32)pDecStatus->outputWidth, (OMX_U32)pDecStatus->outputHeight);
603
604 /*! Check whether the height and width reported by codec matches
605 * that of output port */
606 if( nFrameHeightNew != nFrameHeight || nFrameWidthNew != nFrameWidth
607 || bPortReconfigRequiredForPadding == OMX_TRUE ||
608 pOutputPortDef->nBufferCountMin < tOutBufParams.nBufferCountMin ||
609 nFrameRate < nFrameRateNew ) { /* Compare the min againt the older min buffer count
610 since parameters like display delay also gets set according to ref frame. */
611 /*! Since the dimensions does not match trigger port reconfig */
612 pVidDecComp->nOutPortReconfigRequired = 1;
613 pVidDecComp->nCodecRecreationRequired = 1;
614 /* Return back the Input buffer headers Note that the output header
615 * will be cancelled later so no need to cancel it here */
616 if( ppInBufHeader != NULL ) {
617 pInBufHeader = *(ppInBufHeader);
618 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent, OMX_VIDDEC_INPUT_PORT,
619 pInBufHeader);
620 pInBufHeader = NULL;
621 }
622 /*! Change port definition to match with what codec reports */
623 pInputPortDef->format.video.nFrameHeight = (OMX_U32)pDecStatus->outputHeight;
624 pInputPortDef->format.video.nFrameWidth = (OMX_U32)pDecStatus->outputWidth;
625 pOutputPortDef->format.video.nFrameHeight = (OMX_U32)pDecStatus->outputHeight;
626 pOutputPortDef->format.video.nFrameWidth = (OMX_U32)pDecStatus->outputWidth;
627 pOutputPortDef->format.video.nStride = (OMX_U32)pDecStatus->outputWidth;
628 pOutputPortDef->format.video.nSliceHeight = (OMX_U32)pDecStatus->outputHeight;
629 if( nFrameRate < nFrameRateNew ) {
630 pOutputPortDef->format.video.xFramerate = nFrameRateNew << 16;
631 pVidDecComp->tVideoParams[OMX_VIDDEC_OUTPUT_PORT].xFramerate = nFrameRateNew;
632 }
633 pVidDecComp->tCropDimension.nWidth = (OMX_U32)pDecStatus->outputWidth;
634 pVidDecComp->tCropDimension.nHeight = (OMX_U32)pDecStatus->outputHeight;
635 tOutBufParams = pVidDecComp->fpCalc_OubuffDetails(hComponent,
636 (OMX_U32)pDecStatus->outputWidth,
637 (OMX_U32)pDecStatus->outputHeight);
638 pOutputPortDef->nBufferCountMin = tOutBufParams.nBufferCountMin;
639 pOutputPortDef->nBufferCountActual = tOutBufParams.nBufferCountActual;
640 OMXVidDec_Set2DBuffParams(hComponent, pHandle->pComponentPrivate);
641
642 pOutputPortDef->format.video.nStride = p2DOutBufAllocParam->nWidth;
643 pOutputPortDef->format.video.nSliceHeight = p2DOutBufAllocParam->nHeight;
644
645 pOutputPortDef->nBufferSize = pOutputPortDef->format.video.nStride *
646 ((pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3) >> 1);
647 if( pVidDecComp->bUsePortReconfigForPadding == OMX_TRUE ) {
648 pInputPortDef->format.video.nFrameHeight = p2DOutBufAllocParam->nHeight;
649 pInputPortDef->format.video.nFrameWidth = p2DOutBufAllocParam->nWidth;
650 pOutputPortDef->format.video.nFrameHeight = p2DOutBufAllocParam->nHeight;
651 pOutputPortDef->format.video.nFrameWidth = p2DOutBufAllocParam->nWidth;
652 }
653 }
654
655 if( pVidDecComp->nOutPortReconfigRequired == 1 ) {
656 /*! Notify to Client change in output port settings */
657 eError = pVidDecComp->sBase.fpReturnEventNotify(hComponent,
658 OMX_EventPortSettingsChanged,
659 OMX_VIDDEC_OUTPUT_PORT, 0, NULL);
660 } else if( pDecStatus->sampleAspectRatioHeight != 0 && pDecStatus->sampleAspectRatioWidth != 0 ) {
661 nScaleWidth = (OMX_U32)pDecStatus->sampleAspectRatioWidth;
662 nScaleHeight = (OMX_U32)pDecStatus->sampleAspectRatioHeight;
663 nScale = nScaleWidth / nScaleHeight;
664 if( nScale >= 1 ) {
665 nScaleRem = nScaleWidth % nScaleHeight;
666 nScaleQ16Low = 0xFFFF * nScaleRem / nScaleHeight;
667 nScaleQ16 = nScale << 16;
668 nScaleQ16 |= nScaleQ16Low;
669 if( (OMX_U64)pVidDecComp->tScaleParams.xWidth != nScaleQ16
670 || pVidDecComp->tScaleParams.xHeight != 0x10000 ) {
671 pVidDecComp->tScaleParams.xWidth = nScaleQ16;
672 pVidDecComp->tScaleParams.xHeight = 0x10000;
673 bSendPortReconfigForScale = OMX_TRUE;
674 }
675 } else {
676 nScale = nScaleHeight / nScaleWidth;
677 nScaleRem = nScaleHeight % nScaleWidth;
678 nScaleQ16Low = 0xFFFF * nScaleRem / nScaleWidth;
679 nScaleQ16 = nScale << 16;
680 nScaleQ16 |= nScaleQ16Low;
681 if( pVidDecComp->tScaleParams.xWidth != 0x10000
682 || (OMX_U64)pVidDecComp->tScaleParams.xHeight != nScaleQ16 ) {
683 pVidDecComp->tScaleParams.xWidth = 0x10000;
684 pVidDecComp->tScaleParams.xHeight = nScaleQ16;
685 bSendPortReconfigForScale = OMX_TRUE;
686 }
687 }
688 if( bSendPortReconfigForScale == OMX_TRUE ) {
689 /*! Notify to Client change in output port settings */
690 eError = pVidDecComp->sBase.fpReturnEventNotify(hComponent,
691 OMX_EventPortSettingsChanged, OMX_VIDDEC_OUTPUT_PORT, OMX_IndexConfigCommonScale, NULL);
692 bSendPortReconfigForScale = OMX_FALSE;
693 }
694 }
695
696EXIT:
697 return (eError);
698
699}
700
701OMX_ERRORTYPE OMXVidDec_HandleCodecProcError(OMX_HANDLETYPE hComponent,
702 OMX_BUFFERHEADERTYPE * *ppInBufHeader,
703 OMX_BUFFERHEADERTYPE * *ppOutBufHeader)
704{
705 OMX_ERRORTYPE eError = OMX_ErrorNone;
706 OMX_COMPONENTTYPE *pHandle = NULL;
707 OMX_U32 nFrameWidth, nFrameHeight, nFrameWidthNew, nFrameHeightNew;
708 OMXVidDecComp *pVidDecComp = NULL;
709 XDAS_Int32 status = 0;
710 IVIDDEC3_Status *pDecStatus = NULL;
711 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDef = NULL;
712 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDef = NULL;
713 PaddedBuffParams tOutBufParams;
714 OMX_BUFFERHEADERTYPE *pInBufHeader = *(ppInBufHeader);
715 OMX_BUFFERHEADERTYPE *pDupBufHeader;
716 OMX_BUFFERHEADERTYPE *pNewOutBufHeader = NULL;
717 OMX_BUFFERHEADERTYPE *pOutBufHeader = *(ppOutBufHeader);
718 OMX_U32 ii=0;
719 OMX_U32 nStride =0;
720 OMX_BOOL bPortReconfigRequiredForPadding = OMX_FALSE;
721 OMX_CONFIG_RECTTYPE *p2DOutBufAllocParam = NULL;
722 IMG_native_handle_t* grallocHandle;
723
724 /* Initialize pointers */
725 pHandle = (OMX_COMPONENTTYPE *)hComponent;
726 pVidDecComp = (OMXVidDecComp *)pHandle->pComponentPrivate;
727 pOutputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_OUTPUT_PORT]->sPortDef);
728 pInputPortDef = &(pVidDecComp->sBase.pPorts[OMX_VIDDEC_INPUT_PORT]->sPortDef);
729 p2DOutBufAllocParam = &(pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT]);
730
731 /*! Call the Codec Status function to know cause of error */
732 OMX_CHECK(((pVidDecComp->pDecDynParams != NULL) && (pVidDecComp->pDecStatus != NULL)), OMX_ErrorBadParameter);
733 status = VIDDEC3_control(pVidDecComp->pDecHandle, XDM_GETSTATUS, pVidDecComp->pDecDynParams, pVidDecComp->pDecStatus);
734
735 /* Check whether the Codec Status call was succesful */
736 if( status != VIDDEC3_EOK ) {
737 OSAL_ErrorTrace("VIDDEC3_control XDM_GETSTATUS failed");
738 if( (OMX_U32)pVidDecComp->pDecDynParams->decodeHeader
739 != pVidDecComp->nDecoderMode ) {
740 // Return the Input and Output buffer header
741 grallocHandle = (IMG_native_handle_t*)(pOutBufHeader->pBuffer);
742 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
743 (buffer_handle_t)grallocHandle);
744 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
745 OMX_VIDDEC_OUTPUT_PORT,
746 pOutBufHeader);
747
748 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
749 OMX_VIDDEC_INPUT_PORT,
750 pInBufHeader);
751 /*! Make Input buffer header pointer NULL */
752 pInBufHeader = NULL;
753 }
754 eError = OMX_ErrorInsufficientResources;
755 goto EXIT;
756 }
757 OMX_CHECK(eError == OMX_ErrorNone, eError);
758
759 pDecStatus = (IVIDDEC3_Status *)(pVidDecComp->pDecStatus);
760 nFrameWidth = pOutputPortDef->format.video.nFrameWidth;
761 nFrameHeight = pOutputPortDef->format.video.nFrameHeight;
762 nFrameWidthNew = pDecStatus->outputWidth;
763 nFrameHeightNew = pDecStatus->outputHeight;
764
765 if( nFrameWidth & 0x0F ) {
766 nFrameWidth = nFrameWidth + 16 - (nFrameWidth & 0x0F);
767 }
768 if( nFrameHeight & 0x1F ) {
769 nFrameHeight = nFrameHeight + 32 - (nFrameHeight & 0x1F);
770 }
771 if( nFrameWidthNew & 0x0F ) {
772 nFrameWidthNew = nFrameWidthNew + 16 - (nFrameWidthNew & 0x0F);
773 }
774 if( nFrameHeightNew & 0x1F ) {
775 nFrameHeightNew = nFrameHeightNew + 32 - (nFrameHeightNew & 0x1F);
776 }
777
778 if( pVidDecComp->bUsePortReconfigForPadding == OMX_TRUE ) {
779 if( pOutputPortDef->format.video.nFrameWidth != p2DOutBufAllocParam->nWidth
780 || pOutputPortDef->format.video.nFrameHeight != p2DOutBufAllocParam->nHeight ) {
781 bPortReconfigRequiredForPadding = OMX_TRUE;
782 }
783 nFrameWidth = pVidDecComp->pDecStaticParams->maxWidth;
784 nFrameHeight = pVidDecComp->pDecStaticParams->maxHeight;
785 }
786
787 /*! Check whether the displayWidth already accounts for any
788 * difference between the current and new frame width */
789 if ( nFrameWidth != nFrameWidthNew &&
790 nFrameWidth == (OMX_U32)pVidDecComp->pDecDynParams->displayWidth ) {
791 nFrameWidthNew = nFrameWidth;
792 }
793
794 /*! Check whether the height and width reported by codec matches
795 * that of output port */
796 if( nFrameHeightNew != nFrameHeight || nFrameWidthNew != nFrameWidth
797 || bPortReconfigRequiredForPadding == OMX_TRUE ) {
798 pVidDecComp->nOutPortReconfigRequired = 1;
799 pVidDecComp->nCodecRecreationRequired = 1;
800 }
801
802 if( pVidDecComp->fpHandle_ExtendedError != NULL ) {
803 eError = pVidDecComp->fpHandle_ExtendedError(hComponent);
804 }
805
806 if( pVidDecComp->nOutPortReconfigRequired == 1 ) {
807 pNewOutBufHeader = (OMX_BUFFERHEADERTYPE *) pVidDecComp->pDecOutArgs->outputID[0];
808 if( pNewOutBufHeader != NULL ) {
809 pVidDecComp->tCropDimension.nWidth = pDecStatus->outputWidth;
810 pVidDecComp->tCropDimension.nHeight = pDecStatus->outputHeight;
811 nStride = pVidDecComp->sBase.pPorts[OMX_VIDDEC_OUTPUT_PORT]->sPortDef.format.video.nStride;
812 // Crop rect handles the offsets for Y and UV buffers
813 pNewOutBufHeader->nOffset = 0;
814 // FilledLen
815 pNewOutBufHeader->nFilledLen
816 = (nStride * pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3) / 2;
817 grallocHandle = (IMG_native_handle_t*)(pNewOutBufHeader->pBuffer);
818 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
819 (buffer_handle_t)grallocHandle);
820 pVidDecComp->sBase.pPvtData->fpDioSend(hComponent, OMX_VIDDEC_OUTPUT_PORT,
821 pNewOutBufHeader);
822 }
823
824 if( pVidDecComp->nOutbufInUseFlag == 0
825 && (OMX_U32)pVidDecComp->pDecDynParams->decodeHeader != pVidDecComp->nDecoderMode ) {
826 grallocHandle = (IMG_native_handle_t*)(pOutBufHeader->pBuffer);
827 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
828 (buffer_handle_t)grallocHandle);
829 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
830 OMX_VIDDEC_OUTPUT_PORT, pOutBufHeader); // This buffer header is freed afterwards.
831 } else {
832 pOutBufHeader = NULL;
833 }
834 if( (OMX_U32)pVidDecComp->pDecDynParams->decodeHeader != pVidDecComp->nDecoderMode ) {
835 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
836 OMX_VIDDEC_INPUT_PORT, pInBufHeader);
837
838 while( pVidDecComp->pDecOutArgs->freeBufID[ii] != 0 ) {
839 pDupBufHeader = (OMX_BUFFERHEADERTYPE *)pVidDecComp->pDecOutArgs->freeBufID[ii++];
840 ((OMXBase_BufHdrPvtData *)(pDupBufHeader->pPlatformPrivate))->bIsLocked = OMX_FALSE;
841 if( pDupBufHeader != pOutBufHeader && pDupBufHeader != pNewOutBufHeader ) {
842 grallocHandle = (IMG_native_handle_t*)(pDupBufHeader->pBuffer);
843 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
844 (buffer_handle_t)grallocHandle);
845 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
846 OMX_VIDDEC_OUTPUT_PORT, pDupBufHeader);
847 }
848 }
849 }
850
851 /*! Notify to Client change in output port settings */
852 eError = pVidDecComp->sBase.fpReturnEventNotify(hComponent,
853 OMX_EventPortSettingsChanged,
854 OMX_VIDDEC_OUTPUT_PORT, 0, NULL);
855 }
856 if( pVidDecComp->nOutPortReconfigRequired == 0 ) {
857 if( pVidDecComp->pDecOutArgs->extendedError & 0x8000 ) {
858 eError = OMX_ErrorFormatNotDetected;
859 if( (OMX_U32)pVidDecComp->pDecDynParams->decodeHeader != pVidDecComp->nDecoderMode ) {
860 if( pVidDecComp->nOutbufInUseFlag == 0 ) {
861 grallocHandle = (IMG_native_handle_t*)(pOutBufHeader->pBuffer);
862 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
863 (buffer_handle_t)grallocHandle);
864 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
865 OMX_VIDDEC_OUTPUT_PORT, pOutBufHeader); // This buffer header is freed afterwards.
866 }
867 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
868 OMX_VIDDEC_INPUT_PORT, pInBufHeader);
869 while( pVidDecComp->pDecOutArgs->freeBufID[ii] != 0 ) {
870 pDupBufHeader = (OMX_BUFFERHEADERTYPE *)pVidDecComp->pDecOutArgs->freeBufID[ii++];
871 ((OMXBase_BufHdrPvtData *)(pDupBufHeader->pPlatformPrivate))->bIsLocked = OMX_FALSE;
872 if( pOutBufHeader != pDupBufHeader ) {
873 grallocHandle = (IMG_native_handle_t*)(pDupBufHeader->pBuffer);
874 pVidDecComp->grallocModule->unlock((gralloc_module_t const *) pVidDecComp->grallocModule,
875 (buffer_handle_t)grallocHandle);
876 pVidDecComp->sBase.pPvtData->fpDioCancel(hComponent,
877 OMX_VIDDEC_OUTPUT_PORT, pDupBufHeader);
878 }
879 }
880 }
881 pVidDecComp->nFatalErrorGiven = 1;
882 }
883 }
884
885 if( nFrameHeightNew != nFrameHeight || nFrameWidthNew != nFrameWidth
886 || bPortReconfigRequiredForPadding == OMX_TRUE ) {
887 /*Return back the locked buffers before changing the port definition */
888 OMXVidDec_HandleFLUSH_EOS(hComponent, NULL, NULL);
889 /*! Change Port Definition */
890 pInputPortDef->format.video.nFrameHeight = pDecStatus->outputHeight;
891 pInputPortDef->format.video.nFrameWidth = pDecStatus->outputWidth;
892
893 pOutputPortDef->format.video.nFrameHeight = pDecStatus->outputHeight;
894 pOutputPortDef->format.video.nFrameWidth = pDecStatus->outputWidth;
895 pOutputPortDef->format.video.nSliceHeight = pDecStatus->outputHeight;
896 pVidDecComp->tCropDimension.nWidth = pDecStatus->outputWidth;
897 pVidDecComp->tCropDimension.nHeight = pDecStatus->outputHeight;
898 tOutBufParams = pVidDecComp->fpCalc_OubuffDetails(hComponent,
899 pDecStatus->outputWidth,
900 pDecStatus->outputHeight);
901 pOutputPortDef->nBufferCountMin = tOutBufParams.nBufferCountMin;
902 pOutputPortDef->nBufferCountActual = tOutBufParams.nBufferCountActual;
903 OMXVidDec_Set2DBuffParams(hComponent, pHandle->pComponentPrivate);
904
905 pOutputPortDef->format.video.nStride = p2DOutBufAllocParam->nWidth;
906
907 pOutputPortDef->nBufferSize = pOutputPortDef->format.video.nStride *
908 ((pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3) >> 1);
909 if( pVidDecComp->bUsePortReconfigForPadding == OMX_TRUE ) {
910 pInputPortDef->format.video.nFrameHeight = p2DOutBufAllocParam->nHeight;
911 pInputPortDef->format.video.nFrameWidth = p2DOutBufAllocParam->nWidth;
912 pOutputPortDef->format.video.nFrameHeight = p2DOutBufAllocParam->nHeight;
913 pOutputPortDef->format.video.nFrameWidth = p2DOutBufAllocParam->nWidth;
914 pOutputPortDef->format.video.nStride = p2DOutBufAllocParam->nWidth;
915 pOutputPortDef->format.video.nSliceHeight = p2DOutBufAllocParam->nHeight;
916 }
917 }
918
919EXIT:
920 return (eError);
921}
922
923void OMXVidDec_CalcFilledLen(OMX_HANDLETYPE hComponent,
924 IVIDDEC3_OutArgs *pDecOutArgs,
925 OMX_U32 nStride)
926{
927 OMX_BUFFERHEADERTYPE *pOutBufHeader;
928 OMX_COMPONENTTYPE *pHandle = NULL;
929 OMXVidDecComp *pVidDecComp = NULL;
930
931 /* Initialize the pointers */
932 pHandle = (OMX_COMPONENTTYPE *)hComponent;
933 pVidDecComp = (OMXVidDecComp *)pHandle->pComponentPrivate;
934
935 pOutBufHeader = (OMX_BUFFERHEADERTYPE *)pDecOutArgs->outputID[0];
936 /*Crop rectangle handles the offsets for Y and UV buffers */
937 pOutBufHeader->nOffset = 0;
938
939 /*! Calcullate the Total Filled length */
940 pOutBufHeader->nFilledLen = (nStride * pVidDecComp->t2DBufferAllocParams[OMX_VIDDEC_OUTPUT_PORT].nHeight * 3) / 2;
941
942 return;
943}
944
945