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