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