import exynos 7570 bsp
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / h264 / Exynos_OMX_H264dec.c
CommitLineData
a9bdc01e
T
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_H264dec.c
20 * @brief
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * @version 2.0.0
23 * @history
24 * 2012.02.20 : Create
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include "Exynos_OMX_Macros.h"
32#include "Exynos_OMX_Basecomponent.h"
33#include "Exynos_OMX_Baseport.h"
34#include "Exynos_OMX_Vdec.h"
35#include "Exynos_OMX_VdecControl.h"
36#include "Exynos_OSAL_ETC.h"
37#include "Exynos_OSAL_Semaphore.h"
38#include "Exynos_OSAL_Thread.h"
39#include "Exynos_OMX_H264dec.h"
40#include "ExynosVideoApi.h"
41#include "Exynos_OSAL_SharedMemory.h"
42#include "Exynos_OSAL_Event.h"
43
44#ifdef USE_SKYPE_HD
45#include "Exynos_OSAL_SkypeHD.h"
46#endif
47
48/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
49/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
50#include "csc.h"
51
52#undef EXYNOS_LOG_TAG
53#define EXYNOS_LOG_TAG "EXYNOS_H264_DEC"
54//#define EXYNOS_LOG_OFF
55#include "Exynos_OSAL_Log.h"
56
57#define H264_DEC_NUM_OF_EXTRA_BUFFERS 7
58
59//#define ADD_SPS_PPS_I_FRAME
60//#define FULL_FRAME_SEARCH
61
62static OMX_ERRORTYPE SetProfileLevel(
63 EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
64{
65 OMX_ERRORTYPE ret = OMX_ErrorNone;
66 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
67 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
68
69 int nProfileCnt = 0;
70
71 FunctionIn();
72
73 if (pExynosComponent == NULL) {
74 ret = OMX_ErrorBadParameter;
75 goto EXIT;
76 }
77
78 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
79 if (pVideoDec == NULL) {
80 ret = OMX_ErrorBadParameter;
81 goto EXIT;
82 }
83
84 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
85 if (pH264Dec == NULL) {
86 ret = OMX_ErrorBadParameter;
87 goto EXIT;
88 }
89
90 pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileBaseline;
91 pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileMain;
92 pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileHigh;
93 pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
94 pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
95 pH264Dec->hMFCH264Handle.nProfileCnt = nProfileCnt;
96
97 switch (pH264Dec->hMFCH264Handle.videoInstInfo.HwVersion) {
98 case MFC_100:
99 case MFC_101:
100 pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
101 break;
102 case MFC_80:
103 case MFC_90:
104 case MFC_1010:
105 pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel51;
106 break;
107 case MFC_61:
108 case MFC_65:
109 case MFC_72:
110 case MFC_723:
111 case MFC_77:
112 case MFC_1011:
113 pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel42;
114 break;
115 case MFC_51:
116 case MFC_78:
117 case MFC_78D:
118 case MFC_92:
119 case MFC_1020:
120 default:
121 pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel4;
122 break;
123 }
124
125EXIT:
126 return ret;
127}
128
129static OMX_ERRORTYPE GetIndexToProfileLevel(
130 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
131 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
132{
133 OMX_ERRORTYPE ret = OMX_ErrorNone;
134 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
135 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
136
137 int nLevelCnt = 0;
138 OMX_U32 nMaxIndex = 0;
139
140 FunctionIn();
141
142 if ((pExynosComponent == NULL) ||
143 (pProfileLevelType == NULL)) {
144 ret = OMX_ErrorBadParameter;
145 goto EXIT;
146 }
147
148 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
149 if (pVideoDec == NULL) {
150 ret = OMX_ErrorBadParameter;
151 goto EXIT;
152 }
153
154 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
155 if (pH264Dec == NULL) {
156 ret = OMX_ErrorBadParameter;
157 goto EXIT;
158 }
159
160 while ((pH264Dec->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
161 nLevelCnt++;
162 }
163
164 if ((pH264Dec->hMFCH264Handle.nProfileCnt == 0) ||
165 (nLevelCnt == 0)) {
166 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __FUNCTION__);
167 ret = OMX_ErrorUndefined;
168 goto EXIT;
169 }
170
171 nMaxIndex = pH264Dec->hMFCH264Handle.nProfileCnt * nLevelCnt;
172 if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
173 ret = OMX_ErrorNoMore;
174 goto EXIT;
175 }
176
177 pProfileLevelType->eProfile = pH264Dec->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
178 pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
179
180 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
181
182EXIT:
183 return ret;
184}
185
186static OMX_BOOL CheckProfileLevelSupport(
187 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
188 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
189{
190 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
191 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
192
193 OMX_BOOL bProfileSupport = OMX_FALSE;
194 OMX_BOOL bLevelSupport = OMX_FALSE;
195
196 int nLevelCnt = 0;
197 int i;
198
199 FunctionIn();
200
201 if ((pExynosComponent == NULL) ||
202 (pProfileLevelType == NULL)) {
203 goto EXIT;
204 }
205
206 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
207 if (pVideoDec == NULL)
208 goto EXIT;
209
210 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
211 if (pH264Dec == NULL)
212 goto EXIT;
213
214 while ((pH264Dec->hMFCH264Handle.maxLevel >> nLevelCnt++) > 0);
215
216 if ((pH264Dec->hMFCH264Handle.nProfileCnt == 0) ||
217 (nLevelCnt == 0)) {
218 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __FUNCTION__);
219 goto EXIT;
220 }
221
222 for (i = 0; i < pH264Dec->hMFCH264Handle.nProfileCnt; i++) {
223 if (pH264Dec->hMFCH264Handle.profiles[i] == pProfileLevelType->eProfile) {
224 bProfileSupport = OMX_TRUE;
225 break;
226 }
227 }
228
229 if (bProfileSupport != OMX_TRUE)
230 goto EXIT;
231
232 while (nLevelCnt >= 0) {
233 if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
234 bLevelSupport = OMX_TRUE;
235 break;
236 }
237
238 nLevelCnt--;
239 }
240
241 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
242 pProfileLevelType->eProfile, pProfileLevelType->eLevel,
243 (bProfileSupport && bLevelSupport)? "":"not ");
244
245EXIT:
246 return (bProfileSupport && bLevelSupport);
247}
248
249#if 0 /* unused code */
250static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
251{
252 OMX_ERRORTYPE ret = OMX_ErrorNone;
253
254EXIT:
255 return ret;
256}
257#endif
258
259static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
260{
261 OMX_ERRORTYPE ret = OMX_ErrorNone;
262 ExynosVideoBuffer *pCodecBuffer = NULL;
263
264 if (codecBuffer == NULL) {
265 ret = OMX_ErrorBadParameter;
266 goto EXIT;
267 }
268
269 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
270
271 if (addr != NULL) {
272 addr[0] = pCodecBuffer->planes[0].addr;
273 addr[1] = pCodecBuffer->planes[1].addr;
274 addr[2] = pCodecBuffer->planes[2].addr;
275 }
276
277 if (size != NULL) {
278 size[0] = pCodecBuffer->planes[0].allocSize;
279 size[1] = pCodecBuffer->planes[1].allocSize;
280 size[2] = pCodecBuffer->planes[2].allocSize;
281 }
282
283EXIT:
284 return ret;
285}
286
287#if 0 /* unused code */
288int Check_H264_Frame(
289 OMX_U8 *pInputStream,
290 OMX_U32 buffSize,
291 OMX_U32 flag,
292 OMX_BOOL bPreviousFrameEOF,
293 OMX_BOOL *pbEndOfFrame)
294{
295 OMX_U32 preFourByte = (OMX_U32)-1;
296 int accessUnitSize = 0;
297 int frameTypeBoundary = 0;
298 int nextNaluSize = 0;
299 int naluStart = 0;
300
301 if (bPreviousFrameEOF == OMX_TRUE)
302 naluStart = 0;
303 else
304 naluStart = 1;
305
306 while (1) {
307 int inputOneByte = 0;
308
309 if (accessUnitSize == (int)buffSize)
310 goto EXIT;
311
312 inputOneByte = *(pInputStream++);
313 accessUnitSize += 1;
314
315 if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) {
316 int naluType = inputOneByte & 0x1F;
317
318 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d", naluType);
319 if (naluStart == 0) {
320#ifdef ADD_SPS_PPS_I_FRAME
321 if (naluType == 1 || naluType == 5)
322#else
323 if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8)
324#endif
325 naluStart = 1;
326 } else {
327#ifdef OLD_DETECT
328 frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9)
329#else
330 if (naluType == 9)
331 frameTypeBoundary = -2;
332#endif
333 if (naluType == 1 || naluType == 5) {
334 if (accessUnitSize == (int)buffSize) {
335 accessUnitSize--;
336 goto EXIT;
337 }
338 inputOneByte = *pInputStream++;
339 accessUnitSize += 1;
340
341 if (inputOneByte >= 0x80)
342 frameTypeBoundary = -1;
343 }
344 if (frameTypeBoundary < 0) {
345 break;
346 }
347 }
348
349 }
350 preFourByte = (preFourByte << 8) + inputOneByte;
351 }
352
353 *pbEndOfFrame = OMX_TRUE;
354 nextNaluSize = -5;
355 if (frameTypeBoundary == -1)
356 nextNaluSize = -6;
357 if (preFourByte != 0x00000001)
358 nextNaluSize++;
359 return (accessUnitSize + nextNaluSize);
360
361EXIT:
362 *pbEndOfFrame = OMX_FALSE;
363
364 return accessUnitSize;
365}
366#endif
367
368static OMX_BOOL Check_H264_StartCode(
369 OMX_U8 *pInputStream,
370 OMX_U32 streamSize)
371{
372 if (streamSize < 4) {
373 return OMX_FALSE;
374 }
375
376 if ((pInputStream[0] == 0x00) &&
377 (pInputStream[1] == 0x00) &&
378 (pInputStream[2] == 0x00) &&
379 (pInputStream[3] != 0x00) &&
380 ((pInputStream[4] & 0x1F) != 0xB) && // F/W constraint : in case of EOS data, can't return a buffer
381 ((pInputStream[3] >> 3) == 0x00)) {
382 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[4] & 0x1F), pInputStream[3], pInputStream[4], pInputStream[5]);
383 return OMX_TRUE;
384 } else if ((pInputStream[0] == 0x00) &&
385 (pInputStream[1] == 0x00) &&
386 (pInputStream[2] != 0x00) &&
387 ((pInputStream[3] & 0x1F) != 0xB) && // F/W constraint : in case of EOS data, can't return a buffer
388 ((pInputStream[2] >> 3) == 0x00)) {
389 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[3] & 0x1F), pInputStream[2], pInputStream[3], pInputStream[4]);
390 return OMX_TRUE;
391 } else {
392 return OMX_FALSE;
393 }
394}
395
396OMX_BOOL CheckFormatHWSupport(
397 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
398 OMX_COLOR_FORMATTYPE eColorFormat)
399{
400 OMX_BOOL ret = OMX_FALSE;
401 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
402 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
403 EXYNOS_OMX_BASEPORT *pOutputPort = NULL;
404 ExynosVideoColorFormatType eVideoFormat = VIDEO_CODING_UNKNOWN;
405 int i;
406
407 FunctionIn();
408
409 if (pExynosComponent == NULL)
410 goto EXIT;
411
412 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
413 if (pVideoDec == NULL)
414 goto EXIT;
415
416 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
417 if (pH264Dec == NULL)
418 goto EXIT;
419 pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
420
421 eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
422
423 for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
424 if (pH264Dec->hMFCH264Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
425 break;
426
427 if (pH264Dec->hMFCH264Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
428 ret = OMX_TRUE;
429 break;
430 }
431 }
432
433EXIT:
434 return ret;
435}
436
437OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264DEC_HANDLE *pH264Dec, ExynosVideoInstInfo *pVideoInstInfo)
438{
439 OMX_ERRORTYPE ret = OMX_ErrorNone;
440 ExynosVideoDecOps *pDecOps = NULL;
441 ExynosVideoDecBufferOps *pInbufOps = NULL;
442 ExynosVideoDecBufferOps *pOutbufOps = NULL;
443
444 FunctionIn();
445
446 if (pH264Dec == NULL) {
447 ret = OMX_ErrorBadParameter;
448 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
449 goto EXIT;
450 }
451
452 /* alloc ops structure */
453 pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
454 pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
455 pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
456
457 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
458 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
459 ret = OMX_ErrorInsufficientResources;
460 goto EXIT;
461 }
462
463 pH264Dec->hMFCH264Handle.pDecOps = pDecOps;
464 pH264Dec->hMFCH264Handle.pInbufOps = pInbufOps;
465 pH264Dec->hMFCH264Handle.pOutbufOps = pOutbufOps;
466
467 /* function pointer mapping */
468 pDecOps->nSize = sizeof(ExynosVideoDecOps);
469 pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
470 pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
471
472 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
473
474 /* check mandatory functions for decoder ops */
475 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
476 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
477#ifdef USE_S3D_SUPPORT
478 (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
479#endif
480 (pDecOps->Get_FrameTag == NULL)) {
481 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
482 ret = OMX_ErrorInsufficientResources;
483 goto EXIT;
484 }
485
486 /* check mandatory functions for buffer ops */
487 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
488 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
489 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
490 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
491 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
492 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
493 ret = OMX_ErrorInsufficientResources;
494 goto EXIT;
495 }
496
497 /* alloc context, open, querycap */
498#ifdef USE_DMA_BUF
499 pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
500#else
501 pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
502#endif
503 pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(pVideoInstInfo);
504 if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) {
505 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
506 ret = OMX_ErrorInsufficientResources;
507 goto EXIT;
508 }
509
510#ifdef USE_S3D_SUPPORT
511 /* S3D: Enable SEI parsing to check Frame Packing */
512 if (pDecOps->Enable_SEIParsing(pH264Dec->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
513 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Enable SEI Parsing");
514 ret = OMX_ErrorInsufficientResources;
515 goto EXIT;
516 }
517#endif
518
519 ret = OMX_ErrorNone;
520
521EXIT:
522 if (ret != OMX_ErrorNone) {
523 if (pDecOps != NULL) {
524 Exynos_OSAL_Free(pDecOps);
525 pH264Dec->hMFCH264Handle.pDecOps = NULL;
526 }
527 if (pInbufOps != NULL) {
528 Exynos_OSAL_Free(pInbufOps);
529 pH264Dec->hMFCH264Handle.pInbufOps = NULL;
530 }
531 if (pOutbufOps != NULL) {
532 Exynos_OSAL_Free(pOutbufOps);
533 pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
534 }
535 }
536
537 FunctionOut();
538
539 return ret;
540}
541
542OMX_ERRORTYPE H264CodecClose(EXYNOS_H264DEC_HANDLE *pH264Dec)
543{
544 OMX_ERRORTYPE ret = OMX_ErrorNone;
545 void *hMFCHandle = NULL;
546 ExynosVideoDecOps *pDecOps = NULL;
547 ExynosVideoDecBufferOps *pInbufOps = NULL;
548 ExynosVideoDecBufferOps *pOutbufOps = NULL;
549
550 FunctionIn();
551
552 if (pH264Dec == NULL) {
553 ret = OMX_ErrorBadParameter;
554 goto EXIT;
555 }
556
557 hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
558 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
559 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
560 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
561
562 if (hMFCHandle != NULL) {
563 pDecOps->Finalize(hMFCHandle);
564 pH264Dec->hMFCH264Handle.hMFCHandle = NULL;
565 }
566
567 /* Unregister function pointers */
568 Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
569
570 if (pOutbufOps != NULL) {
571 Exynos_OSAL_Free(pOutbufOps);
572 pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
573 }
574 if (pInbufOps != NULL) {
575 Exynos_OSAL_Free(pInbufOps);
576 pH264Dec->hMFCH264Handle.pInbufOps = NULL;
577 }
578 if (pDecOps != NULL) {
579 Exynos_OSAL_Free(pDecOps);
580 pH264Dec->hMFCH264Handle.pDecOps = NULL;
581 }
582
583 ret = OMX_ErrorNone;
584
585EXIT:
586 FunctionOut();
587
588 return ret;
589}
590
591OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
592{
593 OMX_ERRORTYPE ret = OMX_ErrorNone;
594 void *hMFCHandle = NULL;
595 ExynosVideoDecOps *pDecOps = NULL;
596 ExynosVideoDecBufferOps *pInbufOps = NULL;
597 ExynosVideoDecBufferOps *pOutbufOps = NULL;
598 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
599 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
600
601 FunctionIn();
602
603 if (pOMXComponent == NULL) {
604 ret = OMX_ErrorBadParameter;
605 goto EXIT;
606 }
607
608 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
609 if (pVideoDec == NULL) {
610 ret = OMX_ErrorBadParameter;
611 goto EXIT;
612 }
613
614 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
615 if (pH264Dec == NULL) {
616 ret = OMX_ErrorBadParameter;
617 goto EXIT;
618 }
619
620 hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
621 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
622 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
623 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
624
625 if (nPortIndex == INPUT_PORT_INDEX)
626 pInbufOps->Run(hMFCHandle);
627 else if (nPortIndex == OUTPUT_PORT_INDEX)
628 pOutbufOps->Run(hMFCHandle);
629
630 ret = OMX_ErrorNone;
631
632EXIT:
633 FunctionOut();
634
635 return ret;
636}
637
638OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
639{
640 OMX_ERRORTYPE ret = OMX_ErrorNone;
641 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
642 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
643 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
644 void *hMFCHandle = NULL;
645 ExynosVideoDecOps *pDecOps = NULL;
646 ExynosVideoDecBufferOps *pInbufOps = NULL;
647 ExynosVideoDecBufferOps *pOutbufOps = NULL;
648
649 FunctionIn();
650
651 if (pOMXComponent == NULL) {
652 ret = OMX_ErrorBadParameter;
653 goto EXIT;
654 }
655
656 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
657 if (pExynosComponent == NULL) {
658 ret = OMX_ErrorBadParameter;
659 goto EXIT;
660 }
661
662 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
663 if (pVideoDec == NULL) {
664 ret = OMX_ErrorBadParameter;
665 goto EXIT;
666 }
667
668 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
669 if (pH264Dec == NULL) {
670 ret = OMX_ErrorBadParameter;
671 goto EXIT;
672 }
673
674 hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
675 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
676 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
677 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
678
679 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
680 pInbufOps->Stop(hMFCHandle);
681 } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
682 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
683
684 pOutbufOps->Stop(hMFCHandle);
685
686 if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
687 (pOutputPort->bDynamicDPBMode == OMX_TRUE))
688 pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
689 }
690
691 ret = OMX_ErrorNone;
692
693EXIT:
694 FunctionOut();
695
696 return ret;
697}
698
699OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
700{
701 OMX_ERRORTYPE ret = OMX_ErrorNone;
702 void *hMFCHandle = NULL;
703 ExynosVideoDecOps *pDecOps = NULL;
704 ExynosVideoDecBufferOps *pInbufOps = NULL;
705 ExynosVideoDecBufferOps *pOutbufOps = NULL;
706 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
707 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
708
709 FunctionIn();
710
711 if (pOMXComponent == NULL) {
712 ret = OMX_ErrorBadParameter;
713 goto EXIT;
714 }
715
716 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
717 if (pVideoDec == NULL) {
718 ret = OMX_ErrorBadParameter;
719 goto EXIT;
720 }
721 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
722 if (pH264Dec == NULL) {
723 ret = OMX_ErrorBadParameter;
724 goto EXIT;
725 }
726
727 hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
728 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
729 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
730 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
731
732 if (nPortIndex == INPUT_PORT_INDEX) {
733 if (pH264Dec->bSourceStart == OMX_FALSE) {
734 Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
735 Exynos_OSAL_SleepMillisec(0);
736 }
737 }
738
739 if (nPortIndex == OUTPUT_PORT_INDEX) {
740 if (pH264Dec->bDestinationStart == OMX_FALSE) {
741 Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
742 Exynos_OSAL_SleepMillisec(0);
743 }
744 }
745
746 ret = OMX_ErrorNone;
747
748EXIT:
749 FunctionOut();
750
751 return ret;
752}
753
754OMX_ERRORTYPE H264CodecRegistCodecBuffers(
755 OMX_COMPONENTTYPE *pOMXComponent,
756 OMX_U32 nPortIndex,
757 int nBufferCnt)
758{
759 OMX_ERRORTYPE ret = OMX_ErrorNone;
760 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
761 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
762 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
763 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
764 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
765 ExynosVideoDecBufferOps *pBufOps = NULL;
766 ExynosVideoPlane *pPlanes = NULL;
767
768 int nPlaneCnt = 0;
769 int i, j;
770
771 FunctionIn();
772
773 if (nPortIndex == INPUT_PORT_INDEX) {
774 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
775 pBufOps = pH264Dec->hMFCH264Handle.pInbufOps;
776 } else {
777 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
778 pBufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
779 }
780
781 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
782 pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
783 if (pPlanes == NULL) {
784 ret = OMX_ErrorInsufficientResources;
785 goto EXIT;
786 }
787
788 /* Register buffer */
789 for (i = 0; i < nBufferCnt; i++) {
790 for (j = 0; j < nPlaneCnt; j++) {
791 pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
792 pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
793 pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
794 }
795
796 if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
797 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
798 ret = OMX_ErrorInsufficientResources;
799 Exynos_OSAL_Free(pPlanes);
800 goto EXIT;
801 }
802 }
803
804 Exynos_OSAL_Free(pPlanes);
805
806 ret = OMX_ErrorNone;
807
808EXIT:
809 FunctionOut();
810
811 return ret;
812}
813
814OMX_ERRORTYPE H264CodecReconfigAllBuffers(
815 OMX_COMPONENTTYPE *pOMXComponent,
816 OMX_U32 nPortIndex)
817{
818 OMX_ERRORTYPE ret = OMX_ErrorNone;
819 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
820 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
821 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
822 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
823 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
824 ExynosVideoDecBufferOps *pBufferOps = NULL;
825
826 FunctionIn();
827
828 if ((nPortIndex == INPUT_PORT_INDEX) &&
829 (pH264Dec->bSourceStart == OMX_TRUE)) {
830 ret = OMX_ErrorNotImplemented;
831 goto EXIT;
832 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
833 (pH264Dec->bDestinationStart == OMX_TRUE)) {
834 pBufferOps = pH264Dec->hMFCH264Handle.pOutbufOps;
835
836 if (pExynosPort->bufferProcessType & BUFFER_COPY) {
837 /**********************************/
838 /* Codec Buffer Free & Unregister */
839 /**********************************/
840 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
841 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
842 pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
843 pBufferOps->Cleanup_Buffer(hMFCHandle);
844
845 /******************************************************/
846 /* V4L2 Destnation Setup for DPB Buffer Number Change */
847 /******************************************************/
848 ret = H264CodecDstSetup(pOMXComponent);
849 if (ret != OMX_ErrorNone) {
850 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
851 goto EXIT;
852 }
853
854 pVideoDec->bReconfigDPB = OMX_FALSE;
855 } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
856 /**********************************/
857 /* Codec Buffer Unregister */
858 /**********************************/
859 pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
860 pBufferOps->Cleanup_Buffer(hMFCHandle);
861 }
862
863 Exynos_ResolutionUpdate(pOMXComponent);
864 } else {
865 ret = OMX_ErrorBadParameter;
866 goto EXIT;
867 }
868
869EXIT:
870 FunctionOut();
871
872 return ret;
873}
874
875OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
876{
877 OMX_ERRORTYPE ret = OMX_ErrorNone;
878 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
879 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
880 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
881 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
882 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
883 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
884 int i, nOutbufs;
885
886 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
887 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
888 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
889
890 FunctionIn();
891
892 if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
893 ret = OMX_ErrorBadPortIndex;
894 goto EXIT;
895 }
896
897 if ((nPortIndex == INPUT_PORT_INDEX) &&
898 (pH264Dec->bSourceStart == OMX_TRUE)) {
899 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
900
901 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
902 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
903 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
904
905 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
906 }
907
908 pInbufOps->Clear_Queue(hMFCHandle);
909 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
910 (pH264Dec->bDestinationStart == OMX_TRUE)) {
911 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
912
913 for (i = 0; i < pH264Dec->hMFCH264Handle.maxDPBNum; i++) {
914 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
915 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
916
917 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
918 }
919 pOutbufOps->Clear_Queue(hMFCHandle);
920 }
921
922EXIT:
923 FunctionOut();
924
925 return ret;
926}
927
928#ifdef USE_S3D_SUPPORT
929OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent)
930{
931 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
932 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
933 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
934 ExynosVideoFramePacking framePacking;
935 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
936 OMX_BOOL ret = OMX_FALSE;
937
938 /* Get Frame packing information*/
939 if (pDecOps->Get_FramePackingInfo(pH264Dec->hMFCH264Handle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
940 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Get Frame Packing Information");
941 ret = OMX_FALSE;
942 goto EXIT;
943 }
944
945 if (framePacking.available) {
946 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement ID: 0x%08x", framePacking.arrangement_id);
947 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement_type: %d", framePacking.arrangement_type);
948 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "content_interpretation_type: %d", framePacking.content_interpretation_type);
949 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "current_frame_is_frame0_flag: %d", framePacking.current_frame_is_frame0_flag);
950 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "spatial_flipping_flag: %d", framePacking.spatial_flipping_flag);
951 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", framePacking.frame0_grid_pos_x,
952 framePacking.frame0_grid_pos_y, framePacking.frame1_grid_pos_x, framePacking.frame1_grid_pos_y);
953
954 pH264Dec->hMFCH264Handle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type;
955 /** Send Port Settings changed call back - output color format change */
956 (*(pExynosComponent->pCallbacks->EventHandler))
957 (pOMXComponent,
958 pExynosComponent->callbackData,
959 OMX_EventS3DInformation, /* The command was completed */
960 OMX_TRUE, /* S3D is enabled */
961 (OMX_S32)pH264Dec->hMFCH264Handle.S3DFPArgmtType, /* S3D FPArgmtType */
962 NULL);
963
964 Exynos_OSAL_SleepMillisec(0);
965 } else {
966 pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
967 }
968
969 ret = OMX_TRUE;
970
971EXIT:
972 return ret;
973}
974#endif
975
976OMX_ERRORTYPE H264CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
977{
978 OMX_ERRORTYPE ret = OMX_ErrorNone;
979 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
980 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
981 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
982 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
983 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
984 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
985 EXYNOS_OMX_EXCEPTION_STATE eOutputExcepState = pOutputPort->exceptionFlag;
986
987 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
988 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
989 ExynosVideoGeometry codecOutbufConf;
990
991 OMX_CONFIG_RECTTYPE *pCropRectangle = &(pOutputPort->cropRectangle);
992 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = &(pInputPort->portDefinition);
993 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
994
995 int maxDPBNum = 0;
996
997 FunctionIn();
998
999 /* get geometry */
1000 Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
1001 if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
1002 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
1003 ret = OMX_ErrorHardware;
1004 goto EXIT;
1005 }
1006
1007 /* get dpb count */
1008 maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
1009 if (pVideoDec->bThumbnailMode == OMX_FALSE)
1010 maxDPBNum += EXTRA_DPB_NUM;
1011
1012 if ((codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
1013 (codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
1014 (codecOutbufConf.nStride != pH264Dec->hMFCH264Handle.codecOutbufConf.nStride) ||
1015#if 0 // TODO: check posibility
1016 (codecOutbufConf.eColorFormat != pH264Dec->hMFCH264Handle.codecOutbufConf.eColorFormat) ||
1017 (codecOutbufConf.eFilledDataType != pH264Dec->hMFCH264Handle.codecOutbufConf.eFilledDataType) ||
1018 (codecOutbufConf.bInterlaced != pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced) ||
1019#endif
1020 (maxDPBNum != pH264Dec->hMFCH264Handle.maxDPBNum)) {
1021 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
1022 pExynosComponent, __FUNCTION__,
1023 codecOutbufConf.nFrameWidth,
1024 codecOutbufConf.nFrameHeight,
1025 pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
1026 pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight);
1027 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
1028 pExynosComponent, __FUNCTION__,
1029 maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
1030 pH264Dec->hMFCH264Handle.maxDPBNum,
1031 pH264Dec->hMFCH264Handle.codecOutbufConf.eColorFormat,
1032 pH264Dec->hMFCH264Handle.codecOutbufConf.eFilledDataType);
1033
1034 pInputPortDefinition->format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1035 pInputPortDefinition->format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1036 pInputPortDefinition->format.video.nStride = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1037 pInputPortDefinition->format.video.nSliceHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1038
1039 if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
1040 pOutputPortDefinition->nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum;
1041 pOutputPortDefinition->nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum;
1042 }
1043
1044 Exynos_UpdateFrameSize(pOMXComponent);
1045
1046 if (eOutputExcepState == GENERAL_STATE) {
1047 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1048
1049 /** Send Port Settings changed call back **/
1050 (*(pExynosComponent->pCallbacks->EventHandler))
1051 (pOMXComponent,
1052 pExynosComponent->callbackData,
1053 OMX_EventPortSettingsChanged, /* The command was completed */
1054 OMX_DirOutput, /* This is the port index */
1055 0,
1056 NULL);
1057 }
1058 }
1059
1060 if ((codecOutbufConf.cropRect.nTop != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop) ||
1061 (codecOutbufConf.cropRect.nLeft != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft) ||
1062 (codecOutbufConf.cropRect.nWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
1063 (codecOutbufConf.cropRect.nHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
1064 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CROP: W(%d), H(%d) -> W(%d), H(%d)",
1065 pExynosComponent, __FUNCTION__,
1066 codecOutbufConf.cropRect.nWidth,
1067 codecOutbufConf.cropRect.nHeight,
1068 pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth,
1069 pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight);
1070
1071 pCropRectangle->nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
1072 pCropRectangle->nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
1073 pCropRectangle->nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
1074 pCropRectangle->nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
1075
1076 /** Send crop info call back **/
1077 (*(pExynosComponent->pCallbacks->EventHandler))
1078 (pOMXComponent,
1079 pExynosComponent->callbackData,
1080 OMX_EventPortSettingsChanged, /* The command was completed */
1081 OMX_DirOutput, /* This is the port index */
1082 OMX_IndexConfigCommonOutputCrop,
1083 NULL);
1084 }
1085
1086 Exynos_OSAL_Memcpy(&pH264Dec->hMFCH264Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
1087 pH264Dec->hMFCH264Handle.maxDPBNum = maxDPBNum;
1088
1089 ret = OMX_ErrorNone;
1090
1091EXIT:
1092 FunctionOut();
1093
1094 return ret;
1095}
1096
1097OMX_ERRORTYPE H264CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
1098{
1099 OMX_ERRORTYPE ret = OMX_ErrorNone;
1100 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1101 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1102 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1103 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1104 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1105 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1106 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1107 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1108
1109 OMX_CONFIG_RECTTYPE *pCropRectangle = NULL;
1110 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = NULL;
1111 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL;
1112
1113 FunctionIn();
1114 /* get geometry for output */
1115 Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
1116 if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
1117 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
1118 ret = OMX_ErrorCorruptedHeader;
1119 goto EXIT;
1120 }
1121
1122 /* get dpb count */
1123 pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
1124 if (pVideoDec->bThumbnailMode == OMX_FALSE)
1125 pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
1126 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] H264CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pH264Dec->hMFCH264Handle.maxDPBNum);
1127
1128 /* get interlace info */
1129 if (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
1130 Exynos_OSAL_Log(EXYNOS_LOG_INFO, "detect an interlaced type");
1131
1132 pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
1133
1134 if (pVideoDec->bReconfigDPB != OMX_TRUE) {
1135 pCropRectangle = &(pOutputPort->cropRectangle);
1136 pInputPortDefinition = &(pInputPort->portDefinition);
1137 pOutputPortDefinition = &(pOutputPort->portDefinition);
1138 } else {
1139 pCropRectangle = &(pOutputPort->newCropRectangle);
1140 pInputPortDefinition = &(pInputPort->newPortDefinition);
1141 pOutputPortDefinition = &(pOutputPort->newPortDefinition);
1142 }
1143
1144 pCropRectangle->nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
1145 pCropRectangle->nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
1146 pCropRectangle->nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
1147 pCropRectangle->nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
1148
1149 if (pOutputPort->bufferProcessType & BUFFER_COPY) {
1150 if ((pVideoDec->bReconfigDPB) ||
1151 (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
1152 (pInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
1153 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1154
1155 pInputPortDefinition->format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1156 pInputPortDefinition->format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1157 pInputPortDefinition->format.video.nStride = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1158 pInputPortDefinition->format.video.nSliceHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1159
1160 pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
1161 pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
1162
1163 if (pVideoDec->bReconfigDPB != OMX_TRUE)
1164 Exynos_UpdateFrameSize(pOMXComponent);
1165
1166 /** Send Port Settings changed call back **/
1167 (*(pExynosComponent->pCallbacks->EventHandler))
1168 (pOMXComponent,
1169 pExynosComponent->callbackData,
1170 OMX_EventPortSettingsChanged, /* The command was completed */
1171 OMX_DirOutput, /* This is the port index */
1172 0,
1173 NULL);
1174 }
1175 } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
1176 if ((pVideoDec->bReconfigDPB) ||
1177 (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) ||
1178 (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
1179 (pInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
1180 ((OMX_S32)pOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
1181 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1182
1183 pInputPortDefinition->format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1184 pInputPortDefinition->format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1185 pInputPortDefinition->format.video.nStride = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1186 pInputPortDefinition->format.video.nSliceHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1187
1188 pOutputPortDefinition->nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum;
1189 pOutputPortDefinition->nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum;
1190
1191 if (pVideoDec->bReconfigDPB != OMX_TRUE)
1192 Exynos_UpdateFrameSize(pOMXComponent);
1193
1194 /** Send Port Settings changed call back **/
1195 (*(pExynosComponent->pCallbacks->EventHandler))
1196 (pOMXComponent,
1197 pExynosComponent->callbackData,
1198 OMX_EventPortSettingsChanged, /* The command was completed */
1199 OMX_DirOutput, /* This is the port index */
1200 0,
1201 NULL);
1202 }
1203 }
1204 if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
1205 ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
1206 (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight))) {
1207 /* Check Crop */
1208 pInputPortDefinition->format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1209 pInputPortDefinition->format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1210 pInputPortDefinition->format.video.nStride = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1211 pInputPortDefinition->format.video.nSliceHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1212
1213 Exynos_UpdateFrameSize(pOMXComponent);
1214
1215 /** Send crop info call back **/
1216 (*(pExynosComponent->pCallbacks->EventHandler))
1217 (pOMXComponent,
1218 pExynosComponent->callbackData,
1219 OMX_EventPortSettingsChanged, /* The command was completed */
1220 OMX_DirOutput, /* This is the port index */
1221 OMX_IndexConfigCommonOutputCrop,
1222 NULL);
1223 }
1224
1225 ret = OMX_ErrorNone;
1226
1227EXIT:
1228 FunctionOut();
1229
1230 return ret;
1231}
1232
1233OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1234{
1235 OMX_ERRORTYPE ret = OMX_ErrorNone;
1236 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1237 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1238 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1239 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1240 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1241 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1242 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1243 OMX_COLOR_FORMATTYPE eOutputFormat = pExynosOutputPort->portDefinition.format.video.eColorFormat;
1244
1245 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1246 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1247 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1248 ExynosVideoGeometry bufferConf;
1249
1250 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1251 unsigned int nDataLen[MAX_BUFFER_PLANE] = {oneFrameSize, 0, 0};
1252
1253 OMX_U32 nInBufferCnt = 0;
1254 OMX_BOOL bSupportFormat = OMX_FALSE;
1255 int i;
1256
1257 FunctionIn();
1258
1259 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
1260 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
1261 if (pBufferInfo == NULL) {
1262 ret = OMX_ErrorInsufficientResources;
1263 goto EXIT;
1264 }
1265
1266 pBufferInfo->nFlags = pSrcInputData->nFlags;
1267 pBufferInfo->timeStamp = pSrcInputData->timeStamp;
1268 ret = Exynos_OSAL_Queue(&pH264Dec->bypassBufferInfoQ, (void *)pBufferInfo);
1269 Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
1270
1271 ret = OMX_ErrorNone;
1272 goto EXIT;
1273 }
1274
1275 if (pVideoDec->bThumbnailMode == OMX_TRUE)
1276 pDecOps->Set_IFrameDecoding(hMFCHandle);
1277 else if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
1278 (pH264Dec->hMFCH264Handle.nDisplayDelay <= MAX_H264_DISPLAYDELAY_VALIDNUM)) {
1279 pDecOps->Set_DisplayDelay(hMFCHandle, (int)pH264Dec->hMFCH264Handle.nDisplayDelay);
1280 }
1281
1282#ifdef USE_SKYPE_HD
1283 if (pH264Dec->bLowLatency == OMX_TRUE)
1284 pDecOps->Set_DisplayDelay(hMFCHandle, 0);
1285#endif
1286
1287 if ((pDecOps->Enable_DTSMode != NULL) &&
1288 (pVideoDec->bDTSMode == OMX_TRUE))
1289 pDecOps->Enable_DTSMode(hMFCHandle);
1290
1291 /* input buffer info */
1292 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1293 bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
1294 pInbufOps->Set_Shareable(hMFCHandle);
1295 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1296 bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
1297 } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1298 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1299 }
1300 bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
1301 nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
1302
1303 /* should be done before prepare input buffer */
1304 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1305 ret = OMX_ErrorInsufficientResources;
1306 goto EXIT;
1307 }
1308
1309 /* set input buffer geometry */
1310 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1311 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
1312 ret = OMX_ErrorInsufficientResources;
1313 goto EXIT;
1314 }
1315
1316 /* setup input buffer */
1317 if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
1318 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
1319 ret = OMX_ErrorInsufficientResources;
1320 goto EXIT;
1321 }
1322
1323 /* set output geometry */
1324 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1325
1326 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
1327 if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
1328 if ((pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
1329 (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
1330 /* Needs to eanble DualDPB feature */
1331 if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
1332 ret = OMX_ErrorHardware;
1333 goto EXIT;
1334 }
1335 }
1336 bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
1337 Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
1338 } else {
1339 OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1340 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
1341 if (bSupportFormat != OMX_TRUE) {
1342 eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1343 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
1344 }
1345 if (bSupportFormat == OMX_TRUE) { /* supported by CSC(NV12T/NV12 -> format) */
1346 bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
1347 Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
1348 } else {
1349 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support this format (0x%x)", eOutputFormat);
1350 ret = OMX_ErrorNotImplemented;
1351 goto EXIT;
1352 }
1353 }
1354
1355 pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat;
1356 bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
1357 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1358 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1359 ret = OMX_ErrorInsufficientResources;
1360 goto EXIT;
1361 }
1362
1363 /* input buffer enqueue for header parsing */
1364 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
1365 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
1366 nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
1367 else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
1368 nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1369
1370 /* set buffer process type */
1371 if (pDecOps->Set_BufferProcessType(hMFCHandle, pExynosOutputPort->bufferProcessType) != VIDEO_ERROR_NONE) {
1372 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set buffer process type(not supported)");
1373 }
1374
1375 if (pInbufOps->ExtensionEnqueue(hMFCHandle,
1376 (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
1377 (int *)pSrcInputData->multiPlaneBuffer.fd,
1378 nAllocLen,
1379 nDataLen,
1380 Exynos_GetPlaneFromPort(pExynosInputPort),
1381 pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
1382 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
1383// ret = OMX_ErrorInsufficientResources;
1384 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
1385 goto EXIT;
1386 }
1387
1388 /* start header parsing */
1389 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1390 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
1391 ret = OMX_ErrorCodecInit;
1392 goto EXIT;
1393 }
1394
1395 ret = H264CodecUpdateResolution(pOMXComponent);
1396 if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
1397 (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
1398 (oneFrameSize >= 8))
1399 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
1400 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
1401 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
1402 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
1403 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
1404 if (ret != OMX_ErrorNone) {
1405 H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1406 pInbufOps->Cleanup_Buffer(hMFCHandle);
1407 goto EXIT;
1408 }
1409
1410 Exynos_OSAL_SleepMillisec(0);
1411 ret = OMX_ErrorInputDataDecodeYet;
1412 H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1413
1414EXIT:
1415 FunctionOut();
1416
1417 return ret;
1418}
1419
1420OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
1421{
1422 OMX_ERRORTYPE ret = OMX_ErrorNone;
1423 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1424 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1425 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1426 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1427 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1428 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1429
1430 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1431 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1432 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1433
1434 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1435 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1436 int i, nOutbufs, nPlaneCnt;
1437
1438 FunctionIn();
1439
1440 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
1441 for (i = 0; i < nPlaneCnt; i++)
1442 nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i];
1443
1444 if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
1445 if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
1446 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
1447 ret = OMX_ErrorHardware;
1448 goto EXIT;
1449 }
1450 }
1451
1452 pOutbufOps->Set_Shareable(hMFCHandle);
1453
1454 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1455 /* should be done before prepare output buffer */
1456 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1457 ret = OMX_ErrorInsufficientResources;
1458 goto EXIT;
1459 }
1460
1461 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
1462 /* get dpb count */
1463 nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
1464 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1465 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1466 ret = OMX_ErrorInsufficientResources;
1467 goto EXIT;
1468 }
1469
1470 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
1471 if (ret != OMX_ErrorNone)
1472 goto EXIT;
1473
1474 /* Register output buffer */
1475 ret = H264CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
1476 if (ret != OMX_ErrorNone)
1477 goto EXIT;
1478
1479 /* Enqueue output buffer */
1480 for (i = 0; i < nOutbufs; i++)
1481 pOutbufOps->Enqueue(hMFCHandle,
1482 (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1483 nDataLen,
1484 nPlaneCnt,
1485 NULL);
1486 } else {
1487 if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
1488 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1489 ret = OMX_ErrorInsufficientResources;
1490 goto EXIT;
1491 }
1492
1493 /* get dpb count */
1494 nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
1495 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
1496 if (ret != OMX_ErrorNone)
1497 goto EXIT;
1498
1499 /* without Register output buffer */
1500
1501 /* Enqueue output buffer */
1502 for (i = 0; i < nOutbufs; i++) {
1503 pOutbufOps->ExtensionEnqueue(hMFCHandle,
1504 (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1505 (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
1506 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
1507 nDataLen,
1508 nPlaneCnt,
1509 NULL);
1510 }
1511 }
1512
1513 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1514 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1515 ret = OMX_ErrorInsufficientResources;
1516 goto EXIT;
1517 }
1518 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1519#ifdef USE_ANB
1520 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
1521 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
1522 int plane;
1523
1524 Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
1525
1526 /* get dpb count */
1527 nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
1528 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1529 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1530 ret = OMX_ErrorInsufficientResources;
1531 goto EXIT;
1532 }
1533
1534 if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
1535 (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
1536 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
1537 for (plane = 0; plane < nPlaneCnt; plane++) {
1538 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
1539 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
1540 planes[plane].allocSize = nAllocLen[plane];
1541 }
1542
1543 if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
1544 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1545 ret = OMX_ErrorInsufficientResources;
1546 goto EXIT;
1547 }
1548 pOutbufOps->Enqueue(hMFCHandle,
1549 (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
1550 nDataLen,
1551 nPlaneCnt,
1552 NULL);
1553 }
1554
1555 if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
1556 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
1557 ret = OMX_ErrorHardware;
1558 goto EXIT;
1559 }
1560 } else {
1561 /*************/
1562 /* TBD */
1563 /*************/
1564 ret = OMX_ErrorNotImplemented;
1565 goto EXIT;
1566 }
1567 } else {
1568 /* get dpb count */
1569 nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
1570 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1571 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1572 ret = OMX_ErrorInsufficientResources;
1573 goto EXIT;
1574 }
1575
1576 if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
1577 (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
1578 /*************/
1579 /* TBD */
1580 /*************/
1581 ret = OMX_ErrorNotImplemented;
1582 goto EXIT;
1583 }
1584 }
1585#else
1586 /*************/
1587 /* TBD */
1588 /*************/
1589 ret = OMX_ErrorNotImplemented;
1590 goto EXIT;
1591#endif
1592 }
1593
1594 pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
1595
1596 ret = OMX_ErrorNone;
1597
1598EXIT:
1599 FunctionOut();
1600
1601 return ret;
1602}
1603
1604OMX_ERRORTYPE Exynos_H264Dec_GetParameter(
1605 OMX_IN OMX_HANDLETYPE hComponent,
1606 OMX_IN OMX_INDEXTYPE nParamIndex,
1607 OMX_INOUT OMX_PTR pComponentParameterStructure)
1608{
1609 OMX_ERRORTYPE ret = OMX_ErrorNone;
1610 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1611 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1612
1613 FunctionIn();
1614
1615 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1616 ret = OMX_ErrorBadParameter;
1617 goto EXIT;
1618 }
1619 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1620 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1621 if (ret != OMX_ErrorNone) {
1622 goto EXIT;
1623 }
1624 if (pOMXComponent->pComponentPrivate == NULL) {
1625 ret = OMX_ErrorBadParameter;
1626 goto EXIT;
1627 }
1628
1629 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1630 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1631 ret = OMX_ErrorInvalidState;
1632 goto EXIT;
1633 }
1634
1635 switch ((int)nParamIndex) {
1636 case OMX_IndexParamVideoAvc:
1637 {
1638 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1639 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1640 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1641 /* except nSize, nVersion and nPortIndex */
1642 int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
1643
1644 ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1645 if (ret != OMX_ErrorNone) {
1646 goto EXIT;
1647 }
1648
1649 if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1650 ret = OMX_ErrorBadPortIndex;
1651 goto EXIT;
1652 }
1653
1654 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1655 pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex];
1656
1657 Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
1658 ((char *)pSrcAVCComponent) + nOffset,
1659 sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
1660 }
1661 break;
1662 case OMX_IndexParamStandardComponentRole:
1663 {
1664 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1665 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1666 if (ret != OMX_ErrorNone) {
1667 goto EXIT;
1668 }
1669
1670 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
1671 }
1672 break;
1673 case OMX_IndexParamVideoProfileLevelQuerySupported:
1674 {
1675 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1676
1677 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1678 if (ret != OMX_ErrorNone) {
1679 goto EXIT;
1680 }
1681
1682 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1683 ret = OMX_ErrorBadPortIndex;
1684 goto EXIT;
1685 }
1686
1687 ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
1688 }
1689 break;
1690 case OMX_IndexParamVideoProfileLevelCurrent:
1691 {
1692 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1693 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1694 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1695
1696 ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1697 if (ret != OMX_ErrorNone) {
1698 goto EXIT;
1699 }
1700
1701 if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1702 ret = OMX_ErrorBadPortIndex;
1703 goto EXIT;
1704 }
1705
1706 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1707 pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex];
1708
1709 pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1710 pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1711 }
1712 break;
1713 case OMX_IndexParamVideoErrorCorrection:
1714 {
1715 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1716 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1717 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1718
1719 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1720 if (ret != OMX_ErrorNone) {
1721 goto EXIT;
1722 }
1723
1724 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1725 ret = OMX_ErrorBadPortIndex;
1726 goto EXIT;
1727 }
1728
1729 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1730 pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1731
1732 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1733 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1734 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1735 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1736 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1737 }
1738 break;
1739#ifdef USE_TIMESTAMP_REORDER_SUPPORT
1740 case OMX_IndexExynosParamReorderMode: /* MSRND */
1741 {
1742 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1743 EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
1744
1745 ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
1746 if (ret != OMX_ErrorNone)
1747 goto EXIT;
1748
1749 pReorderParam->bReorderMode = pVideoDec->bReorderMode;
1750 }
1751 break;
1752#endif
1753 case OMX_IndexParamPortDefinition:
1754 {
1755 OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1756 OMX_U32 portIndex = portDefinition->nPortIndex;
1757 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1758 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1759 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1760 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1761
1762 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1763 if (ret != OMX_ErrorNone) {
1764 goto EXIT;
1765 }
1766
1767 if (((pExynosPort->bIsANBEnabled == OMX_TRUE) || (pExynosPort->bStoreMetaData == OMX_TRUE)) &&
1768 (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
1769 (portIndex == OUTPUT_PORT_INDEX)) {
1770 portDefinition->format.video.eColorFormat =
1771 (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace, pExynosPort->ePlaneType);
1772 }
1773 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat: 0x%x", portDefinition->format.video.eColorFormat);
1774 }
1775 break;
1776
1777 default:
1778#ifdef USE_SKYPE_HD
1779 ret = Exynos_H264Dec_GetParameter_SkypeHD(hComponent, nParamIndex, pComponentParameterStructure);
1780 if (ret != OMX_ErrorNone)
1781#endif
1782 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1783 break;
1784 }
1785EXIT:
1786 FunctionOut();
1787
1788 return ret;
1789}
1790
1791OMX_ERRORTYPE Exynos_H264Dec_SetParameter(
1792 OMX_IN OMX_HANDLETYPE hComponent,
1793 OMX_IN OMX_INDEXTYPE nIndex,
1794 OMX_IN OMX_PTR pComponentParameterStructure)
1795{
1796 OMX_ERRORTYPE ret = OMX_ErrorNone;
1797 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1798 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1799
1800 FunctionIn();
1801
1802 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1803 ret = OMX_ErrorBadParameter;
1804 goto EXIT;
1805 }
1806 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1807 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1808 if (ret != OMX_ErrorNone) {
1809 goto EXIT;
1810 }
1811 if (pOMXComponent->pComponentPrivate == NULL) {
1812 ret = OMX_ErrorBadParameter;
1813 goto EXIT;
1814 }
1815
1816 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1817 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1818 ret = OMX_ErrorInvalidState;
1819 goto EXIT;
1820 }
1821
1822 switch ((int)nIndex) {
1823 case OMX_IndexParamVideoAvc:
1824 {
1825 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1826 OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1827 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1828 /* except nSize, nVersion and nPortIndex */
1829 int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
1830
1831 ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1832 if (ret != OMX_ErrorNone) {
1833 goto EXIT;
1834 }
1835
1836 if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1837 ret = OMX_ErrorBadPortIndex;
1838 goto EXIT;
1839 }
1840
1841 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1842 pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex];
1843
1844 Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
1845 ((char *)pSrcAVCComponent) + nOffset,
1846 sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
1847 }
1848 break;
1849 case OMX_IndexParamStandardComponentRole:
1850 {
1851 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1852
1853 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1854 if (ret != OMX_ErrorNone) {
1855 goto EXIT;
1856 }
1857
1858 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1859 ret = OMX_ErrorIncorrectStateOperation;
1860 goto EXIT;
1861 }
1862
1863 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE)) {
1864 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1865 } else {
1866 ret = OMX_ErrorBadParameter;
1867 goto EXIT;
1868 }
1869 }
1870 break;
1871 case OMX_IndexParamVideoProfileLevelCurrent:
1872 {
1873 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1874 OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1875 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1876
1877 ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1878 if (ret != OMX_ErrorNone)
1879 goto EXIT;
1880
1881 if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1882 ret = OMX_ErrorBadPortIndex;
1883 goto EXIT;
1884 }
1885
1886 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1887
1888 pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex];
1889
1890 if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
1891 ret = OMX_ErrorBadParameter;
1892 goto EXIT;
1893 }
1894
1895 pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1896 pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1897 }
1898 break;
1899 case OMX_IndexParamVideoErrorCorrection:
1900 {
1901 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1902 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1903 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1904
1905 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1906 if (ret != OMX_ErrorNone) {
1907 goto EXIT;
1908 }
1909
1910 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1911 ret = OMX_ErrorBadPortIndex;
1912 goto EXIT;
1913 }
1914
1915 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1916 pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1917
1918 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1919 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1920 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1921 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1922 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1923 }
1924 break;
1925#ifdef USE_TIMESTAMP_REORDER_SUPPORT
1926 case OMX_IndexExynosParamReorderMode: /* MSRND */
1927 {
1928 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1929 EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
1930
1931 ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
1932 if (ret != OMX_ErrorNone)
1933 goto EXIT;
1934
1935 pVideoDec->bReorderMode = pReorderParam->bReorderMode;
1936 }
1937 break;
1938#endif
1939 default:
1940#ifdef USE_SKYPE_HD
1941 ret = Exynos_H264Dec_SetParameter_SkypeHD(hComponent, nIndex, pComponentParameterStructure);
1942 if (ret != OMX_ErrorNone)
1943#endif
1944 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1945 break;
1946 }
1947EXIT:
1948 FunctionOut();
1949
1950 return ret;
1951}
1952
1953OMX_ERRORTYPE Exynos_H264Dec_GetConfig(
1954 OMX_HANDLETYPE hComponent,
1955 OMX_INDEXTYPE nIndex,
1956 OMX_PTR pComponentConfigStructure)
1957{
1958 OMX_ERRORTYPE ret = OMX_ErrorNone;
1959 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1960 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1961
1962 FunctionIn();
1963
1964 if (hComponent == NULL) {
1965 ret = OMX_ErrorBadParameter;
1966 goto EXIT;
1967 }
1968 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1969 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1970 if (ret != OMX_ErrorNone) {
1971 goto EXIT;
1972 }
1973 if (pOMXComponent->pComponentPrivate == NULL) {
1974 ret = OMX_ErrorBadParameter;
1975 goto EXIT;
1976 }
1977 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1978 if (pComponentConfigStructure == NULL) {
1979 ret = OMX_ErrorBadParameter;
1980 goto EXIT;
1981 }
1982 if (pExynosComponent->currentState == OMX_StateInvalid) {
1983 ret = OMX_ErrorInvalidState;
1984 goto EXIT;
1985 }
1986
1987 switch ((int)nIndex) {
1988 case OMX_IndexConfigCommonOutputCrop:
1989 {
1990 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
1991 OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
1992 OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
1993 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1994
1995 if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1996 ret = OMX_ErrorNotReady;
1997 break;
1998 }
1999
2000 pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
2001
2002 if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
2003 (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
2004 ret = OMX_ErrorBadPortIndex;
2005 goto EXIT;
2006 }
2007
2008 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
2009
2010 pSrcRectType = &(pExynosPort->cropRectangle);
2011
2012 pDstRectType->nTop = pSrcRectType->nTop;
2013 pDstRectType->nLeft = pSrcRectType->nLeft;
2014 pDstRectType->nHeight = pSrcRectType->nHeight;
2015 pDstRectType->nWidth = pSrcRectType->nWidth;
2016 }
2017 break;
2018#ifdef USE_S3D_SUPPORT
2019 case OMX_IndexVendorS3DMode:
2020 {
2021 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
2022 OMX_U32 *pS3DMode = NULL;
2023 pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2024
2025 pS3DMode = (OMX_U32 *)pComponentConfigStructure;
2026 *pS3DMode = (OMX_U32) pH264Dec->hMFCH264Handle.S3DFPArgmtType;
2027 }
2028 break;
2029#endif
2030 case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
2031 {
2032 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2033
2034 (*((OMX_U32 *)pComponentConfigStructure)) = pH264Dec->hMFCH264Handle.nDisplayDelay;
2035 }
2036 break;
2037 default:
2038 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
2039 break;
2040 }
2041
2042EXIT:
2043 FunctionOut();
2044
2045 return ret;
2046}
2047
2048OMX_ERRORTYPE Exynos_H264Dec_SetConfig(
2049 OMX_HANDLETYPE hComponent,
2050 OMX_INDEXTYPE nIndex,
2051 OMX_PTR pComponentConfigStructure)
2052{
2053 OMX_ERRORTYPE ret = OMX_ErrorNone;
2054 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2055 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2056
2057 FunctionIn();
2058
2059 if (hComponent == NULL) {
2060 ret = OMX_ErrorBadParameter;
2061 goto EXIT;
2062 }
2063 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2064 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
2065 if (ret != OMX_ErrorNone) {
2066 goto EXIT;
2067 }
2068 if (pOMXComponent->pComponentPrivate == NULL) {
2069 ret = OMX_ErrorBadParameter;
2070 goto EXIT;
2071 }
2072 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2073 if (pComponentConfigStructure == NULL) {
2074 ret = OMX_ErrorBadParameter;
2075 goto EXIT;
2076 }
2077 if (pExynosComponent->currentState == OMX_StateInvalid) {
2078 ret = OMX_ErrorInvalidState;
2079 goto EXIT;
2080 }
2081
2082 switch ((int)nIndex) {
2083 case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
2084 {
2085 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2086 OMX_U32 nDisplayDelay;
2087
2088 if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_TRUE) {
2089 ret = OMX_ErrorIncorrectStateOperation;
2090 break;
2091 }
2092
2093 nDisplayDelay = (*((OMX_U32 *)pComponentConfigStructure));
2094 if (nDisplayDelay > MAX_H264_DISPLAYDELAY_VALIDNUM) {
2095 ret = OMX_ErrorBadParameter;
2096 break;
2097 }
2098
2099 pH264Dec->hMFCH264Handle.nDisplayDelay = nDisplayDelay;
2100 }
2101 break;
2102 default:
2103 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
2104 break;
2105 }
2106
2107EXIT:
2108 FunctionOut();
2109
2110 return ret;
2111}
2112
2113OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex(
2114 OMX_IN OMX_HANDLETYPE hComponent,
2115 OMX_IN OMX_STRING cParameterName,
2116 OMX_OUT OMX_INDEXTYPE *pIndexType)
2117{
2118 OMX_ERRORTYPE ret = OMX_ErrorNone;
2119 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2120 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2121
2122 FunctionIn();
2123
2124 if (hComponent == NULL) {
2125 ret = OMX_ErrorBadParameter;
2126 goto EXIT;
2127 }
2128 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2129 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
2130 if (ret != OMX_ErrorNone) {
2131 goto EXIT;
2132 }
2133 if (pOMXComponent->pComponentPrivate == NULL) {
2134 ret = OMX_ErrorBadParameter;
2135 goto EXIT;
2136 }
2137 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2138 if ((cParameterName == NULL) || (pIndexType == NULL)) {
2139 ret = OMX_ErrorBadParameter;
2140 goto EXIT;
2141 }
2142 if (pExynosComponent->currentState == OMX_StateInvalid) {
2143 ret = OMX_ErrorInvalidState;
2144 goto EXIT;
2145 }
2146
2147#ifdef USE_S3D_SUPPORT
2148 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
2149 *pIndexType = OMX_IndexVendorS3DMode;
2150 ret = OMX_ErrorNone;
2151 goto EXIT;
2152 }
2153#endif
2154
2155 if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
2156 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_CONFIG_DISPLAY_DELAY) == 0) {
2157 *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosConfigDisplayDelay;
2158 ret = OMX_ErrorNone;
2159 goto EXIT;
2160 }
2161
2162#ifdef USE_TIMESTAMP_REORDER_SUPPORT
2163 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
2164 *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
2165 ret = OMX_ErrorNone;
2166 goto EXIT;
2167 }
2168#endif
2169 }
2170
2171#ifdef USE_SKYPE_HD
2172 ret = Exynos_H264Dec_GetExtensionIndex_SkypeHD(hComponent, cParameterName, pIndexType);
2173 if (ret != OMX_ErrorNone)
2174#endif
2175 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
2176
2177EXIT:
2178 FunctionOut();
2179
2180 return ret;
2181}
2182
2183OMX_ERRORTYPE Exynos_H264Dec_ComponentRoleEnum(
2184 OMX_HANDLETYPE hComponent,
2185 OMX_U8 *cRole,
2186 OMX_U32 nIndex)
2187{
2188 OMX_ERRORTYPE ret = OMX_ErrorNone;
2189 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2190 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2191
2192 FunctionIn();
2193
2194 if ((hComponent == NULL) || (cRole == NULL)) {
2195 ret = OMX_ErrorBadParameter;
2196 goto EXIT;
2197 }
2198 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
2199 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
2200 ret = OMX_ErrorNone;
2201 } else {
2202 ret = OMX_ErrorNoMore;
2203 }
2204
2205EXIT:
2206 FunctionOut();
2207
2208 return ret;
2209}
2210
2211/* MFC Init */
2212OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
2213{
2214 OMX_ERRORTYPE ret = OMX_ErrorNone;
2215 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2216 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2217 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2218 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2219 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2220 OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2221
2222 ExynosVideoDecOps *pDecOps = NULL;
2223 ExynosVideoDecBufferOps *pInbufOps = NULL;
2224 ExynosVideoDecBufferOps *pOutbufOps = NULL;
2225 ExynosVideoInstInfo *pVideoInstInfo = &(pH264Dec->hMFCH264Handle.videoInstInfo);
2226
2227 CSC_METHOD csc_method = CSC_METHOD_SW;
2228 int i, plane;
2229
2230 FunctionIn();
2231
2232 pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
2233 pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
2234 pExynosComponent->bUseFlagEOF = OMX_TRUE;
2235 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
2236 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2237 pVideoDec->bDiscardCSDError = OMX_FALSE;
2238
2239 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W: %d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
2240 pExynosInputPort->portDefinition.format.video.nFrameWidth,
2241 pExynosInputPort->portDefinition.format.video.nFrameHeight,
2242 pExynosInputPort->portDefinition.format.video.nBitrate,
2243 pExynosInputPort->portDefinition.format.video.xFramerate);
2244 pVideoInstInfo->nSize = sizeof(ExynosVideoInstInfo);
2245 pVideoInstInfo->nWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
2246 pVideoInstInfo->nHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
2247 pVideoInstInfo->nBitrate = pExynosInputPort->portDefinition.format.video.nBitrate;
2248 pVideoInstInfo->xFramerate = pExynosInputPort->portDefinition.format.video.xFramerate;
2249
2250 /* H.264 Codec Open */
2251 ret = H264CodecOpen(pH264Dec, pVideoInstInfo);
2252 if (ret != OMX_ErrorNone) {
2253 goto EXIT;
2254 }
2255
2256 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2257 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
2258 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2259
2260 Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
2261 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2262 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
2263 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
2264 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
2265
2266 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
2267 if (ret != OMX_ErrorNone)
2268 goto EXIT;
2269
2270 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
2271 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
2272 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2273 /*************/
2274 /* TBD */
2275 /*************/
2276 /* Does not require any actions. */
2277 }
2278
2279 Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
2280 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2281 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
2282 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
2283 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2284 /*************/
2285 /* TBD */
2286 /*************/
2287 /* Does not require any actions. */
2288 }
2289
2290 pH264Dec->bSourceStart = OMX_FALSE;
2291 Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent);
2292 pH264Dec->bDestinationStart = OMX_FALSE;
2293 Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationStartEvent);
2294
2295 Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
2296 INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
2297 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
2298 pH264Dec->hMFCH264Handle.indexTimestamp = 0;
2299 pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0;
2300
2301 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
2302
2303 Exynos_OSAL_QueueCreate(&pH264Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
2304
2305#ifdef USE_CSC_HW
2306 csc_method = CSC_METHOD_HW;
2307#endif
2308 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
2309 pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
2310 csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
2311 csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
2312 } else {
2313 pVideoDec->csc_handle = csc_init(csc_method);
2314 }
2315
2316 if (pVideoDec->csc_handle == NULL) {
2317 ret = OMX_ErrorInsufficientResources;
2318 goto EXIT;
2319 }
2320 pVideoDec->csc_set_format = OMX_FALSE;
2321
2322EXIT:
2323 FunctionOut();
2324
2325 return ret;
2326}
2327
2328/* MFC Terminate */
2329OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
2330{
2331 OMX_ERRORTYPE ret = OMX_ErrorNone;
2332 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2333 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2334 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2335 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2336 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2337 OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2338
2339 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2340 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
2341 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2342
2343 int i, plane;
2344
2345 FunctionIn();
2346
2347 if (pVideoDec->csc_handle != NULL) {
2348 csc_deinit(pVideoDec->csc_handle);
2349 pVideoDec->csc_handle = NULL;
2350 }
2351
2352 Exynos_OSAL_QueueTerminate(&pH264Dec->bypassBufferInfoQ);
2353
2354 Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
2355 pH264Dec->hDestinationStartEvent = NULL;
2356 pH264Dec->bDestinationStart = OMX_FALSE;
2357 Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent);
2358 pH264Dec->hSourceStartEvent = NULL;
2359 pH264Dec->bSourceStart = OMX_FALSE;
2360
2361 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2362 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
2363 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
2364 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
2365 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2366 /*************/
2367 /* TBD */
2368 /*************/
2369 /* Does not require any actions. */
2370 }
2371
2372 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2373 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
2374 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
2375 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
2376 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2377 /*************/
2378 /* TBD */
2379 /*************/
2380 /* Does not require any actions. */
2381 }
2382 H264CodecClose(pH264Dec);
2383
2384 Exynos_ResetAllPortConfig(pOMXComponent);
2385
2386EXIT:
2387 FunctionOut();
2388
2389 return ret;
2390}
2391
2392OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2393{
2394 OMX_ERRORTYPE ret = OMX_ErrorNone;
2395 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2396 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2397 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2398 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2399 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2400 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2401 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
2402
2403 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2404 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
2405 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2406 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2407
2408 OMX_BUFFERHEADERTYPE tempBufferHeader;
2409 void *pPrivate = NULL;
2410
2411 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
2412 unsigned int nDataLen[MAX_BUFFER_PLANE] = {oneFrameSize, 0, 0};
2413
2414 OMX_BOOL bInStartCode = OMX_FALSE;
2415 int i;
2416
2417 FunctionIn();
2418
2419 if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
2420 ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
2421 goto EXIT;
2422 }
2423
2424 if ((pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) &&
2425 (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
2426 ret = H264CodecDstSetup(pOMXComponent);
2427 if (ret != OMX_ErrorNone) {
2428 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
2429 goto EXIT;
2430 }
2431 }
2432
2433 if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
2434 ((bInStartCode = Check_H264_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[0], oneFrameSize)) == OMX_TRUE)) ||
2435 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2436
2437 if (pVideoDec->bReorderMode == OMX_FALSE) {
2438 /* next slot will be used like as circular queue */
2439 pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
2440 pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
2441 } else { /* MSRND */
2442 Exynos_SetReorderTimestamp(pExynosComponent, &(pH264Dec->hMFCH264Handle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
2443 }
2444
2445 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
2446 pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Dec->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
2447
2448 pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
2449 pH264Dec->hMFCH264Handle.indexTimestamp++;
2450 pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
2451
2452 if ((pVideoDec->bQosChanged == OMX_TRUE) &&
2453 (pDecOps->Set_QosRatio != NULL)) {
2454 pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
2455 pVideoDec->bQosChanged = OMX_FALSE;
2456 }
2457
2458#ifdef PERFORMANCE_DEBUG
2459 Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
2460#endif
2461
2462 /* queue work for input buffer */
2463 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
2464
2465 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
2466 nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
2467 else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
2468 nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
2469
2470 if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
2471 tempBufferHeader.nFlags = pSrcInputData->nFlags;
2472 tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
2473 pPrivate = (void *)&tempBufferHeader;
2474 } else {
2475 pPrivate = (void *)pSrcInputData->bufferHeader;
2476 }
2477 codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
2478 (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
2479 (int *)pSrcInputData->multiPlaneBuffer.fd,
2480 nAllocLen,
2481 nDataLen,
2482 Exynos_GetPlaneFromPort(pExynosInputPort),
2483 pPrivate);
2484 if (codecReturn != VIDEO_ERROR_NONE) {
2485 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2486 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2487 goto EXIT;
2488 }
2489 H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
2490 if (pH264Dec->bSourceStart == OMX_FALSE) {
2491 pH264Dec->bSourceStart = OMX_TRUE;
2492 Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
2493 Exynos_OSAL_SleepMillisec(0);
2494 }
2495 if (pH264Dec->bDestinationStart == OMX_FALSE) {
2496 pH264Dec->bDestinationStart = OMX_TRUE;
2497 Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
2498 Exynos_OSAL_SleepMillisec(0);
2499 }
2500 } else if (bInStartCode == OMX_FALSE) {
2501 ret = OMX_ErrorCorruptedFrame;
2502 goto EXIT;
2503 }
2504
2505 ret = OMX_ErrorNone;
2506
2507EXIT:
2508 FunctionOut();
2509
2510 return ret;
2511}
2512
2513OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2514{
2515 OMX_ERRORTYPE ret = OMX_ErrorNone;
2516 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2517 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2518 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2519 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2520 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2521 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2522 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
2523 ExynosVideoBuffer *pVideoBuffer;
2524 ExynosVideoBuffer videoBuffer;
2525
2526 FunctionIn();
2527
2528 if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
2529 pVideoBuffer = &videoBuffer;
2530 else
2531 pVideoBuffer = NULL;
2532
2533 pSrcOutputData->dataLen = 0;
2534 pSrcOutputData->usedDataLen = 0;
2535 pSrcOutputData->remainDataLen = 0;
2536 pSrcOutputData->nFlags = 0;
2537 pSrcOutputData->timeStamp = 0;
2538 pSrcOutputData->bufferHeader = NULL;
2539
2540 if (pVideoBuffer == NULL) {
2541 pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = NULL;
2542 pSrcOutputData->allocSize = 0;
2543 pSrcOutputData->pPrivate = NULL;
2544 } else {
2545 pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
2546 pSrcOutputData->multiPlaneBuffer.fd[0] = pVideoBuffer->planes[0].fd;
2547 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
2548
2549 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2550 int i;
2551 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
2552 if (pSrcOutputData->multiPlaneBuffer.dataBuffer[0] ==
2553 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
2554 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
2555 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
2556 break;
2557 }
2558 }
2559
2560 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2561 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2562 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2563 goto EXIT;
2564 }
2565 }
2566
2567 /* For Share Buffer */
2568 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
2569 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2570
2571#ifdef PERFORMANCE_DEBUG
2572 Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
2573#endif
2574 }
2575
2576 ret = OMX_ErrorNone;
2577
2578EXIT:
2579 FunctionOut();
2580
2581 return ret;
2582}
2583
2584OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2585{
2586 OMX_ERRORTYPE ret = OMX_ErrorNone;
2587 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2588 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2589 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2590 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2591 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2592
2593 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2594 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2595 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2596
2597 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
2598 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
2599 int i, nPlaneCnt;
2600
2601 FunctionIn();
2602
2603 if (pDstInputData->multiPlaneBuffer.dataBuffer[0] == NULL) {
2604 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2605 ret = OMX_ErrorBadParameter;
2606 goto EXIT;
2607 }
2608
2609 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
2610 for (i = 0; i < nPlaneCnt; i++) {
2611 nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i];
2612
2613 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
2614 pDstInputData->multiPlaneBuffer.dataBuffer[i]);
2615 }
2616
2617 if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
2618 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2619 (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
2620 ret = H264CodecDstSetup(pOMXComponent);
2621 if (ret != OMX_ErrorNone) {
2622 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
2623 goto EXIT;
2624 }
2625 pVideoDec->bReconfigDPB = OMX_FALSE;
2626 }
2627
2628#ifdef PERFORMANCE_DEBUG
2629 Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
2630#endif
2631
2632 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
2633 codecReturn = pOutbufOps->Enqueue(hMFCHandle,
2634 (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
2635 nDataLen,
2636 nPlaneCnt,
2637 pDstInputData->bufferHeader);
2638 } else {
2639 codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
2640 (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
2641 (int *)pDstInputData->multiPlaneBuffer.fd,
2642 nAllocLen,
2643 nDataLen,
2644 nPlaneCnt,
2645 pDstInputData->bufferHeader);
2646 }
2647
2648 if (codecReturn != VIDEO_ERROR_NONE) {
2649 if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
2650 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2651 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2652 }
2653 goto EXIT;
2654 }
2655 H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2656
2657 ret = OMX_ErrorNone;
2658
2659EXIT:
2660 FunctionOut();
2661
2662 return ret;
2663}
2664
2665OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2666{
2667 OMX_ERRORTYPE ret = OMX_ErrorNone;
2668 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2669 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2670 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2671 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2672 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2673 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2674 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
2675
2676 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
2677 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2678 ExynosVideoBuffer *pVideoBuffer = NULL;
2679 ExynosVideoBuffer videoBuffer;
2680 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2681 ExynosVideoGeometry *bufferGeometry = NULL;
2682 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2683
2684 OMX_S32 indexTimestamp = 0;
2685 int plane, nPlaneCnt;
2686
2687 FunctionIn();
2688
2689 if (pH264Dec->bDestinationStart == OMX_FALSE) {
2690 ret = OMX_ErrorNone;
2691 goto EXIT;
2692 }
2693
2694 while (1) {
2695 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
2696 pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2697 if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2698 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2699 ret = OMX_ErrorHardware;
2700 goto EXIT;
2701 }
2702
2703 if (pVideoBuffer == NULL) {
2704 ret = OMX_ErrorNone;
2705 goto EXIT;
2706 }
2707 } else {
2708 Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
2709
2710 codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
2711 if (codecReturn == VIDEO_ERROR_NONE) {
2712 pVideoBuffer = &videoBuffer;
2713 } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
2714 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2715 pVideoBuffer = NULL;
2716 ret = OMX_ErrorHardware;
2717 goto EXIT;
2718 } else {
2719 pVideoBuffer = NULL;
2720 ret = OMX_ErrorNone;
2721 goto EXIT;
2722 }
2723 }
2724
2725 displayStatus = pVideoBuffer->displayStatus;
2726 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
2727
2728 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2729 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2730 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2731 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2732 (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) ||
2733 (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
2734 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2735 ret = OMX_ErrorNone;
2736 break;
2737 }
2738 }
2739
2740#ifdef USE_S3D_SUPPORT
2741 /* Check Whether frame packing information is available */
2742 if ((pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_INVALID) &&
2743 (pVideoDec->bThumbnailMode == OMX_FALSE) &&
2744 ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2745 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2746 (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
2747 if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) {
2748 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2749 goto EXIT;
2750 }
2751 }
2752#endif
2753
2754 if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
2755 ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2756 (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
2757 if (pVideoDec->bReconfigDPB != OMX_TRUE) {
2758 pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2759 pVideoDec->bReconfigDPB = OMX_TRUE;
2760 H264CodecUpdateResolution(pOMXComponent);
2761 pVideoDec->csc_set_format = OMX_FALSE;
2762#ifdef USE_S3D_SUPPORT
2763 pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
2764#endif
2765 }
2766 ret = OMX_ErrorNone;
2767 goto EXIT;
2768 }
2769
2770 pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
2771 pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2772
2773 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2774 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
2775
2776 for (plane = 0; plane < nPlaneCnt; plane++) {
2777 pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2778 pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2779 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2780 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
2781 }
2782 pDstOutputData->usedDataLen = 0;
2783 pDstOutputData->pPrivate = pVideoBuffer;
2784 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2785 int i = 0;
2786 pDstOutputData->pPrivate = NULL;
2787 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
2788 if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
2789 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
2790 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
2791 break;
2792 }
2793 }
2794
2795 if (pDstOutputData->pPrivate == NULL) {
2796 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2797 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2798 goto EXIT;
2799 }
2800 }
2801
2802 /* For Share Buffer */
2803 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2804
2805 /* get interlace frame info */
2806 if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2807 (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
2808 (pVideoBuffer->planes[2].addr != NULL)) {
2809 /* only NV12 case */
2810 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
2811 *(int *)(pVideoBuffer->planes[2].addr) = pVideoBuffer->interlacedType;
2812 }
2813
2814 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2815 bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf;
2816 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2817 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2818 pBufferInfo->imageStride = bufferGeometry->nStride;
2819 pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
2820 Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
2821
2822 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2823 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
2824
2825 if (pVideoDec->bReorderMode == OMX_FALSE) {
2826 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2827 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2828 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2829 if (indexTimestamp == INDEX_AFTER_EOS) {
2830 pDstOutputData->timeStamp = 0x00;
2831 pDstOutputData->nFlags = 0x00;
2832 } else {
2833 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2834 pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2835 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
2836 }
2837 } else {
2838 pDstOutputData->timeStamp = 0x00;
2839 pDstOutputData->nFlags = 0x00;
2840 }
2841 } else {
2842 /* For timestamp correction. if mfc support frametype detect */
2843 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
2844
2845 /* NEED TIMESTAMP REORDER */
2846 if (pVideoDec->bDTSMode == OMX_TRUE) {
2847 if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
2848 ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
2849 ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
2850 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
2851 pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
2852 else
2853 indexTimestamp = pH264Dec->hMFCH264Handle.outputIndexTimestamp;
2854 }
2855
2856 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2857 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
2858
2859 if (pVideoBuffer->frameType & VIDEO_FRAME_I)
2860 pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2861
2862 if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
2863 pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
2864
2865 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
2866 pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2867 }
2868 } else { /* MSRND */
2869 EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP sCurrentTimestamp;
2870
2871 Exynos_GetReorderTimestamp(pExynosComponent, &sCurrentTimestamp, indexTimestamp, pVideoBuffer->frameType);
2872
2873 pDstOutputData->timeStamp = sCurrentTimestamp.timeStamp;
2874 pDstOutputData->nFlags = sCurrentTimestamp.nFlags | OMX_BUFFERFLAG_ENDOFFRAME;
2875
2876 pExynosComponent->nFlags[sCurrentTimestamp.nIndex] = 0x00;
2877 pExynosComponent->bTimestampSlotUsed[sCurrentTimestamp.nIndex] = OMX_FALSE;
2878
2879 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output reorder timestamp %lld us (%.2f secs), sCurrentTimestamp.nIndex: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
2880 pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, sCurrentTimestamp.nIndex, pDstOutputData->nFlags);
2881 }
2882
2883#ifdef PERFORMANCE_DEBUG
2884 if (pDstOutputData->bufferHeader != NULL) {
2885 pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
2886 Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
2887 }
2888#endif
2889
2890 if (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
2891 if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
2892 (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
2893 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2894 }
2895
2896 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
2897 if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
2898 pDstOutputData->remainDataLen = 0;
2899
2900 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2901 if (indexTimestamp != INDEX_AFTER_EOS)
2902 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] indexTimestamp(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
2903
2904 pDstOutputData->timeStamp = 0x00;
2905 pDstOutputData->nFlags = 0x00;
2906 goto EXIT;
2907 }
2908
2909 if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
2910 (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
2911 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2912 pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
2913 }
2914 } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
2915 pDstOutputData->remainDataLen = 0;
2916
2917 if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
2918 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2919 if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
2920 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2921 } else {
2922 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
2923 pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
2924 }
2925 }
2926 } else {
2927 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2928 }
2929 } else {
2930 if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2931 (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
2932 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2933 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
2934 pDstOutputData->remainDataLen = 0;
2935
2936 if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
2937 (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
2938 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2939
2940 if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
2941 pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
2942 } else {
2943 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2944 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2945 }
2946 }
2947 } else {
2948 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2949 }
2950 }
2951
2952 ret = OMX_ErrorNone;
2953
2954EXIT:
2955 FunctionOut();
2956
2957 return ret;
2958}
2959
2960OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2961{
2962 OMX_ERRORTYPE ret = OMX_ErrorNone;
2963 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2964 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2965 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2966
2967 FunctionIn();
2968
2969 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2970 ret = OMX_ErrorNone;
2971 goto EXIT;
2972 }
2973 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2974 ret = OMX_ErrorNone;
2975 goto EXIT;
2976 }
2977
2978 ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
2979 if ((ret != OMX_ErrorNone) &&
2980 ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
2981 ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
2982
2983 if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
2984 (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
2985 goto EXIT;
2986 }
2987
2988 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2989 pExynosComponent->callbackData,
2990 OMX_EventError, ret, 0, NULL);
2991 }
2992
2993EXIT:
2994 FunctionOut();
2995
2996 return ret;
2997}
2998
2999OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
3000{
3001 OMX_ERRORTYPE ret = OMX_ErrorNone;
3002 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
3003 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
3004 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
3005 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
3006
3007 FunctionIn();
3008
3009 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
3010 ret = OMX_ErrorNone;
3011 goto EXIT;
3012 }
3013
3014 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
3015 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
3016 ret = OMX_ErrorNone;
3017 goto EXIT;
3018 }
3019 }
3020 if ((pH264Dec->bSourceStart == OMX_FALSE) &&
3021 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
3022 Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
3023 if (pVideoDec->bExitBufferProcessThread)
3024 goto EXIT;
3025
3026 Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent);
3027 }
3028
3029 ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
3030 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
3031 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
3032 pExynosComponent->callbackData,
3033 OMX_EventError, ret, 0, NULL);
3034 }
3035
3036EXIT:
3037 FunctionOut();
3038
3039 return ret;
3040}
3041
3042OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
3043{
3044 OMX_ERRORTYPE ret = OMX_ErrorNone;
3045 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
3046 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
3047 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
3048 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
3049
3050 FunctionIn();
3051
3052 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
3053 ret = OMX_ErrorNone;
3054 goto EXIT;
3055 }
3056 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
3057 if (pExynosComponent->currentState == OMX_StatePause)
3058 ret = OMX_ErrorOutputBufferUseYet;
3059 else
3060 ret = OMX_ErrorNone;
3061 goto EXIT;
3062 }
3063 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
3064 if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
3065 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
3066 Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
3067 if (pVideoDec->bExitBufferProcessThread)
3068 goto EXIT;
3069
3070 Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
3071 }
3072 if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
3073 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
3074 if (pBufferInfo == NULL) {
3075 ret = OMX_ErrorUndefined;
3076 goto EXIT;
3077 }
3078
3079 pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags;
3080 pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
3081 Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
3082 Exynos_OSAL_Free(pBufferInfo);
3083
3084 ret = OMX_ErrorNone;
3085 goto EXIT;
3086 }
3087 }
3088 if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
3089 ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
3090 if (ret != OMX_ErrorNone) {
3091 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
3092 pExynosComponent->callbackData,
3093 OMX_EventError, ret, 0, NULL);
3094 }
3095 }
3096
3097EXIT:
3098 FunctionOut();
3099
3100 return ret;
3101}
3102
3103OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
3104{
3105 OMX_ERRORTYPE ret = OMX_ErrorNone;
3106 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
3107 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
3108 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
3109 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
3110
3111 FunctionIn();
3112
3113 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
3114 ret = OMX_ErrorNone;
3115 goto EXIT;
3116 }
3117 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
3118 ret = OMX_ErrorNone;
3119 goto EXIT;
3120 }
3121
3122 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
3123 if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
3124 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
3125 Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
3126 if (pVideoDec->bExitBufferProcessThread)
3127 goto EXIT;
3128
3129 Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
3130 }
3131
3132 if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
3133 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
3134 OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
3135 BYPASS_BUFFER_INFO *pBufferInfo = NULL;
3136
3137 if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
3138 pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
3139 if (pOMXBuffer == NULL) {
3140 ret = OMX_ErrorUndefined;
3141 goto EXIT;
3142 }
3143 } else {
3144 pOMXBuffer = dstOutputUseBuffer->bufferHeader;
3145 }
3146
3147 pBufferInfo = Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
3148 if (pBufferInfo == NULL) {
3149 ret = OMX_ErrorUndefined;
3150 goto EXIT;
3151 }
3152
3153 pOMXBuffer->nFlags = pBufferInfo->nFlags;
3154 pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp;
3155 Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
3156 Exynos_OSAL_Free(pBufferInfo);
3157
3158 dstOutputUseBuffer->dataValid = OMX_FALSE;
3159
3160 ret = OMX_ErrorNone;
3161 goto EXIT;
3162 }
3163 }
3164 ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
3165 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
3166 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
3167 pExynosComponent->callbackData,
3168 OMX_EventError, ret, 0, NULL);
3169 }
3170
3171EXIT:
3172 FunctionOut();
3173
3174 return ret;
3175}
3176
3177OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
3178{
3179 OMX_ERRORTYPE ret = OMX_ErrorNone;
3180 OMX_COMPONENTTYPE *pOMXComponent = NULL;
3181 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
3182 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
3183 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
3184 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
3185 OMX_BOOL bSecureMode = OMX_FALSE;
3186 int i = 0;
3187
3188 Exynos_OSAL_Get_Log_Property(); // For debuging
3189 FunctionIn();
3190
3191 if ((hComponent == NULL) || (componentName == NULL)) {
3192 ret = OMX_ErrorBadParameter;
3193 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
3194 goto EXIT;
3195 }
3196 if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) ||
3197 (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_CUSTOM_DEC, componentName) == 0)) {
3198 bSecureMode = OMX_FALSE;
3199 } else if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) ||
3200 (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_CUSTOM_DRM_DEC, componentName) == 0)) {
3201 bSecureMode = OMX_TRUE;
3202 } else {
3203 ret = OMX_ErrorBadParameter;
3204 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
3205 goto EXIT;
3206 }
3207
3208 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
3209 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
3210 if (ret != OMX_ErrorNone) {
3211 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
3212 goto EXIT;
3213 }
3214 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
3215 pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_DEC_SECURE_CODEC:HW_VIDEO_DEC_CODEC;
3216
3217 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
3218 if (pExynosComponent->componentName == NULL) {
3219 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
3220 ret = OMX_ErrorInsufficientResources;
3221 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
3222 goto EXIT;
3223 }
3224 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
3225
3226 pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE));
3227 if (pH264Dec == NULL) {
3228 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
3229 ret = OMX_ErrorInsufficientResources;
3230 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
3231 goto EXIT;
3232 }
3233 Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE));
3234 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
3235 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec;
3236 Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
3237#ifdef USE_S3D_SUPPORT
3238 pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
3239#endif
3240 pH264Dec->hMFCH264Handle.nDisplayDelay = MAX_H264_DISPLAYDELAY_VALIDNUM + 1;
3241
3242 /* Set componentVersion */
3243 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
3244 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
3245 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
3246 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
3247 /* Set specVersion */
3248 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
3249 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
3250 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
3251 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
3252
3253 /* Input port */
3254 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
3255 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
3256 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
3257 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
3258 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
3259 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
3260 if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
3261 pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
3262
3263 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
3264 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
3265 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
3266 pExynosPort->portDefinition.format.video.pNativeRender = 0;
3267 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
3268 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
3269 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
3270 pExynosPort->bufferProcessType = BUFFER_SHARE;
3271 pExynosPort->portWayType = WAY2_PORT;
3272 pExynosPort->ePlaneType = PLANE_SINGLE;
3273
3274 /* Output port */
3275 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
3276 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
3277 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
3278 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
3279 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
3280 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
3281 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
3282 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
3283 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
3284 pExynosPort->portDefinition.format.video.pNativeRender = 0;
3285 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
3286 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
3287 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
3288 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
3289 pExynosPort->portWayType = WAY2_PORT;
3290 pExynosPort->ePlaneType = PLANE_MULTIPLE;
3291
3292#ifdef USE_SINGLE_PLANE_IN_DRM
3293 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
3294 pExynosPort->ePlaneType = PLANE_SINGLE;
3295#endif
3296
3297 for(i = 0; i < ALL_PORT_NUM; i++) {
3298 INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
3299 pH264Dec->AVCComponent[i].nPortIndex = i;
3300 pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline;
3301 pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4;
3302 }
3303
3304 pOMXComponent->GetParameter = &Exynos_H264Dec_GetParameter;
3305 pOMXComponent->SetParameter = &Exynos_H264Dec_SetParameter;
3306 pOMXComponent->GetConfig = &Exynos_H264Dec_GetConfig;
3307 pOMXComponent->SetConfig = &Exynos_H264Dec_SetConfig;
3308 pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex;
3309 pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum;
3310 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
3311
3312 pExynosComponent->exynos_codec_componentInit = &Exynos_H264Dec_Init;
3313 pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate;
3314
3315 pVideoDec->exynos_codec_srcInputProcess = &Exynos_H264Dec_srcInputBufferProcess;
3316 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess;
3317 pVideoDec->exynos_codec_dstInputProcess = &Exynos_H264Dec_dstInputBufferProcess;
3318 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess;
3319
3320 pVideoDec->exynos_codec_start = &H264CodecStart;
3321 pVideoDec->exynos_codec_stop = &H264CodecStop;
3322 pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
3323 pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
3324
3325#if 0 /* unused code */
3326 pVideoDec->exynos_checkInputFrame = &Check_H264_Frame;
3327 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
3328#endif
3329
3330 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
3331 pVideoDec->exynos_codec_reconfigAllBuffers = &H264CodecReconfigAllBuffers;
3332
3333 pVideoDec->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
3334 pVideoDec->exynos_codec_checkResolutionChange = &H264CodecCheckResolution;
3335
3336 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
3337 if (pVideoDec->hSharedMemory == NULL) {
3338 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
3339 Exynos_OSAL_Free(pH264Dec);
3340 pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
3341 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
3342 ret = OMX_ErrorInsufficientResources;
3343 goto EXIT;
3344 }
3345
3346 pH264Dec->hMFCH264Handle.videoInstInfo.eCodecType = VIDEO_CODING_AVC;
3347 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
3348 pH264Dec->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
3349 else
3350 pH264Dec->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
3351
3352 if (Exynos_Video_GetInstInfo(&(pH264Dec->hMFCH264Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
3353 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
3354 Exynos_OSAL_Free(pH264Dec);
3355 pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
3356 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
3357 ret = OMX_ErrorInsufficientResources;
3358 goto EXIT;
3359 }
3360
3361 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
3362 (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
3363 (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
3364 (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
3365 (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
3366
3367 if (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
3368 pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
3369
3370 Exynos_Output_SetSupportFormat(pExynosComponent);
3371 SetProfileLevel(pExynosComponent);
3372
3373 pExynosComponent->currentState = OMX_StateLoaded;
3374
3375 ret = OMX_ErrorNone;
3376
3377EXIT:
3378 FunctionOut();
3379
3380 return ret;
3381}
3382
3383OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
3384{
3385 OMX_ERRORTYPE ret = OMX_ErrorNone;
3386 OMX_COMPONENTTYPE *pOMXComponent = NULL;
3387 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
3388 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
3389 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
3390
3391 FunctionIn();
3392
3393 if (hComponent == NULL) {
3394 ret = OMX_ErrorBadParameter;
3395 goto EXIT;
3396 }
3397 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
3398 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
3399 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
3400
3401 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
3402
3403 Exynos_OSAL_Free(pExynosComponent->componentName);
3404 pExynosComponent->componentName = NULL;
3405
3406 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
3407 if (pH264Dec != NULL) {
3408 Exynos_OSAL_Free(pH264Dec);
3409 pH264Dec = pVideoDec->hCodecHandle = NULL;
3410 }
3411
3412 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
3413 if (ret != OMX_ErrorNone) {
3414 goto EXIT;
3415 }
3416
3417 ret = OMX_ErrorNone;
3418
3419EXIT:
3420 FunctionOut();
3421
3422 return ret;
3423}