4afc1dec1e48b022edd07d744d2b79a9c2723d9c
[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 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1661
1662 /* H.264 Codec Open */
1663 ret = H264CodecOpen(pH264Dec);
1664 if (ret != OMX_ErrorNone) {
1665 goto EXIT;
1666 }
1667
1668 pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1669 pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1670 pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1671
1672 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1673 OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE};
1674 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1675 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1676
1677 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
1678 if (ret != OMX_ErrorNone)
1679 goto EXIT;
1680
1681 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
1682 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1683 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1684 /*************/
1685 /* TBD */
1686 /*************/
1687 /* Does not require any actions. */
1688 }
1689
1690 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1691 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1692 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1693 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1694 /*************/
1695 /* TBD */
1696 /*************/
1697 /* Does not require any actions. */
1698 }
1699
1700 pH264Dec->bSourceStart = OMX_FALSE;
1701 Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent);
1702 pH264Dec->bDestinationStart = OMX_FALSE;
1703 Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationStartEvent);
1704
1705 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1706 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1707 pH264Dec->hMFCH264Handle.indexTimestamp = 0;
1708 pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0;
1709
1710 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1711
1712 #ifdef USE_CSC_HW
1713 csc_method = CSC_METHOD_HW;
1714 #endif
1715 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
1716 pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
1717 csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
1718 csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode);
1719 } else {
1720 pVideoDec->csc_handle = csc_init(csc_method);
1721 }
1722
1723 if (pVideoDec->csc_handle == NULL) {
1724 ret = OMX_ErrorInsufficientResources;
1725 goto EXIT;
1726 }
1727 pVideoDec->csc_set_format = OMX_FALSE;
1728
1729 EXIT:
1730 FunctionOut();
1731
1732 return ret;
1733 }
1734
1735 /* MFC Terminate */
1736 OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1737 {
1738 OMX_ERRORTYPE ret = OMX_ErrorNone;
1739 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1740 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1741 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1742 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1743 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1744 OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1745
1746 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1747 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1748 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1749
1750 int i, plane;
1751
1752 FunctionIn();
1753
1754 if (pVideoDec->csc_handle != NULL) {
1755 csc_deinit(pVideoDec->csc_handle);
1756 pVideoDec->csc_handle = NULL;
1757 }
1758
1759 Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
1760 pH264Dec->hDestinationStartEvent = NULL;
1761 pH264Dec->bDestinationStart = OMX_FALSE;
1762 Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent);
1763 pH264Dec->hSourceStartEvent = NULL;
1764 pH264Dec->bSourceStart = OMX_FALSE;
1765
1766 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1767 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
1768 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1769 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1770 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1771 /*************/
1772 /* TBD */
1773 /*************/
1774 /* Does not require any actions. */
1775 }
1776
1777 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1778 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
1779 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1780 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1781 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1782 /*************/
1783 /* TBD */
1784 /*************/
1785 /* Does not require any actions. */
1786 }
1787 H264CodecClose(pH264Dec);
1788
1789 Exynos_ResetAllPortConfig(pOMXComponent);
1790
1791 EXIT:
1792 FunctionOut();
1793
1794 return ret;
1795 }
1796
1797 OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1798 {
1799 OMX_ERRORTYPE ret = OMX_ErrorNone;
1800 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1801 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1802 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1803 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1804 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1805 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1806 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1807 OMX_BOOL bInStartCode = OMX_FALSE;
1808 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1809 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1810 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1811 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1812 int i;
1813
1814 FunctionIn();
1815
1816 if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1817 ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1818 goto EXIT;
1819 }
1820 if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1821 ret = H264CodecDstSetup(pOMXComponent);
1822 }
1823
1824 if (((pVideoDec->bDRMPlayerMode == OMX_TRUE) ||
1825 ((bInStartCode = Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE)) ||
1826 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1827 pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1828 pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1829 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);
1830 pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
1831 pH264Dec->hMFCH264Handle.indexTimestamp++;
1832 pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1833
1834 /* queue work for input buffer */
1835 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1836 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1837 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1838 if (codecReturn != VIDEO_ERROR_NONE) {
1839 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1840 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1841 goto EXIT;
1842 }
1843 H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1844 if (pH264Dec->bSourceStart == OMX_FALSE) {
1845 pH264Dec->bSourceStart = OMX_TRUE;
1846 Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
1847 Exynos_OSAL_SleepMillisec(0);
1848 }
1849 if (pH264Dec->bDestinationStart == OMX_FALSE) {
1850 pH264Dec->bDestinationStart = OMX_TRUE;
1851 Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
1852 Exynos_OSAL_SleepMillisec(0);
1853 }
1854 } else if (bInStartCode == OMX_FALSE) {
1855 ret = OMX_ErrorCorruptedFrame;
1856 goto EXIT;
1857 }
1858
1859 ret = OMX_ErrorNone;
1860
1861 EXIT:
1862 FunctionOut();
1863
1864 return ret;
1865 }
1866
1867 OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1868 {
1869 OMX_ERRORTYPE ret = OMX_ErrorNone;
1870 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1871 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1872 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1873 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1874 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1875 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1876 ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
1877 ExynosVideoBuffer *pVideoBuffer;
1878
1879 FunctionIn();
1880
1881 pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1882
1883 pSrcOutputData->dataLen = 0;
1884 pSrcOutputData->usedDataLen = 0;
1885 pSrcOutputData->remainDataLen = 0;
1886 pSrcOutputData->nFlags = 0;
1887 pSrcOutputData->timeStamp = 0;
1888
1889 if (pVideoBuffer == NULL) {
1890 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1891 pSrcOutputData->allocSize = 0;
1892 pSrcOutputData->pPrivate = NULL;
1893 pSrcOutputData->bufferHeader = NULL;
1894 } else {
1895 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1896 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1897 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1898
1899 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1900 int i;
1901 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1902 if (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer ==
1903 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1904 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1905 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1906 break;
1907 }
1908 }
1909
1910 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1911 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1912 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1913 goto EXIT;
1914 }
1915 }
1916
1917 /* For Share Buffer */
1918 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1919 }
1920
1921 ret = OMX_ErrorNone;
1922
1923 EXIT:
1924 FunctionOut();
1925
1926 return ret;
1927 }
1928
1929 OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1930 {
1931 OMX_ERRORTYPE ret = OMX_ErrorNone;
1932 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1933 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1934 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1935 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1936 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1937 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1938 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1939 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
1940 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1941
1942 FunctionIn();
1943
1944 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1945 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1946 ret = OMX_ErrorBadParameter;
1947 goto EXIT;
1948 }
1949
1950 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
1951 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
1952 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
1953
1954 if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
1955 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
1956 (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
1957 ret = H264CodecDstSetup(pOMXComponent);
1958 if (ret != OMX_ErrorNone)
1959 goto EXIT;
1960 pVideoDec->bReconfigDPB = OMX_FALSE;
1961 }
1962
1963 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1964 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
1965
1966 if (codecReturn != VIDEO_ERROR_NONE) {
1967 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1968 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1969 goto EXIT;
1970 }
1971 H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1972
1973 ret = OMX_ErrorNone;
1974
1975 EXIT:
1976 FunctionOut();
1977
1978 return ret;
1979 }
1980
1981 OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1982 {
1983 OMX_ERRORTYPE ret = OMX_ErrorNone;
1984 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1985 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1986 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1987 void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1988 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1989 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1990 ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
1991 ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1992 ExynosVideoBuffer *pVideoBuffer = NULL;
1993 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1994 ExynosVideoGeometry *bufferGeometry;
1995 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1996 OMX_S32 indexTimestamp = 0;
1997 int plane;
1998
1999 FunctionIn();
2000
2001 if (pH264Dec->bDestinationStart == OMX_FALSE) {
2002 ret = OMX_ErrorNone;
2003 goto EXIT;
2004 }
2005
2006 while (1) {
2007 pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2008 if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2009 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2010 ret = OMX_ErrorHardware;
2011 goto EXIT;
2012 }
2013
2014 if (pVideoBuffer == NULL) {
2015 ret = OMX_ErrorNone;
2016 goto EXIT;
2017 }
2018 displayStatus = pVideoBuffer->displayStatus;
2019 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
2020
2021 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2022 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2023 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2024 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2025 (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) ||
2026 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2027 ret = OMX_ErrorNone;
2028 break;
2029 }
2030 }
2031
2032 if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
2033 ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2034 (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
2035 if (pVideoDec->bReconfigDPB != OMX_TRUE) {
2036 pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2037 pVideoDec->bReconfigDPB = OMX_TRUE;
2038 #ifdef USE_S3D_SUPPORT
2039 /* Check Whether frame packing information is available */
2040 if ((displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) &&
2041 (pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_NONE)) {
2042 if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) {
2043 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2044 goto EXIT;
2045 }
2046 }
2047 #endif
2048 H264CodecCheckResolutionChange(pOMXComponent);
2049 pVideoDec->csc_set_format = OMX_FALSE;
2050 }
2051 ret = OMX_ErrorNone;
2052 goto EXIT;
2053 }
2054
2055 pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
2056 pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2057
2058 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2059 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
2060 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2061 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2062 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2063 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
2064 }
2065 pDstOutputData->usedDataLen = 0;
2066 pDstOutputData->pPrivate = pVideoBuffer;
2067 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2068 int i = 0;
2069 pDstOutputData->pPrivate = NULL;
2070 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
2071 if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] ==
2072 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
2073 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
2074 break;
2075 }
2076 }
2077
2078 if (pDstOutputData->pPrivate == NULL) {
2079 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2080 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2081 goto EXIT;
2082 }
2083 }
2084
2085 /* For Share Buffer */
2086 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2087
2088 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2089 bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf;
2090 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2091 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2092 switch (bufferGeometry->eColorFormat) {
2093 case VIDEO_COLORFORMAT_NV12:
2094 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2095 break;
2096 case VIDEO_COLORFORMAT_NV12_TILED:
2097 default:
2098 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
2099 break;
2100 }
2101
2102 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2103 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
2104 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2105 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2106 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2107 if (indexTimestamp == INDEX_AFTER_EOS) {
2108 pDstOutputData->timeStamp = 0x00;
2109 pDstOutputData->nFlags = 0x00;
2110 } else {
2111 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2112 pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2113 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2114 }
2115 } else {
2116 pDstOutputData->timeStamp = 0x00;
2117 pDstOutputData->nFlags = 0x00;
2118 }
2119 } else {
2120 /* For timestamp correction. if mfc support frametype detect */
2121 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
2122
2123 /* NEED TIMESTAMP REORDER */
2124 if (pVideoDec->bDTSMode == OMX_TRUE) {
2125 if (pVideoBuffer->frameType == VIDEO_FRAME_I)
2126 pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
2127 else
2128 indexTimestamp = pH264Dec->hMFCH264Handle.outputIndexTimestamp;
2129 }
2130
2131 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2132 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2133
2134 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2135 }
2136
2137 if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2138 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2139 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2140 pDstOutputData->remainDataLen = 0;
2141
2142 if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
2143 (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
2144 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2145 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2146 }
2147 } else {
2148 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2149 }
2150
2151 ret = OMX_ErrorNone;
2152
2153 EXIT:
2154 FunctionOut();
2155
2156 return ret;
2157 }
2158
2159 OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2160 {
2161 OMX_ERRORTYPE ret = OMX_ErrorNone;
2162 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2163 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2164 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2165
2166 FunctionIn();
2167
2168 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2169 ret = OMX_ErrorNone;
2170 goto EXIT;
2171 }
2172 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2173 ret = OMX_ErrorNone;
2174 goto EXIT;
2175 }
2176
2177 ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
2178 if ((ret != OMX_ErrorNone) &&
2179 (ret != OMX_ErrorInputDataDecodeYet) &&
2180 (ret != OMX_ErrorCorruptedFrame)) {
2181 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2182 pExynosComponent->callbackData,
2183 OMX_EventError, ret, 0, NULL);
2184 }
2185
2186 EXIT:
2187 FunctionOut();
2188
2189 return ret;
2190 }
2191
2192 OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2193 {
2194 OMX_ERRORTYPE ret = OMX_ErrorNone;
2195 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2196 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2197 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2198
2199 FunctionIn();
2200
2201 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2202 ret = OMX_ErrorNone;
2203 goto EXIT;
2204 }
2205
2206 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2207 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2208 ret = OMX_ErrorNone;
2209 goto EXIT;
2210 }
2211 }
2212 if ((pH264Dec->bSourceStart == OMX_FALSE) &&
2213 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2214 Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2215 Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent);
2216 }
2217
2218 ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
2219 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2220 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2221 pExynosComponent->callbackData,
2222 OMX_EventError, ret, 0, NULL);
2223 }
2224
2225 EXIT:
2226 FunctionOut();
2227
2228 return ret;
2229 }
2230
2231 OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2232 {
2233 OMX_ERRORTYPE ret = OMX_ErrorNone;
2234 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2235 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2236 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2237
2238 FunctionIn();
2239
2240 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2241 ret = OMX_ErrorNone;
2242 goto EXIT;
2243 }
2244 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2245 ret = OMX_ErrorNone;
2246 goto EXIT;
2247 }
2248 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2249 if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2250 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2251 Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2252 Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2253 }
2254 }
2255 if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2256 ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
2257 if (ret != OMX_ErrorNone) {
2258 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2259 pExynosComponent->callbackData,
2260 OMX_EventError, ret, 0, NULL);
2261 }
2262 }
2263
2264 EXIT:
2265 FunctionOut();
2266
2267 return ret;
2268 }
2269
2270 OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2271 {
2272 OMX_ERRORTYPE ret = OMX_ErrorNone;
2273 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2274 EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2275 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2276
2277 FunctionIn();
2278
2279 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2280 ret = OMX_ErrorNone;
2281 goto EXIT;
2282 }
2283 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2284 ret = OMX_ErrorNone;
2285 goto EXIT;
2286 }
2287
2288 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2289 if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2290 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2291 Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2292 Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2293 }
2294 }
2295 ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
2296 if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2297 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2298 pExynosComponent->callbackData,
2299 OMX_EventError, ret, 0, NULL);
2300 }
2301
2302 EXIT:
2303 FunctionOut();
2304
2305 return ret;
2306 }
2307
2308 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2309 {
2310 OMX_ERRORTYPE ret = OMX_ErrorNone;
2311 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2312 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2313 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
2314 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2315 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
2316 OMX_BOOL bDRMPlayerMode = OMX_FALSE;
2317 int i = 0;
2318
2319 FunctionIn();
2320
2321 if ((hComponent == NULL) || (componentName == NULL)) {
2322 ret = OMX_ErrorBadParameter;
2323 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2324 goto EXIT;
2325 }
2326 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) {
2327 bDRMPlayerMode = OMX_FALSE;
2328 } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) {
2329 bDRMPlayerMode = OMX_TRUE;
2330 } else {
2331 ret = OMX_ErrorBadParameter;
2332 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2333 goto EXIT;
2334 }
2335
2336 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2337 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2338 if (ret != OMX_ErrorNone) {
2339 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2340 goto EXIT;
2341 }
2342 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2343 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2344
2345 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2346 if (pExynosComponent->componentName == NULL) {
2347 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2348 ret = OMX_ErrorInsufficientResources;
2349 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2350 goto EXIT;
2351 }
2352 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2353
2354 pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE));
2355 if (pH264Dec == NULL) {
2356 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2357 ret = OMX_ErrorInsufficientResources;
2358 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2359 goto EXIT;
2360 }
2361 Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE));
2362 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2363 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec;
2364
2365 if (bDRMPlayerMode == OMX_TRUE)
2366 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC);
2367 else
2368 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DEC);
2369
2370 pVideoDec->bDRMPlayerMode = bDRMPlayerMode;
2371 #ifdef USE_S3D_SUPPORT
2372 pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
2373 #endif
2374
2375 /* Set componentVersion */
2376 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2377 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2378 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2379 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2380 /* Set specVersion */
2381 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2382 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2383 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2384 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2385
2386 /* Input port */
2387 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2388 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2389 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2390 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2391 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2392 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2393 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2394 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2395 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2396 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2397 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2398 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2399 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2400 pExynosPort->bufferProcessType = BUFFER_SHARE;
2401 if (bDRMPlayerMode == OMX_TRUE)
2402 pExynosPort->bufferProcessType = BUFFER_SHARE;
2403 pExynosPort->portWayType = WAY2_PORT;
2404
2405 /* Output port */
2406 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2407 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2408 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2409 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2410 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2411 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2412 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2413 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2414 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2415 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2416 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2417 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2418 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2419 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2420 pExynosPort->portWayType = WAY2_PORT;
2421
2422 for(i = 0; i < ALL_PORT_NUM; i++) {
2423 INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2424 pH264Dec->AVCComponent[i].nPortIndex = i;
2425 pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline;
2426 pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4;
2427 }
2428
2429 pOMXComponent->GetParameter = &Exynos_H264Dec_GetParameter;
2430 pOMXComponent->SetParameter = &Exynos_H264Dec_SetParameter;
2431 pOMXComponent->GetConfig = &Exynos_H264Dec_GetConfig;
2432 pOMXComponent->SetConfig = &Exynos_H264Dec_SetConfig;
2433 pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex;
2434 pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum;
2435 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2436
2437 pExynosComponent->exynos_codec_componentInit = &Exynos_H264Dec_Init;
2438 pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate;
2439
2440 pVideoDec->exynos_codec_srcInputProcess = &Exynos_H264Dec_srcInputBufferProcess;
2441 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess;
2442 pVideoDec->exynos_codec_dstInputProcess = &Exynos_H264Dec_dstInputBufferProcess;
2443 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess;
2444
2445 pVideoDec->exynos_codec_start = &H264CodecStart;
2446 pVideoDec->exynos_codec_stop = &H264CodecStop;
2447 pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2448 pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
2449
2450 pVideoDec->exynos_checkInputFrame = &Check_H264_Frame;
2451 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2452 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2453 pVideoDec->exynos_codec_reconfigAllBuffers = &H264CodecReconfigAllBuffers;
2454
2455 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2456 if (pVideoDec->hSharedMemory == NULL) {
2457 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2458 Exynos_OSAL_Free(pH264Dec);
2459 pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2460 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2461 ret = OMX_ErrorInsufficientResources;
2462 goto EXIT;
2463 }
2464
2465 pExynosComponent->currentState = OMX_StateLoaded;
2466
2467 ret = OMX_ErrorNone;
2468
2469 EXIT:
2470 FunctionOut();
2471
2472 return ret;
2473 }
2474
2475 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2476 {
2477 OMX_ERRORTYPE ret = OMX_ErrorNone;
2478 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2479 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2480 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2481 EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
2482
2483 FunctionIn();
2484
2485 if (hComponent == NULL) {
2486 ret = OMX_ErrorBadParameter;
2487 goto EXIT;
2488 }
2489 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2490 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2491 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2492
2493 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2494
2495 Exynos_OSAL_Free(pExynosComponent->componentName);
2496 pExynosComponent->componentName = NULL;
2497
2498 pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2499 if (pH264Dec != NULL) {
2500 Exynos_OSAL_Free(pH264Dec);
2501 pH264Dec = pVideoDec->hCodecHandle = NULL;
2502 }
2503
2504 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2505 if (ret != OMX_ErrorNone) {
2506 goto EXIT;
2507 }
2508
2509 ret = OMX_ErrorNone;
2510
2511 EXIT:
2512 FunctionOut();
2513
2514 return ret;
2515 }