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