fefdd0ae8522116a254af7ab6b39fa6d894dbda2
[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 if (width && height)
82 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
83 break;
84 default:
85 if (width && height)
86 exynosOutputPort->portDefinition.nBufferSize = width * height * 2;
87 break;
88 }
89 }
90
91 return;
92 }
93
94 void Exynos_Free_CodecBuffers(
95 OMX_COMPONENTTYPE *pOMXComponent,
96 OMX_U32 nPortIndex)
97 {
98 OMX_ERRORTYPE ret = OMX_ErrorNone;
99 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
100 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
101 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
102
103 OMX_U32 nBufferCnt = 0, nPlaneCnt = 0;
104 int i, j;
105
106 FunctionIn();
107
108 if (nPortIndex == INPUT_PORT_INDEX) {
109 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
110 nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
111 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
112 } else {
113 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
114 nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
115 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
116 }
117
118 for (i = 0; i < nBufferCnt; i++) {
119 if (ppCodecBuffer[i] != NULL) {
120 for (j = 0; j < nPlaneCnt; j++) {
121 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
122 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
123 }
124
125 Exynos_OSAL_Free(ppCodecBuffer[i]);
126 ppCodecBuffer[i] = NULL;
127 }
128 }
129
130 FunctionOut();
131 }
132
133 OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
134 OMX_COMPONENTTYPE *pOMXComponent,
135 OMX_U32 nPortIndex,
136 OMX_U32 nBufferCnt,
137 OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE])
138 {
139 OMX_ERRORTYPE ret = OMX_ErrorNone;
140 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
141 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
142 MEMORY_TYPE eMemoryType = SYSTEM_MEMORY;
143 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
144
145 OMX_U32 nPlaneCnt = 0;
146 int i, j;
147
148 FunctionIn();
149
150 if (nPortIndex == INPUT_PORT_INDEX) {
151 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
152 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
153 } else {
154 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
155 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
156 #ifdef USE_CSC_HW
157 eMemoryType = NORMAL_MEMORY;
158 #endif
159 }
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_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
218 {
219 OMX_ERRORTYPE ret = OMX_ErrorNone;
220 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
221 CODEC_DEC_BUFFER *pInputCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer;
222
223 pData->buffer.singlePlaneBuffer.dataBuffer = pInputCodecBuffer->pVirAddr[0];
224 pData->buffer.singlePlaneBuffer.fd = pInputCodecBuffer->fd[0];
225 pData->allocSize = pInputCodecBuffer->bufferSize[0];
226 pData->dataLen = pInputCodecBuffer->dataSize;
227 pData->usedDataLen = 0;
228 pData->remainDataLen = pInputCodecBuffer->dataSize;
229
230 pData->nFlags = 0;
231 pData->timeStamp = 0;
232 pData->pPrivate = codecBuffer;
233 pData->bufferHeader = NULL;
234
235 return ret;
236 }
237
238 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(
239 CODEC_DEC_BUFFER *pCodecBuffer,
240 EXYNOS_OMX_DATA *pData)
241 {
242 OMX_ERRORTYPE ret = OMX_ErrorNone;
243
244 pData->buffer.multiPlaneBuffer.dataBuffer[0] = pCodecBuffer->pVirAddr[0];
245 pData->buffer.multiPlaneBuffer.dataBuffer[1] = pCodecBuffer->pVirAddr[1];
246 pData->buffer.multiPlaneBuffer.dataBuffer[2] = pCodecBuffer->pVirAddr[2];
247 pData->buffer.multiPlaneBuffer.fd[0] = pCodecBuffer->fd[0];
248 pData->buffer.multiPlaneBuffer.fd[1] = pCodecBuffer->fd[1];
249 pData->buffer.multiPlaneBuffer.fd[2] = pCodecBuffer->fd[2];
250 pData->allocSize = pCodecBuffer->bufferSize[0] + pCodecBuffer->bufferSize[1] + pCodecBuffer->bufferSize[2];
251 pData->dataLen = 0;
252 pData->usedDataLen = 0;
253 pData->remainDataLen = 0;
254
255 pData->nFlags = 0;
256 pData->timeStamp = 0;
257 pData->pPrivate = pCodecBuffer;
258 pData->bufferHeader = NULL;
259
260 return ret;
261 }
262
263 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
264 {
265 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
266 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
267 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
268
269 FunctionIn();
270
271 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
272
273 if (((pExynosComponent->currentState == OMX_StatePause) ||
274 (pExynosComponent->currentState == OMX_StateIdle) ||
275 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
276 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
277 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
278 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
279 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
280 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
281 }
282
283 FunctionOut();
284
285 return;
286 }
287
288 OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
289 {
290 OMX_BOOL ret = OMX_FALSE;
291 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
292 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
293 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
294 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
295 OMX_U32 copySize = 0;
296 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
297
298 FunctionIn();
299
300 OMX_U32 width = 0, height = 0;
301 int imageSize = 0;
302 OMX_COLOR_FORMATTYPE colorFormat;
303
304 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
305 void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
306 void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
307
308 CSC_ERRORCODE cscRet = CSC_ErrorNone;
309 CSC_METHOD csc_method = CSC_METHOD_SW;
310 CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
311
312 unsigned int srcCacheable = 1, dstCacheable = 1;
313
314 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
315
316 width = pBufferInfo->imageWidth;
317 height = pBufferInfo->imageHeight;
318 imageSize = width * height;
319 colorFormat = pBufferInfo->ColorFormat;
320
321 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
322 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
323 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
324
325 pYUVBuf[0] = (unsigned char *)pOutputBuf;
326 pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize;
327 pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
328
329 csc_get_method(pVideoDec->csc_handle, &csc_method);
330 if (csc_method == CSC_METHOD_HW)
331 srcCacheable = 0;
332
333 #ifdef USE_DMA_BUF
334 if (csc_method == CSC_METHOD_HW) {
335 csc_memType = CSC_MEMORY_DMABUF;
336 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
337 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
338 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
339 }
340 #endif
341
342 #ifdef USE_ANB
343 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
344 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
345 OMX_U32 stride;
346 Exynos_OSAL_LockANB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
347 width = stride;
348 outputUseBuffer->dataLen = sizeof(void *);
349
350 pYUVBuf[0] = (unsigned char *)planes[0].addr;
351 pYUVBuf[1] = (unsigned char *)planes[1].addr;
352 pYUVBuf[2] = (unsigned char *)planes[2].addr;
353 #ifdef USE_DMA_BUF
354 if (csc_method == CSC_METHOD_HW) {
355 pYUVBuf[0] = (unsigned char *)planes[0].fd;
356 pYUVBuf[1] = (unsigned char *)planes[1].fd;
357 pYUVBuf[2] = (unsigned char *)planes[2].fd;
358 }
359 #endif
360 }
361 #endif
362 #ifdef USE_DMA_BUF
363 if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
364 (csc_method == CSC_METHOD_HW)) {
365 pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
366 pYUVBuf[1] = NULL;
367 pYUVBuf[2] = NULL;
368 }
369 #endif
370
371 if (pVideoDec->csc_set_format == OMX_FALSE) {
372 csc_set_src_format(
373 pVideoDec->csc_handle, /* handle */
374 width, /* width */
375 height, /* height */
376 0, /* crop_left */
377 0, /* crop_right */
378 width, /* crop_width */
379 height, /* crop_height */
380 omx_2_hal_pixel_format(colorFormat), /* color_format */
381 srcCacheable); /* cacheable */
382 csc_set_dst_format(
383 pVideoDec->csc_handle, /* handle */
384 width, /* width */
385 height, /* height */
386 0, /* crop_left */
387 0, /* crop_right */
388 width, /* crop_width */
389 height, /* crop_height */
390 omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
391 dstCacheable); /* cacheable */
392 pVideoDec->csc_set_format = OMX_TRUE;
393 }
394 csc_set_src_buffer(
395 pVideoDec->csc_handle, /* handle */
396 pSrcBuf,
397 csc_memType); /* YUV Addr or FD */
398 csc_set_dst_buffer(
399 pVideoDec->csc_handle, /* handle */
400 pYUVBuf,
401 csc_memType); /* YUV Addr or FD */
402 cscRet = csc_convert(pVideoDec->csc_handle);
403 if (cscRet != CSC_ErrorNone)
404 ret = OMX_FALSE;
405 else
406 ret = OMX_TRUE;
407
408 #ifdef USE_ANB
409 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
410 Exynos_OSAL_UnlockANB(pOutputBuf);
411 }
412 #endif
413
414 EXIT:
415 FunctionOut();
416
417 return ret;
418 }
419
420 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
421 {
422 OMX_BOOL ret = OMX_FALSE;
423 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
424 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
425 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
426 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
427 OMX_U32 copySize = 0;
428 OMX_BYTE checkInputStream = NULL;
429 OMX_U32 checkInputStreamLen = 0;
430
431 FunctionIn();
432
433 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
434 if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
435 (srcInputData->pPrivate == NULL)) {
436 ret = OMX_FALSE;
437 goto EXIT;
438 }
439 }
440
441 if (inputUseBuffer->dataValid == OMX_TRUE) {
442 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
443 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
444
445 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
446 OMX_PTR dataBuffer = NULL;
447
448 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
449 srcInputData->buffer.singlePlaneBuffer.dataBuffer);
450 if (dataBuffer == NULL) {
451 ret = OMX_FALSE;
452 goto EXIT;
453 }
454
455 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
456 }
457
458 /* reset dataBuffer */
459 Exynos_ResetDataBuffer(inputUseBuffer);
460 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
461 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
462 checkInputStreamLen = inputUseBuffer->remainDataLen;
463
464 pExynosComponent->bUseFlagEOF = OMX_TRUE;
465
466 copySize = checkInputStreamLen;
467 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
468
469 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
470 if (copySize > 0) {
471 Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
472 checkInputStream, copySize);
473 }
474
475 inputUseBuffer->dataLen -= copySize;
476 inputUseBuffer->remainDataLen -= copySize;
477 inputUseBuffer->usedDataLen += copySize;
478
479 srcInputData->dataLen += copySize;
480 srcInputData->remainDataLen += copySize;
481
482 srcInputData->timeStamp = inputUseBuffer->timeStamp;
483 srcInputData->nFlags = inputUseBuffer->nFlags;
484 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
485 } else {
486 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
487 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
488 pExynosComponent->callbackData,
489 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
490 ret = OMX_FALSE;
491 }
492
493 Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
494 }
495
496 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
497 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
498 srcInputData->dataLen = 0;
499 srcInputData->remainDataLen = 0;
500 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
501 }
502
503 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
504 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
505 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
506 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
507 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
508 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
509 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
510 }
511
512 ret = OMX_TRUE;
513 }
514
515 EXIT:
516
517 FunctionOut();
518
519 return ret;
520 }
521
522 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
523 {
524 OMX_BOOL ret = OMX_FALSE;
525 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
526 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
527 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
528 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
529 OMX_U32 copySize = 0;
530 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
531
532 FunctionIn();
533
534 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
535 if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) {
536 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
537 outputUseBuffer->dataValid = OMX_TRUE;
538 } else {
539 if (Exynos_Shared_DataToANBBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
540 outputUseBuffer->dataValid = OMX_TRUE;
541 } else {
542 ret = OMX_FALSE;
543 goto EXIT;
544 }
545 }
546 }
547
548 if (outputUseBuffer->dataValid == OMX_TRUE) {
549 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
550 dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
551 if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
552 ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
553 if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
554 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
555 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
556 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
557 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
558 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
559 } else {
560 if (pExynosComponent->checkTimeStamp.startTimeStamp < dstOutputData->timeStamp) {
561 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
562 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
563 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
564 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
565 } else {
566 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
567 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
568 Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
569
570 ret = OMX_TRUE;
571 goto EXIT;
572 }
573 }
574 } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
575 ret = OMX_TRUE;
576 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
577 goto EXIT;
578 }
579
580 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
581 OMX_U32 width = 0, height = 0;
582 int imageSize = 0;
583 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
584
585 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
586
587 width = pBufferInfo->imageWidth;
588 height = pBufferInfo->imageHeight;
589 imageSize = width * height;
590
591 if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
592 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
593 copySize = dstOutputData->remainDataLen;
594 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
595
596 outputUseBuffer->dataLen += copySize;
597 outputUseBuffer->remainDataLen += copySize;
598 outputUseBuffer->nFlags = dstOutputData->nFlags;
599 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
600
601 if (outputUseBuffer->remainDataLen > 0) {
602 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
603 } else {
604 ret = OMX_TRUE;
605 }
606
607 if (ret == OMX_TRUE) {
608 if ((outputUseBuffer->remainDataLen > 0) ||
609 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
610 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
611 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
612 }
613 } else {
614 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
615 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
616 pExynosComponent->callbackData,
617 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
618 ret = OMX_FALSE;
619 }
620 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
621 outputUseBuffer->dataLen = 0;
622 outputUseBuffer->remainDataLen = 0;
623 outputUseBuffer->nFlags = dstOutputData->nFlags;
624 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
625 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
626 } else {
627 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
628 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
629 pExynosComponent->callbackData,
630 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
631 ret = OMX_FALSE;
632 }
633 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
634 if ((outputUseBuffer->remainDataLen > 0) ||
635 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
636 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
637 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
638 }
639 } else {
640 ret = OMX_FALSE;
641 }
642
643 EXIT:
644 FunctionOut();
645
646 return ret;
647 }
648
649 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
650 {
651 OMX_ERRORTYPE ret = OMX_ErrorNone;
652 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
653 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
654 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
655 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
656 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
657 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
658 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
659 OMX_BOOL bCheckInputData = OMX_FALSE;
660 OMX_BOOL bValidCodecData = OMX_FALSE;
661
662 FunctionIn();
663
664 while (!pVideoDec->bExitBufferProcessThread) {
665 Exynos_OSAL_SleepMillisec(0);
666 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
667
668 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
669 (!pVideoDec->bExitBufferProcessThread)) {
670 Exynos_OSAL_SleepMillisec(0);
671
672 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
673 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)))
674 break;
675 if (exynosInputPort->portState != OMX_StateIdle)
676 break;
677
678 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
679 if (ret != OMX_ErrorInputDataDecodeYet) {
680 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
681 OMX_PTR codecBuffer;
682 if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
683 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
684 if (codecBuffer != NULL) {
685 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
686 }
687 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
688 break;
689 }
690 }
691
692 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
693 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
694 } else {
695 bCheckInputData = OMX_FALSE;
696 }
697
698 if ((bCheckInputData == OMX_FALSE) &&
699 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
700 ret = Exynos_InputBufferGetQueue(pExynosComponent);
701 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
702 break;
703 }
704
705 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
706 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
707 break;
708 }
709 }
710
711 ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
712 if (ret == OMX_ErrorCorruptedFrame) {
713 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
714 OMX_PTR codecBuffer;
715 codecBuffer = pSrcInputData->pPrivate;
716 if (codecBuffer != NULL)
717 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
718 }
719
720 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
721 Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
722 }
723 }
724
725 if (ret != OMX_ErrorInputDataDecodeYet) {
726 Exynos_ResetCodecData(pSrcInputData);
727 }
728 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
729 if (ret == OMX_ErrorCodecInit)
730 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
731 }
732 }
733
734 EXIT:
735
736 FunctionOut();
737
738 return ret;
739 }
740
741 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
742 {
743 OMX_ERRORTYPE ret = OMX_ErrorNone;
744 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
745 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
746 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
747 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
748 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
749 EXYNOS_OMX_DATA srcOutputData;
750
751 FunctionIn();
752
753 while (!pVideoDec->bExitBufferProcessThread) {
754 Exynos_OSAL_SleepMillisec(0);
755
756 while (!pVideoDec->bExitBufferProcessThread) {
757 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
758 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
759 break;
760 }
761 Exynos_OSAL_SleepMillisec(0);
762
763 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
764 break;
765
766 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
767 ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
768
769 if (ret == OMX_ErrorNone) {
770 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
771 OMX_PTR codecBuffer;
772 codecBuffer = srcOutputData.pPrivate;
773 if (codecBuffer != NULL)
774 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
775 }
776 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
777 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
778 Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
779 }
780 Exynos_ResetCodecData(&srcOutputData);
781 }
782 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
783 }
784 }
785
786 EXIT:
787
788 FunctionOut();
789
790 return ret;
791 }
792
793 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
794 {
795 OMX_ERRORTYPE ret = OMX_ErrorNone;
796 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
797 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
798 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
799 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
800 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
801 EXYNOS_OMX_DATA dstInputData;
802
803 FunctionIn();
804
805 while (!pVideoDec->bExitBufferProcessThread) {
806 Exynos_OSAL_SleepMillisec(0);
807
808 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
809 (!pVideoDec->bExitBufferProcessThread)) {
810 Exynos_OSAL_SleepMillisec(0);
811
812 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
813 (!CHECK_PORT_POPULATED(exynosOutputPort)))
814 break;
815 if (exynosOutputPort->portState != OMX_StateIdle)
816 break;
817
818 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
819 if (ret != OMX_ErrorOutputBufferUseYet) {
820 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
821 CODEC_DEC_BUFFER *pCodecBuffer = NULL;
822 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
823 if (ret != OMX_ErrorNone) {
824 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
825 break;
826 }
827 Exynos_Output_CodecBufferToData(pCodecBuffer, &dstInputData);
828 }
829
830 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
831 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
832 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
833 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
834 if (ret != OMX_ErrorNone) {
835 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
836 break;
837 }
838 if (exynosOutputPort->bIsANBEnabled == OMX_FALSE) {
839 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
840 } else {
841 ret = Exynos_Shared_ANBBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
842 if (ret != OMX_ErrorNone) {
843 dstInputUseBuffer->dataValid = OMX_FALSE;
844 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
845 break;
846 }
847 }
848 Exynos_ResetDataBuffer(dstInputUseBuffer);
849 }
850 }
851
852 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
853 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
854 break;
855 }
856 }
857
858 ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
859 if (ret != OMX_ErrorOutputBufferUseYet) {
860 Exynos_ResetCodecData(&dstInputData);
861 }
862 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
863 }
864 }
865
866 EXIT:
867
868 FunctionOut();
869
870 return ret;
871 }
872
873 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(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 *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
881 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
882
883 FunctionIn();
884
885 while (!pVideoDec->bExitBufferProcessThread) {
886 Exynos_OSAL_SleepMillisec(0);
887 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
888
889 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
890 (!pVideoDec->bExitBufferProcessThread)) {
891 Exynos_OSAL_SleepMillisec(0);
892
893 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
894 break;
895
896 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
897 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
898 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
899 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
900 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
901 if (ret != OMX_ErrorNone) {
902 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
903 break;
904 }
905 }
906 }
907
908 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
909 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
910 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
911
912 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
913 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
914 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
915 }
916
917 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
918 if (pDstOutputData->pPrivate != NULL) {
919 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
920 pDstOutputData->pPrivate = NULL;
921 }
922 }
923
924 /* reset outputData */
925 Exynos_ResetCodecData(pDstOutputData);
926 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
927 }
928 }
929
930 EXIT:
931
932 FunctionOut();
933
934 return ret;
935 }
936
937 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
938 {
939 OMX_ERRORTYPE ret = OMX_ErrorNone;
940 OMX_COMPONENTTYPE *pOMXComponent = NULL;
941 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
942 EXYNOS_OMX_MESSAGE *message = NULL;
943
944 FunctionIn();
945
946 if (threadData == NULL) {
947 ret = OMX_ErrorBadParameter;
948 goto EXIT;
949 }
950 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
951 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
952 if (ret != OMX_ErrorNone) {
953 goto EXIT;
954 }
955 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
956 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
957
958 Exynos_OSAL_ThreadExit(NULL);
959
960 EXIT:
961 FunctionOut();
962
963 return ret;
964 }
965
966 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
967 {
968 OMX_ERRORTYPE ret = OMX_ErrorNone;
969 OMX_COMPONENTTYPE *pOMXComponent = NULL;
970 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
971 EXYNOS_OMX_MESSAGE *message = NULL;
972
973 FunctionIn();
974
975 if (threadData == NULL) {
976 ret = OMX_ErrorBadParameter;
977 goto EXIT;
978 }
979 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
980 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
981 if (ret != OMX_ErrorNone) {
982 goto EXIT;
983 }
984 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
985 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
986
987 Exynos_OSAL_ThreadExit(NULL);
988
989 EXIT:
990 FunctionOut();
991
992 return ret;
993 }
994
995 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
996 {
997 OMX_ERRORTYPE ret = OMX_ErrorNone;
998 OMX_COMPONENTTYPE *pOMXComponent = NULL;
999 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1000 EXYNOS_OMX_MESSAGE *message = NULL;
1001
1002 FunctionIn();
1003
1004 if (threadData == NULL) {
1005 ret = OMX_ErrorBadParameter;
1006 goto EXIT;
1007 }
1008 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1009 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1010 if (ret != OMX_ErrorNone) {
1011 goto EXIT;
1012 }
1013 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1014 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1015
1016 Exynos_OSAL_ThreadExit(NULL);
1017
1018 EXIT:
1019 FunctionOut();
1020
1021 return ret;
1022 }
1023
1024 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1025 {
1026 OMX_ERRORTYPE ret = OMX_ErrorNone;
1027 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1028 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1029 EXYNOS_OMX_MESSAGE *message = NULL;
1030
1031 FunctionIn();
1032
1033 if (threadData == NULL) {
1034 ret = OMX_ErrorBadParameter;
1035 goto EXIT;
1036 }
1037 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1038 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1039 if (ret != OMX_ErrorNone) {
1040 goto EXIT;
1041 }
1042 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1043 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1044
1045 Exynos_OSAL_ThreadExit(NULL);
1046
1047 EXIT:
1048 FunctionOut();
1049
1050 return ret;
1051 }
1052
1053 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1054 {
1055 OMX_ERRORTYPE ret = OMX_ErrorNone;
1056 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1057 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1058 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1059
1060 FunctionIn();
1061
1062 pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1063
1064 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1065 Exynos_OMX_DstOutputProcessThread,
1066 pOMXComponent);
1067 if (ret == OMX_ErrorNone)
1068 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1069 Exynos_OMX_SrcOutputProcessThread,
1070 pOMXComponent);
1071 if (ret == OMX_ErrorNone)
1072 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1073 Exynos_OMX_DstInputProcessThread,
1074 pOMXComponent);
1075 if (ret == OMX_ErrorNone)
1076 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1077 Exynos_OMX_SrcInputProcessThread,
1078 pOMXComponent);
1079
1080 EXIT:
1081 FunctionOut();
1082
1083 return ret;
1084 }
1085
1086 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1087 {
1088 OMX_ERRORTYPE ret = OMX_ErrorNone;
1089 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1090 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1091 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1092 OMX_S32 countValue = 0;
1093 unsigned int i = 0;
1094
1095 FunctionIn();
1096
1097 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1098
1099 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1100 if (countValue == 0)
1101 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1102 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1103 if (countValue == 0)
1104 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1105 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1106 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1107 pVideoDec->hSrcInputThread = NULL;
1108
1109 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1110 if (countValue == 0)
1111 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1112 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1113 if (countValue == 0)
1114 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1115 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1116 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1117 pVideoDec->hDstInputThread = NULL;
1118
1119 pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1120 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1121 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1122 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1123 pVideoDec->hSrcOutputThread = NULL;
1124
1125 pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1126 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1127 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1128 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1129 pVideoDec->hDstOutputThread = NULL;
1130
1131 EXIT:
1132 FunctionOut();
1133
1134 return ret;
1135 }
1136
1137 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1138 {
1139 OMX_ERRORTYPE ret = OMX_ErrorNone;
1140 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1141 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1142 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1143 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1144
1145 FunctionIn();
1146
1147 if (hComponent == NULL) {
1148 ret = OMX_ErrorBadParameter;
1149 goto EXIT;
1150 }
1151 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1152 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1153 if (ret != OMX_ErrorNone) {
1154 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1155 goto EXIT;
1156 }
1157
1158 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1159 if (ret != OMX_ErrorNone) {
1160 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1161 goto EXIT;
1162 }
1163
1164 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1165 if (ret != OMX_ErrorNone) {
1166 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1167 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1168 goto EXIT;
1169 }
1170
1171 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1172
1173 pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1174 if (pVideoDec == NULL) {
1175 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1176 ret = OMX_ErrorInsufficientResources;
1177 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1178 goto EXIT;
1179 }
1180
1181 Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1182 pVideoDec->bReconfigDPB = OMX_FALSE;
1183 pVideoDec->nSavedDPBCnt = 0;
1184 pVideoDec->bDTSMode = OMX_FALSE;
1185 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1186
1187 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1188 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1189
1190 /* Input port */
1191 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1192 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1193 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1194 pExynosPort->portDefinition.nBufferSize = 0;
1195 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1196
1197 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1198 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1199 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1200 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1201 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1202
1203 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1204 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1205 pExynosPort->portDefinition.format.video.nStride = 0;
1206 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1207 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1208 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1209 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1210 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1211
1212 /* Output port */
1213 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1214 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1215 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1216 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1217 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1218
1219 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1220 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1221 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1222 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1223 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1224
1225 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1226 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1227 pExynosPort->portDefinition.format.video.nStride = 0;
1228 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1229 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1230 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1231 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1232 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1233
1234 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1235
1236 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1237 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1238 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1239 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1240
1241 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1242 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1243 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1244 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1245 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1246
1247 EXIT:
1248 FunctionOut();
1249
1250 return ret;
1251 }
1252
1253 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1254 {
1255 OMX_ERRORTYPE ret = OMX_ErrorNone;
1256 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1257 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1258 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1259 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1260 int i = 0;
1261
1262 FunctionIn();
1263
1264 if (hComponent == NULL) {
1265 ret = OMX_ErrorBadParameter;
1266 goto EXIT;
1267 }
1268 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1269 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1270 if (ret != OMX_ErrorNone) {
1271 goto EXIT;
1272 }
1273
1274 if (pOMXComponent->pComponentPrivate == NULL) {
1275 ret = OMX_ErrorBadParameter;
1276 goto EXIT;
1277 }
1278 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1279
1280 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1281
1282 Exynos_OSAL_Free(pVideoDec);
1283 pExynosComponent->hComponentHandle = pVideoDec = NULL;
1284
1285 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1286 if (pExynosPort->processData.extInfo != NULL) {
1287 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1288 pExynosPort->processData.extInfo = NULL;
1289 }
1290
1291 for(i = 0; i < ALL_PORT_NUM; i++) {
1292 pExynosPort = &pExynosComponent->pExynosPort[i];
1293 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1294 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1295 }
1296
1297 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1298
1299 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1300
1301 EXIT:
1302 FunctionOut();
1303
1304 return ret;
1305 }