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