osal: Fix OSAL lock anb type casting
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / Exynos_OMX_Vdec.c
1 /*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * @file Exynos_OMX_Vdec.c
20 * @brief
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * HyeYeon Chung (hyeon.chung@samsung.com)
23 * Yunji Kim (yunji.kim@samsung.com)
24 * @version 2.0.0
25 * @history
26 * 2012.02.20 : Create
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OSAL_Event.h"
34 #include "Exynos_OMX_Vdec.h"
35 #include "Exynos_OMX_VdecControl.h"
36 #include "Exynos_OMX_Basecomponent.h"
37 #include "Exynos_OSAL_SharedMemory.h"
38 #include "Exynos_OSAL_Thread.h"
39 #include "Exynos_OSAL_Semaphore.h"
40 #include "Exynos_OSAL_Mutex.h"
41 #include "Exynos_OSAL_ETC.h"
42
43 #ifdef USE_ANB
44 #include "Exynos_OSAL_Android.h"
45 #endif
46
47 #include "ExynosVideoApi.h"
48 #include "csc.h"
49
50 #undef EXYNOS_LOG_TAG
51 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DEC"
52 #define EXYNOS_LOG_OFF
53 //#define EXYNOS_TRACE_ON
54 #include "Exynos_OSAL_Log.h"
55
56 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
57 {
58 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
59 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
60 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
61
62 if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
63 exynosInputPort->portDefinition.format.video.nFrameWidth) ||
64 (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
65 exynosInputPort->portDefinition.format.video.nFrameHeight)) {
66 OMX_U32 width = 0, height = 0;
67
68 exynosOutputPort->portDefinition.format.video.nFrameWidth =
69 exynosInputPort->portDefinition.format.video.nFrameWidth;
70 exynosOutputPort->portDefinition.format.video.nFrameHeight =
71 exynosInputPort->portDefinition.format.video.nFrameHeight;
72 width = exynosOutputPort->portDefinition.format.video.nStride =
73 exynosInputPort->portDefinition.format.video.nStride;
74 height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
75 exynosInputPort->portDefinition.format.video.nSliceHeight;
76
77 switch(exynosOutputPort->portDefinition.format.video.eColorFormat) {
78 case OMX_COLOR_FormatYUV420Planar:
79 case OMX_COLOR_FormatYUV420SemiPlanar:
80 case OMX_SEC_COLOR_FormatNV12Tiled:
81 case OMX_SEC_COLOR_FormatYVU420Planar:
82 case OMX_SEC_COLOR_FormatNV21Linear:
83 if (width && height)
84 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
85 break;
86 default:
87 if (width && height)
88 exynosOutputPort->portDefinition.nBufferSize = width * height * 2;
89 break;
90 }
91 }
92
93 return;
94 }
95
96 void Exynos_Free_CodecBuffers(
97 OMX_COMPONENTTYPE *pOMXComponent,
98 OMX_U32 nPortIndex)
99 {
100 OMX_ERRORTYPE ret = OMX_ErrorNone;
101 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
102 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
103 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
104
105 OMX_U32 nBufferCnt = 0, nPlaneCnt = 0;
106 int i, j;
107
108 FunctionIn();
109
110 if (nPortIndex == INPUT_PORT_INDEX) {
111 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
112 nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
113 } else {
114 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
115 nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
116 }
117 nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
118
119 for (i = 0; i < nBufferCnt; i++) {
120 if (ppCodecBuffer[i] != NULL) {
121 for (j = 0; j < nPlaneCnt; j++) {
122 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
123 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
124 }
125
126 Exynos_OSAL_Free(ppCodecBuffer[i]);
127 ppCodecBuffer[i] = NULL;
128 }
129 }
130
131 FunctionOut();
132 }
133
134 OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
135 OMX_COMPONENTTYPE *pOMXComponent,
136 OMX_U32 nPortIndex,
137 OMX_U32 nBufferCnt,
138 OMX_U32 nPlaneSize[MAX_BUFFER_PLANE])
139 {
140 OMX_ERRORTYPE ret = OMX_ErrorNone;
141 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
142 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
143 MEMORY_TYPE eMemoryType = SYSTEM_MEMORY;
144 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
145
146 OMX_U32 nPlaneCnt = 0;
147 int i, j;
148
149 FunctionIn();
150
151 if (nPortIndex == INPUT_PORT_INDEX) {
152 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
153 } else {
154 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
155 #ifdef USE_CSC_HW
156 eMemoryType = NORMAL_MEMORY;
157 #endif
158 }
159 nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
160
161 if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
162 eMemoryType = SECURE_MEMORY;
163
164 for (i = 0; i < nBufferCnt; i++) {
165 ppCodecBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
166 if (ppCodecBuffer[i] == NULL) {
167 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
168 ret = OMX_ErrorInsufficientResources;
169 goto EXIT;
170 }
171 Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
172
173 for (j = 0; j < nPlaneCnt; j++) {
174 ppCodecBuffer[i]->pVirAddr[j] =
175 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nPlaneSize[j], eMemoryType);
176 if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
177 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc plane");
178 ret = OMX_ErrorInsufficientResources;
179 goto EXIT;
180 }
181
182 ppCodecBuffer[i]->fd[j] =
183 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
184 ppCodecBuffer[i]->bufferSize[j] = nPlaneSize[j];
185 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[j]);
186 }
187
188 ppCodecBuffer[i]->dataSize = 0;
189 }
190
191 return OMX_ErrorNone;
192
193 EXIT:
194 Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
195
196 FunctionOut();
197
198 return ret;
199 }
200
201 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
202 {
203 OMX_BOOL ret = OMX_FALSE;
204
205 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
206 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
207 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
208 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
209 ret = OMX_TRUE;
210 } else {
211 ret = OMX_FALSE;
212 }
213
214 return ret;
215 }
216
217 OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
218 {
219 OMX_ERRORTYPE ret = OMX_ErrorNone;
220 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
221 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
222 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
223
224 /* Input port */
225 pInputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
226 pInputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
227 pInputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
228 pInputPort->portDefinition.format.video.nSliceHeight = 0;
229 pInputPort->portDefinition.format.video.pNativeRender = 0;
230 pInputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
231 pInputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
232
233 pInputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
234 pInputPort->portDefinition.bEnabled = OMX_TRUE;
235
236 pInputPort->bufferProcessType = BUFFER_SHARE;
237 pInputPort->portWayType = WAY2_PORT;
238 pInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE;
239
240 /* Output port */
241 pOutputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
242 pOutputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
243 pOutputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
244 pOutputPort->portDefinition.format.video.nSliceHeight = 0;
245 pOutputPort->portDefinition.format.video.pNativeRender = 0;
246 pOutputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
247 pOutputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
248
249 pOutputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
250 pOutputPort->portDefinition.bEnabled = OMX_TRUE;
251
252 pOutputPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
253 pOutputPort->bIsANBEnabled = OMX_FALSE;
254 pOutputPort->portWayType = WAY2_PORT;
255 pOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar);
256
257 return ret;
258 }
259
260 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
261 {
262 OMX_ERRORTYPE ret = OMX_ErrorNone;
263 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
264 CODEC_DEC_BUFFER *pInputCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer;
265
266 pData->buffer.singlePlaneBuffer.dataBuffer = pInputCodecBuffer->pVirAddr[0];
267 pData->buffer.singlePlaneBuffer.fd = pInputCodecBuffer->fd[0];
268 pData->allocSize = pInputCodecBuffer->bufferSize[0];
269 pData->dataLen = pInputCodecBuffer->dataSize;
270 pData->usedDataLen = 0;
271 pData->remainDataLen = pInputCodecBuffer->dataSize;
272
273 pData->nFlags = 0;
274 pData->timeStamp = 0;
275 pData->pPrivate = codecBuffer;
276 pData->bufferHeader = NULL;
277
278 return ret;
279 }
280
281 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(
282 CODEC_DEC_BUFFER *pCodecBuffer,
283 EXYNOS_OMX_DATA *pData)
284 {
285 OMX_ERRORTYPE ret = OMX_ErrorNone;
286
287 pData->buffer.multiPlaneBuffer.dataBuffer[0] = pCodecBuffer->pVirAddr[0];
288 pData->buffer.multiPlaneBuffer.dataBuffer[1] = pCodecBuffer->pVirAddr[1];
289 pData->buffer.multiPlaneBuffer.dataBuffer[2] = pCodecBuffer->pVirAddr[2];
290 pData->buffer.multiPlaneBuffer.fd[0] = pCodecBuffer->fd[0];
291 pData->buffer.multiPlaneBuffer.fd[1] = pCodecBuffer->fd[1];
292 pData->buffer.multiPlaneBuffer.fd[2] = pCodecBuffer->fd[2];
293 pData->allocSize = pCodecBuffer->bufferSize[0] + pCodecBuffer->bufferSize[1] + pCodecBuffer->bufferSize[2];
294 pData->dataLen = 0;
295 pData->usedDataLen = 0;
296 pData->remainDataLen = 0;
297
298 pData->nFlags = 0;
299 pData->timeStamp = 0;
300 pData->pPrivate = pCodecBuffer;
301 pData->bufferHeader = NULL;
302
303 return ret;
304 }
305
306 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
307 {
308 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
309 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
310 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
311
312 FunctionIn();
313
314 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
315
316 if (((pExynosComponent->currentState == OMX_StatePause) ||
317 (pExynosComponent->currentState == OMX_StateIdle) ||
318 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
319 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
320 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
321 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
322 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
323 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
324 }
325
326 FunctionOut();
327
328 return;
329 }
330
331 OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
332 {
333 OMX_BOOL ret = OMX_FALSE;
334 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
335 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
336 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
337 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
338 OMX_U32 copySize = 0;
339 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
340 OMX_COLOR_FORMATTYPE eColorFormat = exynosOutputPort->portDefinition.format.video.eColorFormat;
341
342 FunctionIn();
343
344 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
345 void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
346 void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
347
348 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
349 OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0};
350
351 OMX_U32 nFrameWidth = 0, nFrameHeight = 0;
352 OMX_U32 nImageWidth = 0, nImageHeight = 0, stride = 0;
353
354 CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
355 CSC_METHOD csc_method = CSC_METHOD_SW;
356 CSC_ERRORCODE cscRet = CSC_ErrorNone;
357 unsigned int srcCacheable = 1, dstCacheable = 1;
358
359 nFrameWidth = exynosOutputPort->portDefinition.format.video.nStride;
360 nFrameHeight = exynosOutputPort->portDefinition.format.video.nSliceHeight;
361
362 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
363 nImageWidth = pBufferInfo->imageWidth;
364 nImageHeight = pBufferInfo->imageHeight;
365
366 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
367 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
368 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
369
370 Exynos_OSAL_GetPlaneSize(eColorFormat, nImageWidth, nImageHeight, nPlaneSize);
371
372 pYUVBuf[0] = (unsigned char *)pOutputBuf;
373 pYUVBuf[1] = (unsigned char *)pOutputBuf + nPlaneSize[0];
374 pYUVBuf[2] = (unsigned char *)pOutputBuf + nPlaneSize[0] + nPlaneSize[1];
375
376 #ifdef USE_ANB
377 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
378 Exynos_OSAL_LockANBHandle(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes);
379 nImageWidth = stride;
380 outputUseBuffer->dataLen = sizeof(void *);
381
382 pYUVBuf[0] = (unsigned char *)planes[0].addr;
383 pYUVBuf[1] = (unsigned char *)planes[1].addr;
384 pYUVBuf[2] = (unsigned char *)planes[2].addr;
385 }
386 #endif
387
388 if (pVideoDec->bDualDPBMode == OMX_TRUE) {
389 switch (eColorFormat) {
390 case OMX_COLOR_FormatYUV420SemiPlanar:
391 case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear:
392 case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled:
393 case OMX_COLOR_FormatYUV420Planar:
394 case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar:
395 csc_set_method(pVideoDec->csc_handle, CSC_METHOD_SW);
396 csc_memType = CSC_MEMORY_MFC;
397 if (pVideoDec->csc_set_format == OMX_FALSE) {
398 csc_set_src_format(
399 pVideoDec->csc_handle, /* handle */
400 nFrameWidth, /* width */
401 nFrameHeight, /* height */
402 0, /* crop_left */
403 0, /* crop_right */
404 nImageWidth, /* crop_width */
405 nImageHeight, /* crop_height */
406 omx_2_hal_pixel_format(pBufferInfo->ColorFormat), /* color_format */
407 0); /* cacheable */
408 csc_set_dst_format(
409 pVideoDec->csc_handle, /* handle */
410 nImageWidth, /* width */
411 nImageHeight, /* height */
412 0, /* crop_left */
413 0, /* crop_right */
414 nImageWidth, /* crop_width */
415 nImageHeight, /* crop_height */
416 omx_2_hal_pixel_format(eColorFormat), /* color_format */
417 0); /* cacheable */
418 pVideoDec->csc_set_format = OMX_TRUE;
419 }
420 break;
421 default:
422 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unspported color format : %x. can't support this format", __FUNCTION__, eColorFormat);
423 ret = OMX_FALSE;
424 goto EXIT;
425 break;
426 }
427 } else {
428 csc_get_method(pVideoDec->csc_handle, &csc_method);
429 if (csc_method == CSC_METHOD_HW)
430 srcCacheable = 0;
431
432 #ifdef USE_DMA_BUF
433 if (csc_method == CSC_METHOD_HW) {
434 csc_memType = CSC_MEMORY_DMABUF;
435
436 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
437 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
438 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
439
440 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
441 pYUVBuf[0] = (unsigned char *)planes[0].fd;
442 pYUVBuf[1] = (unsigned char *)planes[1].fd;
443 pYUVBuf[2] = (unsigned char *)planes[2].fd;
444 } else {
445 pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
446 pYUVBuf[1] = NULL;
447 pYUVBuf[2] = NULL;
448 }
449 }
450 #endif
451 if (pVideoDec->csc_set_format == OMX_FALSE) {
452 csc_set_src_format(
453 pVideoDec->csc_handle, /* handle */
454 nImageWidth, /* width */
455 nImageHeight, /* height */
456 0, /* crop_left */
457 0, /* crop_right */
458 nImageWidth, /* crop_width */
459 nImageHeight, /* crop_height */
460 omx_2_hal_pixel_format(pBufferInfo->ColorFormat), /* color_format */
461 srcCacheable); /* cacheable */
462 csc_set_dst_format(
463 pVideoDec->csc_handle, /* handle */
464 nImageWidth, /* width */
465 nImageHeight, /* height */
466 0, /* crop_left */
467 0, /* crop_right */
468 nImageWidth, /* crop_width */
469 nImageHeight, /* crop_height */
470 omx_2_hal_pixel_format(eColorFormat), /* color_format */
471 dstCacheable); /* cacheable */
472 pVideoDec->csc_set_format = OMX_TRUE;
473 }
474 }
475
476 csc_set_src_buffer(
477 pVideoDec->csc_handle, /* handle */
478 pSrcBuf,
479 csc_memType); /* YUV Addr or FD */
480 csc_set_dst_buffer(
481 pVideoDec->csc_handle, /* handle */
482 pYUVBuf,
483 csc_memType); /* YUV Addr or FD */
484 cscRet = csc_convert(pVideoDec->csc_handle);
485 if (cscRet != CSC_ErrorNone)
486 ret = OMX_FALSE;
487 else
488 ret = OMX_TRUE;
489
490 #ifdef USE_ANB
491 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
492 Exynos_OSAL_UnlockANBHandle(pOutputBuf);
493 }
494 #endif
495
496 EXIT:
497 FunctionOut();
498
499 return ret;
500 }
501
502 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
503 {
504 OMX_BOOL ret = OMX_FALSE;
505 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
506 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
507 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
508 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
509 OMX_U32 copySize = 0;
510 OMX_BYTE checkInputStream = NULL;
511 OMX_U32 checkInputStreamLen = 0;
512
513 FunctionIn();
514
515 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
516 if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
517 (srcInputData->pPrivate == NULL)) {
518 ret = OMX_FALSE;
519 goto EXIT;
520 }
521 }
522
523 if (inputUseBuffer->dataValid == OMX_TRUE) {
524 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
525 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
526
527 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
528 OMX_PTR dataBuffer = NULL;
529
530 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
531 srcInputData->buffer.singlePlaneBuffer.dataBuffer);
532 if (dataBuffer == NULL) {
533 ret = OMX_FALSE;
534 goto EXIT;
535 }
536
537 srcInputData->buffer.singlePlaneBuffer.fd = srcInputData->buffer.singlePlaneBuffer.dataBuffer;
538 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
539 } else {
540 srcInputData->buffer.singlePlaneBuffer.fd =
541 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
542 srcInputData->buffer.singlePlaneBuffer.dataBuffer);
543 }
544
545 /* reset dataBuffer */
546 Exynos_ResetDataBuffer(inputUseBuffer);
547 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
548 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
549 checkInputStreamLen = inputUseBuffer->remainDataLen;
550
551 pExynosComponent->bUseFlagEOF = OMX_TRUE;
552
553 copySize = checkInputStreamLen;
554 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
555
556 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
557 if (copySize > 0) {
558 Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
559 checkInputStream, copySize);
560 }
561
562 inputUseBuffer->dataLen -= copySize;
563 inputUseBuffer->remainDataLen -= copySize;
564 inputUseBuffer->usedDataLen += copySize;
565
566 srcInputData->dataLen += copySize;
567 srcInputData->remainDataLen += copySize;
568
569 srcInputData->timeStamp = inputUseBuffer->timeStamp;
570 srcInputData->nFlags = inputUseBuffer->nFlags;
571 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
572 } else {
573 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
574 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
575 pExynosComponent->callbackData,
576 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
577 ret = OMX_FALSE;
578 }
579
580 Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
581 }
582
583 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
584 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
585 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
586 if (srcInputData->dataLen != 0)
587 pExynosComponent->bBehaviorEOS = OMX_TRUE;
588 }
589
590 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
591 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
592 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
593 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
594 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
595 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
596 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
597 }
598
599 ret = OMX_TRUE;
600 }
601
602 EXIT:
603
604 FunctionOut();
605
606 return ret;
607 }
608
609 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
610 {
611 OMX_BOOL ret = OMX_FALSE;
612 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
613 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
614 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
615 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
616 OMX_U32 copySize = 0;
617 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
618
619 FunctionIn();
620
621 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
622 if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) {
623 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
624 outputUseBuffer->dataValid = OMX_TRUE;
625 } else {
626 if (Exynos_Shared_DataToANBBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
627 outputUseBuffer->dataValid = OMX_TRUE;
628 } else {
629 ret = OMX_FALSE;
630 goto EXIT;
631 }
632 }
633 }
634
635 if (outputUseBuffer->dataValid == OMX_TRUE) {
636 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
637 dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
638 if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
639 ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
640 if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
641 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
642 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
643 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
644 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
645 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
646 } else {
647 if (pExynosComponent->checkTimeStamp.startTimeStamp < dstOutputData->timeStamp) {
648 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
649 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
650 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
651 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
652 } else {
653 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
654 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
655 Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
656
657 ret = OMX_TRUE;
658 goto EXIT;
659 }
660 }
661 } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
662 ret = OMX_TRUE;
663 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
664 goto EXIT;
665 }
666
667 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
668 if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
669 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
670 copySize = dstOutputData->remainDataLen;
671 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
672
673 outputUseBuffer->dataLen += copySize;
674 outputUseBuffer->remainDataLen += copySize;
675 outputUseBuffer->nFlags = dstOutputData->nFlags;
676 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
677
678 if (outputUseBuffer->remainDataLen > 0) {
679 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
680 } else {
681 ret = OMX_TRUE;
682 }
683
684 if (ret == OMX_TRUE) {
685 if ((outputUseBuffer->remainDataLen > 0) ||
686 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
687 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
688 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
689 }
690 } else {
691 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
692 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
693 pExynosComponent->callbackData,
694 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
695 ret = OMX_FALSE;
696 }
697 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
698 outputUseBuffer->dataLen = 0;
699 outputUseBuffer->remainDataLen = 0;
700 outputUseBuffer->nFlags = dstOutputData->nFlags;
701 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
702 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
703 } else {
704 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
705 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
706 pExynosComponent->callbackData,
707 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
708 ret = OMX_FALSE;
709 }
710 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
711 if ((outputUseBuffer->remainDataLen > 0) ||
712 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
713 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
714 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
715 else
716 Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
717 }
718 } else {
719 ret = OMX_FALSE;
720 }
721
722 EXIT:
723 FunctionOut();
724
725 return ret;
726 }
727
728 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
729 {
730 OMX_ERRORTYPE ret = OMX_ErrorNone;
731 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
732 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
733 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
734 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
735 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
736 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
737 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
738 OMX_BOOL bCheckInputData = OMX_FALSE;
739 OMX_BOOL bValidCodecData = OMX_FALSE;
740
741 FunctionIn();
742
743 while (!pVideoDec->bExitBufferProcessThread) {
744 Exynos_OSAL_SleepMillisec(0);
745 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
746
747 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
748 (!pVideoDec->bExitBufferProcessThread)) {
749 Exynos_OSAL_SleepMillisec(0);
750
751 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
752 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)) ||
753 (exynosOutputPort->exceptionFlag == INVALID_STATE))
754 break;
755 if (exynosInputPort->portState != OMX_StateIdle)
756 break;
757
758 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
759 if (ret != OMX_ErrorInputDataDecodeYet) {
760 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
761 OMX_PTR codecBuffer;
762 if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
763 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
764 if (codecBuffer != NULL) {
765 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
766 }
767 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
768 break;
769 }
770 }
771
772 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
773 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
774 } else {
775 bCheckInputData = OMX_FALSE;
776 }
777
778 if ((bCheckInputData == OMX_FALSE) &&
779 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
780 ret = Exynos_InputBufferGetQueue(pExynosComponent);
781 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
782 break;
783 }
784
785 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
786 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
787 break;
788 }
789 }
790
791 ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
792 if (ret == OMX_ErrorCorruptedFrame) {
793 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
794 OMX_PTR codecBuffer;
795 codecBuffer = pSrcInputData->pPrivate;
796 if (codecBuffer != NULL)
797 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
798 }
799
800 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
801 Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
802 }
803 }
804
805 if (ret != OMX_ErrorInputDataDecodeYet) {
806 Exynos_ResetCodecData(pSrcInputData);
807 }
808 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
809 if (ret == OMX_ErrorCodecInit)
810 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
811 }
812 }
813
814 EXIT:
815
816 FunctionOut();
817
818 return ret;
819 }
820
821 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
822 {
823 OMX_ERRORTYPE ret = OMX_ErrorNone;
824 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
825 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
826 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
827 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
828 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
829 EXYNOS_OMX_DATA srcOutputData;
830
831 FunctionIn();
832
833 while (!pVideoDec->bExitBufferProcessThread) {
834 Exynos_OSAL_SleepMillisec(0);
835
836 while (!pVideoDec->bExitBufferProcessThread) {
837 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
838 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
839 break;
840 }
841 Exynos_OSAL_SleepMillisec(0);
842
843 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
844 break;
845
846 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
847 ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
848
849 if (ret == OMX_ErrorNone) {
850 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
851 OMX_PTR codecBuffer;
852 codecBuffer = srcOutputData.pPrivate;
853 if (codecBuffer != NULL)
854 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
855 }
856 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
857 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
858 Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
859 }
860 Exynos_ResetCodecData(&srcOutputData);
861 }
862 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
863 }
864 }
865
866 EXIT:
867
868 FunctionOut();
869
870 return ret;
871 }
872
873 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
874 {
875 OMX_ERRORTYPE ret = OMX_ErrorNone;
876 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
877 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
878 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
879 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
880 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
881 EXYNOS_OMX_DATA dstInputData;
882
883 FunctionIn();
884
885 while (!pVideoDec->bExitBufferProcessThread) {
886 Exynos_OSAL_SleepMillisec(0);
887
888 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
889 (!pVideoDec->bExitBufferProcessThread)) {
890 Exynos_OSAL_SleepMillisec(0);
891
892 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
893 (!CHECK_PORT_POPULATED(exynosOutputPort)))
894 break;
895 if (exynosOutputPort->portState != OMX_StateIdle)
896 break;
897
898 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
899 if (ret != OMX_ErrorOutputBufferUseYet) {
900 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
901 CODEC_DEC_BUFFER *pCodecBuffer = NULL;
902 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
903 if (ret != OMX_ErrorNone) {
904 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
905 break;
906 }
907 Exynos_Output_CodecBufferToData(pCodecBuffer, &dstInputData);
908 }
909
910 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
911 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
912 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
913 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
914 if (ret != OMX_ErrorNone) {
915 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
916 break;
917 }
918 if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) {
919 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
920 } else {
921 ret = Exynos_Shared_ANBBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
922 if (ret != OMX_ErrorNone) {
923 dstInputUseBuffer->dataValid = OMX_FALSE;
924 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
925 break;
926 }
927 }
928
929 OMX_PTR pBufferHandle = dstInputData.bufferHeader->pBuffer;
930 if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
931 Exynos_OSAL_GetInfoFromMetaData(dstInputData.bufferHeader->pBuffer, &pBufferHandle);
932 }
933 Exynos_ResetDataBuffer(dstInputUseBuffer);
934 }
935 }
936
937 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
938 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
939 break;
940 }
941 }
942
943 ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
944 if (ret != OMX_ErrorOutputBufferUseYet) {
945 Exynos_ResetCodecData(&dstInputData);
946 }
947 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
948 }
949 }
950
951 EXIT:
952
953 FunctionOut();
954
955 return ret;
956 }
957
958 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
959 {
960 OMX_ERRORTYPE ret = OMX_ErrorNone;
961 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
962 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
963 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
964 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
965 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
966 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
967
968 FunctionIn();
969
970 while (!pVideoDec->bExitBufferProcessThread) {
971 Exynos_OSAL_SleepMillisec(0);
972 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
973
974 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
975 (!pVideoDec->bExitBufferProcessThread)) {
976 Exynos_OSAL_SleepMillisec(0);
977
978 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
979 break;
980
981 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
982 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
983 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
984 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
985 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
986 if (ret != OMX_ErrorNone) {
987 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
988 break;
989 }
990 }
991 }
992
993 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
994 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
995 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
996
997 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
998 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
999 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
1000 }
1001
1002 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1003 if (pDstOutputData->pPrivate != NULL) {
1004 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
1005 pDstOutputData->pPrivate = NULL;
1006 }
1007 }
1008
1009 /* reset outputData */
1010 Exynos_ResetCodecData(pDstOutputData);
1011 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1012 }
1013 }
1014
1015 EXIT:
1016
1017 FunctionOut();
1018
1019 return ret;
1020 }
1021
1022 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
1023 {
1024 OMX_ERRORTYPE ret = OMX_ErrorNone;
1025 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1026 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1027 EXYNOS_OMX_MESSAGE *message = NULL;
1028
1029 FunctionIn();
1030
1031 if (threadData == NULL) {
1032 ret = OMX_ErrorBadParameter;
1033 goto EXIT;
1034 }
1035 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1036 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1037 if (ret != OMX_ErrorNone) {
1038 goto EXIT;
1039 }
1040 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1041 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1042
1043 Exynos_OSAL_ThreadExit(NULL);
1044
1045 EXIT:
1046 FunctionOut();
1047
1048 return ret;
1049 }
1050
1051 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1052 {
1053 OMX_ERRORTYPE ret = OMX_ErrorNone;
1054 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1055 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1056 EXYNOS_OMX_MESSAGE *message = NULL;
1057
1058 FunctionIn();
1059
1060 if (threadData == NULL) {
1061 ret = OMX_ErrorBadParameter;
1062 goto EXIT;
1063 }
1064 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1065 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1066 if (ret != OMX_ErrorNone) {
1067 goto EXIT;
1068 }
1069 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1070 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1071
1072 Exynos_OSAL_ThreadExit(NULL);
1073
1074 EXIT:
1075 FunctionOut();
1076
1077 return ret;
1078 }
1079
1080 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1081 {
1082 OMX_ERRORTYPE ret = OMX_ErrorNone;
1083 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1084 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1085 EXYNOS_OMX_MESSAGE *message = NULL;
1086
1087 FunctionIn();
1088
1089 if (threadData == NULL) {
1090 ret = OMX_ErrorBadParameter;
1091 goto EXIT;
1092 }
1093 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1094 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1095 if (ret != OMX_ErrorNone) {
1096 goto EXIT;
1097 }
1098 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1099 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1100
1101 Exynos_OSAL_ThreadExit(NULL);
1102
1103 EXIT:
1104 FunctionOut();
1105
1106 return ret;
1107 }
1108
1109 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1110 {
1111 OMX_ERRORTYPE ret = OMX_ErrorNone;
1112 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1113 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1114 EXYNOS_OMX_MESSAGE *message = NULL;
1115
1116 FunctionIn();
1117
1118 if (threadData == NULL) {
1119 ret = OMX_ErrorBadParameter;
1120 goto EXIT;
1121 }
1122 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1123 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1124 if (ret != OMX_ErrorNone) {
1125 goto EXIT;
1126 }
1127 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1128 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1129
1130 Exynos_OSAL_ThreadExit(NULL);
1131
1132 EXIT:
1133 FunctionOut();
1134
1135 return ret;
1136 }
1137
1138 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1139 {
1140 OMX_ERRORTYPE ret = OMX_ErrorNone;
1141 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1142 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1143 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1144
1145 FunctionIn();
1146
1147 pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1148
1149 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1150 Exynos_OMX_DstOutputProcessThread,
1151 pOMXComponent);
1152 if (ret == OMX_ErrorNone)
1153 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1154 Exynos_OMX_SrcOutputProcessThread,
1155 pOMXComponent);
1156 if (ret == OMX_ErrorNone)
1157 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1158 Exynos_OMX_DstInputProcessThread,
1159 pOMXComponent);
1160 if (ret == OMX_ErrorNone)
1161 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1162 Exynos_OMX_SrcInputProcessThread,
1163 pOMXComponent);
1164
1165 EXIT:
1166 FunctionOut();
1167
1168 return ret;
1169 }
1170
1171 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1172 {
1173 OMX_ERRORTYPE ret = OMX_ErrorNone;
1174 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1175 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1176 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1177 OMX_S32 countValue = 0;
1178 unsigned int i = 0;
1179
1180 FunctionIn();
1181
1182 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1183
1184 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1185 if (countValue == 0)
1186 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1187 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1188 if (countValue == 0)
1189 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1190 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1191 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1192 pVideoDec->hSrcInputThread = NULL;
1193
1194 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1195 if (countValue == 0)
1196 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1197 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1198 if (countValue == 0)
1199 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1200 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1201 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1202 pVideoDec->hDstInputThread = NULL;
1203
1204 pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1205 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1206 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1207 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1208 pVideoDec->hSrcOutputThread = NULL;
1209
1210 pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1211 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1212 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1213 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1214 pVideoDec->hDstOutputThread = NULL;
1215
1216 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
1217 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
1218
1219 EXIT:
1220 FunctionOut();
1221
1222 return ret;
1223 }
1224
1225 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1226 {
1227 OMX_ERRORTYPE ret = OMX_ErrorNone;
1228 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1229 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1230 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1231 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1232
1233 FunctionIn();
1234
1235 if (hComponent == NULL) {
1236 ret = OMX_ErrorBadParameter;
1237 goto EXIT;
1238 }
1239 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1240 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1241 if (ret != OMX_ErrorNone) {
1242 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1243 goto EXIT;
1244 }
1245
1246 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1247 if (ret != OMX_ErrorNone) {
1248 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1249 goto EXIT;
1250 }
1251
1252 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1253 if (ret != OMX_ErrorNone) {
1254 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1255 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1256 goto EXIT;
1257 }
1258
1259 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1260
1261 pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1262 if (pVideoDec == NULL) {
1263 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1264 ret = OMX_ErrorInsufficientResources;
1265 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1266 goto EXIT;
1267 }
1268
1269 Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1270 pVideoDec->bReconfigDPB = OMX_FALSE;
1271 pVideoDec->bDTSMode = OMX_FALSE;
1272 pVideoDec->bQosChanged = OMX_FALSE;
1273 pVideoDec->nQosRatio = 0;
1274 pVideoDec->bDualDPBMode = OMX_FALSE;
1275 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1276
1277 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1278 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1279 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1280
1281 /* Input port */
1282 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1283 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1284 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1285 pExynosPort->portDefinition.nBufferSize = 0;
1286 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1287
1288 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1289 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1290 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1291 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1292 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1293
1294 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1295 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1296 pExynosPort->portDefinition.format.video.nStride = 0;
1297 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1298 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1299 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1300 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1301 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1302
1303 /* Output port */
1304 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1305 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1306 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1307 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1308 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1309
1310 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1311 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1312 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1313 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1314 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1315
1316 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1317 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1318 pExynosPort->portDefinition.format.video.nStride = 0;
1319 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1320 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1321 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1322 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1323 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1324
1325 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1326
1327 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1328 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1329 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1330 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1331
1332 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1333 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1334 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1335 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1336 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1337
1338 EXIT:
1339 FunctionOut();
1340
1341 return ret;
1342 }
1343
1344 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1345 {
1346 OMX_ERRORTYPE ret = OMX_ErrorNone;
1347 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1348 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1349 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1350 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1351 int i = 0;
1352
1353 FunctionIn();
1354
1355 if (hComponent == NULL) {
1356 ret = OMX_ErrorBadParameter;
1357 goto EXIT;
1358 }
1359 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1360 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1361 if (ret != OMX_ErrorNone) {
1362 goto EXIT;
1363 }
1364
1365 if (pOMXComponent->pComponentPrivate == NULL) {
1366 ret = OMX_ErrorBadParameter;
1367 goto EXIT;
1368 }
1369 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1370
1371 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1372
1373 Exynos_OSAL_Free(pVideoDec);
1374 pExynosComponent->hComponentHandle = pVideoDec = NULL;
1375
1376 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1377 if (pExynosPort->processData.extInfo != NULL) {
1378 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1379 pExynosPort->processData.extInfo = NULL;
1380 }
1381
1382 for(i = 0; i < ALL_PORT_NUM; i++) {
1383 pExynosPort = &pExynosComponent->pExynosPort[i];
1384 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1385 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1386 }
1387
1388 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1389
1390 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1391
1392 EXIT:
1393 FunctionOut();
1394
1395 return ret;
1396 }