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