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