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