exynos_omx: multi_thread: Support EOSBehavior.
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / exynos_omx / openmax / exynos_omx / component / video / dec / mpeg4 / Exynos_OMX_Mpeg4dec.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_Mpeg4dec.c
20 * @brief
21 * @author Yunji Kim (yunji.kim@samsung.com)
22 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
23 * @version 2.0.0
24 * @history
25 * 2012.02.20 : Create
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OMX_Basecomponent.h"
34 #include "Exynos_OMX_Baseport.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OSAL_ETC.h"
37 #include "Exynos_OSAL_Semaphore.h"
38 #include "Exynos_OSAL_Thread.h"
39 #include "library_register.h"
40 #include "Exynos_OMX_Mpeg4dec.h"
41 #include "ExynosVideoApi.h"
42 #include "Exynos_OSAL_SharedMemory.h"
43 #include "Exynos_OSAL_Event.h"
44
45 #ifdef USE_ANB
46 #include "Exynos_OSAL_Android.h"
47 #endif
48
49 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
50 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
51 #include "csc.h"
52
53 #undef EXYNOS_LOG_TAG
54 #define EXYNOS_LOG_TAG "EXYNOS_MPEG4_DEC"
55 #define EXYNOS_LOG_OFF
56 //#define EXYNOS_TRACE_ON
57 #include "Exynos_OSAL_Log.h"
58
59 #define MPEG4_DEC_NUM_OF_EXTRA_BUFFERS 7
60
61 //#define FULL_FRAME_SEARCH
62
63 /* MPEG4 Decoder Supported Levels & profiles */
64 EXYNOS_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={
65 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0},
66 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b},
67 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1},
68 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2},
69 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3},
70 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4},
71 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a},
72 {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5},
73 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0},
74 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b},
75 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1},
76 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2},
77 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3},
78 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4},
79 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a},
80 {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}};
81
82 /* H.263 Decoder Supported Levels & profiles */
83 EXYNOS_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = {
84 /* Baseline (Profile 0) */
85 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10},
86 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20},
87 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30},
88 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40},
89 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45},
90 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50},
91 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60},
92 {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70},
93 /* Profile 1 */
94 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level10},
95 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level20},
96 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level30},
97 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level40},
98 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level45},
99 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level50},
100 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level60},
101 {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level70},
102 /* Profile 2 */
103 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level10},
104 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level20},
105 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level30},
106 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level40},
107 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level45},
108 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level50},
109 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level60},
110 {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level70},
111 /* Profile 3, restricted up to SD resolution */
112 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level10},
113 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level20},
114 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level30},
115 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level40},
116 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level45},
117 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level50},
118 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level60},
119 {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level70}};
120
121
122 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
123 {
124 OMX_ERRORTYPE ret = OMX_ErrorNone;
125
126 EXIT:
127 return ret;
128 }
129
130 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[])
131 {
132 OMX_ERRORTYPE ret = OMX_ErrorNone;
133 ExynosVideoBuffer *pCodecBuffer;
134
135 if (codecBuffer == NULL) {
136 ret = OMX_ErrorBadParameter;
137 goto EXIT;
138 }
139
140 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
141
142 if (addr != NULL) {
143 addr[0] = pCodecBuffer->planes[0].addr;
144 addr[1] = pCodecBuffer->planes[1].addr;
145 addr[2] = pCodecBuffer->planes[2].addr;
146 }
147
148 if (size != NULL) {
149 size[0] = pCodecBuffer->planes[0].allocSize;
150 size[1] = pCodecBuffer->planes[1].allocSize;
151 size[2] = pCodecBuffer->planes[2].allocSize;
152 }
153
154 EXIT:
155 return ret;
156 }
157
158 static OMX_BOOL gbFIMV1 = OMX_FALSE;
159
160 static int Check_Mpeg4_Frame(
161 OMX_U8 *pInputStream,
162 OMX_U32 buffSize,
163 OMX_U32 flag,
164 OMX_BOOL bPreviousFrameEOF,
165 OMX_BOOL *pbEndOfFrame)
166 {
167 OMX_U32 len;
168 int readStream;
169 unsigned startCode;
170 OMX_BOOL bFrameStart;
171
172 len = 0;
173 bFrameStart = OMX_FALSE;
174
175 if (flag & OMX_BUFFERFLAG_CODECCONFIG) {
176 if (*pInputStream == 0x03) { /* FIMV1 */
177 BitmapInfoHhr *pInfoHeader;
178
179 pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1);
180 /* FIXME */
181 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "############## NOT SUPPORTED #################");
182 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "width(%d), height(%d)", pInfoHeader->BiWidth, pInfoHeader->BiHeight);
183 gbFIMV1 = OMX_TRUE;
184 *pbEndOfFrame = OMX_TRUE;
185 return buffSize;
186 }
187 }
188
189 if (gbFIMV1) {
190 *pbEndOfFrame = OMX_TRUE;
191 return buffSize;
192 }
193
194 if (bPreviousFrameEOF == OMX_FALSE)
195 bFrameStart = OMX_TRUE;
196
197 startCode = 0xFFFFFFFF;
198 if (bFrameStart == OMX_FALSE) {
199 /* find VOP start code */
200 while(startCode != 0x1B6) {
201 readStream = *(pInputStream + len);
202 startCode = (startCode << 8) | readStream;
203 len++;
204 if (len > buffSize)
205 goto EXIT;
206 }
207 }
208
209 /* find next VOP start code */
210 startCode = 0xFFFFFFFF;
211 while ((startCode != 0x1B6)) {
212 readStream = *(pInputStream + len);
213 startCode = (startCode << 8) | readStream;
214 len++;
215 if (len > buffSize)
216 goto EXIT;
217 }
218
219 *pbEndOfFrame = OMX_TRUE;
220
221 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize);
222
223 return len - 4;
224
225 EXIT :
226 *pbEndOfFrame = OMX_FALSE;
227
228 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize);
229
230 return --len;
231 }
232
233 static int Check_H263_Frame(
234 OMX_U8 *pInputStream,
235 OMX_U32 buffSize,
236 OMX_U32 flag,
237 OMX_BOOL bPreviousFrameEOF,
238 OMX_BOOL *pbEndOfFrame)
239 {
240 OMX_U32 len;
241 int readStream;
242 unsigned startCode;
243 OMX_BOOL bFrameStart = 0;
244 unsigned pTypeMask = 0x03;
245 unsigned pType = 0;
246
247 len = 0;
248 bFrameStart = OMX_FALSE;
249
250 if (bPreviousFrameEOF == OMX_FALSE)
251 bFrameStart = OMX_TRUE;
252
253 startCode = 0xFFFFFFFF;
254 if (bFrameStart == OMX_FALSE) {
255 /* find PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */
256 while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) {
257 readStream = *(pInputStream + len);
258 startCode = (startCode << 8) | readStream;
259
260 readStream = *(pInputStream + len + 1);
261 pType = readStream & pTypeMask;
262
263 len++;
264 if (len > buffSize)
265 goto EXIT;
266 }
267 }
268
269 /* find next PSC */
270 startCode = 0xFFFFFFFF;
271 pType = 0;
272 while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) {
273 readStream = *(pInputStream + len);
274 startCode = (startCode << 8) | readStream;
275
276 readStream = *(pInputStream + len + 1);
277 pType = readStream & pTypeMask;
278
279 len++;
280 if (len > buffSize)
281 goto EXIT;
282 }
283
284 *pbEndOfFrame = OMX_TRUE;
285
286 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize);
287
288 return len - 3;
289
290 EXIT :
291
292 *pbEndOfFrame = OMX_FALSE;
293
294 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize);
295
296 return --len;
297 }
298
299 static OMX_BOOL Check_Stream_StartCode(
300 OMX_U8 *pInputStream,
301 OMX_U32 streamSize,
302 CODEC_TYPE codecType)
303 {
304 switch (codecType) {
305 case CODEC_TYPE_MPEG4:
306 if (gbFIMV1) {
307 return OMX_TRUE;
308 } else {
309 if (streamSize < 3) {
310 return OMX_FALSE;
311 } else if ((pInputStream[0] == 0x00) &&
312 (pInputStream[1] == 0x00) &&
313 (pInputStream[2] == 0x01)) {
314 return OMX_TRUE;
315 } else {
316 return OMX_FALSE;
317 }
318 }
319 break;
320 case CODEC_TYPE_H263:
321 if (streamSize > 0) {
322 unsigned startCode = 0xFFFFFFFF;
323 unsigned pTypeMask = 0x03;
324 unsigned pType = 0;
325 OMX_U32 len = 0;
326 int readStream;
327 /* Check PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */
328 while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) {
329 readStream = *(pInputStream + len);
330 startCode = (startCode << 8) | readStream;
331
332 readStream = *(pInputStream + len + 1);
333 pType = readStream & pTypeMask;
334
335 len++;
336 if (len > 0x3)
337 break;
338 }
339
340 if (len > 0x3) {
341 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Picture Start Code Missing", __FUNCTION__);
342 return OMX_FALSE;
343 } else {
344 return OMX_TRUE;
345 }
346 } else {
347 return OMX_FALSE;
348 }
349 default:
350 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType);
351 return OMX_FALSE;
352 }
353 }
354
355 OMX_ERRORTYPE Mpeg4CodecOpen(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec)
356 {
357 OMX_ERRORTYPE ret = OMX_ErrorNone;
358 ExynosVideoDecOps *pDecOps = NULL;
359 ExynosVideoDecBufferOps *pInbufOps = NULL;
360 ExynosVideoDecBufferOps *pOutbufOps = NULL;
361
362 FunctionIn();
363
364 if (pMpeg4Dec == NULL) {
365 ret = OMX_ErrorBadParameter;
366 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
367 goto EXIT;
368 }
369
370 /* alloc ops structure */
371 pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
372 pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
373 pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
374
375 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
376 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
377 ret = OMX_ErrorInsufficientResources;
378 goto EXIT;
379 }
380
381 pMpeg4Dec->hMFCMpeg4Handle.pDecOps = pDecOps;
382 pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = pInbufOps;
383 pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = pOutbufOps;
384
385 /* function pointer mapping */
386 pDecOps->nSize = sizeof(ExynosVideoDecOps);
387 pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
388 pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
389
390 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
391
392 /* check mandatory functions for decoder ops */
393 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
394 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
395 (pDecOps->Get_FrameTag == NULL)) {
396 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
397 ret = OMX_ErrorInsufficientResources;
398 goto EXIT;
399 }
400
401 /* check mandatory functions for buffer ops */
402 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
403 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
404 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
405 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
406 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
407 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
408 ret = OMX_ErrorInsufficientResources;
409 goto EXIT;
410 }
411
412 /* alloc context, open, querycap */
413 pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
414 if (pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle == NULL) {
415 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
416 ret = OMX_ErrorInsufficientResources;
417 goto EXIT;
418 }
419
420 ret = OMX_ErrorNone;
421
422 EXIT:
423 if (ret != OMX_ErrorNone) {
424 if (pDecOps != NULL) {
425 Exynos_OSAL_Free(pDecOps);
426 pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL;
427 }
428 if (pInbufOps != NULL) {
429 Exynos_OSAL_Free(pInbufOps);
430 pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL;
431 }
432 if (pOutbufOps != NULL) {
433 Exynos_OSAL_Free(pOutbufOps);
434 pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL;
435 }
436 }
437
438 FunctionOut();
439
440 return ret;
441 }
442
443 OMX_ERRORTYPE Mpeg4CodecClose(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec)
444 {
445 OMX_ERRORTYPE ret = OMX_ErrorNone;
446 void *hMFCHandle = NULL;
447 ExynosVideoDecOps *pDecOps = NULL;
448 ExynosVideoDecBufferOps *pInbufOps = NULL;
449 ExynosVideoDecBufferOps *pOutbufOps = NULL;
450
451 FunctionIn();
452
453 if (pMpeg4Dec == NULL) {
454 ret = OMX_ErrorBadParameter;
455 goto EXIT;
456 }
457
458 hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
459 pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
460 pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
461 pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
462
463 if (hMFCHandle != NULL) {
464 pDecOps->Finalize(hMFCHandle);
465 pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL;
466 }
467 if (pOutbufOps != NULL) {
468 Exynos_OSAL_Free(pOutbufOps);
469 pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL;
470 }
471 if (pInbufOps != NULL) {
472 Exynos_OSAL_Free(pInbufOps);
473 pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL;
474 }
475 if (pDecOps != NULL) {
476 Exynos_OSAL_Free(pDecOps);
477 pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL;
478 }
479
480 ret = OMX_ErrorNone;
481
482 EXIT:
483 FunctionOut();
484
485 return ret;
486 }
487
488 OMX_ERRORTYPE Mpeg4CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
489 {
490 OMX_ERRORTYPE ret = OMX_ErrorNone;
491 void *hMFCHandle = NULL;
492 ExynosVideoDecOps *pDecOps = NULL;
493 ExynosVideoDecBufferOps *pInbufOps = NULL;
494 ExynosVideoDecBufferOps *pOutbufOps = NULL;
495 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
496 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
497
498 FunctionIn();
499
500 if (pOMXComponent == NULL) {
501 ret = OMX_ErrorBadParameter;
502 goto EXIT;
503 }
504
505 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
506 if (pVideoDec == NULL) {
507 ret = OMX_ErrorBadParameter;
508 goto EXIT;
509 }
510
511 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
512 if (pMpeg4Dec == NULL) {
513 ret = OMX_ErrorBadParameter;
514 goto EXIT;
515 }
516
517 hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
518 pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
519 pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
520 pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
521
522 if (nPortIndex == INPUT_PORT_INDEX)
523 pInbufOps->Run(hMFCHandle);
524 else if (nPortIndex == OUTPUT_PORT_INDEX)
525 pOutbufOps->Run(hMFCHandle);
526
527 ret = OMX_ErrorNone;
528
529 EXIT:
530 FunctionOut();
531
532 return ret;
533 }
534
535 OMX_ERRORTYPE Mpeg4CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
536 {
537 OMX_ERRORTYPE ret = OMX_ErrorNone;
538 void *hMFCHandle = NULL;
539 ExynosVideoDecOps *pDecOps = NULL;
540 ExynosVideoDecBufferOps *pInbufOps = NULL;
541 ExynosVideoDecBufferOps *pOutbufOps = NULL;
542 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
543 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
544
545 FunctionIn();
546
547 if (pOMXComponent == NULL) {
548 ret = OMX_ErrorBadParameter;
549 goto EXIT;
550 }
551
552 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
553 if (pVideoDec == NULL) {
554 ret = OMX_ErrorBadParameter;
555 goto EXIT;
556 }
557 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
558 if (pMpeg4Dec == NULL) {
559 ret = OMX_ErrorBadParameter;
560 goto EXIT;
561 }
562
563 hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
564 pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
565 pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
566 pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
567
568 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
569 pInbufOps->Stop(hMFCHandle);
570 else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
571 pOutbufOps->Stop(hMFCHandle);
572
573 ret = OMX_ErrorNone;
574
575 EXIT:
576 FunctionOut();
577
578 return ret;
579 }
580
581 OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
582 {
583 OMX_ERRORTYPE ret = OMX_ErrorNone;
584 void *hMFCHandle = NULL;
585 ExynosVideoDecOps *pDecOps = NULL;
586 ExynosVideoDecBufferOps *pInbufOps = NULL;
587 ExynosVideoDecBufferOps *pOutbufOps = NULL;
588 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
589 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
590
591 FunctionIn();
592
593 if (pOMXComponent == NULL) {
594 ret = OMX_ErrorBadParameter;
595 goto EXIT;
596 }
597
598 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
599 if (pVideoDec == NULL) {
600 ret = OMX_ErrorBadParameter;
601 goto EXIT;
602 }
603 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
604 if (pMpeg4Dec == NULL) {
605 ret = OMX_ErrorBadParameter;
606 goto EXIT;
607 }
608
609 hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
610 pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
611 pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
612 pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
613
614 if (nPortIndex == INPUT_PORT_INDEX) {
615 if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
616 Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
617 Exynos_OSAL_SleepMillisec(0);
618 }
619 }
620
621 if (nPortIndex == OUTPUT_PORT_INDEX) {
622 if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
623 Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
624 Exynos_OSAL_SleepMillisec(0);
625 }
626 }
627
628 ret = OMX_ErrorNone;
629
630 EXIT:
631 FunctionOut();
632
633 return ret;
634 }
635
636 OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
637 {
638 OMX_ERRORTYPE ret = OMX_ErrorNone;
639 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
640 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
641 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
642 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
643 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
644 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
645 int i, nOutbufs;
646
647 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
648 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
649 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
650
651 FunctionIn();
652
653 if ((nPortIndex == INPUT_PORT_INDEX) &&
654 (pMpeg4Dec->bSourceStart == OMX_TRUE)) {
655 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
656
657 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
658 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
659 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
660
661 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
662 }
663
664 pInbufOps->Clear_Queue(hMFCHandle);
665 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
666 (pMpeg4Dec->bDestinationStart == OMX_TRUE)) {
667 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
668 ExynosVideoBuffer *pBuffer = NULL;
669
670 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
671
672 nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
673 nOutbufs += EXTRA_DPB_NUM;
674 for (i = 0; i < nOutbufs; i++) {
675 pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
676 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
677 }
678 pOutbufOps->Clear_Queue(hMFCHandle);
679 } else {
680 ret = OMX_ErrorBadParameter;
681 goto EXIT;
682 }
683
684 EXIT:
685 FunctionOut();
686
687 return ret;
688 }
689
690 OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
691 {
692 OMX_ERRORTYPE ret = OMX_ErrorNone;
693 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
694 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
695 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
696 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
697 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
698 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
699 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
700
701 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
702 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
703 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
704 ExynosVideoGeometry bufferConf;
705 OMX_U32 inputBufferNumber = 0;
706 int i;
707
708 FunctionIn();
709
710 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
711 OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
712 OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
713 if (OMXBuffer == NULL) {
714 ret = OMX_ErrorUndefined;
715 goto EXIT;
716 }
717
718 OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
719 OMXBuffer->nFlags = pSrcInputData->nFlags;
720 Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
721
722 ret = OMX_ErrorNone;
723 goto EXIT;
724 }
725
726 if (pVideoDec->bThumbnailMode == OMX_TRUE)
727 pDecOps->Set_DisplayDelay(hMFCHandle, 0);
728
729 /* input buffer info */
730 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
731 if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
732 bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
733 else
734 bufferConf.eCompressionFormat = VIDEO_CODING_H263;
735
736 pInbufOps->Set_Shareable(hMFCHandle);
737 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
738 bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
739 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
740 inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
741 } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
742 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
743 inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
744 }
745
746 /* should be done before prepare input buffer */
747 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
748 ret = OMX_ErrorInsufficientResources;
749 goto EXIT;
750 }
751
752 /* set input buffer geometry */
753 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
754 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
755 ret = OMX_ErrorInsufficientResources;
756 goto EXIT;
757 }
758
759 /* setup input buffer */
760 if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
761 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
762 ret = OMX_ErrorInsufficientResources;
763 goto EXIT;
764 }
765
766 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
767 /* Register input buffer */
768 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
769 ExynosVideoPlane plane;
770 plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
771 plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
772 plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
773 if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
774 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
775 ret = OMX_ErrorInsufficientResources;
776 goto EXIT;
777 }
778 }
779 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
780 /* Register input buffer */
781 for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
782 ExynosVideoPlane plane;
783 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
784 plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
785 plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
786 if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
787 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
788 ret = OMX_ErrorInsufficientResources;
789 goto EXIT;
790 }
791 }
792 }
793
794 /* set output geometry */
795 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
796 pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
797 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
798 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
799 ret = OMX_ErrorInsufficientResources;
800 goto EXIT;
801 }
802
803 /* input buffer enqueue for header parsing */
804 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
805 if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
806 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
807 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
808 // ret = OMX_ErrorInsufficientResources;
809 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
810 goto EXIT;
811 }
812
813 /* start header parsing */
814 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
815 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
816 ret = OMX_ErrorCodecInit;
817 goto EXIT;
818 }
819
820 /* get geometry for output */
821 Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
822 if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
823 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
824 ret = OMX_ErrorInsufficientResources;
825 goto EXIT;
826 }
827
828 /* get dpb count */
829 pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
830 if (pVideoDec->bThumbnailMode == OMX_FALSE)
831 pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM;
832 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg4CodecSetup nOutbufs: %d", pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum);
833
834 pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
835
836 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
837 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
838 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) {
839 pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
840 pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
841 pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
842 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
843
844 Exynos_UpdateFrameSize(pOMXComponent);
845 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
846
847 /** Send Port Settings changed call back **/
848 (*(pExynosComponent->pCallbacks->EventHandler))
849 (pOMXComponent,
850 pExynosComponent->callbackData,
851 OMX_EventPortSettingsChanged, /* The command was completed */
852 OMX_DirOutput, /* This is the port index */
853 0,
854 NULL);
855 }
856 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
857 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
858 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) ||
859 (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) {
860 pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
861 pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
862 pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
863 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
864
865 pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 2;
866 pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 2;
867
868 Exynos_UpdateFrameSize(pOMXComponent);
869 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
870
871 /** Send Port Settings changed call back **/
872 (*(pExynosComponent->pCallbacks->EventHandler))
873 (pOMXComponent,
874 pExynosComponent->callbackData,
875 OMX_EventPortSettingsChanged, /* The command was completed */
876 OMX_DirOutput, /* This is the port index */
877 0,
878 NULL);
879 }
880 }
881 Exynos_OSAL_SleepMillisec(0);
882 ret = OMX_ErrorInputDataDecodeYet;
883 Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX);
884
885 EXIT:
886 FunctionOut();
887
888 return ret;
889 }
890
891 OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
892 {
893 OMX_ERRORTYPE ret = OMX_ErrorNone;
894 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
895 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
896 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
897 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
898 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
899 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
900
901 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
902 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
903 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
904
905 int i, nOutbufs;
906
907 FunctionIn();
908
909 /* get dpb count */
910 nOutbufs = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
911
912 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
913 /* should be done before prepare output buffer */
914 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
915 ret = OMX_ErrorInsufficientResources;
916 goto EXIT;
917 }
918 }
919 pOutbufOps->Set_Shareable(hMFCHandle);
920 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
921 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
922 ret = OMX_ErrorInsufficientResources;
923 goto EXIT;
924 }
925
926 ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
927 OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
928 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
929 int plane;
930
931 nAllocLen[0] = calc_plane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
932 pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight);
933 nAllocLen[1] = calc_plane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
934 pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight >> 1);
935
936 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
937 /* Register output buffer */
938 for (i = 0; i < nOutbufs; i++) {
939 pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
940 Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
941
942 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
943 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] =
944 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY);
945 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) {
946 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
947 ret = OMX_ErrorInsufficientResources;
948 goto EXIT;
949 }
950 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] =
951 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
952 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
953 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane];
954
955 planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane];
956 planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane];
957 planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane];
958 }
959
960 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
961 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
962 ret = OMX_ErrorInsufficientResources;
963 goto EXIT;
964 }
965 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
966 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
967 }
968 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
969 /* Register output buffer */
970 /*************/
971 /* TBD */
972 /*************/
973 #ifdef USE_ANB
974 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) {
975 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
976 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
977 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
978 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
979 planes[plane].allocSize = nAllocLen[plane];
980 }
981
982 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
983 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
984 ret = OMX_ErrorInsufficientResources;
985 goto EXIT;
986 }
987 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
988 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
989 }
990 } else {
991 ret = OMX_ErrorNotImplemented;
992 goto EXIT;
993 }
994 #else
995 ret = OMX_ErrorNotImplemented;
996 goto EXIT;
997 #endif
998 }
999
1000 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1001 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1002 ret = OMX_ErrorInsufficientResources;
1003 goto EXIT;
1004 }
1005
1006 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1007 Mpeg4CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
1008 }
1009 pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
1010
1011 ret = OMX_ErrorNone;
1012
1013 EXIT:
1014 FunctionOut();
1015
1016 return ret;
1017 }
1018
1019 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetParameter(
1020 OMX_IN OMX_HANDLETYPE hComponent,
1021 OMX_IN OMX_INDEXTYPE nParamIndex,
1022 OMX_INOUT OMX_PTR pComponentParameterStructure)
1023 {
1024 OMX_ERRORTYPE ret = OMX_ErrorNone;
1025 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1026 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1027
1028 FunctionIn();
1029
1030 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1031 ret = OMX_ErrorBadParameter;
1032 goto EXIT;
1033 }
1034 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1035 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1036 if (ret != OMX_ErrorNone) {
1037 goto EXIT;
1038 }
1039 if (pOMXComponent->pComponentPrivate == NULL) {
1040 ret = OMX_ErrorBadParameter;
1041 goto EXIT;
1042 }
1043
1044 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1045 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1046 ret = OMX_ErrorInvalidState;
1047 goto EXIT;
1048 }
1049
1050 switch (nParamIndex) {
1051 case OMX_IndexParamVideoMpeg4:
1052 {
1053 OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
1054 OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL;
1055 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1056
1057 ret = Exynos_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1058 if (ret != OMX_ErrorNone) {
1059 goto EXIT;
1060 }
1061
1062 if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
1063 ret = OMX_ErrorBadPortIndex;
1064 goto EXIT;
1065 }
1066
1067 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1068 pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex];
1069
1070 Exynos_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1071 }
1072 break;
1073 case OMX_IndexParamVideoH263:
1074 {
1075 OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
1076 OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL;
1077 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1078
1079 ret = Exynos_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1080 if (ret != OMX_ErrorNone) {
1081 goto EXIT;
1082 }
1083
1084 if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) {
1085 ret = OMX_ErrorBadPortIndex;
1086 goto EXIT;
1087 }
1088
1089 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1090 pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex];
1091
1092 Exynos_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1093 }
1094 break;
1095 case OMX_IndexParamStandardComponentRole:
1096 {
1097 OMX_S32 codecType;
1098 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1099
1100 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1101 if (ret != OMX_ErrorNone) {
1102 goto EXIT;
1103 }
1104
1105 codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1106 if (codecType == CODEC_TYPE_MPEG4)
1107 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
1108 else
1109 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
1110 }
1111 break;
1112 case OMX_IndexParamVideoProfileLevelQuerySupported:
1113 {
1114 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1115 EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1116 OMX_U32 maxProfileLevelNum = 0;
1117 OMX_S32 codecType;
1118
1119 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1120 if (ret != OMX_ErrorNone) {
1121 goto EXIT;
1122 }
1123
1124 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1125 ret = OMX_ErrorBadPortIndex;
1126 goto EXIT;
1127 }
1128
1129 codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1130 if (codecType == CODEC_TYPE_MPEG4) {
1131 pProfileLevel = supportedMPEG4ProfileLevels;
1132 maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1133 } else {
1134 pProfileLevel = supportedH263ProfileLevels;
1135 maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1136 }
1137
1138 if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1139 ret = OMX_ErrorNoMore;
1140 goto EXIT;
1141 }
1142
1143 pProfileLevel += pDstProfileLevel->nProfileIndex;
1144 pDstProfileLevel->eProfile = pProfileLevel->profile;
1145 pDstProfileLevel->eLevel = pProfileLevel->level;
1146 }
1147 break;
1148 case OMX_IndexParamVideoProfileLevelCurrent:
1149 {
1150 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1151 OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL;
1152 OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL;
1153 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1154 OMX_S32 codecType;
1155
1156 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1157 if (ret != OMX_ErrorNone) {
1158 goto EXIT;
1159 }
1160
1161 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1162 ret = OMX_ErrorBadPortIndex;
1163 goto EXIT;
1164 }
1165
1166 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1167 codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
1168 if (codecType == CODEC_TYPE_MPEG4) {
1169 pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex];
1170 pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile;
1171 pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel;
1172 } else {
1173 pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex];
1174 pDstProfileLevel->eProfile = pSrcH263Param->eProfile;
1175 pDstProfileLevel->eLevel = pSrcH263Param->eLevel;
1176 }
1177 }
1178 break;
1179 case OMX_IndexParamVideoErrorCorrection:
1180 {
1181 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1182 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1183 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1184
1185 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1186 if (ret != OMX_ErrorNone) {
1187 goto EXIT;
1188 }
1189
1190 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1191 ret = OMX_ErrorBadPortIndex;
1192 goto EXIT;
1193 }
1194
1195 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1196 pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
1197
1198 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1199 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1200 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1201 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1202 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1203 }
1204 break;
1205 default:
1206 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1207 break;
1208 }
1209 EXIT:
1210 FunctionOut();
1211
1212 return ret;
1213 }
1214
1215 OMX_ERRORTYPE Exynos_Mpeg4Dec_SetParameter(
1216 OMX_IN OMX_HANDLETYPE hComponent,
1217 OMX_IN OMX_INDEXTYPE nIndex,
1218 OMX_IN OMX_PTR pComponentParameterStructure)
1219 {
1220 OMX_ERRORTYPE ret = OMX_ErrorNone;
1221 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1222 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1223
1224 FunctionIn();
1225
1226 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1227 ret = OMX_ErrorBadParameter;
1228 goto EXIT;
1229 }
1230 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1231 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1232 if (ret != OMX_ErrorNone) {
1233 goto EXIT;
1234 }
1235 if (pOMXComponent->pComponentPrivate == NULL) {
1236 ret = OMX_ErrorBadParameter;
1237 goto EXIT;
1238 }
1239
1240 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1241 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1242 ret = OMX_ErrorInvalidState;
1243 goto EXIT;
1244 }
1245
1246 switch (nIndex) {
1247 case OMX_IndexParamVideoMpeg4:
1248 {
1249 OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL;
1250 OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
1251 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1252
1253 ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1254 if (ret != OMX_ErrorNone) {
1255 goto EXIT;
1256 }
1257
1258 if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
1259 ret = OMX_ErrorBadPortIndex;
1260 goto EXIT;
1261 }
1262
1263 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1264 pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex];
1265
1266 Exynos_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1267 }
1268 break;
1269 case OMX_IndexParamVideoH263:
1270 {
1271 OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL;
1272 OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
1273 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1274
1275 ret = Exynos_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1276 if (ret != OMX_ErrorNone) {
1277 goto EXIT;
1278 }
1279
1280 if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) {
1281 ret = OMX_ErrorBadPortIndex;
1282 goto EXIT;
1283 }
1284
1285 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1286 pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex];
1287
1288 Exynos_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1289 }
1290 break;
1291 case OMX_IndexParamStandardComponentRole:
1292 {
1293 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1294
1295 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1296 if (ret != OMX_ErrorNone) {
1297 goto EXIT;
1298 }
1299
1300 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1301 ret = OMX_ErrorIncorrectStateOperation;
1302 goto EXIT;
1303 }
1304
1305 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE)) {
1306 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1307 } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE)) {
1308 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
1309 } else {
1310 ret = OMX_ErrorBadParameter;
1311 goto EXIT;
1312 }
1313 }
1314 break;
1315 case OMX_IndexParamVideoProfileLevelCurrent:
1316 {
1317 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1318 OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL;
1319 OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL;
1320 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1321 OMX_S32 codecType;
1322
1323 ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1324 if (ret != OMX_ErrorNone)
1325 goto EXIT;
1326
1327 if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1328 ret = OMX_ErrorBadPortIndex;
1329 goto EXIT;
1330 }
1331
1332 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1333 codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
1334 if (codecType == CODEC_TYPE_MPEG4) {
1335 /*
1336 * To do: Check validity of profile & level parameters
1337 */
1338
1339 pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex];
1340 pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile;
1341 pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel;
1342 } else {
1343 /*
1344 * To do: Check validity of profile & level parameters
1345 */
1346
1347 pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex];
1348 pDstH263Param->eProfile = pSrcProfileLevel->eProfile;
1349 pDstH263Param->eLevel = pSrcProfileLevel->eLevel;
1350 }
1351 }
1352 break;
1353 case OMX_IndexParamVideoErrorCorrection:
1354 {
1355 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1356 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1357 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
1358
1359 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1360 if (ret != OMX_ErrorNone) {
1361 goto EXIT;
1362 }
1363
1364 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1365 ret = OMX_ErrorBadPortIndex;
1366 goto EXIT;
1367 }
1368
1369 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1370 pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
1371
1372 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1373 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1374 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1375 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1376 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1377 }
1378 break;
1379 default:
1380 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1381 break;
1382 }
1383 EXIT:
1384 FunctionOut();
1385
1386 return ret;
1387 }
1388
1389 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetConfig(
1390 OMX_IN OMX_HANDLETYPE hComponent,
1391 OMX_IN OMX_INDEXTYPE nIndex,
1392 OMX_IN OMX_PTR pComponentConfigStructure)
1393 {
1394 OMX_ERRORTYPE ret = OMX_ErrorNone;
1395 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1396 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1397
1398 FunctionIn();
1399
1400 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1401 ret = OMX_ErrorBadParameter;
1402 goto EXIT;
1403 }
1404 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1405 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1406 if (ret != OMX_ErrorNone) {
1407 goto EXIT;
1408 }
1409 if (pOMXComponent->pComponentPrivate == NULL) {
1410 ret = OMX_ErrorBadParameter;
1411 goto EXIT;
1412 }
1413 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1414 if (pExynosComponent->currentState == OMX_StateInvalid) {
1415 ret = OMX_ErrorInvalidState;
1416 goto EXIT;
1417 }
1418
1419 switch (nIndex) {
1420 default:
1421 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1422 break;
1423 }
1424
1425 EXIT:
1426 FunctionOut();
1427
1428 return ret;
1429 }
1430
1431 OMX_ERRORTYPE Exynos_Mpeg4Dec_SetConfig(
1432 OMX_IN OMX_HANDLETYPE hComponent,
1433 OMX_IN OMX_INDEXTYPE nIndex,
1434 OMX_IN OMX_PTR pComponentConfigStructure)
1435 {
1436 OMX_ERRORTYPE ret = OMX_ErrorNone;
1437 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1438 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1439
1440 FunctionIn();
1441
1442 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1443 ret = OMX_ErrorBadParameter;
1444 goto EXIT;
1445 }
1446 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1447 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1448 if (ret != OMX_ErrorNone) {
1449 goto EXIT;
1450 }
1451 if (pOMXComponent->pComponentPrivate == NULL) {
1452 ret = OMX_ErrorBadParameter;
1453 goto EXIT;
1454 }
1455 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1456 if (pExynosComponent->currentState == OMX_StateInvalid) {
1457 ret = OMX_ErrorInvalidState;
1458 goto EXIT;
1459 }
1460
1461 switch (nIndex) {
1462 default:
1463 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1464 break;
1465 }
1466
1467 EXIT:
1468 FunctionOut();
1469
1470 return ret;
1471 }
1472
1473 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetExtensionIndex(
1474 OMX_IN OMX_HANDLETYPE hComponent,
1475 OMX_IN OMX_STRING cParameterName,
1476 OMX_OUT OMX_INDEXTYPE *pIndexType)
1477 {
1478 OMX_ERRORTYPE ret = OMX_ErrorNone;
1479 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1480 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1481
1482 FunctionIn();
1483
1484 if (hComponent == NULL) {
1485 ret = OMX_ErrorBadParameter;
1486 goto EXIT;
1487 }
1488 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1489 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1490 if (ret != OMX_ErrorNone) {
1491 goto EXIT;
1492 }
1493 if (pOMXComponent->pComponentPrivate == NULL) {
1494 ret = OMX_ErrorBadParameter;
1495 goto EXIT;
1496 }
1497 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1498 if ((cParameterName == NULL) || (pIndexType == NULL)) {
1499 ret = OMX_ErrorBadParameter;
1500 goto EXIT;
1501 }
1502 if (pExynosComponent->currentState == OMX_StateInvalid) {
1503 ret = OMX_ErrorInvalidState;
1504 goto EXIT;
1505 }
1506
1507 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1508 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1509 *pIndexType = OMX_IndexVendorThumbnailMode;
1510 ret = OMX_ErrorNone;
1511 } else {
1512 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1513 }
1514
1515 EXIT:
1516 FunctionOut();
1517
1518 return ret;
1519 }
1520
1521 OMX_ERRORTYPE Exynos_Mpeg4Dec_ComponentRoleEnum(
1522 OMX_IN OMX_HANDLETYPE hComponent,
1523 OMX_OUT OMX_U8 *cRole,
1524 OMX_IN OMX_U32 nIndex)
1525 {
1526 OMX_ERRORTYPE ret = OMX_ErrorNone;
1527 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1528 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1529 OMX_S32 codecType;
1530
1531 FunctionIn();
1532
1533 if ((hComponent == NULL) || (cRole == NULL)) {
1534 ret = OMX_ErrorBadParameter;
1535 goto EXIT;
1536 }
1537 if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) {
1538 ret = OMX_ErrorNoMore;
1539 goto EXIT;
1540 }
1541 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1542 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1543 if (ret != OMX_ErrorNone) {
1544 goto EXIT;
1545 }
1546 if (pOMXComponent->pComponentPrivate == NULL) {
1547 ret = OMX_ErrorBadParameter;
1548 goto EXIT;
1549 }
1550 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1551 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1552 ret = OMX_ErrorInvalidState;
1553 goto EXIT;
1554 }
1555
1556 codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1557 if (codecType == CODEC_TYPE_MPEG4)
1558 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
1559 else
1560 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
1561
1562 EXIT:
1563 FunctionOut();
1564
1565 return ret;
1566 }
1567
1568 /* MFC Init */
1569 OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1570 {
1571 OMX_ERRORTYPE ret = OMX_ErrorNone;
1572 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1573 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1574 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1575 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1576 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
1577 OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1578
1579 ExynosVideoDecOps *pDecOps = NULL;
1580 ExynosVideoDecBufferOps *pInbufOps = NULL;
1581 ExynosVideoDecBufferOps *pOutbufOps = NULL;
1582
1583 CSC_METHOD csc_method = CSC_METHOD_SW;
1584 int i, plane;
1585
1586 FunctionIn();
1587
1588 pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
1589 pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
1590 pExynosComponent->bUseFlagEOF = OMX_TRUE;
1591 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1592 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1593
1594 /* H.264 Codec Open */
1595 ret = Mpeg4CodecOpen(pMpeg4Dec);
1596 if (ret != OMX_ErrorNone) {
1597 goto EXIT;
1598 }
1599
1600 pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1601 pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
1602 pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1603
1604 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1605 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1606 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1607
1608 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1609 pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1610 Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1611 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
1612
1613 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1614 /* Use ION Allocator */
1615 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
1616 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1617 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1618 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1619 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
1620 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1621 ret = OMX_ErrorInsufficientResources;
1622 goto EXIT;
1623 }
1624 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1625 }
1626
1627 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1628 }
1629 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1630 /*************/
1631 /* TBD */
1632 /*************/
1633 /* Does not require any actions. */
1634 }
1635
1636 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1637 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1638 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1639 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1640 /*************/
1641 /* TBD */
1642 /*************/
1643 /* Does not require any actions. */
1644 }
1645
1646 pMpeg4Dec->bSourceStart = OMX_FALSE;
1647 Exynos_OSAL_SignalCreate(&pMpeg4Dec->hSourceStartEvent);
1648 pMpeg4Dec->bDestinationStart = OMX_FALSE;
1649 Exynos_OSAL_SignalCreate(&pMpeg4Dec->hDestinationStartEvent);
1650
1651 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1652 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1653 pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0;
1654 pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0;
1655
1656 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1657
1658 #if 0//defined(USE_CSC_GSCALER)
1659 csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1660 #endif
1661 pVideoDec->csc_handle = csc_init(csc_method);
1662 if (pVideoDec->csc_handle == NULL) {
1663 ret = OMX_ErrorInsufficientResources;
1664 goto EXIT;
1665 }
1666 pVideoDec->csc_set_format = OMX_FALSE;
1667
1668 EXIT:
1669 FunctionOut();
1670
1671 return ret;
1672 }
1673
1674 /* MFC Terminate */
1675 OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1676 {
1677 OMX_ERRORTYPE ret = OMX_ErrorNone;
1678 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1679 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1680 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1681 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1682 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1683 OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1684
1685 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1686 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
1687 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1688
1689 int i, plane;
1690
1691 FunctionIn();
1692
1693 if (pVideoDec->csc_handle != NULL) {
1694 csc_deinit(pVideoDec->csc_handle);
1695 pVideoDec->csc_handle = NULL;
1696 }
1697
1698 Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationStartEvent);
1699 pMpeg4Dec->hDestinationStartEvent = NULL;
1700 pMpeg4Dec->bDestinationStart = OMX_FALSE;
1701 Exynos_OSAL_SignalTerminate(pMpeg4Dec->hSourceStartEvent);
1702 pMpeg4Dec->hSourceStartEvent = NULL;
1703 pMpeg4Dec->bSourceStart = OMX_FALSE;
1704
1705 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1706 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1707 if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
1708 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1709 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL)
1710 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
1711 }
1712
1713 Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
1714 pVideoDec->pMFCDecOutputBuffer[i] = NULL;
1715 }
1716 }
1717
1718 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1719 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1720 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1721 /*************/
1722 /* TBD */
1723 /*************/
1724 /* Does not require any actions. */
1725 }
1726
1727 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1728 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1729 if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
1730 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1731 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
1732 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1733 }
1734
1735 Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
1736 pVideoDec->pMFCDecInputBuffer[i] = NULL;
1737 }
1738 }
1739
1740 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1741 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1742 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1743 /*************/
1744 /* TBD */
1745 /*************/
1746 /* Does not require any actions. */
1747 }
1748 Mpeg4CodecClose(pMpeg4Dec);
1749
1750 Exynos_ResetAllPortConfig(pOMXComponent);
1751
1752 EXIT:
1753 FunctionOut();
1754
1755 return ret;
1756 }
1757
1758 OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1759 {
1760 OMX_ERRORTYPE ret = OMX_ErrorNone;
1761 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1762 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1763 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1764 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1765 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1766 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1767 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1768 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1769 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
1770 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1771 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1772 int i;
1773
1774 FunctionIn();
1775
1776 if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
1777 ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
1778 goto EXIT;
1779 }
1780 if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
1781 ret = Mpeg4CodecDstSetup(pOMXComponent);
1782 }
1783
1784 if ((Check_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) ||
1785 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1786 pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp;
1787 pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags;
1788 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags);
1789 pDecOps->Set_FrameTag(hMFCHandle, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp);
1790 pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++;
1791 pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
1792
1793 /* queue work for input buffer */
1794 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1795 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1796 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1797 if (codecReturn != VIDEO_ERROR_NONE) {
1798 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1799 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1800 goto EXIT;
1801 }
1802 Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1803 if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
1804 pMpeg4Dec->bSourceStart = OMX_TRUE;
1805 Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
1806 Exynos_OSAL_SleepMillisec(0);
1807 }
1808 if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
1809 pMpeg4Dec->bDestinationStart = OMX_TRUE;
1810 Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
1811 Exynos_OSAL_SleepMillisec(0);
1812 }
1813 }
1814
1815 ret = OMX_ErrorNone;
1816
1817 EXIT:
1818 FunctionOut();
1819
1820 return ret;
1821 }
1822
1823 OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1824 {
1825 OMX_ERRORTYPE ret = OMX_ErrorNone;
1826 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1827 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1828 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1829 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1830 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1831 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1832 ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
1833 ExynosVideoBuffer *pVideoBuffer;
1834
1835 FunctionIn();
1836
1837 pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1838
1839 pSrcOutputData->dataLen = 0;
1840 pSrcOutputData->usedDataLen = 0;
1841 pSrcOutputData->remainDataLen = 0;
1842 pSrcOutputData->nFlags = 0;
1843 pSrcOutputData->timeStamp = 0;
1844
1845 if (pVideoBuffer == NULL) {
1846 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1847 pSrcOutputData->allocSize = 0;
1848 pSrcOutputData->pPrivate = NULL;
1849 pSrcOutputData->bufferHeader = NULL;
1850 } else {
1851 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1852 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1853 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1854
1855 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1856 int i = 0;
1857 while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1858 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1859 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1860 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1861 goto EXIT;
1862 }
1863 i++;
1864 }
1865 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1866 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1867 }
1868
1869 /* For Share Buffer */
1870 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1871 }
1872
1873 ret = OMX_ErrorNone;
1874
1875 EXIT:
1876 FunctionOut();
1877
1878 return ret;
1879 }
1880
1881 OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1882 {
1883 OMX_ERRORTYPE ret = OMX_ErrorNone;
1884 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1885 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1886 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1887 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1888 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1889 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1890 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1891 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
1892 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1893
1894 FunctionIn();
1895
1896 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1897 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1898 ret = OMX_ErrorBadParameter;
1899 goto EXIT;
1900 }
1901
1902 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
1903 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
1904 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
1905
1906 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1907 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
1908
1909 if (codecReturn != VIDEO_ERROR_NONE) {
1910 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1911 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1912 goto EXIT;
1913 }
1914 Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1915
1916 ret = OMX_ErrorNone;
1917
1918 EXIT:
1919 FunctionOut();
1920
1921 return ret;
1922 }
1923
1924 OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1925 {
1926 OMX_ERRORTYPE ret = OMX_ErrorNone;
1927 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1928 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1929 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1930 void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1931 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1932 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1933 ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1934 ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1935 ExynosVideoBuffer *pVideoBuffer;
1936 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1937 ExynosVideoGeometry *bufferGeometry;
1938 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1939 OMX_S32 indexTimestamp = 0;
1940 int plane;
1941
1942 FunctionIn();
1943
1944 if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
1945 ret = OMX_ErrorNone;
1946 goto EXIT;
1947 }
1948
1949 while (1) {
1950 if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1951 ret = OMX_ErrorNone;
1952 goto EXIT;
1953 }
1954 displayStatus = pVideoBuffer->displayStatus;
1955 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1956
1957 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1958 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1959 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1960 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1961 if (pVideoBuffer != NULL) {
1962 ret = OMX_ErrorNone;
1963 break;
1964 } else {
1965 ret = OMX_ErrorUndefined;
1966 break;
1967 }
1968 }
1969 }
1970
1971 if (ret != OMX_ErrorNone)
1972 goto EXIT;
1973
1974 pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++;
1975 pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1976
1977 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
1978 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1979 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1980 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1981 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1982 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
1983 }
1984 pDstOutputData->usedDataLen = 0;
1985 pDstOutputData->pPrivate = pVideoBuffer;
1986 /* For Share Buffer */
1987 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1988
1989 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1990 bufferGeometry = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf;
1991 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1992 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1993 switch (bufferGeometry->eColorFormat) {
1994 case VIDEO_COLORFORMAT_NV12:
1995 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1996 break;
1997 case VIDEO_COLORFORMAT_NV12_TILED:
1998 default:
1999 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
2000 break;
2001 }
2002
2003 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2004 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
2005 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2006 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2007 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2008 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2009 pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2010 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2011 } else {
2012 pDstOutputData->timeStamp = 0x00;
2013 pDstOutputData->nFlags = 0x00;
2014 }
2015 } else {
2016 /* For timestamp correction. if mfc support frametype detect */
2017 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
2018 #ifdef NEED_TIMESTAMP_REORDER
2019 if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
2020 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2021 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2022 pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp;
2023 } else {
2024 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2025 pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2026 }
2027 #else
2028 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2029 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2030 #endif
2031 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2032 }
2033
2034 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2035 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2036 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2037 pDstOutputData->remainDataLen = 0;
2038 if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
2039 (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
2040 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2041 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2042 }
2043 } else {
2044 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2045 }
2046
2047 ret = OMX_ErrorNone;
2048
2049 EXIT:
2050 FunctionOut();
2051
2052 return ret;
2053 }
2054
2055 OMX_ERRORTYPE Exynos_Mpeg4Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2056 {
2057 OMX_ERRORTYPE ret = OMX_ErrorNone;
2058 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2059 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2060 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2061
2062 FunctionIn();
2063
2064 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2065 ret = OMX_ErrorNone;
2066 goto EXIT;
2067 }
2068 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2069 ret = OMX_ErrorNone;
2070 goto EXIT;
2071 }
2072
2073 ret = Exynos_Mpeg4Dec_SrcIn(pOMXComponent, pSrcInputData);
2074 if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
2075 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2076 pExynosComponent->callbackData,
2077 OMX_EventError, ret, 0, NULL);
2078 }
2079
2080 EXIT:
2081 FunctionOut();
2082
2083 return ret;
2084 }
2085
2086 OMX_ERRORTYPE Exynos_Mpeg4Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2087 {
2088 OMX_ERRORTYPE ret = OMX_ErrorNone;
2089 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2090 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2091 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2092
2093 FunctionIn();
2094
2095 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2096 ret = OMX_ErrorNone;
2097 goto EXIT;
2098 }
2099
2100 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2101 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2102 ret = OMX_ErrorNone;
2103 goto EXIT;
2104 }
2105 }
2106 if ((pMpeg4Dec->bSourceStart == OMX_FALSE) &&
2107 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2108 Exynos_OSAL_SignalWait(pMpeg4Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2109 Exynos_OSAL_SignalReset(pMpeg4Dec->hSourceStartEvent);
2110 }
2111
2112 ret = Exynos_Mpeg4Dec_SrcOut(pOMXComponent, pSrcOutputData);
2113 if ((ret != OMX_ErrorNone) &&
2114 (pExynosComponent->currentState == OMX_StateExecuting)) {
2115 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2116 pExynosComponent->callbackData,
2117 OMX_EventError, ret, 0, NULL);
2118 }
2119
2120 EXIT:
2121 FunctionOut();
2122
2123 return ret;
2124 }
2125
2126 OMX_ERRORTYPE Exynos_Mpeg4Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2127 {
2128 OMX_ERRORTYPE ret = OMX_ErrorNone;
2129 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2130 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2131 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2132
2133 FunctionIn();
2134
2135 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2136 ret = OMX_ErrorNone;
2137 goto EXIT;
2138 }
2139 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2140 ret = OMX_ErrorNone;
2141 goto EXIT;
2142 }
2143 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
2144 if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
2145 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2146 Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2147 Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
2148 }
2149 }
2150 if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) {
2151 ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData);
2152 if (ret != OMX_ErrorNone) {
2153 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2154 pExynosComponent->callbackData,
2155 OMX_EventError, ret, 0, NULL);
2156 }
2157 }
2158
2159 EXIT:
2160 FunctionOut();
2161
2162 return ret;
2163 }
2164
2165 OMX_ERRORTYPE Exynos_Mpeg4Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2166 {
2167 OMX_ERRORTYPE ret = OMX_ErrorNone;
2168 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2169 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2170 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2171
2172 FunctionIn();
2173
2174 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2175 ret = OMX_ErrorNone;
2176 goto EXIT;
2177 }
2178 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2179 ret = OMX_ErrorNone;
2180 goto EXIT;
2181 }
2182
2183 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2184 if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
2185 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2186 Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2187 Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
2188 }
2189 }
2190 ret = Exynos_Mpeg4Dec_DstOut(pOMXComponent, pDstOutputData);
2191 if ((ret != OMX_ErrorNone) &&
2192 (pExynosComponent->currentState == OMX_StateExecuting)) {
2193 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2194 pExynosComponent->callbackData,
2195 OMX_EventError, ret, 0, NULL);
2196 }
2197
2198 EXIT:
2199 FunctionOut();
2200
2201 return ret;
2202 }
2203
2204 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2205 {
2206 OMX_ERRORTYPE ret = OMX_ErrorNone;
2207 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2208 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2209 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
2210 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2211 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
2212 int i = 0;
2213 OMX_S32 codecType = -1;
2214
2215 FunctionIn();
2216
2217 if ((hComponent == NULL) || (componentName == NULL)) {
2218 ret = OMX_ErrorBadParameter;
2219 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2220 goto EXIT;
2221 }
2222 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) {
2223 codecType = CODEC_TYPE_MPEG4;
2224 } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_DEC, componentName) == 0) {
2225 codecType = CODEC_TYPE_H263;
2226 } else {
2227 ret = OMX_ErrorBadParameter;
2228 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2229 goto EXIT;
2230 }
2231
2232 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2233 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2234 if (ret != OMX_ErrorNone) {
2235 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2236 goto EXIT;
2237 }
2238 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2239 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2240
2241 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2242 if (pExynosComponent->componentName == NULL) {
2243 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2244 ret = OMX_ErrorInsufficientResources;
2245 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2246 goto EXIT;
2247 }
2248 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2249
2250 pMpeg4Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4DEC_HANDLE));
2251 if (pMpeg4Dec == NULL) {
2252 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2253 ret = OMX_ErrorInsufficientResources;
2254 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2255 goto EXIT;
2256 }
2257 Exynos_OSAL_Memset(pMpeg4Dec, 0, sizeof(EXYNOS_MPEG4DEC_HANDLE));
2258 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2259 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec;
2260 pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType;
2261
2262 if (codecType == CODEC_TYPE_MPEG4)
2263 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DEC);
2264 else
2265 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H263_DEC);
2266
2267 /* Set componentVersion */
2268 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2269 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2270 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2271 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2272 /* Set specVersion */
2273 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2274 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2275 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2276 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2277
2278 /* Input port */
2279 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2280 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2281 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2282 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2283 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2284 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2285 if (codecType == CODEC_TYPE_MPEG4) {
2286 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
2287 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2288 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4");
2289 } else {
2290 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
2291 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2292 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263");
2293 }
2294 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2295 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2296 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2297 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2298 pExynosPort->bufferProcessType = BUFFER_SHARE;
2299 pExynosPort->portWayType = WAY2_PORT;
2300
2301 /* Output port */
2302 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2303 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2304 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2305 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2306 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2307 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2308 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2309 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2310 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2311 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2312 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2313 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2314 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2315 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2316 pExynosPort->portWayType = WAY2_PORT;
2317
2318 if (codecType == CODEC_TYPE_MPEG4) {
2319 for(i = 0; i < ALL_PORT_NUM; i++) {
2320 INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE);
2321 pMpeg4Dec->mpeg4Component[i].nPortIndex = i;
2322 pMpeg4Dec->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2323 pMpeg4Dec->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level3;
2324 }
2325 } else {
2326 for(i = 0; i < ALL_PORT_NUM; i++) {
2327 INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE);
2328 pMpeg4Dec->h263Component[i].nPortIndex = i;
2329 pMpeg4Dec->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2;
2330 pMpeg4Dec->h263Component[i].eLevel = OMX_VIDEO_H263Level45;
2331 }
2332 }
2333
2334 pOMXComponent->GetParameter = &Exynos_Mpeg4Dec_GetParameter;
2335 pOMXComponent->SetParameter = &Exynos_Mpeg4Dec_SetParameter;
2336 pOMXComponent->GetConfig = &Exynos_Mpeg4Dec_GetConfig;
2337 pOMXComponent->SetConfig = &Exynos_Mpeg4Dec_SetConfig;
2338 pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Dec_GetExtensionIndex;
2339 pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Dec_ComponentRoleEnum;
2340 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2341
2342 pExynosComponent->exynos_codec_componentInit = &Exynos_Mpeg4Dec_Init;
2343 pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Dec_Terminate;
2344
2345 pVideoDec->exynos_codec_srcInputProcess = &Exynos_Mpeg4Dec_srcInputBufferProcess;
2346 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Dec_srcOutputBufferProcess;
2347 pVideoDec->exynos_codec_dstInputProcess = &Exynos_Mpeg4Dec_dstInputBufferProcess;
2348 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Dec_dstOutputBufferProcess;
2349
2350 pVideoDec->exynos_codec_start = &Mpeg4CodecStart;
2351 pVideoDec->exynos_codec_stop = &Mpeg4CodecStop;
2352 pVideoDec->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun;
2353 pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnQueueAllBuffer;
2354
2355 if (codecType == CODEC_TYPE_MPEG4)
2356 pVideoDec->exynos_checkInputFrame = &Check_Mpeg4_Frame;
2357 else
2358 pVideoDec->exynos_checkInputFrame = &Check_H263_Frame;
2359
2360 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2361 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2362
2363 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2364 if (pVideoDec->hSharedMemory == NULL) {
2365 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2366 Exynos_OSAL_Free(pMpeg4Dec);
2367 pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2368 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2369 ret = OMX_ErrorInsufficientResources;
2370 goto EXIT;
2371 }
2372
2373 pExynosComponent->currentState = OMX_StateLoaded;
2374
2375 ret = OMX_ErrorNone;
2376
2377 EXIT:
2378 FunctionOut();
2379
2380 return ret;
2381 }
2382
2383 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2384 {
2385 OMX_ERRORTYPE ret = OMX_ErrorNone;
2386 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2387 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2388 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2389 EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
2390
2391 FunctionIn();
2392
2393 if (hComponent == NULL) {
2394 ret = OMX_ErrorBadParameter;
2395 goto EXIT;
2396 }
2397 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2398 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2399 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2400
2401 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2402
2403 Exynos_OSAL_Free(pExynosComponent->componentName);
2404 pExynosComponent->componentName = NULL;
2405
2406 pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
2407 if (pMpeg4Dec != NULL) {
2408 Exynos_OSAL_Free(pMpeg4Dec);
2409 pMpeg4Dec = pVideoDec->hCodecHandle = NULL;
2410 }
2411
2412 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2413 if (ret != OMX_ErrorNone) {
2414 goto EXIT;
2415 }
2416
2417 ret = OMX_ErrorNone;
2418
2419 EXIT:
2420 FunctionOut();
2421
2422 return ret;
2423 }