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