diff options
Diffstat (limited to 'libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c')
-rw-r--r-- | libstagefrighthw/omx/videodecode/omx_video_decoder_internal.c | 945 |
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 | |||
25 | OMX_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 | |||
55 | EXIT: | ||
56 | return (eError); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | */ | ||
61 | void 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 | |||
131 | void 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 | |||
157 | void 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 | |||
178 | void 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 | |||
217 | OMX_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 | |||
371 | EXIT: | ||
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 | /* ==========================================================================*/ | ||
394 | OMX_U32 Calc_InbufSize(OMX_U32 width, OMX_U32 height) | ||
395 | { | ||
396 | return ((width * height * 3) / 2); | ||
397 | } | ||
398 | |||
399 | OMX_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 | |||
489 | EXIT: | ||
490 | return (eError); | ||
491 | |||
492 | } | ||
493 | |||
494 | OMX_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 | |||
517 | OMX_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 | |||
696 | EXIT: | ||
697 | return (eError); | ||
698 | |||
699 | } | ||
700 | |||
701 | OMX_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 | |||
919 | EXIT: | ||
920 | return (eError); | ||
921 | } | ||
922 | |||
923 | void 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 | |||