Exynos_OMX_Vp8dec.c revision bef6209319d736ba1006de1699a04b5ad89e2454
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
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
238EXIT:
239    FunctionOut();
240
241    return ret;
242}
243
244OMX_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
281EXIT:
282    FunctionOut();
283
284    return ret;
285}
286
287OMX_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
326EXIT:
327    FunctionOut();
328
329    return ret;
330}
331
332OMX_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
372EXIT:
373    FunctionOut();
374
375    return ret;
376}
377
378OMX_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
425EXIT:
426    FunctionOut();
427
428    return ret;
429}
430
431OMX_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
479EXIT:
480    FunctionOut();
481
482    return ret;
483}
484
485OMX_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
687EXIT:
688    FunctionOut();
689
690    return ret;
691}
692
693OMX_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
823EXIT:
824    FunctionOut();
825
826    return ret;
827}
828
829OMX_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    }
902EXIT:
903    FunctionOut();
904
905    return ret;
906}
907
908OMX_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    }
992EXIT:
993    FunctionOut();
994
995    return ret;
996}
997
998OMX_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
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) {
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
1090EXIT:
1091    FunctionOut();
1092
1093    return ret;
1094}
1095
1096OMX_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
1140EXIT:
1141    FunctionOut();
1142
1143    return ret;
1144}
1145
1146OMX_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
1168EXIT:
1169    FunctionOut();
1170
1171    return ret;
1172}
1173
1174/* MFC Init */
1175OMX_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
1276EXIT:
1277    FunctionOut();
1278
1279    return ret;
1280}
1281
1282/* MFC Terminate */
1283OMX_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
1367EXIT:
1368    FunctionOut();
1369
1370    return ret;
1371}
1372
1373OMX_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
1432EXIT:
1433
1434    FunctionOut();
1435
1436    return ret;
1437}
1438
1439OMX_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
1495EXIT:
1496    FunctionOut();
1497
1498    return ret;
1499}
1500
1501OMX_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
1531EXIT:
1532    FunctionOut();
1533
1534    return ret;
1535}
1536
1537OMX_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
1673EXIT:
1674    FunctionOut();
1675
1676    return ret;
1677}
1678
1679OMX_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
1705EXIT:
1706    FunctionOut();
1707
1708    return ret;
1709}
1710
1711OMX_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
1746EXIT:
1747    FunctionOut();
1748
1749    return ret;
1750}
1751
1752OMX_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
1787EXIT:
1788    FunctionOut();
1789
1790    return ret;
1791}
1792
1793OMX_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
1828EXIT:
1829    FunctionOut();
1830
1831    return ret;
1832}
1833
1834OSCL_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    /* Input port */
1902    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1903    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
1904    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
1905    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
1906    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1907    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
1908    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX;
1909    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
1910    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8");
1911    pExynosPort->portDefinition.format.video.pNativeRender = 0;
1912    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1913    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1914    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
1915    pExynosPort->bufferProcessType = BUFFER_SHARE;
1916    pExynosPort->portWayType = WAY2_PORT;
1917
1918    /* Output port */
1919    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1920    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
1921    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
1922    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
1923    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1924    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1925    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1926    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
1927    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1928    pExynosPort->portDefinition.format.video.pNativeRender = 0;
1929    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1930    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
1931    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
1932    pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
1933    pExynosPort->portWayType = WAY2_PORT;
1934
1935    pOMXComponent->GetParameter      = &Exynos_VP8Dec_GetParameter;
1936    pOMXComponent->SetParameter      = &Exynos_VP8Dec_SetParameter;
1937    pOMXComponent->GetConfig         = &Exynos_VP8Dec_GetConfig;
1938    pOMXComponent->SetConfig         = &Exynos_VP8Dec_SetConfig;
1939    pOMXComponent->GetExtensionIndex = &Exynos_VP8Dec_GetExtensionIndex;
1940    pOMXComponent->ComponentRoleEnum = &Exynos_VP8Dec_ComponentRoleEnum;
1941    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
1942
1943    pExynosComponent->exynos_codec_componentInit      = &Exynos_VP8Dec_Init;
1944    pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Dec_Terminate;
1945
1946    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_VP8Dec_srcInputBufferProcess;
1947    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP8Dec_srcOutputBufferProcess;
1948    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_VP8Dec_dstInputBufferProcess;
1949    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP8Dec_dstOutputBufferProcess;
1950
1951    pVideoDec->exynos_codec_start         = &VP8CodecStart;
1952    pVideoDec->exynos_codec_stop          = &VP8CodecStop;
1953    pVideoDec->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun;
1954    pVideoDec->exynos_codec_enqueueAllBuffer = &VP8CodecEnQueueAllBuffer;
1955
1956    pVideoDec->exynos_checkInputFrame                 = &Check_VP8_Frame;
1957    pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
1958    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
1959
1960    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
1961    if (pVideoDec->hSharedMemory == NULL) {
1962        Exynos_OSAL_Free(pVp8Dec);
1963        pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
1964        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1965        ret = OMX_ErrorInsufficientResources;
1966        goto EXIT;
1967    }
1968
1969    pExynosComponent->currentState = OMX_StateLoaded;
1970
1971    ret = OMX_ErrorNone;
1972
1973EXIT:
1974    FunctionOut();
1975
1976    return ret;
1977}
1978
1979OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
1980    OMX_HANDLETYPE hComponent)
1981{
1982    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
1983    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
1984    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
1985    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1986    EXYNOS_VP8DEC_HANDLE        *pVp8Dec            = NULL;
1987
1988    FunctionIn();
1989
1990    if (hComponent == NULL) {
1991        ret = OMX_ErrorBadParameter;
1992        goto EXIT;
1993    }
1994    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1995    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1996    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1997
1998    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
1999
2000    Exynos_OSAL_Free(pExynosComponent->componentName);
2001    pExynosComponent->componentName = NULL;
2002
2003    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
2004    if (pVp8Dec != NULL) {
2005        Exynos_OSAL_Free(pVp8Dec);
2006        pVp8Dec = pVideoDec->hCodecHandle = NULL;
2007    }
2008
2009    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2010    if (ret != OMX_ErrorNone) {
2011        goto EXIT;
2012    }
2013
2014    ret = OMX_ErrorNone;
2015
2016EXIT:
2017    FunctionOut();
2018
2019    return ret;
2020}
2021