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