osal: add libui dependency
[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 "csc.h"
48
49 #undef EXYNOS_LOG_TAG
50 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DEC"
51 //#define EXYNOS_LOG_OFF
52 #include "Exynos_OSAL_Log.h"
53
54 void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
55 {
56 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
57 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
58 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
59
60 if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
61 exynosInputPort->portDefinition.format.video.nFrameWidth) ||
62 (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
63 exynosInputPort->portDefinition.format.video.nFrameHeight)) {
64 OMX_U32 width = 0, height = 0;
65
66 exynosOutputPort->portDefinition.format.video.nFrameWidth =
67 exynosInputPort->portDefinition.format.video.nFrameWidth;
68 exynosOutputPort->portDefinition.format.video.nFrameHeight =
69 exynosInputPort->portDefinition.format.video.nFrameHeight;
70 width = exynosOutputPort->portDefinition.format.video.nStride =
71 exynosInputPort->portDefinition.format.video.nStride;
72 height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
73 exynosInputPort->portDefinition.format.video.nSliceHeight;
74
75 switch((int)exynosOutputPort->portDefinition.format.video.eColorFormat) {
76 case OMX_COLOR_FormatYUV420Planar:
77 case OMX_COLOR_FormatYUV420SemiPlanar:
78 case OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace:
79 case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
80 case OMX_SEC_COLOR_FormatNV12Tiled:
81 case OMX_SEC_COLOR_FormatYVU420Planar:
82 case OMX_SEC_COLOR_FormatNV21Linear:
83 if (width && height)
84 exynosOutputPort->portDefinition.nBufferSize = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
85 break;
86 default:
87 if (width && height)
88 exynosOutputPort->portDefinition.nBufferSize = ALIGN(width, 16) * ALIGN(height, 16) * 2;
89 break;
90 }
91 }
92
93 return;
94 }
95
96 void Exynos_Output_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
97 {
98 OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
99 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
100 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
101
102 if ((pVideoDec == NULL) || (pOutputPort == NULL))
103 return ;
104
105 if (pOutputPort->supportFormat != NULL) {
106 OMX_BOOL ret = OMX_FALSE;
107 int nLastIndex = OUTPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM;
108 int i;
109
110 /* Default supported formats */
111 /* Customer wants OMX_COLOR_FormatYUV420SemiPlanar in the default colors format. */
112 /* But, Google wants OMX_COLOR_FormatYUV420Planar in the default colors format. */
113 /* Google's Videoeditor uses OMX_COLOR_FormatYUV420Planar(YV12) in the default colors format. */
114 /* Therefore, only when you load the OpenMAX IL component by the customer name, */
115 /* to change the default OMX_COLOR_FormatYUV420SemiPlanar color format. */
116 /* It is determined by case-sensitive. */
117 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s, custom?:(%d)",pExynosComponent->componentName, IS_CUSTOM_COMPONENT(pExynosComponent->componentName));
118 if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) != OMX_TRUE) {
119 /* Google GED & S.LSI Component, for video editor*/
120 pOutputPort->supportFormat[0] = OMX_COLOR_FormatYUV420Planar;
121 pOutputPort->supportFormat[1] = OMX_COLOR_FormatYUV420SemiPlanar;
122 } else {
123 /* Customer Component*/
124 pOutputPort->supportFormat[0] = OMX_COLOR_FormatYUV420SemiPlanar;
125 pOutputPort->supportFormat[1] = OMX_COLOR_FormatYUV420Planar;
126 }
127
128 /* add extra formats, if It is supported by H/W. (CSC doesn't exist) */
129 /* OMX_SEC_COLOR_FormatNV12Tiled */
130 ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent,
131 (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
132 if (ret == OMX_TRUE)
133 pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
134
135 /* OMX_SEC_COLOR_FormatYVU420Planar */
136 ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent,
137 (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar);
138 if (ret == OMX_TRUE)
139 pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar;
140
141 /* OMX_SEC_COLOR_FormatNV21Linear */
142 ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, OMX_SEC_COLOR_FormatNV21Linear);
143 if (ret == OMX_TRUE)
144 pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear;
145
146 for (i = 0; i < nLastIndex; i++)
147 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Support Format[%d] : 0x%x", i, pOutputPort->supportFormat[i]);
148
149 pOutputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
150 }
151
152 return ;
153 }
154
155 OMX_ERRORTYPE Exynos_ResolutionUpdate(OMX_COMPONENTTYPE *pOMXComponent)
156 {
157 OMX_ERRORTYPE ret = OMX_ErrorNone;
158 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
159 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
160 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
161 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
162
163 pOutputPort->cropRectangle.nTop = pOutputPort->newCropRectangle.nTop;
164 pOutputPort->cropRectangle.nLeft = pOutputPort->newCropRectangle.nLeft;
165 pOutputPort->cropRectangle.nWidth = pOutputPort->newCropRectangle.nWidth;
166 pOutputPort->cropRectangle.nHeight = pOutputPort->newCropRectangle.nHeight;
167
168 pInputPort->portDefinition.format.video.nFrameWidth = pInputPort->newPortDefinition.format.video.nFrameWidth;
169 pInputPort->portDefinition.format.video.nFrameHeight = pInputPort->newPortDefinition.format.video.nFrameHeight;
170 pInputPort->portDefinition.format.video.nStride = pInputPort->newPortDefinition.format.video.nStride;
171 pInputPort->portDefinition.format.video.nSliceHeight = pInputPort->newPortDefinition.format.video.nSliceHeight;
172
173 pOutputPort->portDefinition.nBufferCountActual = pOutputPort->newPortDefinition.nBufferCountActual;
174 pOutputPort->portDefinition.nBufferCountMin = pOutputPort->newPortDefinition.nBufferCountMin;
175
176 Exynos_UpdateFrameSize(pOMXComponent);
177
178 /** Send crop info call back **/
179 (*(pExynosComponent->pCallbacks->EventHandler))
180 (pOMXComponent,
181 pExynosComponent->callbackData,
182 OMX_EventPortSettingsChanged, /* The command was completed */
183 OMX_DirOutput, /* This is the port index */
184 OMX_IndexConfigCommonOutputCrop,
185 NULL);
186
187 return ret;
188 }
189
190 void Exynos_Free_CodecBuffers(
191 OMX_COMPONENTTYPE *pOMXComponent,
192 OMX_U32 nPortIndex)
193 {
194 OMX_ERRORTYPE ret = OMX_ErrorNone;
195 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
196 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
197 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
198
199 int nBufferCnt = 0, nPlaneCnt = 0;
200 int i, j;
201
202 FunctionIn();
203
204 if (nPortIndex == INPUT_PORT_INDEX) {
205 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
206 nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
207 } else {
208 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
209 nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
210 }
211
212 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
213 for (i = 0; i < nBufferCnt; i++) {
214 if (ppCodecBuffer[i] != NULL) {
215 for (j = 0; j < nPlaneCnt; j++) {
216 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
217 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
218 }
219
220 Exynos_OSAL_Free(ppCodecBuffer[i]);
221 ppCodecBuffer[i] = NULL;
222 }
223 }
224
225 FunctionOut();
226 }
227
228 OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
229 OMX_COMPONENTTYPE *pOMXComponent,
230 OMX_U32 nPortIndex,
231 int nBufferCnt,
232 unsigned int nAllocLen[MAX_BUFFER_PLANE])
233 {
234 OMX_ERRORTYPE ret = OMX_ErrorNone;
235 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
236 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
237 MEMORY_TYPE eMemoryType = CACHED_MEMORY;
238 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
239
240 int nPlaneCnt = 0;
241 int i, j;
242
243 FunctionIn();
244
245 if (nPortIndex == INPUT_PORT_INDEX) {
246 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
247 } else {
248 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
249 #ifdef USE_CSC_HW
250 eMemoryType = NORMAL_MEMORY;
251 #endif
252 }
253 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
254
255 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
256 eMemoryType = SECURE_MEMORY;
257
258 for (i = 0; i < nBufferCnt; i++) {
259 ppCodecBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
260 if (ppCodecBuffer[i] == NULL) {
261 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
262 ret = OMX_ErrorInsufficientResources;
263 goto EXIT;
264 }
265 Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
266
267 for (j = 0; j < nPlaneCnt; j++) {
268 ppCodecBuffer[i]->pVirAddr[j] =
269 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType);
270 if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
271 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc plane");
272 ret = OMX_ErrorInsufficientResources;
273 goto EXIT;
274 }
275
276 ppCodecBuffer[i]->fd[j] =
277 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
278 ppCodecBuffer[i]->bufferSize[j] = nAllocLen[j];
279 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[j]);
280 }
281
282 ppCodecBuffer[i]->dataSize = 0;
283 }
284
285 return OMX_ErrorNone;
286
287 EXIT:
288 Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
289
290 FunctionOut();
291
292 return ret;
293 }
294
295 void Exynos_SetReorderTimestamp(
296 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
297 OMX_U32 *nIndex,
298 OMX_TICKS timeStamp,
299 OMX_U32 nFlags) {
300
301 int i;
302
303 FunctionIn();
304
305 if ((pExynosComponent == NULL) || (nIndex == NULL)) {
306 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter : pExynosComponent(%p), nIndex(%p)", pExynosComponent, nIndex);
307 return;
308 }
309
310 /* find a empty slot */
311 for (i = 0; i < MAX_TIMESTAMP; i++) {
312 if (pExynosComponent->bTimestampSlotUsed[*nIndex] == OMX_FALSE)
313 break;
314
315 (*nIndex)++;
316 (*nIndex) %= MAX_TIMESTAMP;
317 }
318
319 if (i >= MAX_TIMESTAMP)
320 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find empty slot of timestamp. Timestamp slot is full.");
321
322 pExynosComponent->timeStamp[*nIndex] = timeStamp;
323 pExynosComponent->nFlags[*nIndex] = nFlags;
324 pExynosComponent->bTimestampSlotUsed[*nIndex] = OMX_TRUE;
325
326 FunctionOut();
327 return;
328 }
329
330 void Exynos_GetReorderTimestamp(
331 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
332 EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP *sCurrentTimestamp,
333 OMX_S32 nFrameIndex,
334 OMX_S32 eFrameType) {
335
336 EXYNOS_OMX_BASEPORT *pExynosOutputPort = NULL;
337 int i = 0;
338
339 FunctionIn();
340
341 if ((pExynosComponent == NULL) || (sCurrentTimestamp == NULL)) {
342 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter : pExynosComponent(%p), sCurrentTimestamp(%p)", pExynosComponent, sCurrentTimestamp);
343 return;
344 }
345
346 pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
347
348 Exynos_OSAL_Memset(sCurrentTimestamp, 0, sizeof(EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP));
349 sCurrentTimestamp->timeStamp = DEFAULT_TIMESTAMP_VAL;
350
351 for (i = 0; i < MAX_TIMESTAMP; i++) {
352 /* NOTE: In case of CODECCONFIG, no return any frame */
353 if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_TRUE) &&
354 (pExynosComponent->nFlags[i] != (OMX_BUFFERFLAG_CODECCONFIG | OMX_BUFFERFLAG_ENDOFFRAME))) {
355
356 /* NOTE: In case of EOS, timestamp is not valid */
357 if ((sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL) ||
358 ((sCurrentTimestamp->timeStamp > pExynosComponent->timeStamp[i]) &&
359 (((pExynosComponent->nFlags[i] & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) ||
360 (pExynosComponent->bBehaviorEOS == OMX_TRUE))) ||
361 ((sCurrentTimestamp->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
362 sCurrentTimestamp->timeStamp = pExynosComponent->timeStamp[i];
363 sCurrentTimestamp->nFlags = pExynosComponent->nFlags[i];
364 sCurrentTimestamp->nIndex = i;
365 }
366 }
367 }
368
369 if (sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL)
370 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] could not find a valid timestamp", pExynosComponent, __FUNCTION__);
371
372 /* PTS : all index is same as tag */
373 /* DTS : only in case of I-Frame, the index is same as tag */
374 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, eFrameType);
375 if ((ExynosVideoFrameType)eFrameType & VIDEO_FRAME_I) {
376 /* Timestamp is weird */
377 if (sCurrentTimestamp->nIndex != nFrameIndex) {
378 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Timestamp is not same in spite of I-Frame", pExynosComponent, __FUNCTION__);
379
380 /* trust a tag index returned from D/D */
381 sCurrentTimestamp->timeStamp = pExynosComponent->timeStamp[nFrameIndex];
382 sCurrentTimestamp->nFlags = pExynosComponent->nFlags[nFrameIndex];
383 sCurrentTimestamp->nIndex = nFrameIndex;
384
385 /* delete past timestamps */
386 for(i = 0; i < MAX_TIMESTAMP; i++) {
387 if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_TRUE) &&
388 ((sCurrentTimestamp->timeStamp > pExynosComponent->timeStamp[i]) &&
389 ((pExynosComponent->nFlags[i] & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS))) {
390 pExynosComponent->nFlags[i] = 0x00;
391 pExynosComponent->bTimestampSlotUsed[i] = OMX_FALSE;
392 }
393
394 if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_FALSE) &&
395 (sCurrentTimestamp->timeStamp < pExynosComponent->timeStamp[i])) {
396 pExynosComponent->bTimestampSlotUsed[i] = OMX_TRUE;
397 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] revive an old timestamp index for I-frame sync", pExynosComponent, __FUNCTION__);
398 }
399 }
400 }
401
402 if (sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL)
403 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "the index of frame(%d) about I-frame is wrong", nFrameIndex);
404
405 sCurrentTimestamp->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
406 }
407
408 if (eFrameType & VIDEO_FRAME_CORRUPT)
409 sCurrentTimestamp->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
410
411 if (sCurrentTimestamp->timeStamp != DEFAULT_TIMESTAMP_VAL) {
412 if (pExynosOutputPort->latestTimeStamp <= sCurrentTimestamp->timeStamp) {
413 pExynosOutputPort->latestTimeStamp = sCurrentTimestamp->timeStamp;
414 } else {
415 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "sCurrentTimestamp(%lld) is smaller than latestTimeStamp(%lld), uses latestTimeStamp",
416 sCurrentTimestamp->timeStamp, pExynosOutputPort->latestTimeStamp);
417 sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
418 }
419 } else {
420 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "uses latestTimeStamp(%lld)", pExynosOutputPort->latestTimeStamp);
421 sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
422 }
423
424 FunctionOut();
425 return;
426 }
427
428 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
429 {
430 OMX_BOOL ret = OMX_FALSE;
431
432 if ((pExynosComponent == NULL) ||
433 (pExynosComponent->pExynosPort == NULL))
434 return OMX_FALSE;
435
436 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
437 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
438 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
439 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
440 ret = OMX_TRUE;
441 } else {
442 ret = OMX_FALSE;
443 }
444
445 return ret;
446 }
447
448 OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
449 {
450 OMX_ERRORTYPE ret = OMX_ErrorNone;
451 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
452 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
453 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
454
455 /* Input port */
456 pInputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
457 pInputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
458 pInputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
459 pInputPort->portDefinition.format.video.nSliceHeight = 0;
460 pInputPort->portDefinition.format.video.pNativeRender = 0;
461 pInputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
462 pInputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
463
464 pInputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
465 pInputPort->portDefinition.bEnabled = OMX_TRUE;
466
467 pInputPort->bufferProcessType = BUFFER_SHARE;
468 pInputPort->portWayType = WAY2_PORT;
469 Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
470
471 /* Output port */
472 pOutputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
473 pOutputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
474 pOutputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
475 pOutputPort->portDefinition.format.video.nSliceHeight = 0;
476 pOutputPort->portDefinition.format.video.pNativeRender = 0;
477 pOutputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
478 pOutputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
479
480 pOutputPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
481 pOutputPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
482 pOutputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
483 pOutputPort->portDefinition.bEnabled = OMX_TRUE;
484
485 pOutputPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
486 #ifdef USE_ANB
487 pOutputPort->bIsANBEnabled = OMX_FALSE;
488 #ifdef USE_STOREMETADATA
489 pOutputPort->bStoreMetaData = OMX_FALSE;
490 #endif
491 #endif
492 pOutputPort->portWayType = WAY2_PORT;
493 pOutputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
494 Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar, pOutputPort->ePlaneType));
495
496 pOutputPort->cropRectangle.nTop = 0;
497 pOutputPort->cropRectangle.nLeft = 0;
498 pOutputPort->cropRectangle.nWidth = DEFAULT_FRAME_WIDTH;
499 pOutputPort->cropRectangle.nHeight = DEFAULT_FRAME_HEIGHT;
500
501 return ret;
502 }
503
504 OMX_ERRORTYPE Exynos_CodecBufferToData(
505 CODEC_DEC_BUFFER *pCodecBuffer,
506 EXYNOS_OMX_DATA *pData,
507 OMX_U32 nPortIndex)
508 {
509 OMX_ERRORTYPE ret = OMX_ErrorNone;
510 int i;
511
512 if (nPortIndex > OUTPUT_PORT_INDEX) {
513 ret = OMX_ErrorBadPortIndex;
514 goto EXIT;
515 }
516
517 pData->allocSize = 0;
518 pData->usedDataLen = 0;
519 pData->nFlags = 0;
520 pData->timeStamp = 0;
521 pData->pPrivate = pCodecBuffer;
522 pData->bufferHeader = NULL;
523
524 for (i = 0; i < MAX_BUFFER_PLANE; i++) {
525 pData->multiPlaneBuffer.dataBuffer[i] = pCodecBuffer->pVirAddr[i];
526 pData->multiPlaneBuffer.fd[i] = pCodecBuffer->fd[i];
527 pData->allocSize += pCodecBuffer->bufferSize[i];
528 }
529
530 if (nPortIndex == INPUT_PORT_INDEX) {
531 pData->dataLen = pCodecBuffer->dataSize;
532 pData->remainDataLen = pCodecBuffer->dataSize;
533 } else {
534 pData->dataLen = 0;
535 pData->remainDataLen = 0;
536 }
537
538 EXIT:
539 return ret;
540 }
541
542 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
543 {
544 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
545 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
546 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
547 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
548
549 FunctionIn();
550
551 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
552
553 if (((pExynosComponent->currentState == OMX_StatePause) ||
554 (pExynosComponent->currentState == OMX_StateIdle) ||
555 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
556 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
557 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
558 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
559 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
560 if (pVideoDec->bExitBufferProcessThread)
561 goto EXIT;
562 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
563 }
564
565 EXIT:
566 FunctionOut();
567
568 return;
569 }
570
571 OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
572 {
573 OMX_BOOL ret = OMX_FALSE;
574 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
575 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
576 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
577 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
578 OMX_U32 copySize = 0;
579 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
580 OMX_COLOR_FORMATTYPE eColorFormat = exynosOutputPort->portDefinition.format.video.eColorFormat;
581
582 FunctionIn();
583
584 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
585 void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
586 void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
587
588 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
589
590 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
591 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
592
593 OMX_U32 nFrameWidth = 0, nFrameHeight = 0;
594 OMX_U32 nImageWidth = 0, nImageHeight = 0, stride = 0;
595
596 CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
597 CSC_METHOD csc_method = CSC_METHOD_SW;
598 CSC_ERRORCODE cscRet = CSC_ErrorNone;
599 unsigned int srcCacheable = 1, dstCacheable = 1;
600
601 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
602
603 nFrameWidth = pBufferInfo->imageStride;
604 nFrameHeight = exynosOutputPort->portDefinition.format.video.nSliceHeight;
605
606 /* If crop info is used, width & height will be info about frame */
607 nImageWidth = pBufferInfo->imageWidth;
608 nImageHeight = pBufferInfo->imageHeight;
609
610 pSrcBuf[0] = dstOutputData->multiPlaneBuffer.dataBuffer[0];
611 pSrcBuf[1] = dstOutputData->multiPlaneBuffer.dataBuffer[1];
612 pSrcBuf[2] = dstOutputData->multiPlaneBuffer.dataBuffer[2];
613
614 if (exynosOutputPort->ePlaneType == PLANE_SINGLE) { /* from H/W. only Y addr is valid */
615 /* get a count of color plane */
616 int nPlaneCnt = Exynos_OSAL_GetPlaneCount(pBufferInfo->ColorFormat, PLANE_MULTIPLE);
617
618 if (nPlaneCnt == 2) { /* Semi-Planar : interleaved */
619 pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) +
620 ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_UV_OFFSET(nImageWidth, nImageHeight):GET_UV_OFFSET(nImageWidth, nImageHeight)));
621 } else if (nPlaneCnt == 3) { /* Planar */
622 pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) +
623 ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_CB_OFFSET(nImageWidth, nImageHeight):GET_CB_OFFSET(nImageWidth, nImageHeight)));
624 pSrcBuf[2] = (void *)(((char *)pSrcBuf[0]) +
625 ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_CR_OFFSET(nImageWidth, nImageHeight):GET_CR_OFFSET(nImageWidth, nImageHeight)));
626 }
627 }
628
629 /* calculate each plane info for the application */
630 Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_MULTIPLE, nImageWidth, nImageHeight, nDataLen, nAllocLen);
631
632 pYUVBuf[0] = (void *)((char *)pOutputBuf);
633 pYUVBuf[1] = (void *)((char *)pOutputBuf + nDataLen[0]);
634 pYUVBuf[2] = (void *)((char *)pOutputBuf + nDataLen[0] + nDataLen[1]);
635
636 #ifdef USE_ANB
637 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
638 if (OMX_ErrorNone != Exynos_OSAL_LockANBHandle(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes)) {
639 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__);
640 ret = OMX_FALSE;
641 goto EXIT;
642 }
643
644 nImageWidth = stride;
645 outputUseBuffer->dataLen = sizeof(void *);
646
647 pYUVBuf[0] = (void *)planes[0].addr;
648 pYUVBuf[1] = (void *)planes[1].addr;
649 pYUVBuf[2] = (void *)planes[2].addr;
650 }
651 #ifdef USE_STOREMETADATA
652 else if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
653 if (OMX_ErrorNone != Exynos_OSAL_LockMetaData(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes)) {
654 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockMetaData() failed", __FUNCTION__);
655 ret = OMX_FALSE;
656 goto EXIT;
657 }
658
659 nImageWidth = stride;
660 outputUseBuffer->dataLen = sizeof(void *);
661
662 pYUVBuf[0] = (void *)planes[0].addr;
663 pYUVBuf[1] = (void *)planes[1].addr;
664 pYUVBuf[2] = (void *)planes[2].addr;
665 }
666 #endif
667 #endif
668
669 if (pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
670 csc_memType = CSC_MEMORY_MFC; /* to remove stride value */
671 if (pVideoDec->csc_set_format == OMX_FALSE) {
672 csc_set_method(pVideoDec->csc_handle, CSC_METHOD_SW);
673 csc_set_src_format(
674 pVideoDec->csc_handle, /* handle */
675 nFrameWidth, /* width */
676 nFrameHeight, /* height */
677 0, /* crop_left */
678 0, /* crop_right */
679 nImageWidth, /* crop_width */
680 nImageHeight, /* crop_height */
681 Exynos_OSAL_OMX2HALPixelFormat(
682 pBufferInfo->ColorFormat, exynosOutputPort->ePlaneType), /* color_format */
683 srcCacheable); /* cacheable */
684 }
685 } else {
686 csc_get_method(pVideoDec->csc_handle, &csc_method);
687 if (csc_method == CSC_METHOD_HW) {
688 srcCacheable = 0;
689 dstCacheable = 0;
690 }
691
692 #ifdef USE_DMA_BUF
693 if (csc_method == CSC_METHOD_HW) {
694 csc_memType = CSC_MEMORY_DMABUF;
695
696 pSrcBuf[0] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[0]);
697 pSrcBuf[1] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[1]);
698 pSrcBuf[2] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[2]);
699
700 #ifdef USE_ANB
701 if ((exynosOutputPort->bIsANBEnabled == OMX_TRUE) ||
702 (exynosOutputPort->bStoreMetaData == OMX_TRUE)) {
703 pYUVBuf[0] = INT_TO_PTR(planes[0].fd);
704 pYUVBuf[1] = INT_TO_PTR(planes[1].fd);
705 pYUVBuf[2] = INT_TO_PTR(planes[2].fd);
706 } else {
707 pYUVBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf));
708 pYUVBuf[1] = NULL;
709 pYUVBuf[2] = NULL;
710 }
711 #else
712 pYUVBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf));
713 pYUVBuf[1] = NULL;
714 pYUVBuf[2] = NULL;
715 #endif
716 }
717 #endif
718
719 if (pVideoDec->csc_set_format == OMX_FALSE) {
720 csc_set_src_format(
721 pVideoDec->csc_handle, /* handle */
722 nFrameWidth, /* width */
723 nFrameHeight, /* height */
724 0, /* crop_left */
725 0, /* crop_right */
726 nImageWidth, /* crop_width */
727 nImageHeight, /* crop_height */
728 Exynos_OSAL_OMX2HALPixelFormat(
729 pBufferInfo->ColorFormat, exynosOutputPort->ePlaneType), /* color_format */
730 srcCacheable); /* cacheable */
731 }
732 }
733
734 if (pVideoDec->csc_set_format == OMX_FALSE) {
735 unsigned int pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, PLANE_SINGLE_USER);
736
737 if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
738 (nFrameWidth != nImageWidth) &&
739 (csc_method == CSC_METHOD_HW)) {
740 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "H/W CSC isn't supported by the constraint (w:%d/h:%d)", nImageWidth, nImageHeight);
741 ret = OMX_FALSE;
742 goto EXIT;
743 }
744
745 #ifdef USE_ANB
746 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE)
747 pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, exynosOutputPort->ePlaneType);
748 #ifdef USE_STOREMETADATA
749 else if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
750 pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, exynosOutputPort->ePlaneType);
751 #endif
752 #endif
753
754 csc_set_dst_format(
755 pVideoDec->csc_handle, /* handle */
756 nImageWidth, /* width */
757 nImageHeight, /* height */
758 0, /* crop_left */
759 0, /* crop_right */
760 nImageWidth, /* crop_width */
761 nImageHeight, /* crop_height */
762 pixelFormat, /* color_format */
763 dstCacheable); /* cacheable */
764
765 csc_set_eq_property(
766 pVideoDec->csc_handle, /* handle */
767 CSC_EQ_MODE_USER, /* user select */
768 CSC_EQ_RANGE_NARROW, /* narrow */
769 CSC_EQ_COLORSPACE_SMPTE170M); /* bt.601 */
770
771 pVideoDec->csc_set_format = OMX_TRUE;
772 }
773
774 csc_set_src_buffer(
775 pVideoDec->csc_handle, /* handle */
776 pSrcBuf,
777 csc_memType); /* YUV Addr or FD */
778 csc_set_dst_buffer(
779 pVideoDec->csc_handle, /* handle */
780 pYUVBuf,
781 csc_memType); /* YUV Addr or FD */
782 cscRet = csc_convert(pVideoDec->csc_handle);
783 if (cscRet != CSC_ErrorNone)
784 ret = OMX_FALSE;
785 else
786 ret = OMX_TRUE;
787
788 #ifdef USE_ANB
789 if (exynosOutputPort->bIsANBEnabled == OMX_TRUE)
790 Exynos_OSAL_UnlockANBHandle(pOutputBuf);
791 #ifdef USE_STOREMETADATA
792 else if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
793 Exynos_OSAL_UnlockMetaData(pOutputBuf);
794 #endif
795 #endif
796
797 EXIT:
798 FunctionOut();
799
800 return ret;
801 }
802
803 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
804 {
805 OMX_BOOL ret = OMX_FALSE;
806 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
807 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
808 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
809 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
810 OMX_U32 copySize = 0;
811 OMX_BYTE checkInputStream = NULL;
812 OMX_U32 checkInputStreamLen = 0;
813
814 FunctionIn();
815
816 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
817 if ((srcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) ||
818 (srcInputData->pPrivate == NULL)) {
819 ret = OMX_FALSE;
820 goto EXIT;
821 }
822 }
823
824 if (inputUseBuffer->dataValid == OMX_TRUE) {
825 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
826 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
827
828 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
829 int ionFD = -1;
830 OMX_PTR dataBuffer = NULL;
831
832 /* caution : data loss */
833 ionFD = PTR_TO_INT(srcInputData->multiPlaneBuffer.dataBuffer[0]);
834
835 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, ionFD);
836 if (dataBuffer == NULL) {
837 ret = OMX_FALSE;
838 goto EXIT;
839 }
840
841 srcInputData->multiPlaneBuffer.fd[0] = ionFD;
842 srcInputData->multiPlaneBuffer.dataBuffer[0] = dataBuffer;
843 } else {
844 srcInputData->multiPlaneBuffer.fd[0] =
845 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
846 srcInputData->multiPlaneBuffer.dataBuffer[0]);
847 }
848
849 /* reset dataBuffer */
850 Exynos_ResetDataBuffer(inputUseBuffer);
851 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
852 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
853 checkInputStreamLen = inputUseBuffer->remainDataLen;
854
855 pExynosComponent->bUseFlagEOF = OMX_TRUE;
856
857 copySize = checkInputStreamLen;
858
859 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
860 if (copySize > 0) {
861 Exynos_OSAL_Memcpy((OMX_PTR)((char *)srcInputData->multiPlaneBuffer.dataBuffer[0] + srcInputData->dataLen),
862 checkInputStream, copySize);
863 }
864
865 inputUseBuffer->dataLen -= copySize;
866 inputUseBuffer->remainDataLen -= copySize;
867 inputUseBuffer->usedDataLen += copySize;
868
869 srcInputData->dataLen += copySize;
870 srcInputData->remainDataLen += copySize;
871
872 srcInputData->timeStamp = inputUseBuffer->timeStamp;
873 srcInputData->nFlags = inputUseBuffer->nFlags;
874 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
875 } else {
876 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
877 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
878 pExynosComponent->callbackData,
879 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
880 ret = OMX_FALSE;
881 }
882
883 Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
884 }
885
886 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
887 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bSaveFlagEOS : OMX_TRUE", pExynosComponent, __FUNCTION__);
888 if (srcInputData->dataLen != 0)
889 pExynosComponent->bBehaviorEOS = OMX_TRUE;
890 }
891
892 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) &&
893 ((srcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) {
894 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
895
896 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
897 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
898 pOutputPort->latestTimeStamp = srcInputData->timeStamp; // for reordering timestamp mode
899 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
900 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
901 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame timestamp after seeking %lld us (%.2f secs)",
902 pExynosComponent, __FUNCTION__, srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
903 }
904
905 ret = OMX_TRUE;
906 }
907
908 EXIT:
909
910 FunctionOut();
911
912 return ret;
913 }
914
915 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
916 {
917 OMX_BOOL ret = OMX_FALSE;
918 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
919 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
920 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
921 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
922 OMX_U32 copySize = 0;
923 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
924
925 FunctionIn();
926
927 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
928 #ifdef USE_ANB
929 if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
930 (exynosOutputPort->bStoreMetaData == OMX_FALSE)) {
931 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
932 outputUseBuffer->dataValid = OMX_TRUE;
933 } else {
934 if (Exynos_Shared_DataToANBBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
935 outputUseBuffer->dataValid = OMX_TRUE;
936 } else {
937 ret = OMX_FALSE;
938 goto EXIT;
939 }
940 }
941 #else
942 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
943 outputUseBuffer->dataValid = OMX_TRUE;
944 #endif
945 }
946
947 if (outputUseBuffer->dataValid == OMX_TRUE) {
948 if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
949 ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
950 if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
951 (pExynosComponent->checkTimeStamp.nStartFlags ==
952 (dstOutputData->nFlags & ~(OMX_BUFFERFLAG_SYNCFRAME | OMX_BUFFERFLAG_DATACORRUPT)))) {
953 pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
954 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
955 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
956 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
957 } else {
958 if (pExynosComponent->checkTimeStamp.startTimeStamp < dstOutputData->timeStamp) {
959 pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
960 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
961 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
962 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
963 } else {
964 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] drop frame after seeking", pExynosComponent, __FUNCTION__);
965 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
966 Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
967
968 ret = OMX_TRUE;
969 goto EXIT;
970 }
971 }
972 } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
973 ret = OMX_TRUE;
974 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] not set check timestame after seeking", pExynosComponent, __FUNCTION__);
975 goto EXIT;
976 }
977
978 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
979 if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
980 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
981 copySize = dstOutputData->remainDataLen;
982 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
983
984 outputUseBuffer->dataLen += copySize;
985 outputUseBuffer->remainDataLen += copySize;
986 outputUseBuffer->nFlags = dstOutputData->nFlags;
987 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
988
989 if (outputUseBuffer->remainDataLen > 0) {
990 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
991 } else {
992 ret = OMX_TRUE;
993 }
994
995 if (ret == OMX_TRUE) {
996 if ((outputUseBuffer->remainDataLen > 0) ||
997 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
998 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
999 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
1000 }
1001 } else {
1002 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
1003 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1004 pExynosComponent->callbackData,
1005 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1006 ret = OMX_FALSE;
1007 }
1008 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
1009 outputUseBuffer->dataLen = 0;
1010 outputUseBuffer->remainDataLen = 0;
1011 outputUseBuffer->nFlags = dstOutputData->nFlags;
1012 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
1013 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
1014 } else {
1015 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
1016 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1017 pExynosComponent->callbackData,
1018 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1019 ret = OMX_FALSE;
1020 }
1021 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1022 if ((outputUseBuffer->remainDataLen > 0) ||
1023 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
1024 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1025 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
1026 } else {
1027 Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
1028 Exynos_ResetDataBuffer(outputUseBuffer);
1029 }
1030 }
1031 } else {
1032 ret = OMX_FALSE;
1033 }
1034
1035 EXIT:
1036 FunctionOut();
1037
1038 return ret;
1039 }
1040
1041 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
1042 {
1043 OMX_ERRORTYPE ret = OMX_ErrorNone;
1044 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1045 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1046 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1047 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1048 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1049 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
1050 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
1051 OMX_BOOL bCheckInputData = OMX_FALSE;
1052 OMX_BOOL bValidCodecData = OMX_FALSE;
1053
1054 FunctionIn();
1055
1056 while (!pVideoDec->bExitBufferProcessThread) {
1057 Exynos_OSAL_SleepMillisec(0);
1058 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
1059 if ((exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
1060 (!CHECK_PORT_ENABLED(exynosInputPort))) {
1061 /* sema will be posted at PortEnable */
1062 Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
1063 continue;
1064 }
1065
1066 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
1067 (!pVideoDec->bExitBufferProcessThread)) {
1068 Exynos_OSAL_SleepMillisec(0);
1069
1070 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
1071 ((exynosOutputPort->exceptionFlag != GENERAL_STATE) &&
1072 (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorInputDataDecodeYet) ||
1073 ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorNoneSrcSetupFinish))) ||
1074 (exynosOutputPort->exceptionFlag == INVALID_STATE))
1075 break;
1076 if (exynosInputPort->portState != OMX_StateIdle)
1077 break;
1078
1079 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
1080 if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) {
1081 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1082 OMX_PTR codecBuffer;
1083 if ((pSrcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) {
1084 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
1085 if (pVideoDec->bExitBufferProcessThread) {
1086 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1087 goto EXIT;
1088 }
1089
1090 if (codecBuffer != NULL) {
1091 Exynos_CodecBufferToData(codecBuffer, pSrcInputData, INPUT_PORT_INDEX);
1092 }
1093 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1094 break;
1095 }
1096 }
1097
1098 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
1099 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
1100 } else {
1101 bCheckInputData = OMX_FALSE;
1102 }
1103
1104 if ((bCheckInputData == OMX_FALSE) &&
1105 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
1106 ret = Exynos_InputBufferGetQueue(pExynosComponent);
1107 if (pVideoDec->bExitBufferProcessThread) {
1108 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1109 goto EXIT;
1110 }
1111
1112 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1113 break;
1114 }
1115
1116 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
1117 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1118 break;
1119 }
1120 }
1121
1122 /* if input flush is occured before obtaining bufferMutex,
1123 * bufferHeader can be NULL.
1124 */
1125 if (pSrcInputData->bufferHeader == NULL) {
1126 ret = OMX_ErrorNone;
1127 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1128 break;
1129 }
1130
1131 ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
1132 if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedFrame) ||
1133 ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader)) {
1134 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1135 OMX_PTR codecBuffer;
1136 codecBuffer = pSrcInputData->pPrivate;
1137 if (codecBuffer != NULL)
1138 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
1139 }
1140
1141 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
1142 Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
1143 }
1144 }
1145
1146 if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) {
1147 Exynos_ResetCodecData(pSrcInputData);
1148 }
1149 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1150 if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCodecInit)
1151 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1152 }
1153 }
1154
1155 EXIT:
1156
1157 FunctionOut();
1158
1159 return ret;
1160 }
1161
1162 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
1163 {
1164 OMX_ERRORTYPE ret = OMX_ErrorNone;
1165 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1166 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1167 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1168 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1169 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
1170 EXYNOS_OMX_DATA srcOutputData;
1171
1172 FunctionIn();
1173
1174 Exynos_ResetCodecData(&srcOutputData);
1175
1176 while (!pVideoDec->bExitBufferProcessThread) {
1177 Exynos_OSAL_SleepMillisec(0);
1178 if ((exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
1179 (!CHECK_PORT_ENABLED(exynosInputPort))) {
1180 /* sema will be posted at PortEnable */
1181 Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
1182 continue;
1183 }
1184
1185 while (!pVideoDec->bExitBufferProcessThread) {
1186 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1187 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
1188 break;
1189 }
1190 Exynos_OSAL_SleepMillisec(0);
1191
1192 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
1193 break;
1194
1195 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
1196 ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
1197
1198 if (ret == OMX_ErrorNone) {
1199 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1200 OMX_PTR codecBuffer;
1201 codecBuffer = srcOutputData.pPrivate;
1202 if (codecBuffer != NULL)
1203 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
1204 }
1205 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
1206 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
1207 Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
1208 }
1209 Exynos_ResetCodecData(&srcOutputData);
1210 }
1211 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
1212 }
1213 }
1214
1215 EXIT:
1216
1217 FunctionOut();
1218
1219 return ret;
1220 }
1221
1222 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
1223 {
1224 OMX_ERRORTYPE ret = OMX_ErrorNone;
1225 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1226 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1227 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1228 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1229 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
1230 EXYNOS_OMX_DATA dstInputData;
1231
1232 FunctionIn();
1233
1234 Exynos_ResetCodecData(&dstInputData);
1235
1236 while (!pVideoDec->bExitBufferProcessThread) {
1237 Exynos_OSAL_SleepMillisec(0);
1238 if ((exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
1239 (!CHECK_PORT_ENABLED(exynosOutputPort))) {
1240 /* sema will be posted at PortEnable */
1241 Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
1242 continue;
1243 }
1244
1245 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1246 (!pVideoDec->bExitBufferProcessThread)) {
1247 Exynos_OSAL_SleepMillisec(0);
1248
1249 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
1250 (!CHECK_PORT_POPULATED(exynosOutputPort)) ||
1251 (exynosOutputPort->exceptionFlag != GENERAL_STATE))
1252 break;
1253 if (exynosOutputPort->portState != OMX_StateIdle)
1254 break;
1255
1256 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
1257 if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorOutputBufferUseYet) {
1258 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1259 CODEC_DEC_BUFFER *pCodecBuffer = NULL;
1260 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
1261 if (pVideoDec->bExitBufferProcessThread) {
1262 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1263 goto EXIT;
1264 }
1265
1266 if (ret != OMX_ErrorNone) {
1267 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1268 break;
1269 }
1270 Exynos_CodecBufferToData(pCodecBuffer, &dstInputData, OUTPUT_PORT_INDEX);
1271 }
1272
1273 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1274 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
1275 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1276 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1277 if (pVideoDec->bExitBufferProcessThread) {
1278 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1279 goto EXIT;
1280 }
1281
1282 if (ret != OMX_ErrorNone) {
1283 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1284 break;
1285 }
1286 #ifdef USE_ANB
1287 if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
1288 (exynosOutputPort->bStoreMetaData == OMX_FALSE)) {
1289 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
1290 } else {
1291 ret = Exynos_Shared_ANBBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort);
1292 if (ret != OMX_ErrorNone) {
1293 dstInputUseBuffer->dataValid = OMX_FALSE;
1294 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1295 break;
1296 }
1297
1298 OMX_PTR pANBHandle = NULL;
1299 #ifdef USE_STOREMETADATA
1300 if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
1301 OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
1302
1303 ret = Exynos_OSAL_GetInfoFromMetaData(dstInputData.bufferHeader->pBuffer, ppBuf);
1304 if (ret != OMX_ErrorNone) {
1305 /* actually, the error will be happen at ANBBufferToData, if metadata is invalid. */
1306 dstInputUseBuffer->dataValid = OMX_FALSE;
1307 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1308 break;
1309 }
1310
1311 pANBHandle = ppBuf[0];
1312 } else
1313 #endif
1314 {
1315 pANBHandle = dstInputData.bufferHeader->pBuffer;
1316 }
1317
1318 Exynos_OSAL_RefANB_Increase(pVideoDec->hRefHandle, pANBHandle, exynosOutputPort->ePlaneType);
1319 }
1320 #else
1321 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
1322 #endif
1323 Exynos_ResetDataBuffer(dstInputUseBuffer);
1324 }
1325 }
1326
1327 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
1328 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1329 break;
1330 }
1331 }
1332
1333 ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
1334 if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorOutputBufferUseYet) {
1335 Exynos_ResetCodecData(&dstInputData);
1336 }
1337 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1338 }
1339 }
1340
1341 EXIT:
1342
1343 FunctionOut();
1344
1345 return ret;
1346 }
1347
1348 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
1349 {
1350 OMX_ERRORTYPE ret = OMX_ErrorNone;
1351 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1352 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1353 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1354 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1355 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
1356 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
1357
1358 FunctionIn();
1359
1360 while (!pVideoDec->bExitBufferProcessThread) {
1361 Exynos_OSAL_SleepMillisec(0);
1362 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
1363 if ((exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
1364 (!CHECK_PORT_ENABLED(exynosOutputPort))) {
1365 /* sema will be posted at PortEnable */
1366 Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
1367 continue;
1368 }
1369
1370 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1371 (!pVideoDec->bExitBufferProcessThread)) {
1372 Exynos_OSAL_SleepMillisec(0);
1373
1374 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
1375 break;
1376
1377 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
1378 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1379 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
1380 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1381 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1382 if (pVideoDec->bExitBufferProcessThread) {
1383 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1384 goto EXIT;
1385 }
1386
1387 if (ret != OMX_ErrorNone) {
1388 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1389 break;
1390 }
1391 }
1392 }
1393
1394 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
1395 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
1396 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
1397
1398 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
1399 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
1400 #ifdef USE_ANB
1401 if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1402 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1403 int i;
1404
1405 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1406 for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
1407 if (pBufferInfo->PDSB.dpbFD[i].fd > -1) {
1408 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "decRefCnt-FD:%d", pBufferInfo->PDSB.dpbFD[i].fd);
1409 Exynos_OSAL_RefANB_Decrease(pVideoDec->hRefHandle, pBufferInfo->PDSB.dpbFD[i].fd);
1410 } else {
1411 break;
1412 }
1413 }
1414 }
1415 #endif
1416 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
1417 }
1418
1419 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1420 if (pDstOutputData->pPrivate != NULL) {
1421 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
1422 pDstOutputData->pPrivate = NULL;
1423 }
1424 }
1425
1426 /* reset outputData */
1427 Exynos_ResetCodecData(pDstOutputData);
1428 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1429 }
1430 }
1431
1432 EXIT:
1433
1434 FunctionOut();
1435
1436 return ret;
1437 }
1438
1439 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
1440 {
1441 OMX_ERRORTYPE ret = OMX_ErrorNone;
1442 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1443 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1444 EXYNOS_OMX_MESSAGE *message = NULL;
1445
1446 FunctionIn();
1447
1448 if (threadData == NULL) {
1449 ret = OMX_ErrorBadParameter;
1450 goto EXIT;
1451 }
1452 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1453 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1454 if (ret != OMX_ErrorNone) {
1455 goto EXIT;
1456 }
1457 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1458 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1459
1460 Exynos_OSAL_ThreadExit(NULL);
1461
1462 EXIT:
1463 FunctionOut();
1464
1465 return ret;
1466 }
1467
1468 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1469 {
1470 OMX_ERRORTYPE ret = OMX_ErrorNone;
1471 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1472 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1473 EXYNOS_OMX_MESSAGE *message = NULL;
1474
1475 FunctionIn();
1476
1477 if (threadData == NULL) {
1478 ret = OMX_ErrorBadParameter;
1479 goto EXIT;
1480 }
1481 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1482 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1483 if (ret != OMX_ErrorNone) {
1484 goto EXIT;
1485 }
1486 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1487 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1488
1489 Exynos_OSAL_ThreadExit(NULL);
1490
1491 EXIT:
1492 FunctionOut();
1493
1494 return ret;
1495 }
1496
1497 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1498 {
1499 OMX_ERRORTYPE ret = OMX_ErrorNone;
1500 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1501 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1502 EXYNOS_OMX_MESSAGE *message = NULL;
1503
1504 FunctionIn();
1505
1506 if (threadData == NULL) {
1507 ret = OMX_ErrorBadParameter;
1508 goto EXIT;
1509 }
1510 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1511 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1512 if (ret != OMX_ErrorNone) {
1513 goto EXIT;
1514 }
1515 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1516 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1517
1518 Exynos_OSAL_ThreadExit(NULL);
1519
1520 EXIT:
1521 FunctionOut();
1522
1523 return ret;
1524 }
1525
1526 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1527 {
1528 OMX_ERRORTYPE ret = OMX_ErrorNone;
1529 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1530 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1531 EXYNOS_OMX_MESSAGE *message = NULL;
1532
1533 FunctionIn();
1534
1535 if (threadData == NULL) {
1536 ret = OMX_ErrorBadParameter;
1537 goto EXIT;
1538 }
1539 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1540 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1541 if (ret != OMX_ErrorNone) {
1542 goto EXIT;
1543 }
1544 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1545 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1546
1547 Exynos_OSAL_ThreadExit(NULL);
1548
1549 EXIT:
1550 FunctionOut();
1551
1552 return ret;
1553 }
1554
1555 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1556 {
1557 OMX_ERRORTYPE ret = OMX_ErrorNone;
1558 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1559 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1560 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1561
1562 FunctionIn();
1563
1564 pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1565
1566 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1567 Exynos_OMX_DstOutputProcessThread,
1568 pOMXComponent);
1569 if (ret == OMX_ErrorNone)
1570 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1571 Exynos_OMX_SrcOutputProcessThread,
1572 pOMXComponent);
1573 if (ret == OMX_ErrorNone)
1574 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1575 Exynos_OMX_DstInputProcessThread,
1576 pOMXComponent);
1577 if (ret == OMX_ErrorNone)
1578 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1579 Exynos_OMX_SrcInputProcessThread,
1580 pOMXComponent);
1581
1582 EXIT:
1583 FunctionOut();
1584
1585 return ret;
1586 }
1587
1588 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1589 {
1590 OMX_ERRORTYPE ret = OMX_ErrorNone;
1591 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1592 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1593 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1594 OMX_S32 countValue = 0;
1595 unsigned int i = 0;
1596
1597 FunctionIn();
1598
1599 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1600
1601 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1602 if (countValue == 0)
1603 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1604 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1605 if (countValue == 0)
1606 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1607
1608 /* srcInput */
1609 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1610 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
1611 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1612 pVideoDec->hSrcInputThread = NULL;
1613 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
1614
1615 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1616 if (countValue == 0)
1617 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1618 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1619 if (countValue == 0)
1620 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1621 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
1622
1623 /* dstInput */
1624 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1625 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
1626 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1627 pVideoDec->hDstInputThread = NULL;
1628 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
1629
1630 pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1631 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1632
1633 /* srcOutput */
1634 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1635 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
1636 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1637 pVideoDec->hSrcOutputThread = NULL;
1638 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
1639
1640 pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1641 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
1642
1643 /* dstOutput */
1644 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1645 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
1646 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1647 pVideoDec->hDstOutputThread = NULL;
1648 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
1649
1650 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
1651 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
1652
1653 EXIT:
1654 FunctionOut();
1655
1656 return ret;
1657 }
1658
1659 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1660 {
1661 OMX_ERRORTYPE ret = OMX_ErrorNone;
1662 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1663 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1664 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1665 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1666
1667 FunctionIn();
1668
1669 if (hComponent == NULL) {
1670 ret = OMX_ErrorBadParameter;
1671 goto EXIT;
1672 }
1673 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1674 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1675 if (ret != OMX_ErrorNone) {
1676 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1677 goto EXIT;
1678 }
1679
1680 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1681 if (ret != OMX_ErrorNone) {
1682 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1683 goto EXIT;
1684 }
1685
1686 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1687 if (ret != OMX_ErrorNone) {
1688 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1689 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1690 goto EXIT;
1691 }
1692
1693 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1694
1695 pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1696 if (pVideoDec == NULL) {
1697 Exynos_OMX_Port_Destructor(pOMXComponent);
1698 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1699 ret = OMX_ErrorInsufficientResources;
1700 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1701 goto EXIT;
1702 }
1703
1704 Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1705 pVideoDec->bForceHeaderParsing = OMX_FALSE;
1706 pVideoDec->bReconfigDPB = OMX_FALSE;
1707 pVideoDec->bDTSMode = OMX_FALSE;
1708 pVideoDec->bReorderMode = OMX_FALSE;
1709 pVideoDec->b10bitData = OMX_FALSE;
1710 pVideoDec->bQosChanged = OMX_FALSE;
1711 pVideoDec->nQosRatio = 0;
1712 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1713
1714 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1715 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1716 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1717
1718 /* Input port */
1719 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1720 pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX);
1721 if (pExynosPort->supportFormat == NULL) {
1722 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1723 ret = OMX_ErrorInsufficientResources;
1724 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1725 goto EXIT;
1726 }
1727 Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX));
1728
1729 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1730 pExynosPort->portDefinition.nBufferCountMin = MIN_VIDEO_INPUTBUFFER_NUM;
1731 pExynosPort->portDefinition.nBufferSize = 0;
1732 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1733
1734 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1735 if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
1736 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1737 ret = OMX_ErrorInsufficientResources;
1738 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1739 goto EXIT;
1740 }
1741 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1742 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1743 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1744 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1745
1746 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1747 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1748 pExynosPort->portDefinition.format.video.nStride = 0;
1749 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1750 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1751 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1752 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1753 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1754
1755 /* Output port */
1756 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1757 pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX);
1758 if (pExynosPort->supportFormat == NULL) {
1759 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1760 ret = OMX_ErrorInsufficientResources;
1761 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1762 goto EXIT;
1763 }
1764 Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX));
1765
1766 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1767 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1768 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1769 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1770
1771 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1772 if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
1773 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1774 ret = OMX_ErrorInsufficientResources;
1775 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1776 goto EXIT;
1777 }
1778 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1779 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1780 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1781 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1782
1783 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1784 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1785 pExynosPort->portDefinition.format.video.nStride = 0;
1786 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1787 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1788 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1789 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1790 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1791
1792 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1793 Exynos_OSAL_Memset(((char *)pExynosPort->processData.extInfo), 0, sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1794
1795 int i = 0;
1796 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1797 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo);
1798 for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
1799 pBufferInfo->PDSB.dpbFD[i].fd = -1;
1800 pBufferInfo->PDSB.dpbFD[i].fd1 = -1;
1801 pBufferInfo->PDSB.dpbFD[i].fd2 = -1;
1802 }
1803
1804 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1805 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1806 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1807
1808 #ifdef TUNNELING_SUPPORT
1809 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1810 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1811 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1812 #endif
1813
1814 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1815 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1816 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1817
1818 #ifdef USE_ANB
1819 pVideoDec->hRefHandle = Exynos_OSAL_RefANB_Create();
1820 #endif
1821
1822 EXIT:
1823 FunctionOut();
1824
1825 return ret;
1826 }
1827
1828 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1829 {
1830 OMX_ERRORTYPE ret = OMX_ErrorNone;
1831 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1832 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1833 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1834 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1835 int i = 0;
1836
1837 FunctionIn();
1838
1839 if (hComponent == NULL) {
1840 ret = OMX_ErrorBadParameter;
1841 goto EXIT;
1842 }
1843 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1844 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1845 if (ret != OMX_ErrorNone) {
1846 goto EXIT;
1847 }
1848
1849 if (pOMXComponent->pComponentPrivate == NULL) {
1850 ret = OMX_ErrorBadParameter;
1851 goto EXIT;
1852 }
1853 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1854
1855 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1856
1857 #ifdef USE_ANB
1858 Exynos_OSAL_RefANB_Terminate(pVideoDec->hRefHandle);
1859 #endif
1860
1861 Exynos_OSAL_Free(pVideoDec);
1862 pExynosComponent->hComponentHandle = pVideoDec = NULL;
1863
1864 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1865 if (pExynosPort->processData.extInfo != NULL) {
1866 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1867 pExynosPort->processData.extInfo = NULL;
1868 }
1869
1870 for(i = 0; i < ALL_PORT_NUM; i++) {
1871 pExynosPort = &pExynosComponent->pExynosPort[i];
1872 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1873 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1874
1875 Exynos_OSAL_Free(pExynosPort->supportFormat);
1876 pExynosPort->supportFormat = NULL;
1877 }
1878
1879 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1880
1881 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1882
1883 EXIT:
1884 FunctionOut();
1885
1886 return ret;
1887 }