openmax: Change DPB setting scheme.
[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 VP8CodecRegistCodecBuffers(
456 OMX_COMPONENTTYPE *pOMXComponent,
457 OMX_U32 nPortIndex,
458 OMX_U32 nBufferCnt)
459 {
460 OMX_ERRORTYPE ret = OMX_ErrorNone;
461 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
462 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
463 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
464 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
465 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
466 ExynosVideoDecBufferOps *pBufOps = NULL;
467 ExynosVideoPlane *pPlanes = NULL;
468
469 OMX_U32 nPlaneCnt = 0;
470 int i, j;
471
472 FunctionIn();
473
474 if (nPortIndex == INPUT_PORT_INDEX) {
475 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
476 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
477 pBufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
478 } else {
479 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
480 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
481 pBufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
482 }
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 OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
591 OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
592 if (OMXBuffer == NULL) {
593 ret = OMX_ErrorUndefined;
594 goto EXIT;
595 }
596
597 OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
598 OMXBuffer->nFlags = pSrcInputData->nFlags;
599 Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
600
601 ret = OMX_ErrorNone;
602 goto EXIT;
603 }
604
605 if (pVideoDec->bThumbnailMode == OMX_TRUE)
606 pDecOps->Set_DisplayDelay(hMFCHandle, 0);
607
608 if ((pDecOps->Enable_DTSMode != NULL) &&
609 (pVideoDec->bDTSMode == OMX_TRUE))
610 pDecOps->Enable_DTSMode(hMFCHandle);
611
612 /* input buffer info */
613 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
614 bufferConf.eCompressionFormat = VIDEO_CODING_VP8;
615 pInbufOps->Set_Shareable(hMFCHandle);
616 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
617 bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
618 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
619 inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
620 } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
621 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
622 inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
623 }
624
625 /* should be done before prepare input buffer */
626 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
627 ret = OMX_ErrorInsufficientResources;
628 goto EXIT;
629 }
630
631 /* set input buffer geometry */
632 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
633 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
634 ret = OMX_ErrorInsufficientResources;
635 goto EXIT;
636 }
637
638 /* setup input buffer */
639 if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
640 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
641 ret = OMX_ErrorInsufficientResources;
642 goto EXIT;
643 }
644
645 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
646 ret = VP8CodecRegistCodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX);
647 if (ret != OMX_ErrorNone)
648 goto EXIT;
649 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
650 /* Register input buffer */
651 for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
652 ExynosVideoPlane plane;
653 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
654 plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
655 plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
656 if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
657 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
658 ret = OMX_ErrorInsufficientResources;
659 goto EXIT;
660 }
661 }
662 }
663
664 /* set output geometry */
665 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
666 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
667 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
668 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
669 ret = OMX_ErrorInsufficientResources;
670 goto EXIT;
671 }
672
673 /* input buffer enqueue for header parsing */
674 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
675 if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
676 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
677 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
678 // ret = OMX_ErrorInsufficientResources;
679 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
680 goto EXIT;
681 }
682
683 /* start header parsing */
684 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
685 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
686 ret = OMX_ErrorCodecInit;
687 goto EXIT;
688 }
689
690 /* get geometry for output */
691 Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
692 if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
693 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
694 ret = OMX_ErrorInsufficientResources;
695 goto EXIT;
696 }
697
698 /* get dpb count */
699 pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
700 if (pVideoDec->bThumbnailMode == OMX_FALSE)
701 pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM;
702 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8CodecSetup nOutbufs: %d", pVp8Dec->hMFCVp8Handle.maxDPBNum);
703
704 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE;
705
706 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
707 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
708 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) {
709 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
710
711 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
712 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
713 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
714 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
715
716 Exynos_UpdateFrameSize(pOMXComponent);
717
718 /** Send Port Settings changed call back **/
719 (*(pExynosComponent->pCallbacks->EventHandler))
720 (pOMXComponent,
721 pExynosComponent->callbackData,
722 OMX_EventPortSettingsChanged, /* The command was completed */
723 OMX_DirOutput, /* This is the port index */
724 0,
725 NULL);
726 }
727 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
728 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
729 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) ||
730 (pExynosOutputPort->portDefinition.nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) {
731 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
732
733 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
734 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
735 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
736 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
737
738 pExynosOutputPort->portDefinition.nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum - 2;
739 pExynosOutputPort->portDefinition.nBufferCountMin = pVp8Dec->hMFCVp8Handle.maxDPBNum - 2;
740
741 Exynos_UpdateFrameSize(pOMXComponent);
742
743 /** Send Port Settings changed call back **/
744 (*(pExynosComponent->pCallbacks->EventHandler))
745 (pOMXComponent,
746 pExynosComponent->callbackData,
747 OMX_EventPortSettingsChanged, /* The command was completed */
748 OMX_DirOutput, /* This is the port index */
749 0,
750 NULL);
751 }
752 }
753 Exynos_OSAL_SleepMillisec(0);
754 ret = OMX_ErrorInputDataDecodeYet;
755 VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
756
757 EXIT:
758 FunctionOut();
759
760 return ret;
761 }
762
763 OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
764 {
765 OMX_ERRORTYPE ret = OMX_ErrorNone;
766 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
767 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
768 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
769 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
770 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
771 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
772
773 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
774 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
775 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
776
777 int i, nOutbufs;
778
779 OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
780 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
781
782 FunctionIn();
783
784 nAllocLen[0] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[0];
785 nAllocLen[1] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[1];
786
787 pOutbufOps->Set_Shareable(hMFCHandle);
788
789 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
790 /* should be done before prepare output buffer */
791 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
792 ret = OMX_ErrorInsufficientResources;
793 goto EXIT;
794 }
795
796 /* get dpb count */
797 nOutbufs = pVp8Dec->hMFCVp8Handle.maxDPBNum;
798 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
799 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
800 ret = OMX_ErrorInsufficientResources;
801 goto EXIT;
802 }
803
804 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
805 if (ret != OMX_ErrorNone)
806 goto EXIT;
807
808 ret = VP8CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
809 if (ret != OMX_ErrorNone)
810 goto EXIT;
811
812 /* Enqueue output buffer */
813 for (i = 0; i < nOutbufs; i++) {
814 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
815 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
816 }
817
818 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
819 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
820 ret = OMX_ErrorInsufficientResources;
821 goto EXIT;
822 }
823 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
824 ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
825 int plane;
826
827 /* get dpb count */
828 nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
829 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
830 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
831 ret = OMX_ErrorInsufficientResources;
832 goto EXIT;
833 }
834
835 /* Register output buffer */
836 /*************/
837 /* TBD */
838 /*************/
839 #ifdef USE_ANB
840 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) {
841 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
842 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
843 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
844 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
845 planes[plane].allocSize = nAllocLen[plane];
846 }
847
848 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
849 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
850 ret = OMX_ErrorInsufficientResources;
851 goto EXIT;
852 }
853 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
854 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
855 }
856
857 if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
858 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
859 ret = OMX_ErrorHardware;
860 goto EXIT;
861 }
862 } else {
863 ret = OMX_ErrorNotImplemented;
864 goto EXIT;
865 }
866 #else
867 ret = OMX_ErrorNotImplemented;
868 goto EXIT;
869 #endif
870 }
871
872 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
873
874 ret = OMX_ErrorNone;
875
876 EXIT:
877 FunctionOut();
878
879 return ret;
880 }
881
882 OMX_ERRORTYPE Exynos_VP8Dec_GetParameter(
883 OMX_IN OMX_HANDLETYPE hComponent,
884 OMX_IN OMX_INDEXTYPE nParamIndex,
885 OMX_INOUT OMX_PTR pComponentParameterStructure)
886 {
887 OMX_ERRORTYPE ret = OMX_ErrorNone;
888 OMX_COMPONENTTYPE *pOMXComponent = NULL;
889 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
890
891 FunctionIn();
892
893 if (hComponent == NULL || pComponentParameterStructure == NULL) {
894 ret = OMX_ErrorBadParameter;
895 goto EXIT;
896 }
897 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
898 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
899 if (ret != OMX_ErrorNone) {
900 goto EXIT;
901 }
902 if (pOMXComponent->pComponentPrivate == NULL) {
903 ret = OMX_ErrorBadParameter;
904 goto EXIT;
905 }
906
907 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
908 if (pExynosComponent->currentState == OMX_StateInvalid ) {
909 ret = OMX_ErrorInvalidState;
910 goto EXIT;
911 }
912
913 switch (nParamIndex) {
914 case OMX_IndexParamStandardComponentRole:
915 {
916 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
917 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
918 if (ret != OMX_ErrorNone) {
919 goto EXIT;
920 }
921
922 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
923 }
924 break;
925 case OMX_IndexParamVideoErrorCorrection:
926 {
927 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
928 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
929 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
930
931 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
932 if (ret != OMX_ErrorNone) {
933 goto EXIT;
934 }
935
936 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
937 ret = OMX_ErrorBadPortIndex;
938 goto EXIT;
939 }
940
941 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
942 pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
943
944 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
945 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
946 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
947 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
948 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
949 }
950 break;
951 default:
952 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
953 break;
954 }
955 EXIT:
956 FunctionOut();
957
958 return ret;
959 }
960
961 OMX_ERRORTYPE Exynos_VP8Dec_SetParameter(
962 OMX_IN OMX_HANDLETYPE hComponent,
963 OMX_IN OMX_INDEXTYPE nIndex,
964 OMX_IN OMX_PTR pComponentParameterStructure)
965 {
966 OMX_ERRORTYPE ret = OMX_ErrorNone;
967 OMX_COMPONENTTYPE *pOMXComponent = NULL;
968 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
969
970 FunctionIn();
971
972 if (hComponent == NULL || pComponentParameterStructure == NULL) {
973 ret = OMX_ErrorBadParameter;
974 goto EXIT;
975 }
976 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
977 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
978 if (ret != OMX_ErrorNone) {
979 goto EXIT;
980 }
981 if (pOMXComponent->pComponentPrivate == NULL) {
982 ret = OMX_ErrorBadParameter;
983 goto EXIT;
984 }
985
986 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
987 if (pExynosComponent->currentState == OMX_StateInvalid ) {
988 ret = OMX_ErrorInvalidState;
989 goto EXIT;
990 }
991
992 switch (nIndex) {
993 case OMX_IndexParamStandardComponentRole:
994 {
995 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
996
997 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
998 if (ret != OMX_ErrorNone) {
999 goto EXIT;
1000 }
1001
1002 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1003 ret = OMX_ErrorIncorrectStateOperation;
1004 goto EXIT;
1005 }
1006
1007 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) {
1008 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX;
1009 } else {
1010 ret = OMX_ErrorBadParameter;
1011 goto EXIT;
1012 }
1013 }
1014 break;
1015 case OMX_IndexParamVideoErrorCorrection:
1016 {
1017 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1018 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1019 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
1020
1021 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1022 if (ret != OMX_ErrorNone) {
1023 goto EXIT;
1024 }
1025
1026 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1027 ret = OMX_ErrorBadPortIndex;
1028 goto EXIT;
1029 }
1030
1031 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1032 pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
1033
1034 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1035 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1036 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1037 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1038 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1039 }
1040 break;
1041 default:
1042 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1043 break;
1044 }
1045 EXIT:
1046 FunctionOut();
1047
1048 return ret;
1049 }
1050
1051 OMX_ERRORTYPE Exynos_VP8Dec_GetConfig(
1052 OMX_HANDLETYPE hComponent,
1053 OMX_INDEXTYPE nIndex,
1054 OMX_PTR pComponentConfigStructure)
1055 {
1056 OMX_ERRORTYPE ret = OMX_ErrorNone;
1057 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1058 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1059
1060 FunctionIn();
1061
1062 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1063 ret = OMX_ErrorBadParameter;
1064 goto EXIT;
1065 }
1066 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1067 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1068 if (ret != OMX_ErrorNone) {
1069 goto EXIT;
1070 }
1071 if (pOMXComponent->pComponentPrivate == NULL) {
1072 ret = OMX_ErrorBadParameter;
1073 goto EXIT;
1074 }
1075 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1076 if (pExynosComponent->currentState == OMX_StateInvalid) {
1077 ret = OMX_ErrorInvalidState;
1078 goto EXIT;
1079 }
1080
1081 switch (nIndex) {
1082 default:
1083 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1084 break;
1085 }
1086
1087 EXIT:
1088 FunctionOut();
1089
1090 return ret;
1091 }
1092
1093 OMX_ERRORTYPE Exynos_VP8Dec_SetConfig(
1094 OMX_HANDLETYPE hComponent,
1095 OMX_INDEXTYPE nIndex,
1096 OMX_PTR pComponentConfigStructure)
1097 {
1098 OMX_ERRORTYPE ret = OMX_ErrorNone;
1099 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1100 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1101
1102 FunctionIn();
1103
1104 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1105 ret = OMX_ErrorBadParameter;
1106 goto EXIT;
1107 }
1108 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1109 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1110 if (ret != OMX_ErrorNone) {
1111 goto EXIT;
1112 }
1113 if (pOMXComponent->pComponentPrivate == NULL) {
1114 ret = OMX_ErrorBadParameter;
1115 goto EXIT;
1116 }
1117 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1118 if (pExynosComponent->currentState == OMX_StateInvalid) {
1119 ret = OMX_ErrorInvalidState;
1120 goto EXIT;
1121 }
1122
1123 switch (nIndex) {
1124 default:
1125 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1126 break;
1127 }
1128
1129 EXIT:
1130 FunctionOut();
1131
1132 return ret;
1133 }
1134
1135 OMX_ERRORTYPE Exynos_VP8Dec_GetExtensionIndex(
1136 OMX_IN OMX_HANDLETYPE hComponent,
1137 OMX_IN OMX_STRING cParameterName,
1138 OMX_OUT OMX_INDEXTYPE *pIndexType)
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) {
1147 ret = OMX_ErrorBadParameter;
1148 goto EXIT;
1149 }
1150 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1151 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1152 if (ret != OMX_ErrorNone) {
1153 goto EXIT;
1154 }
1155 if (pOMXComponent->pComponentPrivate == NULL) {
1156 ret = OMX_ErrorBadParameter;
1157 goto EXIT;
1158 }
1159 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1160 if ((cParameterName == NULL) || (pIndexType == NULL)) {
1161 ret = OMX_ErrorBadParameter;
1162 goto EXIT;
1163 }
1164 if (pExynosComponent->currentState == OMX_StateInvalid) {
1165 ret = OMX_ErrorInvalidState;
1166 goto EXIT;
1167 }
1168
1169 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1170 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1171 *pIndexType = OMX_IndexVendorThumbnailMode;
1172 ret = OMX_ErrorNone;
1173 } else {
1174 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1175 }
1176
1177 EXIT:
1178 FunctionOut();
1179
1180 return ret;
1181 }
1182
1183 OMX_ERRORTYPE Exynos_VP8Dec_ComponentRoleEnum(
1184 OMX_HANDLETYPE hComponent,
1185 OMX_U8 *cRole,
1186 OMX_U32 nIndex)
1187 {
1188 OMX_ERRORTYPE ret = OMX_ErrorNone;
1189 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1190 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1191
1192 FunctionIn();
1193
1194 if ((hComponent == NULL) || (cRole == NULL)) {
1195 ret = OMX_ErrorBadParameter;
1196 goto EXIT;
1197 }
1198 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1199 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
1200 ret = OMX_ErrorNone;
1201 } else {
1202 ret = OMX_ErrorNoMore;
1203 }
1204
1205 EXIT:
1206 FunctionOut();
1207
1208 return ret;
1209 }
1210
1211 /* MFC Init */
1212 OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1213 {
1214 OMX_ERRORTYPE ret = OMX_ErrorNone;
1215 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1216 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1217 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1218 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1219 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
1220 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1221
1222 ExynosVideoDecOps *pDecOps = NULL;
1223 ExynosVideoDecBufferOps *pInbufOps = NULL;
1224 ExynosVideoDecBufferOps *pOutbufOps = NULL;
1225
1226 CSC_METHOD csc_method = CSC_METHOD_SW;
1227 int i, plane;
1228
1229 FunctionIn();
1230
1231 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
1232 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
1233 pExynosComponent->bUseFlagEOF = OMX_TRUE;
1234 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1235
1236 /* VP8 Codec Open */
1237 ret = VP8CodecOpen(pVp8Dec);
1238 if (ret != OMX_ErrorNone) {
1239 goto EXIT;
1240 }
1241
1242 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1243 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1244 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1245
1246 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1247 OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE};
1248 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1249 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1250 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
1251 if (ret != OMX_ErrorNone)
1252 goto EXIT;
1253
1254 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
1255 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1256 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1257 /*************/
1258 /* TBD */
1259 /*************/
1260 /* Does not require any actions. */
1261 }
1262
1263 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1264 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1265 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1266 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1267 /*************/
1268 /* TBD */
1269 /*************/
1270 /* Does not require any actions. */
1271 }
1272
1273 pVp8Dec->bSourceStart = OMX_FALSE;
1274 Exynos_OSAL_SignalCreate(&pVp8Dec->hSourceStartEvent);
1275 pVp8Dec->bDestinationStart = OMX_FALSE;
1276 Exynos_OSAL_SignalCreate(&pVp8Dec->hDestinationStartEvent);
1277
1278 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1279 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1280 pVp8Dec->hMFCVp8Handle.indexTimestamp = 0;
1281 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0;
1282
1283 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1284
1285 #ifdef USE_CSC_HW
1286 csc_method = CSC_METHOD_HW;
1287 #endif
1288 pVideoDec->csc_handle = csc_init(csc_method);
1289 if (pVideoDec->csc_handle == NULL) {
1290 ret = OMX_ErrorInsufficientResources;
1291 goto EXIT;
1292 }
1293 pVideoDec->csc_set_format = OMX_FALSE;
1294
1295 EXIT:
1296 FunctionOut();
1297
1298 return ret;
1299 }
1300
1301 /* MFC Terminate */
1302 OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1303 {
1304 OMX_ERRORTYPE ret = OMX_ErrorNone;
1305 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1306 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1307 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1308 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1309 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1310 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1311
1312 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1313 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1314 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1315
1316 int i, plane;
1317
1318 FunctionIn();
1319
1320 if (pVideoDec->csc_handle != NULL) {
1321 csc_deinit(pVideoDec->csc_handle);
1322 pVideoDec->csc_handle = NULL;
1323 }
1324
1325 Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationStartEvent);
1326 pVp8Dec->hDestinationStartEvent = NULL;
1327 pVp8Dec->bDestinationStart = OMX_FALSE;
1328 Exynos_OSAL_SignalTerminate(pVp8Dec->hSourceStartEvent);
1329 pVp8Dec->hSourceStartEvent = NULL;
1330 pVp8Dec->bSourceStart = OMX_FALSE;
1331
1332 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1333 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
1334 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1335 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1336 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1337 /*************/
1338 /* TBD */
1339 /*************/
1340 /* Does not require any actions. */
1341 }
1342
1343 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1344 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
1345 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1346 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1347 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1348 /*************/
1349 /* TBD */
1350 /*************/
1351 /* Does not require any actions. */
1352 }
1353 VP8CodecClose(pVp8Dec);
1354
1355 EXIT:
1356 FunctionOut();
1357
1358 return ret;
1359 }
1360
1361 OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1362 {
1363 OMX_ERRORTYPE ret = OMX_ErrorNone;
1364 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1365 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1366 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1367 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1368 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1369 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1370 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1371 OMX_BOOL bInStartCode = OMX_FALSE;
1372 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1373 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1374 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1375 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1376 int i;
1377
1378 FunctionIn();
1379
1380 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
1381 ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
1382 goto EXIT;
1383 }
1384 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) {
1385 ret = VP8CodecDstSetup(pOMXComponent);
1386 }
1387
1388 if (((bInStartCode = Check_VP8_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE) ||
1389 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1390 pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->timeStamp;
1391 pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->nFlags;
1392 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);
1393 pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp);
1394 pVp8Dec->hMFCVp8Handle.indexTimestamp++;
1395 pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP;
1396
1397 /* queue work for input buffer */
1398 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1399 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1400 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1401 if (codecReturn != VIDEO_ERROR_NONE) {
1402 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1403 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1404 goto EXIT;
1405 }
1406 VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1407 if (pVp8Dec->bSourceStart == OMX_FALSE) {
1408 pVp8Dec->bSourceStart = OMX_TRUE;
1409 Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent);
1410 Exynos_OSAL_SleepMillisec(0);
1411 }
1412 if (pVp8Dec->bDestinationStart == OMX_FALSE) {
1413 pVp8Dec->bDestinationStart = OMX_TRUE;
1414 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
1415 Exynos_OSAL_SleepMillisec(0);
1416 }
1417 } else if (bInStartCode == OMX_FALSE) {
1418 ret = OMX_ErrorCorruptedFrame;
1419 goto EXIT;
1420 }
1421
1422 ret = OMX_ErrorNone;
1423
1424 EXIT:
1425 FunctionOut();
1426
1427 return ret;
1428 }
1429
1430 OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1431 {
1432 OMX_ERRORTYPE ret = OMX_ErrorNone;
1433 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1434 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1435 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1436 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1437 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1438 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1439 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
1440 ExynosVideoBuffer *pVideoBuffer;
1441
1442 FunctionIn();
1443
1444 pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1445
1446 pSrcOutputData->dataLen = 0;
1447 pSrcOutputData->usedDataLen = 0;
1448 pSrcOutputData->remainDataLen = 0;
1449 pSrcOutputData->nFlags = 0;
1450 pSrcOutputData->timeStamp = 0;
1451
1452 if (pVideoBuffer == NULL) {
1453 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1454 pSrcOutputData->allocSize = 0;
1455 pSrcOutputData->pPrivate = NULL;
1456 pSrcOutputData->bufferHeader = NULL;
1457 } else {
1458 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1459 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1460 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1461
1462 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1463 int i;
1464 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1465 if (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer ==
1466 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1467 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1468 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1469 break;
1470 }
1471 }
1472
1473 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1474 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1475 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1476 goto EXIT;
1477 }
1478 }
1479
1480 /* For Share Buffer */
1481 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1482 }
1483
1484 ret = OMX_ErrorNone;
1485
1486 EXIT:
1487 FunctionOut();
1488
1489 return ret;
1490 }
1491
1492 OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1493 {
1494 OMX_ERRORTYPE ret = OMX_ErrorNone;
1495 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1496 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1497 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1498 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1499 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1500 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1501 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1502 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
1503 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1504
1505 FunctionIn();
1506
1507 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1508 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1509 ret = OMX_ErrorBadParameter;
1510 goto EXIT;
1511 }
1512
1513 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
1514 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
1515 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
1516
1517 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1518 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
1519
1520 if (codecReturn != VIDEO_ERROR_NONE) {
1521 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1522 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1523 goto EXIT;
1524 }
1525 VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1526
1527 ret = OMX_ErrorNone;
1528
1529 EXIT:
1530 FunctionOut();
1531
1532 return ret;
1533 }
1534
1535 OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1536 {
1537 OMX_ERRORTYPE ret = OMX_ErrorNone;
1538 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1539 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1540 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1541 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
1542 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1543 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1544 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
1545 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
1546 ExynosVideoBuffer *pVideoBuffer = NULL;
1547 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1548 ExynosVideoGeometry *bufferGeometry;
1549 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1550 OMX_S32 indexTimestamp = 0;
1551 int plane;
1552
1553 FunctionIn();
1554
1555 if (pVp8Dec->bDestinationStart == OMX_FALSE) {
1556 ret = OMX_ErrorNone;
1557 goto EXIT;
1558 }
1559
1560 while (1) {
1561 if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1562 ret = OMX_ErrorNone;
1563 goto EXIT;
1564 }
1565 displayStatus = pVideoBuffer->displayStatus;
1566 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1567
1568 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1569 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1570 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1571 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
1572 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1573 ret = OMX_ErrorNone;
1574 break;
1575 }
1576 }
1577
1578 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++;
1579 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1580
1581 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
1582 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1583 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1584 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1585 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1586 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
1587 }
1588 pDstOutputData->usedDataLen = 0;
1589 pDstOutputData->pPrivate = pVideoBuffer;
1590 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1591 int i = 0;
1592 pDstOutputData->pPrivate = NULL;
1593 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1594 if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] ==
1595 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
1596 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
1597 break;
1598 }
1599 }
1600
1601 if (pDstOutputData->pPrivate == NULL) {
1602 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1603 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1604 goto EXIT;
1605 }
1606 }
1607
1608 /* For Share Buffer */
1609 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1610
1611 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1612 bufferGeometry = &pVp8Dec->hMFCVp8Handle.codecOutbufConf;
1613 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1614 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1615 switch (bufferGeometry->eColorFormat) {
1616 case VIDEO_COLORFORMAT_NV12:
1617 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1618 break;
1619 case VIDEO_COLORFORMAT_NV12_TILED:
1620 default:
1621 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1622 break;
1623 }
1624
1625 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
1626 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
1627 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1628 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
1629 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
1630 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
1631 pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
1632 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
1633 } else {
1634 pDstOutputData->timeStamp = 0x00;
1635 pDstOutputData->nFlags = 0x00;
1636 }
1637 } else {
1638 /* For timestamp correction. if mfc support frametype detect */
1639 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
1640
1641 /* NEED TIMESTAMP REORDER */
1642 if (pVideoDec->bDTSMode == OMX_TRUE) {
1643 if (pVideoBuffer->frameType == VIDEO_FRAME_I)
1644 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp;
1645 else
1646 indexTimestamp = pVp8Dec->hMFCVp8Handle.outputIndexTimestamp;
1647 }
1648
1649 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1650 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1651
1652 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
1653 }
1654
1655 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1656 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
1657 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1658 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
1659 pDstOutputData->remainDataLen = 0;
1660 } else {
1661 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
1662 }
1663
1664 ret = OMX_ErrorNone;
1665
1666 EXIT:
1667 FunctionOut();
1668
1669 return ret;
1670 }
1671
1672 OMX_ERRORTYPE Exynos_VP8Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1673 {
1674 OMX_ERRORTYPE ret = OMX_ErrorNone;
1675 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1676 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1677 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1678
1679 FunctionIn();
1680
1681 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1682 ret = OMX_ErrorNone;
1683 goto EXIT;
1684 }
1685 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1686 ret = OMX_ErrorNone;
1687 goto EXIT;
1688 }
1689
1690 ret = Exynos_VP8Dec_SrcIn(pOMXComponent, pSrcInputData);
1691 if ((ret != OMX_ErrorNone) &&
1692 (ret != OMX_ErrorInputDataDecodeYet) &&
1693 (ret != OMX_ErrorCorruptedFrame)) {
1694 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1695 pExynosComponent->callbackData,
1696 OMX_EventError, ret, 0, NULL);
1697 }
1698
1699 EXIT:
1700 FunctionOut();
1701
1702 return ret;
1703 }
1704
1705 OMX_ERRORTYPE Exynos_VP8Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1706 {
1707 OMX_ERRORTYPE ret = OMX_ErrorNone;
1708 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1709 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1710 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1711
1712 FunctionIn();
1713
1714 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1715 ret = OMX_ErrorNone;
1716 goto EXIT;
1717 }
1718
1719 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1720 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1721 ret = OMX_ErrorNone;
1722 goto EXIT;
1723 }
1724 }
1725 if ((pVp8Dec->bSourceStart == OMX_FALSE) &&
1726 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
1727 Exynos_OSAL_SignalWait(pVp8Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
1728 Exynos_OSAL_SignalReset(pVp8Dec->hSourceStartEvent);
1729 }
1730
1731 ret = Exynos_VP8Dec_SrcOut(pOMXComponent, pSrcOutputData);
1732 if ((ret != OMX_ErrorNone) &&
1733 (pExynosComponent->currentState == OMX_StateExecuting)) {
1734 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1735 pExynosComponent->callbackData,
1736 OMX_EventError, ret, 0, NULL);
1737 }
1738
1739 EXIT:
1740 FunctionOut();
1741
1742 return ret;
1743 }
1744
1745 OMX_ERRORTYPE Exynos_VP8Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1746 {
1747 OMX_ERRORTYPE ret = OMX_ErrorNone;
1748 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1749 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1750 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1751
1752 FunctionIn();
1753
1754 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1755 ret = OMX_ErrorNone;
1756 goto EXIT;
1757 }
1758 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1759 ret = OMX_ErrorNone;
1760 goto EXIT;
1761 }
1762 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1763 if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
1764 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1765 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1766 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
1767 }
1768 }
1769 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) {
1770 ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData);
1771 if (ret != OMX_ErrorNone) {
1772 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1773 pExynosComponent->callbackData,
1774 OMX_EventError, ret, 0, NULL);
1775 }
1776 }
1777
1778 EXIT:
1779 FunctionOut();
1780
1781 return ret;
1782 }
1783
1784 OMX_ERRORTYPE Exynos_VP8Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1785 {
1786 OMX_ERRORTYPE ret = OMX_ErrorNone;
1787 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1788 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1789 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1790
1791 FunctionIn();
1792
1793 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1794 ret = OMX_ErrorNone;
1795 goto EXIT;
1796 }
1797 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1798 ret = OMX_ErrorNone;
1799 goto EXIT;
1800 }
1801
1802 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1803 if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
1804 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1805 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1806 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
1807 }
1808 }
1809 ret = Exynos_VP8Dec_DstOut(pOMXComponent, pDstOutputData);
1810 if ((ret != OMX_ErrorNone) &&
1811 (pExynosComponent->currentState == OMX_StateExecuting)) {
1812 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1813 pExynosComponent->callbackData,
1814 OMX_EventError, ret, 0, NULL);
1815 }
1816
1817 EXIT:
1818 FunctionOut();
1819
1820 return ret;
1821 }
1822
1823 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
1824 OMX_HANDLETYPE hComponent,
1825 OMX_STRING componentName)
1826 {
1827 OMX_ERRORTYPE ret = OMX_ErrorNone;
1828 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1829 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1830 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1831 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1832 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
1833 int i = 0;
1834
1835 FunctionIn();
1836
1837 if ((hComponent == NULL) || (componentName == NULL)) {
1838 ret = OMX_ErrorBadParameter;
1839 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
1840 goto EXIT;
1841 }
1842 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) {
1843 ret = OMX_ErrorBadParameter;
1844 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
1845 goto EXIT;
1846 }
1847
1848 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1849 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
1850 if (ret != OMX_ErrorNone) {
1851 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1852 goto EXIT;
1853 }
1854 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1855 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
1856
1857 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
1858 if (pExynosComponent->componentName == NULL) {
1859 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1860 ret = OMX_ErrorInsufficientResources;
1861 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1862 goto EXIT;
1863 }
1864 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
1865
1866 pVp8Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8DEC_HANDLE));
1867 if (pVp8Dec == NULL) {
1868 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1869 ret = OMX_ErrorInsufficientResources;
1870 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1871 goto EXIT;
1872 }
1873 Exynos_OSAL_Memset(pVp8Dec, 0, sizeof(EXYNOS_VP8DEC_HANDLE));
1874 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1875 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec;
1876
1877 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_DEC);
1878
1879 /* Set componentVersion */
1880 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
1881 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
1882 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
1883 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
1884 /* Set specVersion */
1885 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
1886 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
1887 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
1888 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
1889
1890 /* Input port */
1891 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1892 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
1893 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
1894 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
1895 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1896 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
1897 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX;
1898 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
1899 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8");
1900 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1901 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1902 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1903 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
1904 pExynosPort->bufferProcessType = BUFFER_SHARE;
1905 pExynosPort->portWayType = WAY2_PORT;
1906
1907 /* Output port */
1908 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1909 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
1910 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
1911 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
1912 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1913 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1914 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1915 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
1916 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1917 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1918 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1919 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
1920 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
1921 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
1922 pExynosPort->portWayType = WAY2_PORT;
1923
1924 pOMXComponent->GetParameter = &Exynos_VP8Dec_GetParameter;
1925 pOMXComponent->SetParameter = &Exynos_VP8Dec_SetParameter;
1926 pOMXComponent->GetConfig = &Exynos_VP8Dec_GetConfig;
1927 pOMXComponent->SetConfig = &Exynos_VP8Dec_SetConfig;
1928 pOMXComponent->GetExtensionIndex = &Exynos_VP8Dec_GetExtensionIndex;
1929 pOMXComponent->ComponentRoleEnum = &Exynos_VP8Dec_ComponentRoleEnum;
1930 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
1931
1932 pExynosComponent->exynos_codec_componentInit = &Exynos_VP8Dec_Init;
1933 pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Dec_Terminate;
1934
1935 pVideoDec->exynos_codec_srcInputProcess = &Exynos_VP8Dec_srcInputBufferProcess;
1936 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP8Dec_srcOutputBufferProcess;
1937 pVideoDec->exynos_codec_dstInputProcess = &Exynos_VP8Dec_dstInputBufferProcess;
1938 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP8Dec_dstOutputBufferProcess;
1939
1940 pVideoDec->exynos_codec_start = &VP8CodecStart;
1941 pVideoDec->exynos_codec_stop = &VP8CodecStop;
1942 pVideoDec->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun;
1943 pVideoDec->exynos_codec_enqueueAllBuffer = &VP8CodecEnQueueAllBuffer;
1944
1945 pVideoDec->exynos_checkInputFrame = &Check_VP8_Frame;
1946 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
1947 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
1948
1949 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
1950 if (pVideoDec->hSharedMemory == NULL) {
1951 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1952 Exynos_OSAL_Free(pVp8Dec);
1953 pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
1954 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1955 ret = OMX_ErrorInsufficientResources;
1956 goto EXIT;
1957 }
1958
1959 pExynosComponent->currentState = OMX_StateLoaded;
1960
1961 ret = OMX_ErrorNone;
1962
1963 EXIT:
1964 FunctionOut();
1965
1966 return ret;
1967 }
1968
1969 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
1970 OMX_HANDLETYPE hComponent)
1971 {
1972 OMX_ERRORTYPE ret = OMX_ErrorNone;
1973 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1974 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1975 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1976 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
1977
1978 FunctionIn();
1979
1980 if (hComponent == NULL) {
1981 ret = OMX_ErrorBadParameter;
1982 goto EXIT;
1983 }
1984 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1985 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1986 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1987
1988 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
1989
1990 Exynos_OSAL_Free(pExynosComponent->componentName);
1991 pExynosComponent->componentName = NULL;
1992
1993 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
1994 if (pVp8Dec != NULL) {
1995 Exynos_OSAL_Free(pVp8Dec);
1996 pVp8Dec = pVideoDec->hCodecHandle = NULL;
1997 }
1998
1999 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2000 if (ret != OMX_ErrorNone) {
2001 goto EXIT;
2002 }
2003
2004 ret = OMX_ErrorNone;
2005
2006 EXIT:
2007 FunctionOut();
2008
2009 return ret;
2010 }