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