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