video_dec: Add ThumbnailMode decoding to h264
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / vp8 / Exynos_OMX_Vp8dec.c
1 /*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * @file Exynos_OMX_Vp8dec.c
20 * @brief
21 * @author Satish Kumar Reddy (palli.satish@samsung.com)
22 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
23 * @version 2.0.0
24 * @history
25 * 2012.02.20 : Create
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OMX_Basecomponent.h"
34 #include "Exynos_OMX_Baseport.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OMX_VdecControl.h"
37 #include "Exynos_OSAL_ETC.h"
38 #include "Exynos_OSAL_Semaphore.h"
39 #include "Exynos_OSAL_Thread.h"
40 #include "library_register.h"
41 #include "Exynos_OMX_Vp8dec.h"
42 #include "ExynosVideoApi.h"
43 #include "Exynos_OSAL_SharedMemory.h"
44 #include "Exynos_OSAL_Event.h"
45
46 #ifdef USE_ANB
47 #include "Exynos_OSAL_Android.h"
48 #endif
49
50 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
51 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
52 #include "csc.h"
53
54 #undef EXYNOS_LOG_TAG
55 #define EXYNOS_LOG_TAG "EXYNOS_VP8_DEC"
56 #define EXYNOS_LOG_OFF
57 //#define EXYNOS_TRACE_ON
58 #include "Exynos_OSAL_Log.h"
59
60 #define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7
61
62 //#define FULL_FRAME_SEARCH /* Full frame search not support*/
63
64 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
65 {
66 OMX_ERRORTYPE ret = OMX_ErrorNone;
67
68 EXIT:
69 return ret;
70 }
71
72 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[])
73 {
74 OMX_ERRORTYPE ret = OMX_ErrorNone;
75 ExynosVideoBuffer *pCodecBuffer;
76
77 if (codecBuffer == NULL) {
78 ret = OMX_ErrorBadParameter;
79 goto EXIT;
80 }
81
82 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
83
84 if (addr != NULL) {
85 addr[0] = pCodecBuffer->planes[0].addr;
86 addr[1] = pCodecBuffer->planes[1].addr;
87 addr[2] = pCodecBuffer->planes[2].addr;
88 }
89
90 if (size != NULL) {
91 size[0] = pCodecBuffer->planes[0].allocSize;
92 size[1] = pCodecBuffer->planes[1].allocSize;
93 size[2] = pCodecBuffer->planes[2].allocSize;
94 }
95
96 EXIT:
97 return ret;
98 }
99
100 static int Check_VP8_Frame(
101 OMX_U8 *pInputStream,
102 int buffSize,
103 OMX_U32 flag,
104 OMX_BOOL bPreviousFrameEOF,
105 OMX_BOOL *pbEndOfFrame)
106 {
107 /* Uncompressed data Chunk comprises a common
108 (for key frames and interframes) 3-byte frame tag that
109 contains four fields
110 - 1-bit frame type (0 - key frame, 1 - inter frame)
111 - 3-bit version number (0 - 3 are defined as four different
112 profiles with different decoding complexity)
113 - 1-bit show_frame flag ( 0 - current frame not for display,
114 1 - current frame is for dispaly)
115 - 19-bit field - size of the first data partition in bytes
116
117 Key Frames : frame tag followed by 7 bytes of uncompressed
118 data
119 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a)
120 Next 4-bytes: Width & height, Horizontal and vertical scale information
121 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
122 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
123 */
124 int width, height;
125 int horizSscale, vertScale;
126
127 FunctionIn();
128
129 *pbEndOfFrame = OMX_TRUE;
130
131 /*Check for Key frame*/
132 if (!(pInputStream[0] & 0x01)){
133 /* Key Frame Start code*/
134 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
135 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found");
136 *pbEndOfFrame = OMX_FALSE;
137 }
138 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code");
139 width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff;
140 horizSscale = pInputStream[7] >> 6;
141 height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff;
142 vertScale = pInputStream[9] >> 6;
143 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale);
144 }
145
146 FunctionOut();
147 return buffSize;
148 }
149
150 OMX_BOOL Check_VP8_StartCode(
151 OMX_U8 *pInputStream,
152 OMX_U32 streamSize)
153 {
154 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize);
155 if (streamSize < 3) {
156 return OMX_FALSE;
157 }
158
159 if (!(pInputStream[0] & 0x01)){
160 /* Key Frame Start code*/
161 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
162 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found");
163 return OMX_FALSE;
164 }
165 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code");
166 }
167
168 return OMX_TRUE;
169 }
170
171 OMX_ERRORTYPE VP8CodecOpen(EXYNOS_VP8DEC_HANDLE *pVp8Dec)
172 {
173 OMX_ERRORTYPE ret = OMX_ErrorNone;
174 ExynosVideoDecOps *pDecOps = NULL;
175 ExynosVideoDecBufferOps *pInbufOps = NULL;
176 ExynosVideoDecBufferOps *pOutbufOps = NULL;
177
178 FunctionIn();
179
180 if (pVp8Dec == NULL) {
181 ret = OMX_ErrorBadParameter;
182 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
183 goto EXIT;
184 }
185
186 /* alloc ops structure */
187 pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
188 pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
189 pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
190
191 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
192 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
193 ret = OMX_ErrorInsufficientResources;
194 goto EXIT;
195 }
196
197 pVp8Dec->hMFCVp8Handle.pDecOps = pDecOps;
198 pVp8Dec->hMFCVp8Handle.pInbufOps = pInbufOps;
199 pVp8Dec->hMFCVp8Handle.pOutbufOps = pOutbufOps;
200
201 /* function pointer mapping */
202 pDecOps->nSize = sizeof(ExynosVideoDecOps);
203 pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
204 pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
205
206 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
207
208 /* check mandatory functions for decoder ops */
209 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
210 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
211 (pDecOps->Get_FrameTag == NULL)) {
212 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
213 ret = OMX_ErrorInsufficientResources;
214 goto EXIT;
215 }
216
217 /* check mandatory functions for buffer ops */
218 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
219 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
220 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
221 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
222 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
223 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
224 ret = OMX_ErrorInsufficientResources;
225 goto EXIT;
226 }
227
228 /* alloc context, open, querycap */
229 #ifdef USE_DMA_BUF
230 pVp8Dec->hMFCVp8Handle.hMFCHandle = pVp8Dec->hMFCVp8Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
231 #else
232 pVp8Dec->hMFCVp8Handle.hMFCHandle = pVp8Dec->hMFCVp8Handle.pDecOps->Init(V4L2_MEMORY_USERPTR);
233 #endif
234 if (pVp8Dec->hMFCVp8Handle.hMFCHandle == NULL) {
235 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
236 ret = OMX_ErrorInsufficientResources;
237 goto EXIT;
238 }
239
240 ret = OMX_ErrorNone;
241
242 EXIT:
243 if (ret != OMX_ErrorNone) {
244 if (pDecOps != NULL) {
245 Exynos_OSAL_Free(pDecOps);
246 pVp8Dec->hMFCVp8Handle.pDecOps = NULL;
247 }
248 if (pInbufOps != NULL) {
249 Exynos_OSAL_Free(pInbufOps);
250 pVp8Dec->hMFCVp8Handle.pInbufOps = NULL;
251 }
252 if (pOutbufOps != NULL) {
253 Exynos_OSAL_Free(pOutbufOps);
254 pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL;
255 }
256 }
257
258 FunctionOut();
259
260 return ret;
261 }
262
263 OMX_ERRORTYPE VP8CodecClose(EXYNOS_VP8DEC_HANDLE *pVp8Dec)
264 {
265 OMX_ERRORTYPE ret = OMX_ErrorNone;
266 void *hMFCHandle = NULL;
267 ExynosVideoDecOps *pDecOps = NULL;
268 ExynosVideoDecBufferOps *pInbufOps = NULL;
269 ExynosVideoDecBufferOps *pOutbufOps = NULL;
270
271 FunctionIn();
272
273 if (pVp8Dec == NULL) {
274 ret = OMX_ErrorBadParameter;
275 goto EXIT;
276 }
277
278 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
279 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
280 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
281 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
282
283 if (hMFCHandle != NULL) {
284 pDecOps->Finalize(hMFCHandle);
285 pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL;
286 }
287 if (pOutbufOps != NULL) {
288 Exynos_OSAL_Free(pOutbufOps);
289 pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL;
290 }
291 if (pInbufOps != NULL) {
292 Exynos_OSAL_Free(pInbufOps);
293 pVp8Dec->hMFCVp8Handle.pInbufOps = NULL;
294 }
295 if (pDecOps != NULL) {
296 Exynos_OSAL_Free(pDecOps);
297 pVp8Dec->hMFCVp8Handle.pDecOps = NULL;
298 }
299
300 ret = OMX_ErrorNone;
301
302 EXIT:
303 FunctionOut();
304
305 return ret;
306 }
307
308 OMX_ERRORTYPE VP8CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
309 {
310 OMX_ERRORTYPE ret = OMX_ErrorNone;
311 void *hMFCHandle = NULL;
312 ExynosVideoDecOps *pDecOps = NULL;
313 ExynosVideoDecBufferOps *pInbufOps = NULL;
314 ExynosVideoDecBufferOps *pOutbufOps = NULL;
315 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
316 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
317
318 FunctionIn();
319
320 if (pOMXComponent == NULL) {
321 ret = OMX_ErrorBadParameter;
322 goto EXIT;
323 }
324
325 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
326 if (pVideoDec == NULL) {
327 ret = OMX_ErrorBadParameter;
328 goto EXIT;
329 }
330
331 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
332 if (pVp8Dec == NULL) {
333 ret = OMX_ErrorBadParameter;
334 goto EXIT;
335 }
336
337 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
338 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
339 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
340 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
341
342 if (nPortIndex == INPUT_PORT_INDEX)
343 pInbufOps->Run(hMFCHandle);
344 else if (nPortIndex == OUTPUT_PORT_INDEX)
345 pOutbufOps->Run(hMFCHandle);
346
347 ret = OMX_ErrorNone;
348
349 EXIT:
350 FunctionOut();
351
352 return ret;
353 }
354
355 OMX_ERRORTYPE VP8CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
356 {
357 OMX_ERRORTYPE ret = OMX_ErrorNone;
358 void *hMFCHandle = NULL;
359 ExynosVideoDecOps *pDecOps = NULL;
360 ExynosVideoDecBufferOps *pInbufOps = NULL;
361 ExynosVideoDecBufferOps *pOutbufOps = NULL;
362 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
363 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
364
365 FunctionIn();
366
367 if (pOMXComponent == NULL) {
368 ret = OMX_ErrorBadParameter;
369 goto EXIT;
370 }
371
372 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
373 if (pVideoDec == NULL) {
374 ret = OMX_ErrorBadParameter;
375 goto EXIT;
376 }
377 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
378 if (pVp8Dec == NULL) {
379 ret = OMX_ErrorBadParameter;
380 goto EXIT;
381 }
382
383 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
384 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
385 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
386 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
387
388 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
389 pInbufOps->Stop(hMFCHandle);
390 else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
391 pOutbufOps->Stop(hMFCHandle);
392
393 ret = OMX_ErrorNone;
394
395 EXIT:
396 FunctionOut();
397
398 return ret;
399 }
400
401 OMX_ERRORTYPE VP8CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
402 {
403 OMX_ERRORTYPE ret = OMX_ErrorNone;
404 void *hMFCHandle = NULL;
405 ExynosVideoDecOps *pDecOps = NULL;
406 ExynosVideoDecBufferOps *pInbufOps = NULL;
407 ExynosVideoDecBufferOps *pOutbufOps = NULL;
408 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
409 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
410
411 FunctionIn();
412
413 if (pOMXComponent == NULL) {
414 ret = OMX_ErrorBadParameter;
415 goto EXIT;
416 }
417
418 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
419 if (pVideoDec == NULL) {
420 ret = OMX_ErrorBadParameter;
421 goto EXIT;
422 }
423 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
424 if (pVp8Dec == NULL) {
425 ret = OMX_ErrorBadParameter;
426 goto EXIT;
427 }
428
429 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
430 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
431 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
432 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
433
434 if (nPortIndex == INPUT_PORT_INDEX) {
435 if (pVp8Dec->bSourceStart == OMX_FALSE) {
436 Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent);
437 Exynos_OSAL_SleepMillisec(0);
438 }
439 }
440
441 if (nPortIndex == OUTPUT_PORT_INDEX) {
442 if (pVp8Dec->bDestinationStart == OMX_FALSE) {
443 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
444 Exynos_OSAL_SleepMillisec(0);
445 }
446 }
447
448 ret = OMX_ErrorNone;
449
450 EXIT:
451 FunctionOut();
452
453 return ret;
454 }
455
456 OMX_ERRORTYPE VP8CodecRegistCodecBuffers(
457 OMX_COMPONENTTYPE *pOMXComponent,
458 OMX_U32 nPortIndex,
459 OMX_U32 nBufferCnt)
460 {
461 OMX_ERRORTYPE ret = OMX_ErrorNone;
462 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
463 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
464 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
465 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
466 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
467 ExynosVideoDecBufferOps *pBufOps = NULL;
468 ExynosVideoPlane *pPlanes = NULL;
469
470 OMX_U32 nPlaneCnt = 0;
471 int i, j;
472
473 FunctionIn();
474
475 if (nPortIndex == INPUT_PORT_INDEX) {
476 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
477 pBufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
478 } else {
479 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
480 pBufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
481 }
482 nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
483
484 pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
485 if (pPlanes == NULL) {
486 ret = OMX_ErrorInsufficientResources;
487 goto EXIT;
488 }
489
490 /* Register buffer */
491 for (i = 0; i < nBufferCnt; i++) {
492 for (j = 0; j < nPlaneCnt; j++) {
493 pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
494 pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
495 pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
496 }
497
498 if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
499 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
500 ret = OMX_ErrorInsufficientResources;
501 Exynos_OSAL_Free(pPlanes);
502 goto EXIT;
503 }
504 }
505
506 Exynos_OSAL_Free(pPlanes);
507
508 ret = OMX_ErrorNone;
509
510 EXIT:
511 FunctionOut();
512
513 return ret;
514 }
515
516 OMX_ERRORTYPE VP8CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
517 {
518 OMX_ERRORTYPE ret = OMX_ErrorNone;
519 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
520 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
521 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
522 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
523 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
524 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
525 int i, nOutbufs;
526
527 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
528 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
529 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
530
531 FunctionIn();
532
533 if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
534 ret = OMX_ErrorBadPortIndex;
535 goto EXIT;
536 }
537
538 if ((nPortIndex == INPUT_PORT_INDEX) &&
539 (pVp8Dec->bSourceStart == OMX_TRUE)) {
540 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
541
542 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
543 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
544 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
545
546 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
547 }
548
549 pInbufOps->Clear_Queue(hMFCHandle);
550 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
551 (pVp8Dec->bDestinationStart == OMX_TRUE)) {
552 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
553
554 for (i = 0; i < pVp8Dec->hMFCVp8Handle.maxDPBNum; i++) {
555 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
556 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
557
558 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
559 }
560 pOutbufOps->Clear_Queue(hMFCHandle);
561 }
562
563 EXIT:
564 FunctionOut();
565
566 return ret;
567 }
568
569 OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
570 {
571 OMX_ERRORTYPE ret = OMX_ErrorNone;
572 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
573 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
574 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
575 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
576 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
577 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
578 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
579
580 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
581 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
582 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
583 ExynosVideoGeometry bufferConf;
584 OMX_U32 inputBufferNumber = 0;
585 int i;
586
587 FunctionIn();
588
589 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
590 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
591 if (pBufferInfo == NULL) {
592 ret = OMX_ErrorInsufficientResources;
593 goto EXIT;
594 }
595
596 pBufferInfo->nFlags = pSrcInputData->nFlags;
597 pBufferInfo->timeStamp = pSrcInputData->timeStamp;
598 ret = Exynos_OSAL_Queue(&pVp8Dec->bypassBufferInfoQ, (void *)pBufferInfo);
599 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
600
601 ret = OMX_ErrorNone;
602 goto EXIT;
603 }
604
605 if (pVideoDec->bThumbnailMode == OMX_TRUE) {
606 pDecOps->Set_IFrameDecoding(hMFCHandle);
607 }
608
609 if ((pDecOps->Enable_DTSMode != NULL) &&
610 (pVideoDec->bDTSMode == OMX_TRUE))
611 pDecOps->Enable_DTSMode(hMFCHandle);
612
613 /* input buffer info */
614 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
615 bufferConf.eCompressionFormat = VIDEO_CODING_VP8;
616 pInbufOps->Set_Shareable(hMFCHandle);
617 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
618 bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
619 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
620 } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
621 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
622 }
623 bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt;
624 inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
625
626 /* should be done before prepare input buffer */
627 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
628 ret = OMX_ErrorInsufficientResources;
629 goto EXIT;
630 }
631
632 /* set input buffer geometry */
633 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
634 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
635 ret = OMX_ErrorInsufficientResources;
636 goto EXIT;
637 }
638
639 /* setup input buffer */
640 if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
641 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
642 ret = OMX_ErrorInsufficientResources;
643 goto EXIT;
644 }
645
646 /* set output geometry */
647 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
648
649 #ifdef USE_DUALDPB_MODE
650 switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) {
651 case OMX_COLOR_FormatYUV420SemiPlanar:
652 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
653 break;
654 case OMX_COLOR_FormatYUV420Planar:
655 bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420;
656 break;
657 case OMX_SEC_COLOR_FormatYVU420Planar:
658 bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12;
659 break;
660 case OMX_SEC_COLOR_FormatNV21Linear:
661 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21;
662 break;
663 case OMX_SEC_COLOR_FormatNV12Tiled:
664 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
665 break;
666 default:
667 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
668 break;
669 }
670
671 if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) {
672 if ((pDecOps->Enable_DualDPBMode != NULL) &&
673 (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) {
674 pVideoDec->bDualDPBMode = OMX_TRUE;
675 pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat);
676 } else {
677 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
678 pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE;
679 }
680 }
681 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat;
682 #else
683 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
684 #endif
685 bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt;
686 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
687 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
688 ret = OMX_ErrorInsufficientResources;
689 goto EXIT;
690 }
691
692 /* input buffer enqueue for header parsing */
693 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
694 OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0};
695 if (pInbufOps->ExtensionEnqueue(hMFCHandle,
696 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
697 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd,
698 (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize,
699 pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
700 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
701 // ret = OMX_ErrorInsufficientResources;
702 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
703 goto EXIT;
704 }
705
706 /* start header parsing */
707 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
708 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
709 ret = OMX_ErrorCodecInit;
710 goto EXIT;
711 }
712
713 /* get geometry for output */
714 Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
715 if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
716 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
717 VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
718 pInbufOps->Cleanup_Buffer(hMFCHandle);
719 ret = OMX_ErrorInsufficientResources;
720 goto EXIT;
721 }
722
723 /* get dpb count */
724 pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
725 if (pVideoDec->bThumbnailMode == OMX_FALSE) {
726 pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM;
727 } else {
728 pVp8Dec->hMFCVp8Handle.maxDPBNum += PLATFORM_DISPLAY_BUFFER;
729 }
730 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8CodecSetup nOutbufs: %d", pVp8Dec->hMFCVp8Handle.maxDPBNum);
731
732 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE;
733
734 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
735 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
736 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) {
737 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
738
739 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
740 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
741 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
742 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
743
744 Exynos_UpdateFrameSize(pOMXComponent);
745
746 /** Send Port Settings changed call back **/
747 (*(pExynosComponent->pCallbacks->EventHandler))
748 (pOMXComponent,
749 pExynosComponent->callbackData,
750 OMX_EventPortSettingsChanged, /* The command was completed */
751 OMX_DirOutput, /* This is the port index */
752 0,
753 NULL);
754 }
755 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
756 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
757 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) ||
758 (pExynosOutputPort->portDefinition.nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) {
759 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
760
761 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
762 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
763 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
764 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
765
766 pExynosOutputPort->portDefinition.nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum - PLATFORM_DISPLAY_BUFFER;
767 pExynosOutputPort->portDefinition.nBufferCountMin = pVp8Dec->hMFCVp8Handle.maxDPBNum - PLATFORM_DISPLAY_BUFFER;
768
769 Exynos_UpdateFrameSize(pOMXComponent);
770
771 /** Send Port Settings changed call back **/
772 (*(pExynosComponent->pCallbacks->EventHandler))
773 (pOMXComponent,
774 pExynosComponent->callbackData,
775 OMX_EventPortSettingsChanged, /* The command was completed */
776 OMX_DirOutput, /* This is the port index */
777 0,
778 NULL);
779 }
780 }
781 Exynos_OSAL_SleepMillisec(0);
782 ret = OMX_ErrorInputDataDecodeYet;
783 VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
784
785 EXIT:
786 FunctionOut();
787
788 return ret;
789 }
790
791 OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
792 {
793 OMX_ERRORTYPE ret = OMX_ErrorNone;
794 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
795 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
796 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
797 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
798 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
799 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
800
801 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
802 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
803 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
804
805 int i, nOutbufs;
806
807 OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
808 OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
809
810 FunctionIn();
811
812 for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++)
813 nAllocLen[i] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[i];
814
815 pOutbufOps->Set_Shareable(hMFCHandle);
816
817 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
818 /* should be done before prepare output buffer */
819 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
820 ret = OMX_ErrorInsufficientResources;
821 goto EXIT;
822 }
823
824 /* get dpb count */
825 nOutbufs = pVp8Dec->hMFCVp8Handle.maxDPBNum;
826 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
827 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
828 ret = OMX_ErrorInsufficientResources;
829 goto EXIT;
830 }
831
832 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
833 if (ret != OMX_ErrorNone)
834 goto EXIT;
835
836 ret = VP8CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
837 if (ret != OMX_ErrorNone)
838 goto EXIT;
839
840 /* Enqueue output buffer */
841 for (i = 0; i < nOutbufs; i++) {
842 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
843 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
844 }
845
846 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
847 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
848 ret = OMX_ErrorInsufficientResources;
849 goto EXIT;
850 }
851 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
852 ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0};
853 int plane;
854
855 /* get dpb count */
856 nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
857 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
858 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
859 ret = OMX_ErrorInsufficientResources;
860 goto EXIT;
861 }
862
863 /* Register output buffer */
864 /*************/
865 /* TBD */
866 /*************/
867 #ifdef USE_ANB
868 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) {
869 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
870 for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
871 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
872 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
873 planes[plane].allocSize = nAllocLen[plane];
874 }
875
876 if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) {
877 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
878 ret = OMX_ErrorInsufficientResources;
879 goto EXIT;
880 }
881 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
882 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
883 }
884
885 if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
886 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
887 ret = OMX_ErrorHardware;
888 goto EXIT;
889 }
890 } else {
891 ret = OMX_ErrorNotImplemented;
892 goto EXIT;
893 }
894 #else
895 ret = OMX_ErrorNotImplemented;
896 goto EXIT;
897 #endif
898 }
899
900 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
901
902 ret = OMX_ErrorNone;
903
904 EXIT:
905 FunctionOut();
906
907 return ret;
908 }
909
910 OMX_ERRORTYPE Exynos_VP8Dec_GetParameter(
911 OMX_IN OMX_HANDLETYPE hComponent,
912 OMX_IN OMX_INDEXTYPE nParamIndex,
913 OMX_INOUT OMX_PTR pComponentParameterStructure)
914 {
915 OMX_ERRORTYPE ret = OMX_ErrorNone;
916 OMX_COMPONENTTYPE *pOMXComponent = NULL;
917 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
918
919 FunctionIn();
920
921 if (hComponent == NULL || pComponentParameterStructure == NULL) {
922 ret = OMX_ErrorBadParameter;
923 goto EXIT;
924 }
925 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
926 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
927 if (ret != OMX_ErrorNone) {
928 goto EXIT;
929 }
930 if (pOMXComponent->pComponentPrivate == NULL) {
931 ret = OMX_ErrorBadParameter;
932 goto EXIT;
933 }
934
935 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
936 if (pExynosComponent->currentState == OMX_StateInvalid ) {
937 ret = OMX_ErrorInvalidState;
938 goto EXIT;
939 }
940
941 switch (nParamIndex) {
942 case OMX_IndexParamStandardComponentRole:
943 {
944 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
945 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
946 if (ret != OMX_ErrorNone) {
947 goto EXIT;
948 }
949
950 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
951 }
952 break;
953 case OMX_IndexParamVideoErrorCorrection:
954 {
955 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
956 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
957 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
958
959 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
960 if (ret != OMX_ErrorNone) {
961 goto EXIT;
962 }
963
964 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
965 ret = OMX_ErrorBadPortIndex;
966 goto EXIT;
967 }
968
969 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
970 pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
971
972 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
973 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
974 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
975 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
976 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
977 }
978 break;
979 default:
980 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
981 break;
982 }
983 EXIT:
984 FunctionOut();
985
986 return ret;
987 }
988
989 OMX_ERRORTYPE Exynos_VP8Dec_SetParameter(
990 OMX_IN OMX_HANDLETYPE hComponent,
991 OMX_IN OMX_INDEXTYPE nIndex,
992 OMX_IN OMX_PTR pComponentParameterStructure)
993 {
994 OMX_ERRORTYPE ret = OMX_ErrorNone;
995 OMX_COMPONENTTYPE *pOMXComponent = NULL;
996 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
997
998 FunctionIn();
999
1000 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1001 ret = OMX_ErrorBadParameter;
1002 goto EXIT;
1003 }
1004 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1005 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1006 if (ret != OMX_ErrorNone) {
1007 goto EXIT;
1008 }
1009 if (pOMXComponent->pComponentPrivate == NULL) {
1010 ret = OMX_ErrorBadParameter;
1011 goto EXIT;
1012 }
1013
1014 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1015 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1016 ret = OMX_ErrorInvalidState;
1017 goto EXIT;
1018 }
1019
1020 switch (nIndex) {
1021 case OMX_IndexParamStandardComponentRole:
1022 {
1023 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1024
1025 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1026 if (ret != OMX_ErrorNone) {
1027 goto EXIT;
1028 }
1029
1030 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1031 ret = OMX_ErrorIncorrectStateOperation;
1032 goto EXIT;
1033 }
1034
1035 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) {
1036 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
1037 } else {
1038 ret = OMX_ErrorBadParameter;
1039 goto EXIT;
1040 }
1041 }
1042 break;
1043 case OMX_IndexParamVideoErrorCorrection:
1044 {
1045 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1046 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1047 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
1048
1049 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1050 if (ret != OMX_ErrorNone) {
1051 goto EXIT;
1052 }
1053
1054 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1055 ret = OMX_ErrorBadPortIndex;
1056 goto EXIT;
1057 }
1058
1059 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1060 pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
1061
1062 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1063 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1064 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1065 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1066 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1067 }
1068 break;
1069 default:
1070 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1071 break;
1072 }
1073 EXIT:
1074 FunctionOut();
1075
1076 return ret;
1077 }
1078
1079 OMX_ERRORTYPE Exynos_VP8Dec_GetConfig(
1080 OMX_HANDLETYPE hComponent,
1081 OMX_INDEXTYPE nIndex,
1082 OMX_PTR pComponentConfigStructure)
1083 {
1084 OMX_ERRORTYPE ret = OMX_ErrorNone;
1085 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1086 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1087
1088 FunctionIn();
1089
1090 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1091 ret = OMX_ErrorBadParameter;
1092 goto EXIT;
1093 }
1094 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1095 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1096 if (ret != OMX_ErrorNone) {
1097 goto EXIT;
1098 }
1099 if (pOMXComponent->pComponentPrivate == NULL) {
1100 ret = OMX_ErrorBadParameter;
1101 goto EXIT;
1102 }
1103 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1104 if (pExynosComponent->currentState == OMX_StateInvalid) {
1105 ret = OMX_ErrorInvalidState;
1106 goto EXIT;
1107 }
1108
1109 switch (nIndex) {
1110 default:
1111 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1112 break;
1113 }
1114
1115 EXIT:
1116 FunctionOut();
1117
1118 return ret;
1119 }
1120
1121 OMX_ERRORTYPE Exynos_VP8Dec_SetConfig(
1122 OMX_HANDLETYPE hComponent,
1123 OMX_INDEXTYPE nIndex,
1124 OMX_PTR pComponentConfigStructure)
1125 {
1126 OMX_ERRORTYPE ret = OMX_ErrorNone;
1127 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1128 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1129
1130 FunctionIn();
1131
1132 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1133 ret = OMX_ErrorBadParameter;
1134 goto EXIT;
1135 }
1136 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1137 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1138 if (ret != OMX_ErrorNone) {
1139 goto EXIT;
1140 }
1141 if (pOMXComponent->pComponentPrivate == NULL) {
1142 ret = OMX_ErrorBadParameter;
1143 goto EXIT;
1144 }
1145 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1146 if (pExynosComponent->currentState == OMX_StateInvalid) {
1147 ret = OMX_ErrorInvalidState;
1148 goto EXIT;
1149 }
1150
1151 switch (nIndex) {
1152 default:
1153 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1154 break;
1155 }
1156
1157 EXIT:
1158 FunctionOut();
1159
1160 return ret;
1161 }
1162
1163 OMX_ERRORTYPE Exynos_VP8Dec_GetExtensionIndex(
1164 OMX_IN OMX_HANDLETYPE hComponent,
1165 OMX_IN OMX_STRING cParameterName,
1166 OMX_OUT OMX_INDEXTYPE *pIndexType)
1167 {
1168 OMX_ERRORTYPE ret = OMX_ErrorNone;
1169 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1170 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1171
1172 FunctionIn();
1173
1174 if (hComponent == NULL) {
1175 ret = OMX_ErrorBadParameter;
1176 goto EXIT;
1177 }
1178 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1179 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1180 if (ret != OMX_ErrorNone) {
1181 goto EXIT;
1182 }
1183 if (pOMXComponent->pComponentPrivate == NULL) {
1184 ret = OMX_ErrorBadParameter;
1185 goto EXIT;
1186 }
1187 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1188 if ((cParameterName == NULL) || (pIndexType == NULL)) {
1189 ret = OMX_ErrorBadParameter;
1190 goto EXIT;
1191 }
1192 if (pExynosComponent->currentState == OMX_StateInvalid) {
1193 ret = OMX_ErrorInvalidState;
1194 goto EXIT;
1195 }
1196
1197 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1198
1199 EXIT:
1200 FunctionOut();
1201
1202 return ret;
1203 }
1204
1205 OMX_ERRORTYPE Exynos_VP8Dec_ComponentRoleEnum(
1206 OMX_HANDLETYPE hComponent,
1207 OMX_U8 *cRole,
1208 OMX_U32 nIndex)
1209 {
1210 OMX_ERRORTYPE ret = OMX_ErrorNone;
1211 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1212 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1213
1214 FunctionIn();
1215
1216 if ((hComponent == NULL) || (cRole == NULL)) {
1217 ret = OMX_ErrorBadParameter;
1218 goto EXIT;
1219 }
1220 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1221 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
1222 ret = OMX_ErrorNone;
1223 } else {
1224 ret = OMX_ErrorNoMore;
1225 }
1226
1227 EXIT:
1228 FunctionOut();
1229
1230 return ret;
1231 }
1232
1233 /* MFC Init */
1234 OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1235 {
1236 OMX_ERRORTYPE ret = OMX_ErrorNone;
1237 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1238 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1239 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1240 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1241 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
1242 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1243
1244 ExynosVideoDecOps *pDecOps = NULL;
1245 ExynosVideoDecBufferOps *pInbufOps = NULL;
1246 ExynosVideoDecBufferOps *pOutbufOps = NULL;
1247
1248 CSC_METHOD csc_method = CSC_METHOD_SW;
1249 int i, plane;
1250
1251 FunctionIn();
1252
1253 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
1254 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
1255 pExynosComponent->bUseFlagEOF = OMX_TRUE;
1256 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1257 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1258
1259 /* VP8 Codec Open */
1260 ret = VP8CodecOpen(pVp8Dec);
1261 if (ret != OMX_ErrorNone) {
1262 goto EXIT;
1263 }
1264
1265 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1266 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1267 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1268
1269 pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE;
1270 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1271 OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
1272 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1273 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1274 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
1275 if (ret != OMX_ErrorNone)
1276 goto EXIT;
1277
1278 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
1279 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1280 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1281 /*************/
1282 /* TBD */
1283 /*************/
1284 /* Does not require any actions. */
1285 }
1286
1287 pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE;
1288 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1289 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1290 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1291 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1292 /*************/
1293 /* TBD */
1294 /*************/
1295 /* Does not require any actions. */
1296 }
1297
1298 pVp8Dec->bSourceStart = OMX_FALSE;
1299 Exynos_OSAL_SignalCreate(&pVp8Dec->hSourceStartEvent);
1300 pVp8Dec->bDestinationStart = OMX_FALSE;
1301 Exynos_OSAL_SignalCreate(&pVp8Dec->hDestinationStartEvent);
1302
1303 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1304 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1305 pVp8Dec->hMFCVp8Handle.indexTimestamp = 0;
1306 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0;
1307
1308 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1309
1310 Exynos_OSAL_QueueCreate(&pVp8Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
1311
1312 #ifdef USE_CSC_HW
1313 csc_method = CSC_METHOD_HW;
1314 #endif
1315 pVideoDec->csc_handle = csc_init(csc_method);
1316 if (pVideoDec->csc_handle == NULL) {
1317 ret = OMX_ErrorInsufficientResources;
1318 goto EXIT;
1319 }
1320 pVideoDec->csc_set_format = OMX_FALSE;
1321
1322 EXIT:
1323 FunctionOut();
1324
1325 return ret;
1326 }
1327
1328 /* MFC Terminate */
1329 OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1330 {
1331 OMX_ERRORTYPE ret = OMX_ErrorNone;
1332 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1333 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1334 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1335 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1336 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1337 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1338
1339 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1340 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1341 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1342
1343 int i, plane;
1344
1345 FunctionIn();
1346
1347 if (pVideoDec->csc_handle != NULL) {
1348 csc_deinit(pVideoDec->csc_handle);
1349 pVideoDec->csc_handle = NULL;
1350 }
1351
1352 Exynos_OSAL_QueueTerminate(&pVp8Dec->bypassBufferInfoQ);
1353
1354 Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationStartEvent);
1355 pVp8Dec->hDestinationStartEvent = NULL;
1356 pVp8Dec->bDestinationStart = OMX_FALSE;
1357 Exynos_OSAL_SignalTerminate(pVp8Dec->hSourceStartEvent);
1358 pVp8Dec->hSourceStartEvent = NULL;
1359 pVp8Dec->bSourceStart = OMX_FALSE;
1360
1361 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1362 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
1363 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1364 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1365 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1366 /*************/
1367 /* TBD */
1368 /*************/
1369 /* Does not require any actions. */
1370 }
1371
1372 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1373 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
1374 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1375 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1376 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1377 /*************/
1378 /* TBD */
1379 /*************/
1380 /* Does not require any actions. */
1381 }
1382 VP8CodecClose(pVp8Dec);
1383
1384 Exynos_ResetAllPortConfig(pOMXComponent);
1385
1386 EXIT:
1387 FunctionOut();
1388
1389 return ret;
1390 }
1391
1392 OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1393 {
1394 OMX_ERRORTYPE ret = OMX_ErrorNone;
1395 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1396 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1397 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
1398 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1399 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1400 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1401
1402 OMX_BUFFERHEADERTYPE tempBufferHeader;
1403 void *pPrivate = NULL;
1404
1405 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1406 OMX_BOOL bInStartCode = OMX_FALSE;
1407
1408 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1409 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1410 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1411 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1412
1413 int i;
1414
1415 FunctionIn();
1416
1417 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
1418 ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
1419 goto EXIT;
1420 }
1421 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) {
1422 ret = VP8CodecDstSetup(pOMXComponent);
1423 }
1424
1425 if (((bInStartCode = Check_VP8_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE) ||
1426 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1427 pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->timeStamp;
1428 pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->nFlags;
1429 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp8Dec->hMFCVp8Handle.indexTimestamp, pSrcInputData->nFlags);
1430 pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp);
1431 pVp8Dec->hMFCVp8Handle.indexTimestamp++;
1432 pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP;
1433 #ifdef USE_QOS_CTRL
1434 if ((pVideoDec->bQosChanged == OMX_TRUE) &&
1435 (pDecOps->Set_QosRatio != NULL)) {
1436 pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
1437 pVideoDec->bQosChanged = OMX_FALSE;
1438 }
1439 #endif
1440 /* queue work for input buffer */
1441 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1442 OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0};
1443
1444 if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
1445 tempBufferHeader.nFlags = pSrcInputData->nFlags;
1446 tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
1447 pPrivate = (void *)&tempBufferHeader;
1448 } else {
1449 pPrivate = (void *)pSrcInputData->bufferHeader;
1450 }
1451 codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
1452 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1453 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd,
1454 (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize,
1455 pExynosInputPort->nPlaneCnt, pPrivate);
1456 if (codecReturn != VIDEO_ERROR_NONE) {
1457 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1458 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1459 goto EXIT;
1460 }
1461 VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1462 if (pVp8Dec->bSourceStart == OMX_FALSE) {
1463 pVp8Dec->bSourceStart = OMX_TRUE;
1464 Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent);
1465 Exynos_OSAL_SleepMillisec(0);
1466 }
1467 if (pVp8Dec->bDestinationStart == OMX_FALSE) {
1468 pVp8Dec->bDestinationStart = OMX_TRUE;
1469 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
1470 Exynos_OSAL_SleepMillisec(0);
1471 }
1472 } else if (bInStartCode == OMX_FALSE) {
1473 ret = OMX_ErrorCorruptedFrame;
1474 goto EXIT;
1475 }
1476
1477 ret = OMX_ErrorNone;
1478
1479 EXIT:
1480 FunctionOut();
1481
1482 return ret;
1483 }
1484
1485 OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1486 {
1487 OMX_ERRORTYPE ret = OMX_ErrorNone;
1488 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1489 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1490 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1491 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1492 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1493 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1494 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1495 ExynosVideoBuffer *pVideoBuffer;
1496 ExynosVideoBuffer videoBuffer;
1497
1498 FunctionIn();
1499
1500 if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
1501 pVideoBuffer = &videoBuffer;
1502 else
1503 pVideoBuffer = NULL;
1504
1505 pSrcOutputData->dataLen = 0;
1506 pSrcOutputData->usedDataLen = 0;
1507 pSrcOutputData->remainDataLen = 0;
1508 pSrcOutputData->nFlags = 0;
1509 pSrcOutputData->timeStamp = 0;
1510 pSrcOutputData->bufferHeader = NULL;
1511
1512 if (pVideoBuffer == NULL) {
1513 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1514 pSrcOutputData->allocSize = 0;
1515 pSrcOutputData->pPrivate = NULL;
1516 } else {
1517 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1518 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1519 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1520
1521 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1522 int i;
1523 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1524 if (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer ==
1525 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1526 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1527 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1528 break;
1529 }
1530 }
1531
1532 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1533 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1534 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1535 goto EXIT;
1536 }
1537 }
1538
1539 /* For Share Buffer */
1540 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
1541 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1542 }
1543
1544 ret = OMX_ErrorNone;
1545
1546 EXIT:
1547 FunctionOut();
1548
1549 return ret;
1550 }
1551
1552 OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1553 {
1554 OMX_ERRORTYPE ret = OMX_ErrorNone;
1555 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1556 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1557 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
1558 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1559 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1560
1561 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1562 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1563 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1564
1565 OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1566 int i;
1567
1568 FunctionIn();
1569
1570 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1571 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1572 ret = OMX_ErrorBadParameter;
1573 goto EXIT;
1574 }
1575
1576 for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) {
1577 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i,
1578 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]);
1579 }
1580
1581 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1582 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader);
1583
1584 if (codecReturn != VIDEO_ERROR_NONE) {
1585 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1586 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1587 goto EXIT;
1588 }
1589 VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1590
1591 ret = OMX_ErrorNone;
1592
1593 EXIT:
1594 FunctionOut();
1595
1596 return ret;
1597 }
1598
1599 OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1600 {
1601 OMX_ERRORTYPE ret = OMX_ErrorNone;
1602 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1603 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1604 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1605 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1606 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1607 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1608 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1609 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1610 ExynosVideoBuffer *pVideoBuffer = NULL;
1611 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1612 ExynosVideoGeometry *bufferGeometry;
1613 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1614 OMX_S32 indexTimestamp = 0;
1615 int plane;
1616
1617 FunctionIn();
1618
1619 if (pVp8Dec->bDestinationStart == OMX_FALSE) {
1620 ret = OMX_ErrorNone;
1621 goto EXIT;
1622 }
1623
1624 while (1) {
1625 pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
1626 if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
1627 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
1628 ret = OMX_ErrorHardware;
1629 goto EXIT;
1630 }
1631
1632 if (pVideoBuffer == NULL) {
1633 ret = OMX_ErrorNone;
1634 goto EXIT;
1635 }
1636 displayStatus = pVideoBuffer->displayStatus;
1637 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1638
1639 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1640 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1641 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1642 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
1643 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1644 ret = OMX_ErrorNone;
1645 break;
1646 }
1647 }
1648
1649 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++;
1650 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1651
1652 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
1653 for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
1654 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1655 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1656 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1657 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
1658 }
1659 pDstOutputData->usedDataLen = 0;
1660 pDstOutputData->pPrivate = pVideoBuffer;
1661 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1662 int i = 0;
1663 pDstOutputData->pPrivate = NULL;
1664 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1665 if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] ==
1666 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
1667 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
1668 break;
1669 }
1670 }
1671
1672 if (pDstOutputData->pPrivate == NULL) {
1673 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1674 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1675 goto EXIT;
1676 }
1677 }
1678
1679 /* For Share Buffer */
1680 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1681
1682 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1683 bufferGeometry = &pVp8Dec->hMFCVp8Handle.codecOutbufConf;
1684 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1685 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1686 switch (bufferGeometry->eColorFormat) {
1687 case VIDEO_COLORFORMAT_NV12:
1688 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1689 break;
1690 #ifdef USE_DUALDPB_MODE
1691 case VIDEO_COLORFORMAT_I420:
1692 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar;
1693 break;
1694 case VIDEO_COLORFORMAT_YV12:
1695 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar;
1696 break;
1697 case VIDEO_COLORFORMAT_NV21:
1698 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear;
1699 break;
1700 #endif
1701 case VIDEO_COLORFORMAT_NV12_TILED:
1702 default:
1703 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1704 break;
1705 }
1706
1707 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
1708 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
1709 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1710 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
1711 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
1712 if (indexTimestamp == INDEX_AFTER_EOS) {
1713 pDstOutputData->timeStamp = 0x00;
1714 pDstOutputData->nFlags = 0x00;
1715 } else {
1716 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
1717 pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
1718 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
1719 }
1720 } else {
1721 pDstOutputData->timeStamp = 0x00;
1722 pDstOutputData->nFlags = 0x00;
1723 }
1724 } else {
1725 /* For timestamp correction. if mfc support frametype detect */
1726 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
1727
1728 /* NEED TIMESTAMP REORDER */
1729 if (pVideoDec->bDTSMode == OMX_TRUE) {
1730 if ((pVideoBuffer->frameType == VIDEO_FRAME_I) ||
1731 ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) &&
1732 ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
1733 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
1734 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp;
1735 else
1736 indexTimestamp = pVp8Dec->hMFCVp8Handle.outputIndexTimestamp;
1737 }
1738
1739 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1740 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1741
1742 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
1743 }
1744
1745 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1746 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
1747 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1748 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
1749 pDstOutputData->remainDataLen = 0;
1750
1751 if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
1752 (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
1753 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
1754 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1755 }
1756 } else {
1757 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
1758 }
1759
1760 ret = OMX_ErrorNone;
1761
1762 EXIT:
1763 FunctionOut();
1764
1765 return ret;
1766 }
1767
1768 OMX_ERRORTYPE Exynos_VP8Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1769 {
1770 OMX_ERRORTYPE ret = OMX_ErrorNone;
1771 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1772 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1773 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1774
1775 FunctionIn();
1776
1777 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1778 ret = OMX_ErrorNone;
1779 goto EXIT;
1780 }
1781 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1782 ret = OMX_ErrorNone;
1783 goto EXIT;
1784 }
1785
1786 ret = Exynos_VP8Dec_SrcIn(pOMXComponent, pSrcInputData);
1787 if ((ret != OMX_ErrorNone) &&
1788 (ret != OMX_ErrorInputDataDecodeYet) &&
1789 (ret != OMX_ErrorCorruptedFrame)) {
1790 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1791 pExynosComponent->callbackData,
1792 OMX_EventError, ret, 0, NULL);
1793 }
1794
1795 EXIT:
1796 FunctionOut();
1797
1798 return ret;
1799 }
1800
1801 OMX_ERRORTYPE Exynos_VP8Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1802 {
1803 OMX_ERRORTYPE ret = OMX_ErrorNone;
1804 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1805 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1806 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1807
1808 FunctionIn();
1809
1810 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1811 ret = OMX_ErrorNone;
1812 goto EXIT;
1813 }
1814
1815 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1816 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1817 ret = OMX_ErrorNone;
1818 goto EXIT;
1819 }
1820 }
1821 if ((pVp8Dec->bSourceStart == OMX_FALSE) &&
1822 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
1823 Exynos_OSAL_SignalWait(pVp8Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
1824 Exynos_OSAL_SignalReset(pVp8Dec->hSourceStartEvent);
1825 }
1826
1827 ret = Exynos_VP8Dec_SrcOut(pOMXComponent, pSrcOutputData);
1828 if ((ret != OMX_ErrorNone) &&
1829 (pExynosComponent->currentState == OMX_StateExecuting)) {
1830 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1831 pExynosComponent->callbackData,
1832 OMX_EventError, ret, 0, NULL);
1833 }
1834
1835 EXIT:
1836 FunctionOut();
1837
1838 return ret;
1839 }
1840
1841 OMX_ERRORTYPE Exynos_VP8Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1842 {
1843 OMX_ERRORTYPE ret = OMX_ErrorNone;
1844 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1845 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1846 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1847
1848 FunctionIn();
1849
1850 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1851 ret = OMX_ErrorNone;
1852 goto EXIT;
1853 }
1854 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1855 ret = OMX_ErrorNone;
1856 goto EXIT;
1857 }
1858 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1859 if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
1860 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1861 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1862 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
1863 }
1864 if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) {
1865 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ);
1866 if (pBufferInfo == NULL) {
1867 ret = OMX_ErrorUndefined;
1868 goto EXIT;
1869 }
1870
1871 pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags;
1872 pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
1873 Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
1874 Exynos_OSAL_Free(pBufferInfo);
1875
1876 ret = OMX_ErrorNone;
1877 goto EXIT;
1878 }
1879 }
1880 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) {
1881 ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData);
1882 if (ret != OMX_ErrorNone) {
1883 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1884 pExynosComponent->callbackData,
1885 OMX_EventError, ret, 0, NULL);
1886 }
1887 }
1888
1889 EXIT:
1890 FunctionOut();
1891
1892 return ret;
1893 }
1894
1895 OMX_ERRORTYPE Exynos_VP8Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1896 {
1897 OMX_ERRORTYPE ret = OMX_ErrorNone;
1898 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1899 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1900 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1901
1902 FunctionIn();
1903
1904 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1905 ret = OMX_ErrorNone;
1906 goto EXIT;
1907 }
1908 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1909 ret = OMX_ErrorNone;
1910 goto EXIT;
1911 }
1912
1913 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1914 if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
1915 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1916 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1917 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
1918 }
1919 if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) {
1920 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
1921 OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
1922 BYPASS_BUFFER_INFO *pBufferInfo = NULL;
1923
1924 if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
1925 pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
1926 if (pOMXBuffer == NULL) {
1927 ret = OMX_ErrorUndefined;
1928 goto EXIT;
1929 }
1930 } else {
1931 pOMXBuffer = dstOutputUseBuffer->bufferHeader;
1932 }
1933
1934 pBufferInfo = Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ);
1935 if (pBufferInfo == NULL) {
1936 ret = OMX_ErrorUndefined;
1937 goto EXIT;
1938 }
1939
1940 pOMXBuffer->nFlags = pBufferInfo->nFlags;
1941 pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp;
1942 Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
1943 Exynos_OSAL_Free(pBufferInfo);
1944
1945 dstOutputUseBuffer->dataValid = OMX_FALSE;
1946
1947 ret = OMX_ErrorNone;
1948 goto EXIT;
1949 }
1950 }
1951 ret = Exynos_VP8Dec_DstOut(pOMXComponent, pDstOutputData);
1952 if ((ret != OMX_ErrorNone) &&
1953 (pExynosComponent->currentState == OMX_StateExecuting)) {
1954 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1955 pExynosComponent->callbackData,
1956 OMX_EventError, ret, 0, NULL);
1957 }
1958
1959 EXIT:
1960 FunctionOut();
1961
1962 return ret;
1963 }
1964
1965 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
1966 OMX_HANDLETYPE hComponent,
1967 OMX_STRING componentName)
1968 {
1969 OMX_ERRORTYPE ret = OMX_ErrorNone;
1970 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1971 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1972 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1973 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1974 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
1975 int i = 0;
1976
1977 FunctionIn();
1978
1979 if ((hComponent == NULL) || (componentName == NULL)) {
1980 ret = OMX_ErrorBadParameter;
1981 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
1982 goto EXIT;
1983 }
1984 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) {
1985 ret = OMX_ErrorBadParameter;
1986 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
1987 goto EXIT;
1988 }
1989
1990 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1991 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
1992 if (ret != OMX_ErrorNone) {
1993 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1994 goto EXIT;
1995 }
1996 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1997 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
1998
1999 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2000 if (pExynosComponent->componentName == NULL) {
2001 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2002 ret = OMX_ErrorInsufficientResources;
2003 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2004 goto EXIT;
2005 }
2006 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2007
2008 pVp8Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8DEC_HANDLE));
2009 if (pVp8Dec == NULL) {
2010 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2011 ret = OMX_ErrorInsufficientResources;
2012 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2013 goto EXIT;
2014 }
2015 Exynos_OSAL_Memset(pVp8Dec, 0, sizeof(EXYNOS_VP8DEC_HANDLE));
2016 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2017 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec;
2018
2019 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_DEC);
2020
2021 /* Set componentVersion */
2022 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2023 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2024 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2025 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2026 /* Set specVersion */
2027 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2028 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2029 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2030 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2031
2032 /* Input port */
2033 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2034 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2035 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2036 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2037 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2038 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2039 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
2040 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2041 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8");
2042 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2043 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2044 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2045 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2046 pExynosPort->bufferProcessType = BUFFER_SHARE;
2047 pExynosPort->portWayType = WAY2_PORT;
2048
2049 /* Output port */
2050 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2051 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2052 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2053 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2054 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2055 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2056 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2057 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2058 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2059 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2060 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2061 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2062 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2063 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2064 pExynosPort->portWayType = WAY2_PORT;
2065
2066 pOMXComponent->GetParameter = &Exynos_VP8Dec_GetParameter;
2067 pOMXComponent->SetParameter = &Exynos_VP8Dec_SetParameter;
2068 pOMXComponent->GetConfig = &Exynos_VP8Dec_GetConfig;
2069 pOMXComponent->SetConfig = &Exynos_VP8Dec_SetConfig;
2070 pOMXComponent->GetExtensionIndex = &Exynos_VP8Dec_GetExtensionIndex;
2071 pOMXComponent->ComponentRoleEnum = &Exynos_VP8Dec_ComponentRoleEnum;
2072 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2073
2074 pExynosComponent->exynos_codec_componentInit = &Exynos_VP8Dec_Init;
2075 pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Dec_Terminate;
2076
2077 pVideoDec->exynos_codec_srcInputProcess = &Exynos_VP8Dec_srcInputBufferProcess;
2078 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP8Dec_srcOutputBufferProcess;
2079 pVideoDec->exynos_codec_dstInputProcess = &Exynos_VP8Dec_dstInputBufferProcess;
2080 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP8Dec_dstOutputBufferProcess;
2081
2082 pVideoDec->exynos_codec_start = &VP8CodecStart;
2083 pVideoDec->exynos_codec_stop = &VP8CodecStop;
2084 pVideoDec->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun;
2085 pVideoDec->exynos_codec_enqueueAllBuffer = &VP8CodecEnQueueAllBuffer;
2086
2087 pVideoDec->exynos_checkInputFrame = &Check_VP8_Frame;
2088 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2089 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2090
2091 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2092 if (pVideoDec->hSharedMemory == NULL) {
2093 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2094 Exynos_OSAL_Free(pVp8Dec);
2095 pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2096 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2097 ret = OMX_ErrorInsufficientResources;
2098 goto EXIT;
2099 }
2100
2101 pExynosComponent->currentState = OMX_StateLoaded;
2102
2103 ret = OMX_ErrorNone;
2104
2105 EXIT:
2106 FunctionOut();
2107
2108 return ret;
2109 }
2110
2111 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
2112 OMX_HANDLETYPE hComponent)
2113 {
2114 OMX_ERRORTYPE ret = OMX_ErrorNone;
2115 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2116 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2117 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2118 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
2119
2120 FunctionIn();
2121
2122 if (hComponent == NULL) {
2123 ret = OMX_ErrorBadParameter;
2124 goto EXIT;
2125 }
2126 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2127 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2128 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2129
2130 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2131
2132 Exynos_OSAL_Free(pExynosComponent->componentName);
2133 pExynosComponent->componentName = NULL;
2134
2135 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
2136 if (pVp8Dec != NULL) {
2137 Exynos_OSAL_Free(pVp8Dec);
2138 pVp8Dec = pVideoDec->hCodecHandle = NULL;
2139 }
2140
2141 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2142 if (ret != OMX_ErrorNone) {
2143 goto EXIT;
2144 }
2145
2146 ret = OMX_ErrorNone;
2147
2148 EXIT:
2149 FunctionOut();
2150
2151 return ret;
2152 }