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