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