b14d8e067c0d2444f1cefdd04e8a1224ceb21c87
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / dec / vc1 / Exynos_OMX_Wmvdec.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file        Exynos_OMX_Wmvdec.c
20  * @brief
21  * @author      HyeYeon Chung (hyeon.chung@samsung.com)
22  * @author      Satish Kumar Reddy (palli.satish@samsung.com)
23  * @version     2.0.0
24  * @history
25  *   2012.07.10 : Create
26  *              : Support WMV3 (Vc-1 Simple/Main Profile)
27  *              : Support WMvC1 (Vc-1 Advanced Profile)
28  */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "Exynos_OMX_Macros.h"
35 #include "Exynos_OMX_Basecomponent.h"
36 #include "Exynos_OMX_Baseport.h"
37 #include "Exynos_OMX_Vdec.h"
38 #include "Exynos_OSAL_ETC.h"
39 #include "Exynos_OSAL_Semaphore.h"
40 #include "Exynos_OSAL_Thread.h"
41 #include "library_register.h"
42 #include "Exynos_OMX_Wmvdec.h"
43 #include "ExynosVideoApi.h"
44 #include "Exynos_OSAL_SharedMemory.h"
45 #include "Exynos_OSAL_Event.h"
46
47 #ifdef USE_PB
48 #include "Exynos_OSAL_Platform_Specific.h"
49 #endif
50
51 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
52 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
53 #include "csc.h"
54
55 #undef  EXYNOS_LOG_TAG
56 #define EXYNOS_LOG_TAG    "EXYNOS_WMV_DEC"
57 #define EXYNOS_LOG_OFF
58 //#define EXYNOS_TRACE_ON
59 #include "Exynos_OSAL_Log.h"
60
61 #define WMV_DEC_NUM_OF_EXTRA_BUFFERS 7
62
63 //#define FULL_FRAME_SEARCH
64
65 /* ASF parser does not send start code on Stagefright */
66 #define WO_START_CODE
67 /* Enable or disable "WMV3_ADDITIONAL_START_CODE" based on MFC F/W's need */
68 //#define WMV3_ADDITIONAL_START_CODE
69
70 const OMX_U32 wmv3 = 0x33564d57;
71 const OMX_U32 wvc1 = 0x31435657;
72 const OMX_U32 wmva = 0x41564d57;
73
74
75 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
76 {
77     OMX_ERRORTYPE       ret = OMX_ErrorNone;
78
79 EXIT:
80     return ret;
81 }
82
83 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[])
84 {
85     OMX_ERRORTYPE       ret = OMX_ErrorNone;
86     ExynosVideoBuffer  *pCodecBuffer;
87
88     if (codecBuffer == NULL) {
89         ret = OMX_ErrorBadParameter;
90         goto EXIT;
91     }
92
93     pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
94
95     if (addr != NULL) {
96         addr[0] = pCodecBuffer->planes[0].addr;
97         addr[1] = pCodecBuffer->planes[1].addr;
98         addr[2] = pCodecBuffer->planes[2].addr;
99     }
100
101     if (size != NULL) {
102         size[0] = pCodecBuffer->planes[0].allocSize;
103         size[1] = pCodecBuffer->planes[1].allocSize;
104         size[2] = pCodecBuffer->planes[2].allocSize;
105     }
106
107 EXIT:
108     return ret;
109 }
110
111 int Check_Wmv_Frame(
112     OMX_U8   *pInputStream,
113     OMX_U32   buffSize,
114     OMX_U32   flag,
115     OMX_BOOL  bPreviousFrameEOF,
116     OMX_BOOL *pbEndOfFrame)
117 {
118     OMX_U32  compressionID;
119     OMX_BOOL bFrameStart;
120     OMX_U32  len, readStream;
121     OMX_U32  startCode;
122     WMV_FORMAT gWvmFormat = WMV_FORMAT_UNKNOWN;
123
124     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "buffSize = %d", buffSize);
125
126     len = 0;
127     bFrameStart = OMX_FALSE;
128
129     if (flag & OMX_BUFFERFLAG_CODECCONFIG) {
130         BitmapInfoHhr *pBitmapInfoHeader;
131         pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream;
132
133         compressionID = pBitmapInfoHeader->BiCompression;
134         if (compressionID == wmv3) {
135             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3");
136             gWvmFormat  = WMV_FORMAT_WMV3;
137
138             *pbEndOfFrame = OMX_TRUE;
139             return buffSize;
140         }
141         else if ((compressionID == wvc1) || (compressionID == wmva)) {
142             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1");
143             gWvmFormat  = WMV_FORMAT_VC1;
144
145 #ifdef WO_START_CODE
146 /* ASF parser does not send start code on Stagefright */
147             *pbEndOfFrame = OMX_TRUE;
148             return buffSize;
149 #endif
150         }
151     }
152
153     if (gWvmFormat == WMV_FORMAT_WMV3) {
154         *pbEndOfFrame = OMX_TRUE;
155         return buffSize;
156     }
157
158 #ifdef WO_START_CODE
159 /* ASF parser does not send start code on Stagefright */
160     if (gWvmFormat == WMV_FORMAT_VC1) {
161         *pbEndOfFrame = OMX_TRUE;
162         return buffSize;
163     }
164 #else
165  /* TODO : for comformanc test based on common buffer scheme w/o parser */
166
167     if (bPreviousFrameEOF == OMX_FALSE)
168         bFrameStart = OMX_TRUE;
169
170     startCode = 0xFFFFFFFF;
171     if (bFrameStart == OMX_FALSE) {
172         /* find Frame start code */
173         while(startCode != 0x10D) {
174             readStream = *(pInputStream + len);
175             startCode = (startCode << 8) | readStream;
176             len++;
177             if (len > buffSize)
178                 goto EXIT;
179         }
180     }
181
182     /* find next Frame start code */
183     startCode = 0xFFFFFFFF;
184     while ((startCode != 0x10D)) {
185         readStream = *(pInputStream + len);
186         startCode = (startCode << 8) | readStream;
187         len++;
188         if (len > buffSize)
189             goto EXIT;
190     }
191
192     *pbEndOfFrame = OMX_TRUE;
193
194     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize);
195
196     return len - 4;
197 #endif
198
199 EXIT :
200     *pbEndOfFrame = OMX_FALSE;
201
202     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize);
203
204     return --len;
205 }
206
207 static OMX_BOOL Check_Stream_PrefixCode(
208     OMX_U8    *pInputStream,
209     OMX_U32    streamSize,
210     WMV_FORMAT wmvFormat)
211 {
212     switch (wmvFormat) {
213     case WMV_FORMAT_WMV3:
214 #ifdef WMV3_ADDITIONAL_START_CODE
215         return OMX_FALSE;
216 #endif
217         if (streamSize > 0)
218             return OMX_TRUE;
219         else
220             return OMX_FALSE;
221         break;
222     case WMV_FORMAT_VC1:
223         /* TODO : for comformanc test based on common buffer scheme w/o parser */
224         if (streamSize < 3) {
225             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: streamSize is too small (%d)", __FUNCTION__, streamSize);
226             return OMX_FALSE;
227         } else if ((pInputStream[0] == 0x00) &&
228                    (pInputStream[1] == 0x00) &&
229                    (pInputStream[2] == 0x01)) {
230             return OMX_TRUE;
231         } else {
232             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Cannot find prefix", __FUNCTION__);
233             return OMX_FALSE;
234         }
235         break;
236
237     default:
238         Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat);
239         return OMX_FALSE;
240         break;
241     }
242 }
243
244 static OMX_BOOL Make_Stream_MetaData(
245     OMX_U8    *pInputStream,
246     OMX_U32   *pStreamSize,
247     WMV_FORMAT wmvFormat
248 #ifdef SLP_PLATFORM
249     , OMX_U32 width, OMX_U32 height
250 #endif
251     )
252 {
253     OMX_U8  *pCurrBuf = pInputStream;
254     OMX_U32  currPos  = 0;
255 #ifndef SLP_PLATFORM
256     OMX_U32  width, height;
257 #endif
258     FunctionIn();
259
260     /* Sequence Layer Data Structure */
261     OMX_U8 const_C5[4] = {0x00, 0x00, 0x00, 0xc5};
262     OMX_U8 const_04[4] = {0x04, 0x00, 0x00, 0x00};
263     OMX_U8 const_0C[4] = {0x0C, 0x00, 0x00, 0x00};
264     OMX_U8 struct_B_1[4] = {0xB3, 0x19, 0x00, 0x00};
265     OMX_U8 struct_B_2[4] = {0x44, 0x62, 0x05, 0x00};
266     OMX_U8 struct_B_3[4] = {0x0F, 0x00, 0x00, 0x00};
267     OMX_U8 struct_C[4] = {0x30, 0x00, 0x00, 0x00};
268
269     switch (wmvFormat) {
270     case WMV_FORMAT_WMV3:
271         if (*pStreamSize >= BITMAPINFOHEADER_SIZE) {
272 #ifndef SLP_PLATFORM
273             BitmapInfoHhr *pBitmapInfoHeader;
274             pBitmapInfoHeader = (BitmapInfoHhr *)pInputStream;
275
276             width = pBitmapInfoHeader->BiWidth;
277             height = pBitmapInfoHeader->BiHeight;
278 #endif
279             if (*pStreamSize > BITMAPINFOHEADER_SIZE)
280                 Exynos_OSAL_Memcpy(struct_C, pInputStream+BITMAPINFOHEADER_SIZE, 4);
281
282             Exynos_OSAL_Memcpy(pCurrBuf + currPos, const_C5, 4);
283             currPos +=4;
284
285             Exynos_OSAL_Memcpy(pCurrBuf + currPos, const_04, 4);
286             currPos +=4;
287
288             Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_C, 4);
289             currPos +=4;
290
291             /* struct_A : VERT_SIZE */
292             pCurrBuf[currPos] =  height & 0xFF;
293             pCurrBuf[currPos+1] = (height>>8) & 0xFF;
294             pCurrBuf[currPos+2] = (height>>16) & 0xFF;
295             pCurrBuf[currPos+3] = (height>>24) & 0xFF;
296             currPos +=4;
297
298             /* struct_A : HORIZ_SIZE */
299             pCurrBuf[currPos] =  width & 0xFF;
300             pCurrBuf[currPos+1] = (width>>8) & 0xFF;
301             pCurrBuf[currPos+2] = (width>>16) & 0xFF;
302             pCurrBuf[currPos+3] = (width>>24) & 0xFF;
303             currPos +=4;
304
305             Exynos_OSAL_Memcpy(pCurrBuf + currPos,const_0C, 4);
306             currPos +=4;
307
308             Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_1, 4);
309             currPos +=4;
310
311             Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_2, 4);
312             currPos +=4;
313
314             Exynos_OSAL_Memcpy(pCurrBuf + currPos, struct_B_3, 4);
315             currPos +=4;
316
317             *pStreamSize = currPos;
318             return OMX_TRUE;
319         } else {
320             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize);
321             return OMX_FALSE;
322         }
323         break;
324     case WMV_FORMAT_VC1:
325         if (*pStreamSize >= BITMAPINFOHEADER_ASFBINDING_SIZE) {
326             Exynos_OSAL_Memcpy(pCurrBuf, pInputStream + BITMAPINFOHEADER_ASFBINDING_SIZE, *pStreamSize - BITMAPINFOHEADER_ASFBINDING_SIZE);
327             *pStreamSize -= BITMAPINFOHEADER_ASFBINDING_SIZE;
328             return OMX_TRUE;
329         } else {
330             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize);
331             return OMX_FALSE;
332         }
333         break;
334     default:
335         Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: It is not necessary to make bitstream metadata for wmvFormat (%d)", __FUNCTION__, wmvFormat);
336         return OMX_FALSE;
337         break;
338     }
339 }
340
341 static OMX_BOOL Make_Stream_StartCode(
342     OMX_U8    *pInputStream,
343     OMX_U32    *pStreamSize,
344     WMV_FORMAT wmvFormat)
345 {
346     OMX_U8  frameStartCode[4] = {0x00, 0x00, 0x01, 0x0d};
347 #ifdef WMV3_ADDITIONAL_START_CODE
348      /* first 4 bytes : size of Frame, second 4 bytes : present Time stamp */
349     OMX_U8  frameStartCode2[8] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
350 #endif
351     OMX_U32 i;
352
353     switch (wmvFormat) {
354     case WMV_FORMAT_WMV3:
355 #ifdef WMV3_ADDITIONAL_START_CODE
356         Exynos_OSAL_Memmove(pInputStream+8, pInputStream, *pStreamSize);
357         Exynos_OSAL_Memcpy(pInputStream, frameStartCode2, 8);
358         *pStreamSize += 8;
359 #endif
360         return OMX_TRUE;
361         break;
362
363     case WMV_FORMAT_VC1:
364         /* Should find better way to shift data */
365         Exynos_OSAL_Memmove(pInputStream+4, pInputStream, *pStreamSize);
366         Exynos_OSAL_Memcpy(pInputStream, frameStartCode, 4);
367         *pStreamSize += 4;
368         return OMX_TRUE;
369         break;
370
371     default:
372         Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined wmvFormat (%d)", __FUNCTION__, wmvFormat);
373         return OMX_FALSE;
374         break;
375     }
376 }
377
378 OMX_ERRORTYPE Process_Wmv_CodecConfigData(OMX_COMPONENTTYPE *pOMXComponent, void *pConfig)
379 {
380     OMX_ERRORTYPE          ret = OMX_ErrorNone;
381     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
382     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
383     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
384     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
385     EXYNOS_WMVDEC_HANDLE          *pWmvDec           = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
386     OMX_PTR                hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
387 #ifdef SLP_PLATFORM
388     EXYNOS_OMX_DATABUFFER *pSrcInputData = (EXYNOS_OMX_DATA *)pConfig;
389     OMX_U8 *pInputStream = pSrcInputData->bufferHeader->pBuffer;
390 #endif
391
392     FunctionIn();
393
394 #ifdef SLP_PLATFORM
395     if (pWmvDec->wmvFormat == WMV_FORMAT_UNKNOWN) {
396         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Process_Wmv_CodecConfigData. dataLen = %d", pSrcInputData->dataLen);
397         if (pSrcInputData->dataLen < 4) {
398             pWmvDec->wmvFormat = WMV_FORMAT_UNKNOWN;
399             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_UNKNOWN");
400         } else if ((pInputStream[1] == 0x00) &&
401                  (pInputStream[2] == 0x00) &&
402                  (pInputStream[3] == 0x01)) {
403             pWmvDec->wmvFormat = WMV_FORMAT_VC1;
404             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1");
405         } else {
406             pWmvDec->wmvFormat = WMV_FORMAT_WMV3;
407             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3");
408         }
409     }
410
411     pWmvDec->hMFCWmvHandle.wmvFormat = pWmvDec->wmvFormat;
412 #else
413     BitmapInfoHhr *pBitmapInfoHeader;
414     pBitmapInfoHeader = (BitmapInfoHhr *)pConfig;
415     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_BUFFERFLAG_CODECCONFIG");
416     if (pBitmapInfoHeader->BiCompression == wmv3) {
417         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_WMV3");
418         pWmvDec->hMFCWmvHandle.wmvFormat  = WMV_FORMAT_WMV3;
419     } else if ((pBitmapInfoHeader->BiCompression == wvc1) || (pBitmapInfoHeader->BiCompression == wmva)) {
420         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_VC1");
421         pWmvDec->hMFCWmvHandle.wmvFormat  = WMV_FORMAT_VC1;
422     } else {
423         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WMV_FORMAT_UNKNOWN (0x%x), default value will be used", pBitmapInfoHeader->BiCompression);
424     }
425 #endif
426     ret = WmvCodecSrcInit(pOMXComponent);
427     if (ret != OMX_ErrorNone) {
428         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to WmvCodecSrcInit");
429         goto EXIT;
430     }
431
432     ret = OMX_ErrorNone;
433
434 EXIT:
435     FunctionOut();
436
437     return ret;
438 }
439
440 OMX_ERRORTYPE WmvCodecOpen(EXYNOS_WMVDEC_HANDLE *pWmvDec)
441 {
442     OMX_ERRORTYPE           ret = OMX_ErrorNone;
443     ExynosVideoDecOps       *pDecOps    = NULL;
444     ExynosVideoDecBufferOps *pInbufOps  = NULL;
445     ExynosVideoDecBufferOps *pOutbufOps = NULL;
446     enum v4l2_memory         v4l2MemoryType = V4L2_MEMORY_USERPTR;
447
448     FunctionIn();
449
450     if (pWmvDec == NULL) {
451         ret = OMX_ErrorBadParameter;
452         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
453         goto EXIT;
454     }
455
456     /* alloc ops structure */
457     pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
458     pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
459     pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
460
461     if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
462         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
463         ret = OMX_ErrorInsufficientResources;
464         goto EXIT;
465     }
466
467     pWmvDec->hMFCWmvHandle.pDecOps    = pDecOps;
468     pWmvDec->hMFCWmvHandle.pInbufOps  = pInbufOps;
469     pWmvDec->hMFCWmvHandle.pOutbufOps = pOutbufOps;
470
471     /* function pointer mapping */
472     pDecOps->nSize    = sizeof(ExynosVideoDecOps);
473     pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
474     pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
475
476     Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
477
478     /* check mandatory functions for decoder ops */
479     if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
480         (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
481         (pDecOps->Get_FrameTag == NULL)) {
482         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
483         ret = OMX_ErrorInsufficientResources;
484         goto EXIT;
485     }
486
487     /* check mandatory functions for buffer ops */
488     if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
489         (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
490         (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
491         (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
492         (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
493         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
494         ret = OMX_ErrorInsufficientResources;
495         goto EXIT;
496     }
497
498     // For slp platform
499     if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) {
500 #ifdef USE_DMA_BUF
501         v4l2MemoryType = V4L2_MEMORY_DMABUF;
502         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_DMABUF");
503 #else
504         v4l2MemoryType = V4L2_MEMORY_USERPTR;
505         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_USEPTR");
506 #endif
507     } else {
508         v4l2MemoryType = V4L2_MEMORY_DMABUF;
509         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Dec V4L2_MEMORY_DMABUF");
510     }
511
512     /* alloc context, open, querycap */
513     pWmvDec->hMFCWmvHandle.hMFCHandle = pWmvDec->hMFCWmvHandle.pDecOps->Init(v4l2MemoryType);
514     if (pWmvDec->hMFCWmvHandle.hMFCHandle == NULL) {
515         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
516         ret = OMX_ErrorInsufficientResources;
517         goto EXIT;
518     }
519
520     ret = OMX_ErrorNone;
521
522 EXIT:
523     if (ret != OMX_ErrorNone) {
524         if (pDecOps != NULL) {
525             Exynos_OSAL_Free(pDecOps);
526             pWmvDec->hMFCWmvHandle.pDecOps = NULL;
527         }
528         if (pInbufOps != NULL) {
529             Exynos_OSAL_Free(pInbufOps);
530             pWmvDec->hMFCWmvHandle.pInbufOps = NULL;
531         }
532         if (pOutbufOps != NULL) {
533             Exynos_OSAL_Free(pOutbufOps);
534             pWmvDec->hMFCWmvHandle.pOutbufOps = NULL;
535         }
536     }
537
538     FunctionOut();
539
540     return ret;
541 }
542
543 OMX_ERRORTYPE WmvCodecClose(EXYNOS_WMVDEC_HANDLE *pWmvDec)
544 {
545     OMX_ERRORTYPE            ret = OMX_ErrorNone;
546     void                    *hMFCHandle = NULL;
547     ExynosVideoDecOps       *pDecOps    = NULL;
548     ExynosVideoDecBufferOps *pInbufOps  = NULL;
549     ExynosVideoDecBufferOps *pOutbufOps = NULL;
550
551     FunctionIn();
552
553     if (pWmvDec == NULL) {
554         ret = OMX_ErrorBadParameter;
555         goto EXIT;
556     }
557
558     hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
559     pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
560     pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
561     pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
562
563     if (hMFCHandle != NULL) {
564         pDecOps->Finalize(hMFCHandle);
565         pWmvDec->hMFCWmvHandle.hMFCHandle = NULL;
566     }
567     if (pOutbufOps != NULL) {
568         Exynos_OSAL_Free(pOutbufOps);
569         pWmvDec->hMFCWmvHandle.pOutbufOps = NULL;
570     }
571     if (pInbufOps != NULL) {
572         Exynos_OSAL_Free(pInbufOps);
573         pWmvDec->hMFCWmvHandle.pInbufOps = NULL;
574     }
575     if (pDecOps != NULL) {
576         Exynos_OSAL_Free(pDecOps);
577         pWmvDec->hMFCWmvHandle.pDecOps = NULL;
578     }
579
580     ret = OMX_ErrorNone;
581
582 EXIT:
583     FunctionOut();
584
585     return ret;
586 }
587
588 OMX_ERRORTYPE WmvCodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
589 {
590     OMX_ERRORTYPE            ret = OMX_ErrorNone;
591     void                    *hMFCHandle = NULL;
592     ExynosVideoDecOps       *pDecOps    = NULL;
593     ExynosVideoDecBufferOps *pInbufOps  = NULL;
594     ExynosVideoDecBufferOps *pOutbufOps = NULL;
595     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
596     EXYNOS_WMVDEC_HANDLE   *pWmvDec = NULL;
597
598     FunctionIn();
599
600     if (pOMXComponent == NULL) {
601         ret = OMX_ErrorBadParameter;
602         goto EXIT;
603     }
604
605     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
606     if (pVideoDec == NULL) {
607         ret = OMX_ErrorBadParameter;
608         goto EXIT;
609     }
610
611     pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
612     if (pWmvDec == NULL) {
613         ret = OMX_ErrorBadParameter;
614         goto EXIT;
615     }
616
617     hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
618     pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
619     pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
620     pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
621
622     if (nPortIndex == INPUT_PORT_INDEX)
623         pInbufOps->Run(hMFCHandle);
624     else if (nPortIndex == OUTPUT_PORT_INDEX)
625         pOutbufOps->Run(hMFCHandle);
626
627     ret = OMX_ErrorNone;
628
629 EXIT:
630     FunctionOut();
631
632     return ret;
633 }
634
635 OMX_ERRORTYPE WmvCodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
636 {
637     OMX_ERRORTYPE            ret = OMX_ErrorNone;
638     void                    *hMFCHandle = NULL;
639     ExynosVideoDecOps       *pDecOps    = NULL;
640     ExynosVideoDecBufferOps *pInbufOps  = NULL;
641     ExynosVideoDecBufferOps *pOutbufOps = NULL;
642     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
643     EXYNOS_WMVDEC_HANDLE   *pWmvDec = NULL;
644
645     FunctionIn();
646
647     if (pOMXComponent == NULL) {
648         ret = OMX_ErrorBadParameter;
649         goto EXIT;
650     }
651
652     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
653     if (pVideoDec == NULL) {
654         ret = OMX_ErrorBadParameter;
655         goto EXIT;
656     }
657     pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
658     if (pWmvDec == NULL) {
659         ret = OMX_ErrorBadParameter;
660         goto EXIT;
661     }
662
663     hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
664     pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
665     pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
666     pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
667
668     if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
669         pInbufOps->Stop(hMFCHandle);
670     else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
671         pOutbufOps->Stop(hMFCHandle);
672
673     ret = OMX_ErrorNone;
674
675 EXIT:
676     FunctionOut();
677
678     return ret;
679 }
680
681
682 OMX_ERRORTYPE WmvCodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent)
683 {
684     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
685     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
686     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
687     EXYNOS_WMVDEC_HANDLE          *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
688     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
689     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
690     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
691
692     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
693     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
694     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
695     ExynosVideoGeometry      bufferConf;
696     OMX_U32                  inputBufferNumber = 0;
697     int i, plane;
698
699     FunctionIn();
700
701     if (pVideoDec->bThumbnailMode == OMX_TRUE)
702         pDecOps->Set_DisplayDelay(hMFCHandle, 0);
703
704     /* input buffer info */
705     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
706     if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) {
707         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_CODING_VC1_RCV");
708         bufferConf.eCompressionFormat = VIDEO_CODING_VC1_RCV;
709     } else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) {
710         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_CODING_VC1");
711         bufferConf.eCompressionFormat = VIDEO_CODING_VC1;
712     } else {
713         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Unsupported WMV Codec Format Type");
714         ret = OMX_ErrorUndefined;
715         goto EXIT;
716     }
717
718     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE
719         ||pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE)
720         pInbufOps->Set_Shareable(hMFCHandle);
721
722     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
723         bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
724                                 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
725         inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
726     } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
727         bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
728         inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
729     }
730
731     /* should be done before prepare input buffer */
732     if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
733         ret = OMX_ErrorInsufficientResources;
734         goto EXIT;
735     }
736
737     /* set input buffer geometry */
738     if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
739         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
740         ret = OMX_ErrorInsufficientResources;
741         goto EXIT;
742     }
743
744     /* setup input buffer */
745     if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
746         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
747         ret = OMX_ErrorInsufficientResources;
748         goto EXIT;
749     }
750
751     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
752         pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) {
753         /* Register input buffer */
754         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
755             ExynosVideoPlane plane;
756             plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
757             plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
758             plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
759             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
760                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
761                 ret = OMX_ErrorInsufficientResources;
762                 goto EXIT;
763             }
764         }
765     } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
766         pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE) {
767         ExynosVideoBuffer *pBuffer = NULL;
768
769         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
770             pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
771             Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
772             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
773             /* get input buffer info */
774             if (pInbufOps->Get_Buffer) {
775                 if (pInbufOps->Get_Buffer(pWmvDec->hMFCWmvHandle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
776                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info");
777                     ret = OMX_ErrorInsufficientResources;
778                     goto EXIT;
779                 }
780             }
781
782             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
783                 /* Use ION Allocator */
784                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
785                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
786                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
787                 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
788                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
789             }
790
791             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
792         }
793     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
794         /* Register input buffer */
795         for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
796             ExynosVideoPlane plane;
797             plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
798             plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
799             plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
800             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
801                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
802                 ret = OMX_ErrorInsufficientResources;
803                 goto EXIT;
804             }
805         }
806     }
807
808 EXIT:
809     FunctionOut();
810
811     return ret;
812 }
813
814 OMX_ERRORTYPE WmvCodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
815 {
816     OMX_ERRORTYPE            ret = OMX_ErrorNone;
817     void                    *hMFCHandle = NULL;
818     ExynosVideoDecOps       *pDecOps    = NULL;
819     ExynosVideoDecBufferOps *pInbufOps  = NULL;
820     ExynosVideoDecBufferOps *pOutbufOps = NULL;
821     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
822     EXYNOS_WMVDEC_HANDLE   *pWmvDec = NULL;
823
824     FunctionIn();
825
826     if (pOMXComponent == NULL) {
827         ret = OMX_ErrorBadParameter;
828         goto EXIT;
829     }
830
831     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
832     if (pVideoDec == NULL) {
833         ret = OMX_ErrorBadParameter;
834         goto EXIT;
835     }
836     pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
837     if (pWmvDec == NULL) {
838         ret = OMX_ErrorBadParameter;
839         goto EXIT;
840     }
841
842     hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
843     pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
844     pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
845     pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
846
847     if (nPortIndex == INPUT_PORT_INDEX) {
848         if (pWmvDec->bSourceStart == OMX_FALSE) {
849             Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent);
850             Exynos_OSAL_SleepMillisec(0);
851         }
852     }
853
854     if (nPortIndex == OUTPUT_PORT_INDEX) {
855         if (pWmvDec->bDestinationStart == OMX_FALSE) {
856             Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent);
857             Exynos_OSAL_SleepMillisec(0);
858         }
859     }
860
861     ret = OMX_ErrorNone;
862
863 EXIT:
864     FunctionOut();
865
866     return ret;
867 }
868
869 OMX_ERRORTYPE WmvCodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
870 {
871     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
872     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
873     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
874     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
875     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
876     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
877     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
878     int i, nOutbufs;
879
880     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
881     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
882     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
883
884     FunctionIn();
885
886     if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
887         ret = OMX_ErrorBadPortIndex;
888         goto EXIT;
889     }
890
891     if ((nPortIndex == INPUT_PORT_INDEX) &&
892         (pWmvDec->bSourceStart == OMX_TRUE)) {
893         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
894
895         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
896             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
897             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
898
899             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
900         }
901
902         pInbufOps->Clear_Queue(hMFCHandle);
903     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
904                (pWmvDec->bDestinationStart == OMX_TRUE)) {
905         OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
906         ExynosVideoBuffer *pBuffer = NULL;
907
908         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
909
910         nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
911         nOutbufs += EXTRA_DPB_NUM;
912         for (i = 0; i < nOutbufs; i++) {
913             pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
914             Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
915         }
916         pOutbufOps->Clear_Queue(hMFCHandle);
917     }
918
919 EXIT:
920     FunctionOut();
921
922     return ret;
923 }
924
925 OMX_ERRORTYPE WmvCodecDstFreeCodecBuffers(
926     OMX_COMPONENTTYPE *pOMXComponent)
927 {
928     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
929     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
930     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
931     EXYNOS_WMVDEC_HANDLE          *pWmvDec          = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
932
933     int i, j;
934
935     FunctionIn();
936
937     for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
938         if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
939             for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
940                 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL &&
941                     pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE)
942                     Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
943             }
944
945             Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
946         }
947     }
948
949     Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer));
950
951     FunctionOut();
952
953     return OMX_ErrorNone;
954 }
955
956 OMX_ERRORTYPE WmvCodecDstAllocCodecBuffers(
957     OMX_COMPONENTTYPE *pOMXComponent,
958     OMX_U32            nOutbufs)
959 {
960     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
961     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
962     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
963     EXYNOS_WMVDEC_HANDLE          *pWmvDec          = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
964
965     MEMORY_TYPE eMemoryType                        = NORMAL_MEMORY;
966     OMX_U32     nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
967     int i, j;
968
969     FunctionIn();
970
971     nAllocLen[0] = calc_yplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
972                         pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight);
973     nAllocLen[1] = calc_uvplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
974                         pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight >> 1);
975
976     for (i = 0; i < nOutbufs; i++) {
977         pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
978         if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) {
979             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
980             ret = OMX_ErrorInsufficientResources;
981             goto EXIT;
982         }
983         Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
984
985         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
986             pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] =
987                 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType);
988             if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) {
989                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
990                 ret = OMX_ErrorInsufficientResources;
991                 goto EXIT;
992             }
993
994            pVideoDec->pMFCDecOutputBuffer[i]->fd[j] =
995                 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
996                                                  pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
997            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j];
998         }
999     }
1000
1001     return OMX_ErrorNone;
1002
1003 EXIT:
1004     WmvCodecDstFreeCodecBuffers(pOMXComponent);
1005
1006     FunctionOut();
1007
1008     return ret;
1009 }
1010
1011 OMX_ERRORTYPE WmvCodecDstRegistCodecBuffers(
1012     OMX_COMPONENTTYPE *pOMXComponent,
1013     OMX_U32            nOutbufs)
1014 {
1015     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1016     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1017     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1018     EXYNOS_WMVDEC_HANDLE          *pWmvDec          = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1019     void                          *hMFCHandle       = pWmvDec->hMFCWmvHandle.hMFCHandle;
1020     ExynosVideoDecBufferOps       *pOutbufOps       = pWmvDec->hMFCWmvHandle.pOutbufOps;
1021
1022     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
1023     OMX_U32          nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1024     int i, j;
1025
1026     FunctionIn();
1027
1028     /* Register output buffer */
1029     for (i = 0; i < nOutbufs; i++) {
1030         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
1031             planes[j].addr      = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j];
1032             planes[j].fd        = pVideoDec->pMFCDecOutputBuffer[i]->fd[j];
1033             planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j];
1034         }
1035
1036         if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1037             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1038             ret = OMX_ErrorInsufficientResources;
1039             goto EXIT;
1040         }
1041
1042         pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1043                         (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1044     }
1045
1046     ret = OMX_ErrorNone;
1047
1048 EXIT:
1049     FunctionOut();
1050
1051     return ret;
1052 }
1053
1054 OMX_ERRORTYPE WmvCodecResetupAllElement(
1055     OMX_COMPONENTTYPE   *pOMXComponent,
1056     OMX_U32              nPortIndex)
1057 {
1058     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1059     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1060     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1061     EXYNOS_WMVDEC_HANDLE          *pWmvDec          = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1062     void                          *hMFCHandle       = pWmvDec->hMFCWmvHandle.hMFCHandle;
1063     EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1064     ExynosVideoDecBufferOps       *pOutbufOps       = pWmvDec->hMFCWmvHandle.pOutbufOps;
1065
1066     int i, j, nOutbufs;
1067
1068     FunctionIn();
1069
1070     if ((nPortIndex == INPUT_PORT_INDEX) &&
1071         (pWmvDec->bSourceStart == OMX_TRUE)) {
1072         ret = OMX_ErrorNotImplemented;
1073         goto EXIT;
1074     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
1075                (pWmvDec->bDestinationStart == OMX_TRUE)) {
1076         if (pOutputPort->bufferProcessType & BUFFER_COPY) {
1077
1078             /**********************************/
1079             /* Codec Buffer Free & Unregister */
1080             /**********************************/
1081             WmvCodecDstFreeCodecBuffers(pOMXComponent);
1082             Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
1083
1084             if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE)
1085                 pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
1086
1087             pOutbufOps->Cleanup(hMFCHandle);
1088             /******************************************************/
1089             /* V4L2 Destnation Setup for DPB Buffer Number Change */
1090             /******************************************************/
1091             WmvCodecDstSetup(pOMXComponent);
1092
1093             pVideoDec->bDRCProcessing = OMX_FALSE;
1094         } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
1095
1096             /**********************************/
1097             /* Codec Buffer Unregister */
1098             /**********************************/
1099             pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
1100             pOutbufOps->Cleanup(hMFCHandle);
1101         }
1102     } else {
1103         ret = OMX_ErrorBadParameter;
1104         goto EXIT;
1105     }
1106
1107 EXIT:
1108     FunctionOut();
1109
1110     return ret;
1111 }
1112
1113 OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1114 {
1115     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1116     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1117     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1118     EXYNOS_WMVDEC_HANDLE          *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1119     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1120     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1121     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1122     OMX_U32                     oneFrameSize = pSrcInputData->dataLen;
1123     OMX_BOOL                    bMetaData         = OMX_FALSE;
1124
1125     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
1126     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
1127     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1128     ExynosVideoGeometry      bufferConf;
1129     OMX_U32                  inputBufferNumber = 0;
1130     int i;
1131
1132     FunctionIn();
1133
1134     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
1135         OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
1136         OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
1137         if (OMXBuffer == NULL) {
1138             ret = OMX_ErrorUndefined;
1139             goto EXIT;
1140         }
1141
1142         OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
1143         OMXBuffer->nFlags = pSrcInputData->nFlags;
1144         Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
1145
1146         ret = OMX_ErrorNone;
1147         goto EXIT;
1148     }
1149
1150     if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
1151         pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE)) {
1152         if (pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1153             BitmapInfoHhr *pBitmapInfoHeader;
1154             pBitmapInfoHeader = (BitmapInfoHhr *)pSrcInputData->buffer.singlePlaneBuffer.dataBuffer;
1155             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_BUFFERFLAG_CODECCONFIG");
1156             if (pBitmapInfoHeader->BiCompression == wmv3) {
1157                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "WMV_FORMAT_WMV3");
1158                 pWmvDec->hMFCWmvHandle.wmvFormat  = WMV_FORMAT_WMV3;
1159             } else if ((pBitmapInfoHeader->BiCompression == wvc1) || (pBitmapInfoHeader->BiCompression == wmva)) {
1160                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "WMV_FORMAT_VC1");
1161                 pWmvDec->hMFCWmvHandle.wmvFormat  = WMV_FORMAT_VC1;
1162             }
1163         }
1164
1165         ret = WmvCodecSrcInit(pOMXComponent);
1166         if (ret != OMX_ErrorNone)
1167             goto EXIT;
1168     }
1169
1170     /* set output geometry */
1171     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1172     pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
1173     if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1174         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1175         ret = OMX_ErrorInsufficientResources;
1176         goto EXIT;
1177     }
1178
1179     bMetaData = Make_Stream_MetaData(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat
1180 #ifdef SLP_PLATFORM
1181         , pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.nFrameWidth
1182         , pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.nFrameHeight
1183 #endif
1184         );
1185     if (bMetaData == OMX_FALSE) {
1186         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream MetaData");
1187         ret = OMX_ErrorInsufficientResources;
1188         goto EXIT;
1189     }
1190
1191     /* input buffer enqueue for header parsing */
1192     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
1193     if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1194                         (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
1195         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
1196 //        ret = OMX_ErrorInsufficientResources;
1197         ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
1198         goto EXIT;
1199     }
1200
1201     /* start header parsing */
1202     if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1203         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
1204         ret = OMX_ErrorCodecInit;
1205         goto EXIT;
1206     }
1207
1208     ret = WmvCodecCheckResolutionChange(pOMXComponent);
1209     if (ret != OMX_ErrorNone) {
1210         ret = OMX_ErrorCodecInit;
1211         goto EXIT;
1212     }
1213
1214     Exynos_OSAL_SleepMillisec(0);
1215     ret = OMX_ErrorInputDataDecodeYet;
1216
1217 #ifdef USE_IMMEDIATE_DISPLAY
1218     /* Set Immediately display for I Frame*/    
1219     pDecOps->Set_ImmediateDisplay(hMFCHandle);
1220 #endif
1221 EXIT:
1222     WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
1223     FunctionOut();
1224
1225     return ret;
1226 }
1227
1228 OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
1229 {
1230     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1231     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1232     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1233     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1234     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1235     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1236     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1237
1238     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
1239     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
1240     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1241
1242     int i, nOutbufs;
1243
1244     FunctionIn();
1245
1246     /* get dpb count */
1247     nOutbufs = pWmvDec->hMFCWmvHandle.maxDPBNum;
1248
1249     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1250         /* should be done before prepare output buffer */
1251         if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1252             ret = OMX_ErrorInsufficientResources;
1253             goto EXIT;
1254         }
1255     }
1256
1257     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE
1258         ||pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE)
1259         pOutbufOps->Set_Shareable(hMFCHandle);
1260
1261     if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1262         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1263         ret = OMX_ErrorInsufficientResources;
1264         goto EXIT;
1265     }
1266
1267     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
1268     OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1269     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1270     int plane;
1271
1272     nAllocLen[0] = calc_yplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
1273                         pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight);
1274     nAllocLen[1] = calc_uvplane(pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
1275                         pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight >> 1);
1276
1277     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1278         pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) {
1279         WmvCodecDstAllocCodecBuffers(pOMXComponent, nOutbufs);
1280         WmvCodecDstRegistCodecBuffers(pOMXComponent, nOutbufs);
1281     } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1282         pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_FALSE) {
1283         /* Register output buffer */
1284         for (i = 0; i < nOutbufs; i++) {
1285             int plane;
1286             OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1287             ExynosVideoBuffer *pBuffer = NULL;
1288             pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1289             Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1290
1291             if (pOutbufOps->Get_Buffer) {
1292                  if (pOutbufOps->Get_Buffer(pWmvDec->hMFCWmvHandle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
1293                      Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info");
1294                      ret = OMX_ErrorInsufficientResources;
1295                      goto EXIT;
1296                  }
1297             }
1298
1299             for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1300                 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
1301                 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
1302                pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
1303             }
1304
1305             pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1306                            (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1307         }
1308
1309     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1310 #ifdef USE_PB
1311         if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) {
1312             for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
1313                 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1314                     planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
1315                     planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
1316                     planes[plane].allocSize = nAllocLen[plane];
1317                 }
1318
1319                 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1320                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1321                     ret = OMX_ErrorInsufficientResources;
1322                     goto EXIT;
1323                 }
1324                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
1325                               (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1326             }
1327         } else {
1328             ret = OMX_ErrorNotImplemented;
1329             goto EXIT;
1330         }
1331 #else
1332         ret = OMX_ErrorNotImplemented;
1333         goto EXIT;
1334 #endif
1335     }
1336
1337     if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1338         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1339         ret = OMX_ErrorInsufficientResources;
1340         goto EXIT;
1341     }
1342
1343     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1344         WmvCodecStop (pOMXComponent, OUTPUT_PORT_INDEX);
1345     }
1346     pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE;
1347
1348     ret = OMX_ErrorNone;
1349
1350 EXIT:
1351     FunctionOut();
1352
1353     return ret;
1354 }
1355
1356 OMX_ERRORTYPE WmvCodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent)
1357 {
1358     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1359     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1360     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1361     EXYNOS_WMVDEC_HANDLE           *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1362     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1363     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1364     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1365
1366     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
1367     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
1368     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1369     ExynosVideoGeometry      bufferConf;
1370     int i;
1371
1372     FunctionIn();
1373
1374     /* get geometry for output */
1375     Exynos_OSAL_Memset(&pWmvDec->hMFCWmvHandle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
1376     if (pOutbufOps->Get_Geometry(hMFCHandle, &pWmvDec->hMFCWmvHandle.codecOutbufConf) != VIDEO_ERROR_NONE) {
1377         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
1378         ret = OMX_ErrorInsufficientResources;
1379         goto EXIT;
1380     }
1381
1382     /* get dpb count */
1383     pWmvDec->hMFCWmvHandle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
1384     if (pVideoDec->bThumbnailMode == OMX_FALSE)
1385         pWmvDec->hMFCWmvHandle.maxDPBNum += EXTRA_DPB_NUM;
1386     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "WmvCodecCheckResolutionChange WmvCodecSetup nOutbufs: %d", pWmvDec->hMFCWmvHandle.maxDPBNum);
1387
1388     pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_TRUE;
1389
1390     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1391         if ((pVideoDec->bDRCProcessing) ||
1392             (pExynosInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
1393             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight)) {
1394             pExynosInputPort->portDefinition.format.video.nFrameWidth = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
1395             pExynosInputPort->portDefinition.format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
1396             pExynosInputPort->portDefinition.format.video.nStride = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth + 15) & (~15));
1397             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight + 15) & (~15));
1398
1399             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1400                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1401             }
1402             Exynos_UpdateFrameSize(pOMXComponent);
1403             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1404
1405             /** Send Port Settings changed call back **/
1406         (*(pExynosComponent->pCallbacks->EventHandler))
1407             (pOMXComponent,
1408              pExynosComponent->callbackData,
1409              OMX_EventPortSettingsChanged, /* The command was completed */
1410              OMX_DirOutput, /* This is the port index */
1411                  0,
1412              NULL);
1413     }
1414     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1415         if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
1416             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight) ||
1417             (pExynosOutputPort->portDefinition.nBufferCountActual != pWmvDec->hMFCWmvHandle.maxDPBNum)) {
1418             pExynosInputPort->portDefinition.format.video.nFrameWidth = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
1419             pExynosInputPort->portDefinition.format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
1420             pExynosInputPort->portDefinition.format.video.nStride = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth + 15) & (~15));
1421             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight + 15) & (~15));
1422
1423             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1424                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1425             }
1426 #ifdef SLP_PLATFORM
1427             pExynosOutputPort->portDefinition.nBufferCountActual = pWmvDec->hMFCWmvHandle.maxDPBNum;
1428             pExynosOutputPort->portDefinition.nBufferCountMin = pWmvDec->hMFCWmvHandle.maxDPBNum;
1429 #else
1430             pExynosOutputPort->portDefinition.nBufferCountActual = pWmvDec->hMFCWmvHandle.maxDPBNum - 4;
1431             pExynosOutputPort->portDefinition.nBufferCountMin = pWmvDec->hMFCWmvHandle.maxDPBNum - 4;
1432 #endif
1433             Exynos_UpdateFrameSize(pOMXComponent);
1434             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1435
1436             /** Send Port Settings changed call back **/
1437             (*(pExynosComponent->pCallbacks->EventHandler))
1438                 (pOMXComponent,
1439                  pExynosComponent->callbackData,
1440                  OMX_EventPortSettingsChanged, /* The command was completed */
1441                  OMX_DirOutput, /* This is the port index */
1442                  0,
1443                  NULL);
1444         }
1445     }
1446
1447     ret = OMX_ErrorNone;
1448
1449 EXIT:
1450     FunctionOut();
1451
1452     return ret;
1453 }
1454
1455 OMX_ERRORTYPE Exynos_WmvDec_GetParameter(
1456     OMX_IN OMX_HANDLETYPE hComponent,
1457     OMX_IN OMX_INDEXTYPE  nParamIndex,
1458     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1459 {
1460     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1461     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1462     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1463
1464     FunctionIn();
1465
1466     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1467         ret = OMX_ErrorBadParameter;
1468         goto EXIT;
1469     }
1470     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1471     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1472     if (ret != OMX_ErrorNone) {
1473         goto EXIT;
1474     }
1475     if (pOMXComponent->pComponentPrivate == NULL) {
1476         ret = OMX_ErrorBadParameter;
1477         goto EXIT;
1478     }
1479
1480     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1481     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1482         ret = OMX_ErrorInvalidState;
1483         goto EXIT;
1484     }
1485
1486     switch (nParamIndex) {
1487     case OMX_IndexParamVideoWmv:
1488     {
1489         OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
1490         OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = NULL;
1491         EXYNOS_WMVDEC_HANDLE    *pWmvDec = NULL;
1492         ret = Exynos_OMX_Check_SizeVersion(pDstWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
1493         if (ret != OMX_ErrorNone) {
1494             goto EXIT;
1495         }
1496
1497         if (pDstWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
1498             ret = OMX_ErrorBadPortIndex;
1499         }
1500
1501         pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1502         pSrcWmvParam = &pWmvDec->WmvComponent[pDstWmvParam->nPortIndex];
1503
1504         Exynos_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
1505     }
1506         break;
1507
1508     case OMX_IndexParamStandardComponentRole:
1509     {
1510         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1511         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1512         if (ret != OMX_ErrorNone) {
1513             goto EXIT;
1514         }
1515
1516         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
1517     }
1518         break;
1519     case OMX_IndexParamVideoErrorCorrection:
1520     {
1521         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1522         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1523         EXYNOS_WMVDEC_HANDLE                *pWmvDec                 = NULL;
1524
1525         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1526         if (ret != OMX_ErrorNone) {
1527             goto EXIT;
1528         }
1529
1530         if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1531             ret = OMX_ErrorBadPortIndex;
1532             goto EXIT;
1533         }
1534
1535         pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1536         pSrcErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX];
1537
1538         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1539         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1540         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1541         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1542         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1543     }
1544         break;
1545     default:
1546         ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1547         break;
1548     }
1549 EXIT:
1550     FunctionOut();
1551
1552     return ret;
1553 }
1554
1555 OMX_ERRORTYPE Exynos_WmvDec_SetParameter(
1556     OMX_IN OMX_HANDLETYPE hComponent,
1557     OMX_IN OMX_INDEXTYPE  nIndex,
1558     OMX_IN OMX_PTR        pComponentParameterStructure)
1559 {
1560     OMX_ERRORTYPE           ret = OMX_ErrorNone;
1561     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1562     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1563
1564     FunctionIn();
1565
1566     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1567         ret = OMX_ErrorBadParameter;
1568         goto EXIT;
1569     }
1570     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1571     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1572     if (ret != OMX_ErrorNone) {
1573         goto EXIT;
1574     }
1575     if (pOMXComponent->pComponentPrivate == NULL) {
1576         ret = OMX_ErrorBadParameter;
1577         goto EXIT;
1578     }
1579
1580     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1581     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1582         ret = OMX_ErrorInvalidState;
1583         goto EXIT;
1584     }
1585
1586     switch (nIndex) {
1587     case OMX_IndexParamVideoWmv:
1588     {
1589         OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = NULL;
1590         OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
1591         EXYNOS_WMVDEC_HANDLE    *pWmvDec = NULL;
1592         ret = Exynos_OMX_Check_SizeVersion(pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
1593         if (ret != OMX_ErrorNone) {
1594             goto EXIT;
1595         }
1596
1597         if (pSrcWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
1598             ret = OMX_ErrorBadPortIndex;
1599             goto EXIT;
1600         }
1601
1602         pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1603         pDstWmvParam = &pWmvDec->WmvComponent[pSrcWmvParam->nPortIndex];
1604
1605         Exynos_OSAL_Memcpy(pDstWmvParam, pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
1606     }
1607         break;
1608     case OMX_IndexParamStandardComponentRole:
1609     {
1610         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1611
1612         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1613         if (ret != OMX_ErrorNone) {
1614             goto EXIT;
1615         }
1616
1617         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1618             ret = OMX_ErrorIncorrectStateOperation;
1619             goto EXIT;
1620         }
1621
1622         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE)) {
1623             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
1624         } else {
1625             ret = OMX_ErrorBadParameter;
1626             goto EXIT;
1627         }
1628     }
1629         break;
1630     case OMX_IndexParamPortDefinition:
1631     {
1632         OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1633         OMX_U32                       portIndex       = pPortDefinition->nPortIndex;
1634         EXYNOS_OMX_BASEPORT          *pExynosPort;
1635         OMX_U32                       width, height, size;
1636         OMX_U32                       realWidth, realHeight;
1637         OMX_PARAM_PORTDEFINITIONTYPE  portDefinition_backup;
1638
1639         if (portIndex >= pExynosComponent->portParam.nPorts) {
1640             ret = OMX_ErrorBadPortIndex;
1641             goto EXIT;
1642         }
1643         ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1644         if (ret != OMX_ErrorNone) {
1645             goto EXIT;
1646         }
1647
1648         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1649
1650         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1651             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1652                 ret = OMX_ErrorIncorrectStateOperation;
1653                 goto EXIT;
1654             }
1655         }
1656         if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1657             ret = OMX_ErrorBadParameter;
1658             goto EXIT;
1659         }
1660
1661         Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize);
1662         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1663         RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup);
1664
1665         realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1666         realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1667         width = ((realWidth + 15) & (~15));
1668         height = ((realHeight + 15) & (~15));
1669         size = (width * height * 3) / 2;
1670         pExynosPort->portDefinition.format.video.nStride = width;
1671         pExynosPort->portDefinition.format.video.nSliceHeight = height;
1672         pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
1673
1674         if (portIndex == INPUT_PORT_INDEX) {
1675             EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1676             pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1677             pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1678             pExynosOutputPort->portDefinition.format.video.nStride = width;
1679             pExynosOutputPort->portDefinition.format.video.nSliceHeight = height;
1680
1681             switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) {
1682             case OMX_COLOR_FormatYUV420Planar:
1683             case OMX_COLOR_FormatYUV420SemiPlanar:
1684                 pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
1685                 break;
1686 #ifdef SLP_PLATFORM /* NV12T fd */
1687             case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
1688                 pExynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB);
1689                 break;
1690 #endif
1691             case OMX_SEC_COLOR_FormatNV12Tiled:
1692                 pExynosOutputPort->portDefinition.nBufferSize =
1693                     calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1694                     calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1695                 break;
1696             default:
1697                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
1698                 ret = OMX_ErrorUnsupportedSetting;
1699                 break;
1700             }
1701
1702             if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1703                 pExynosOutputPort->portDefinition.nBufferSize =
1704                     calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1705                     calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1706             }
1707         }
1708     }
1709         break;
1710     case OMX_IndexParamVideoErrorCorrection:
1711     {
1712         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1713         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1714         EXYNOS_WMVDEC_HANDLE                *pWmvDec                 = NULL;
1715
1716         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1717         if (ret != OMX_ErrorNone) {
1718             goto EXIT;
1719         }
1720
1721         if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1722             ret = OMX_ErrorBadPortIndex;
1723             goto EXIT;
1724         }
1725
1726         pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1727         pDstErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX];
1728
1729         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1730         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1731         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1732         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1733         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1734     }
1735         break;
1736     default:
1737         ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1738         break;
1739     }
1740 EXIT:
1741     FunctionOut();
1742
1743     return ret;
1744 }
1745
1746 OMX_ERRORTYPE Exynos_WmvDec_GetConfig(
1747     OMX_HANDLETYPE hComponent,
1748     OMX_INDEXTYPE  nIndex,
1749     OMX_PTR        pComponentConfigStructure)
1750 {
1751     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1752     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1753     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1754
1755     FunctionIn();
1756
1757     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1758         ret = OMX_ErrorBadParameter;
1759         goto EXIT;
1760     }
1761     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1762     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1763     if (ret != OMX_ErrorNone) {
1764         goto EXIT;
1765     }
1766     if (pOMXComponent->pComponentPrivate == NULL) {
1767         ret = OMX_ErrorBadParameter;
1768         goto EXIT;
1769     }
1770     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1771     if (pExynosComponent->currentState == OMX_StateInvalid) {
1772         ret = OMX_ErrorInvalidState;
1773         goto EXIT;
1774     }
1775
1776     switch (nIndex) {
1777     default:
1778         ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1779         break;
1780     }
1781
1782 EXIT:
1783     FunctionOut();
1784
1785     return ret;
1786 }
1787
1788 OMX_ERRORTYPE Exynos_WmvDec_SetConfig(
1789     OMX_HANDLETYPE hComponent,
1790     OMX_INDEXTYPE  nIndex,
1791     OMX_PTR        pComponentConfigStructure)
1792 {
1793     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1794     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1795     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1796
1797     FunctionIn();
1798
1799     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1800         ret = OMX_ErrorBadParameter;
1801         goto EXIT;
1802     }
1803     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1804     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1805     if (ret != OMX_ErrorNone) {
1806         goto EXIT;
1807     }
1808     if (pOMXComponent->pComponentPrivate == NULL) {
1809         ret = OMX_ErrorBadParameter;
1810         goto EXIT;
1811     }
1812     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1813     if (pExynosComponent->currentState == OMX_StateInvalid) {
1814         ret = OMX_ErrorInvalidState;
1815         goto EXIT;
1816     }
1817
1818     switch (nIndex) {
1819     default:
1820         ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1821         break;
1822     }
1823
1824 EXIT:
1825     FunctionOut();
1826
1827     return ret;
1828 }
1829
1830 OMX_ERRORTYPE Exynos_WmvDec_GetExtensionIndex(
1831     OMX_IN  OMX_HANDLETYPE  hComponent,
1832     OMX_IN  OMX_STRING      cParameterName,
1833     OMX_OUT OMX_INDEXTYPE   *pIndexType)
1834 {
1835     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1836     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1837     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1838
1839     FunctionIn();
1840
1841     if (hComponent == NULL) {
1842         ret = OMX_ErrorBadParameter;
1843         goto EXIT;
1844     }
1845     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1846     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1847     if (ret != OMX_ErrorNone) {
1848         goto EXIT;
1849     }
1850     if (pOMXComponent->pComponentPrivate == NULL) {
1851         ret = OMX_ErrorBadParameter;
1852         goto EXIT;
1853     }
1854     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1855     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1856         ret = OMX_ErrorBadParameter;
1857         goto EXIT;
1858     }
1859     if (pExynosComponent->currentState == OMX_StateInvalid) {
1860         ret = OMX_ErrorInvalidState;
1861         goto EXIT;
1862     }
1863
1864     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1865         EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1866         *pIndexType = OMX_IndexVendorThumbnailMode;
1867         ret = OMX_ErrorNone;
1868     } else {
1869         ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1870     }
1871
1872 EXIT:
1873     FunctionOut();
1874
1875     return ret;
1876 }
1877
1878 OMX_ERRORTYPE Exynos_WmvDec_ComponentRoleEnum(
1879     OMX_HANDLETYPE hComponent,
1880     OMX_U8        *cRole,
1881     OMX_U32        nIndex)
1882 {
1883     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1884     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1885     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1886
1887     FunctionIn();
1888
1889     if ((hComponent == NULL) || (cRole == NULL)) {
1890         ret = OMX_ErrorBadParameter;
1891         goto EXIT;
1892     }
1893     if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1894         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
1895         ret = OMX_ErrorNone;
1896     } else {
1897         ret = OMX_ErrorNoMore;
1898     }
1899
1900 EXIT:
1901     FunctionOut();
1902
1903     return ret;
1904 }
1905
1906 /* MFC Init */
1907 OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1908 {
1909     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1910     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1911     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1912     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1913     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1914     EXYNOS_WMVDEC_HANDLE          *pWmvDec           = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1915     OMX_PTR                hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1916
1917     ExynosVideoDecOps       *pDecOps    = NULL;
1918     ExynosVideoDecBufferOps *pInbufOps  = NULL;
1919     ExynosVideoDecBufferOps *pOutbufOps = NULL;
1920
1921     CSC_METHOD csc_method = CSC_METHOD_SW;
1922     int i, plane;
1923
1924     FunctionIn();
1925
1926     pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
1927     pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
1928     pExynosComponent->bUseFlagEOF = OMX_TRUE;
1929     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1930
1931     /* WMV Codec Open */
1932     ret = WmvCodecOpen(pWmvDec);
1933     if (ret != OMX_ErrorNone) {
1934         goto EXIT;
1935     }
1936
1937     pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
1938     pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
1939     pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1940
1941     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1942         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1943         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1944
1945         if (pWmvDec->hMFCWmvHandle.bShareableBuf == OMX_TRUE) {
1946             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1947                 pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1948                 Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1949                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
1950
1951                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1952                 /* Use ION Allocator */
1953                     pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
1954                     pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1955                     pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1956                 pVideoDec->pMFCDecInputBuffer[i]->dataSize   = 0;
1957                     if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
1958                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1959                     ret = OMX_ErrorInsufficientResources;
1960                     goto EXIT;
1961                 }
1962                     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1963                 }
1964                 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1965             }
1966         } else {
1967             /*************/
1968             /*    TBD    */
1969             /*************/
1970             /* Does not require any actions. */
1971         }
1972     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1973         /*************/
1974         /*    TBD    */
1975         /*************/
1976         /* Does not require any actions. */
1977     }
1978
1979     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1980         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1981         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1982     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1983         /*************/
1984         /*    TBD    */
1985         /*************/
1986         /* Does not require any actions. */
1987     }
1988
1989     pWmvDec->bSourceStart = OMX_FALSE;
1990     Exynos_OSAL_SignalCreate(&pWmvDec->hSourceStartEvent);
1991     pWmvDec->bDestinationStart = OMX_FALSE;
1992     Exynos_OSAL_SignalCreate(&pWmvDec->hDestinationStartEvent);
1993
1994     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1995     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1996     pWmvDec->hMFCWmvHandle.indexTimestamp = 0;
1997     pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0;
1998     /* Default WMV codec format is set as VC1*/
1999     pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_WMV3;//WMV_FORMAT_VC1;
2000
2001     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
2002
2003 #if 0//defined(USE_CSC_GSCALER)
2004     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
2005 #endif
2006     pVideoDec->csc_handle = csc_init(csc_method);
2007     if (pVideoDec->csc_handle == NULL) {
2008         ret = OMX_ErrorInsufficientResources;
2009         goto EXIT;
2010     }
2011     pVideoDec->csc_set_format = OMX_FALSE;
2012
2013 EXIT:
2014     FunctionOut();
2015
2016     return ret;
2017 }
2018
2019 /* MFC Terminate */
2020 OMX_ERRORTYPE Exynos_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
2021 {
2022     OMX_ERRORTYPE          ret = OMX_ErrorNone;
2023     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2024     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2025     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2026     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2027     EXYNOS_WMVDEC_HANDLE    *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2028     OMX_PTR                hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
2029
2030     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
2031     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
2032     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
2033
2034     int i, plane;
2035
2036     FunctionIn();
2037
2038     if (pVideoDec->csc_handle != NULL) {
2039         csc_deinit(pVideoDec->csc_handle);
2040         pVideoDec->csc_handle = NULL;
2041     }
2042
2043     Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationStartEvent);
2044     pWmvDec->hDestinationStartEvent = NULL;
2045     pWmvDec->bDestinationStart = OMX_FALSE;
2046     Exynos_OSAL_SignalTerminate(pWmvDec->hSourceStartEvent);
2047     pWmvDec->hSourceStartEvent = NULL;
2048     pWmvDec->bSourceStart = OMX_FALSE;
2049
2050     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2051         WmvCodecDstFreeCodecBuffers(pOMXComponent);
2052
2053         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
2054         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
2055     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2056         /*************/
2057         /*    TBD    */
2058         /*************/
2059         /* Does not require any actions. */
2060     }
2061
2062     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2063         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
2064             if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
2065                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2066                     if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
2067                         Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
2068                 }
2069
2070                 Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
2071                 pVideoDec->pMFCDecInputBuffer[i] = NULL;
2072             }
2073         }
2074
2075         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
2076         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
2077     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2078         /*************/
2079         /*    TBD    */
2080         /*************/
2081         /* Does not require any actions. */
2082     }
2083     WmvCodecClose(pWmvDec);
2084
2085 EXIT:
2086     FunctionOut();
2087
2088     return ret;
2089 }
2090
2091 OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2092 {
2093     OMX_ERRORTYPE               ret = OMX_ErrorNone;
2094     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2095     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2096     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2097     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
2098     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2099     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2100     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
2101     OMX_BOOL                 bStartCode        = OMX_FALSE;
2102     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
2103     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
2104     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
2105     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2106     int i;
2107
2108     FunctionIn();
2109
2110     if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) {
2111         ret = WmvCodecSrcSetup(pOMXComponent, pSrcInputData);
2112         goto EXIT;
2113     }
2114     if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE) {
2115         ret = WmvCodecDstSetup(pOMXComponent);
2116     }
2117
2118     bStartCode = Check_Stream_PrefixCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
2119     if (bStartCode == OMX_FALSE && ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
2120         if (pSrcInputData->allocSize < oneFrameSize+4) {
2121             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can't attach startcode due to lack of buffer space");
2122             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2123             goto EXIT;
2124         }
2125
2126         bStartCode = Make_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
2127         if (bStartCode == OMX_FALSE) {
2128             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream Start Code");
2129             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2130             goto EXIT;
2131         }
2132     }
2133
2134     if ((bStartCode == OMX_TRUE) || ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){
2135         pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->timeStamp;
2136         pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->nFlags;
2137         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pWmvDec->hMFCWmvHandle.indexTimestamp, pSrcInputData->nFlags);
2138         pDecOps->Set_FrameTag(hMFCHandle, pWmvDec->hMFCWmvHandle.indexTimestamp);
2139         pWmvDec->hMFCWmvHandle.indexTimestamp++;
2140         pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP;
2141
2142 #ifdef USE_IMMEDIATE_DISPLAY
2143     /* Set Immediately display for I Frame*/    
2144         if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
2145             if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) {
2146                 /* Enable Immediately display After seek*/
2147                 pDecOps->Set_ImmediateDisplay(hMFCHandle);
2148                 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE;
2149             }
2150         }
2151 #endif
2152         
2153         /* queue work for input buffer */
2154         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
2155         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
2156                                     (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
2157         if (codecReturn != VIDEO_ERROR_NONE) {
2158             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2159             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2160             goto EXIT;
2161         }
2162         WmvCodecStart(pOMXComponent, INPUT_PORT_INDEX);
2163         if (pWmvDec->bSourceStart == OMX_FALSE) {
2164             pWmvDec->bSourceStart = OMX_TRUE;
2165             Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent);
2166             Exynos_OSAL_SleepMillisec(0);
2167         }
2168         if (pWmvDec->bDestinationStart == OMX_FALSE) {
2169             pWmvDec->bDestinationStart = OMX_TRUE;
2170             Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent);
2171             Exynos_OSAL_SleepMillisec(0);
2172         }
2173     }
2174
2175     ret = OMX_ErrorNone;
2176
2177 EXIT:
2178     FunctionOut();
2179
2180     return ret;
2181 }
2182
2183 OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2184 {
2185     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2186     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2187     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2188     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2189     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
2190     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2191     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
2192     ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
2193     ExynosVideoBuffer       *pVideoBuffer;
2194
2195     FunctionIn();
2196
2197     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
2198
2199     pSrcOutputData->dataLen       = 0;
2200     pSrcOutputData->usedDataLen   = 0;
2201     pSrcOutputData->remainDataLen = 0;
2202     pSrcOutputData->nFlags    = 0;
2203     pSrcOutputData->timeStamp = 0;
2204
2205     if (pVideoBuffer == NULL) {
2206         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2207         pSrcOutputData->allocSize  = 0;
2208         pSrcOutputData->pPrivate = NULL;
2209         pSrcOutputData->bufferHeader = NULL;
2210     } else {
2211         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2212         pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2213         pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
2214
2215         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2216             int i = 0;
2217             while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
2218                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2219                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2220                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2221                     goto EXIT;
2222                 }
2223                 i++;
2224             }
2225             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
2226             pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
2227         }
2228
2229         /* For Share Buffer */
2230         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2231     }
2232
2233     ret = OMX_ErrorNone;
2234
2235 EXIT:
2236     FunctionOut();
2237
2238     return ret;
2239 }
2240
2241 OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2242 {
2243     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2244     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2245     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2246     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2247     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
2248     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2249     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
2250     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
2251     OMX_U32 dataLen[2] = {0,};
2252     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2253
2254     FunctionIn();
2255
2256     if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
2257         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2258         ret = OMX_ErrorBadParameter;
2259         goto EXIT;
2260     }
2261
2262     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
2263                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
2264                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
2265
2266     if ((pVideoDec->bDRCProcessing == OMX_TRUE) &&
2267         (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2268         (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
2269         ret = WmvCodecDstSetup(pOMXComponent);
2270         if (ret != OMX_ErrorNone) {
2271             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig CodecDstSetup Failed");
2272             goto EXIT;
2273         }
2274         pVideoDec->bDRCProcessing = OMX_FALSE;
2275     }
2276
2277         codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
2278                       (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2279
2280
2281     if (codecReturn != VIDEO_ERROR_NONE) {
2282         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2283         ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2284         goto EXIT;
2285     }
2286     WmvCodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2287
2288     ret = OMX_ErrorNone;
2289
2290 EXIT:
2291     FunctionOut();
2292
2293     return ret;
2294 }
2295
2296 OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2297 {
2298     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2299     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2300     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2301     EXYNOS_WMVDEC_HANDLE         *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2302     void                          *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
2303     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2304     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2305     ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
2306     ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
2307     ExynosVideoBuffer       *pVideoBuffer;
2308     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2309     ExynosVideoGeometry *bufferGeometry;
2310     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
2311     OMX_S32 indexTimestamp = 0;
2312     int plane;
2313
2314     FunctionIn();
2315
2316     if (pWmvDec->bDestinationStart == OMX_FALSE) {
2317         ret = OMX_ErrorNone;
2318         goto EXIT;
2319     }
2320
2321     while (1) {
2322         pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2323         if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2324             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2325             ret = OMX_ErrorHardware;
2326             goto EXIT;
2327         }
2328
2329         if (pVideoBuffer == NULL) {
2330             ret = OMX_ErrorNone;
2331             goto EXIT;
2332         }
2333         displayStatus = pVideoBuffer->displayStatus;
2334         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
2335
2336         if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2337             (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2338             (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2339             (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2340             (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2341             if (pVideoBuffer != NULL) {
2342                 ret = OMX_ErrorNone;
2343                 break;
2344             } else {
2345                 ret = OMX_ErrorUndefined;
2346                 break;
2347             }
2348         }
2349     }
2350
2351     if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) {
2352         if (pVideoDec->bDRCProcessing != OMX_TRUE) {
2353             pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2354             pVideoDec->bDRCProcessing = OMX_TRUE;
2355             WmvCodecCheckResolutionChange(pOMXComponent);
2356             pVideoDec->csc_set_format = OMX_FALSE;
2357         }
2358         ret = OMX_ErrorNone;
2359         goto EXIT;
2360     }
2361
2362     pWmvDec->hMFCWmvHandle.outputIndexTimestamp++;
2363     pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
2364
2365     pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2366     for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
2367         pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2368         pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2369         pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2370         pDstOutputData->dataLen +=  pVideoBuffer->planes[plane].dataSize;
2371     }
2372     pDstOutputData->usedDataLen = 0;
2373     pDstOutputData->pPrivate = pVideoBuffer;
2374     /* For Share Buffer */
2375     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2376
2377     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2378     bufferGeometry = &pWmvDec->hMFCWmvHandle.codecOutbufConf;
2379     pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2380     pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2381     switch (bufferGeometry->eColorFormat) {
2382     case VIDEO_COLORFORMAT_NV12:
2383 #ifdef SLP_PLATFORM /* NV12T fd */
2384         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd;
2385 #else
2386         pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2387 #endif
2388         break;
2389     case VIDEO_COLORFORMAT_NV12_TILED:
2390     default:
2391         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
2392         break;
2393     }
2394
2395     indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2396     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
2397     if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2398         if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2399             (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2400             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2401             pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2402             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2403         } else {
2404             pDstOutputData->timeStamp = 0x00;
2405             pDstOutputData->nFlags = 0x00;
2406         }
2407     } else {
2408         /* For timestamp correction. if mfc support frametype detect */
2409         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
2410
2411 //#ifdef NEED_TIMESTAMP_REORDER
2412         if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) { /* SLP_PLATFORM */
2413             if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
2414                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2415                 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2416                 pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp;
2417             } else {
2418                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2419                 pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2420             }
2421 //#else
2422         } else {
2423             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2424             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2425 //#endif
2426         }
2427         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2428     }
2429
2430     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2431         (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2432         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2433         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2434         pDstOutputData->remainDataLen = 0;
2435     } else {
2436         pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2437     }
2438
2439     ret = OMX_ErrorNone;
2440
2441 EXIT:
2442     FunctionOut();
2443
2444     return ret;
2445 }
2446
2447 OMX_ERRORTYPE Exynos_WmvDec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2448 {
2449     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2450     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2451     EXYNOS_WMVDEC_HANDLE    *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2452     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2453
2454     FunctionIn();
2455
2456     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2457         ret = OMX_ErrorNone;
2458         goto EXIT;
2459     }
2460     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2461         ret = OMX_ErrorNone;
2462         goto EXIT;
2463     }
2464
2465     ret = Exynos_WmvDec_SrcIn(pOMXComponent, pSrcInputData);
2466     if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
2467         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2468                                                 pExynosComponent->callbackData,
2469                                                 OMX_EventError, ret, 0, NULL);
2470     }
2471
2472 EXIT:
2473     FunctionOut();
2474
2475     return ret;
2476 }
2477
2478 OMX_ERRORTYPE Exynos_WmvDec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2479 {
2480     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2481     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2482     EXYNOS_WMVDEC_HANDLE    *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2483     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2484
2485     FunctionIn();
2486
2487     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2488         ret = OMX_ErrorNone;
2489         goto EXIT;
2490     }
2491
2492     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2493         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2494             ret = OMX_ErrorNone;
2495             goto EXIT;
2496         }
2497     }
2498     if ((pWmvDec->bSourceStart == OMX_FALSE) &&
2499        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2500         Exynos_OSAL_SignalWait(pWmvDec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2501         Exynos_OSAL_SignalReset(pWmvDec->hSourceStartEvent);
2502     }
2503
2504     ret = Exynos_WmvDec_SrcOut(pOMXComponent, pSrcOutputData);
2505     if ((ret != OMX_ErrorNone) &&
2506         (pExynosComponent->currentState == OMX_StateExecuting)) {
2507         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2508                                                 pExynosComponent->callbackData,
2509                                                 OMX_EventError, ret, 0, NULL);
2510     }
2511
2512 EXIT:
2513     FunctionOut();
2514
2515     return ret;
2516 }
2517
2518 OMX_ERRORTYPE Exynos_WmvDec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2519 {
2520     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2521     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2522     EXYNOS_WMVDEC_HANDLE    *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2523     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2524
2525     FunctionIn();
2526
2527     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2528         ret = OMX_ErrorNone;
2529         goto EXIT;
2530     }
2531     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2532         ret = OMX_ErrorNone;
2533         goto EXIT;
2534     }
2535     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2536         if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
2537            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2538             Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2539             Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
2540         }
2541     }
2542     if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) {
2543         ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData);
2544         if (ret != OMX_ErrorNone) {
2545             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2546                                                 pExynosComponent->callbackData,
2547                                                 OMX_EventError, ret, 0, NULL);
2548         }
2549     }
2550
2551 EXIT:
2552     FunctionOut();
2553
2554     return ret;
2555 }
2556
2557 OMX_ERRORTYPE Exynos_WmvDec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2558 {
2559     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2560     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2561     EXYNOS_WMVDEC_HANDLE    *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2562     EXYNOS_OMX_BASEPORT     *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2563
2564     FunctionIn();
2565
2566     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2567         ret = OMX_ErrorNone;
2568         goto EXIT;
2569     }
2570     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2571         ret = OMX_ErrorNone;
2572         goto EXIT;
2573     }
2574
2575     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2576         if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
2577            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2578             Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2579             Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
2580         }
2581     }
2582     ret = Exynos_WmvDec_DstOut(pOMXComponent, pDstOutputData);
2583     if ((ret != OMX_ErrorNone) &&
2584         (pExynosComponent->currentState == OMX_StateExecuting)) {
2585         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2586                                                 pExynosComponent->callbackData,
2587                                                 OMX_EventError, ret, 0, NULL);
2588     }
2589
2590 EXIT:
2591     FunctionOut();
2592
2593     return ret;
2594 }
2595
2596 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2597     OMX_HANDLETYPE  hComponent,
2598     OMX_STRING      componentName)
2599 {
2600     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
2601     OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
2602     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
2603     EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
2604     EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
2605     EXYNOS_WMVDEC_HANDLE            *pWmvDec            = NULL;
2606     OMX_S32                          wmvFormat          = WMV_FORMAT_UNKNOWN;
2607     int i = 0;
2608
2609     FunctionIn();
2610
2611     if ((hComponent == NULL) || (componentName == NULL)) {
2612         ret = OMX_ErrorBadParameter;
2613         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2614         goto EXIT;
2615     }
2616     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_DEC, componentName) != 0) {
2617         ret = OMX_ErrorBadParameter;
2618         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2619         goto EXIT;
2620     }
2621
2622     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2623     ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2624     if (ret != OMX_ErrorNone) {
2625         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2626         goto EXIT;
2627     }
2628     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2629     pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2630
2631     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2632     if (pExynosComponent->componentName == NULL) {
2633         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2634         ret = OMX_ErrorInsufficientResources;
2635         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2636         goto EXIT;
2637     }
2638     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2639
2640     pWmvDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_WMVDEC_HANDLE));
2641     if (pWmvDec == NULL) {
2642         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2643         ret = OMX_ErrorInsufficientResources;
2644         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2645         goto EXIT;
2646     }
2647     Exynos_OSAL_Memset(pWmvDec, 0, sizeof(EXYNOS_WMVDEC_HANDLE));
2648     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2649     pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec;
2650     pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat;
2651
2652     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_WMV_DEC);
2653
2654     /* In case of BUFFER_COPY mode
2655             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2656             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2657          In case of BUFFER_SHARE
2658             bShareableBuf should be TRUE, FALSE is ignored
2659     */
2660     pWmvDec->hMFCWmvHandle.bShareableBuf = OMX_FALSE;
2661
2662     /* Set componentVersion */
2663     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2664     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2665     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2666     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2667     /* Set specVersion */
2668     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2669     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2670     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2671     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2672
2673     /* Input port */
2674     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2675     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2676     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2677     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2678     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2679     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2680     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
2681     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2682     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/wmv");
2683     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2684     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2685     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2686     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2687     pExynosPort->bufferProcessType = BUFFER_COPY;
2688     pExynosPort->portWayType = WAY2_PORT;
2689
2690     /* Output port */
2691     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2692     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2693     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2694     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2695     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2696     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2697     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2698     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2699     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2700     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2701     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2702 #ifdef SLP_PLATFORM
2703     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd;
2704 #else
2705     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2706 #endif
2707     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2708 #ifdef SLP_PLATFORM
2709     pExynosPort->bufferProcessType = BUFFER_SHARE;
2710 #else
2711     pExynosPort->bufferProcessType = BUFFER_COPY;
2712 #endif
2713     pExynosPort->portWayType = WAY2_PORT;
2714
2715     for(i = 0; i < ALL_PORT_NUM; i++) {
2716         INIT_SET_SIZE_VERSION(&pWmvDec->WmvComponent[i], OMX_VIDEO_PARAM_WMVTYPE);
2717         pWmvDec->WmvComponent[i].nPortIndex = i;
2718         pWmvDec->WmvComponent[i].eFormat    = OMX_VIDEO_WMVFormat9;
2719     }
2720
2721 #ifdef SLP_PLATFORM
2722     pWmvDec->wmvFormat = WMV_FORMAT_UNKNOWN;
2723 #endif
2724
2725     pOMXComponent->GetParameter      = &Exynos_WmvDec_GetParameter;
2726     pOMXComponent->SetParameter      = &Exynos_WmvDec_SetParameter;
2727     pOMXComponent->GetConfig         = &Exynos_WmvDec_GetConfig;
2728     pOMXComponent->SetConfig         = &Exynos_WmvDec_SetConfig;
2729     pOMXComponent->GetExtensionIndex = &Exynos_WmvDec_GetExtensionIndex;
2730     pOMXComponent->ComponentRoleEnum = &Exynos_WmvDec_ComponentRoleEnum;
2731     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2732
2733     pExynosComponent->exynos_codec_componentInit      = &Exynos_WmvDec_Init;
2734     pExynosComponent->exynos_codec_componentTerminate = &Exynos_WmvDec_Terminate;
2735
2736     pVideoDec->exynos_codec_srcInputProcess  = &Exynos_WmvDec_srcInputBufferProcess;
2737     pVideoDec->exynos_codec_srcOutputProcess = &Exynos_WmvDec_srcOutputBufferProcess;
2738     pVideoDec->exynos_codec_dstInputProcess  = &Exynos_WmvDec_dstInputBufferProcess;
2739     pVideoDec->exynos_codec_dstOutputProcess = &Exynos_WmvDec_dstOutputBufferProcess;
2740
2741     pVideoDec->exynos_codec_start         = &WmvCodecStart;
2742     pVideoDec->exynos_codec_stop          = &WmvCodecStop;
2743     pVideoDec->exynos_codec_bufferProcessRun = &WmvCodecOutputBufferProcessRun;
2744     pVideoDec->exynos_codec_enqueueAllBuffer = &WmvCodecEnQueueAllBuffer;
2745     pVideoDec->exynos_codec_resetupAllElement = &WmvCodecResetupAllElement;
2746
2747     pVideoDec->exynos_checkInputFrame                 = &Check_Wmv_Frame;
2748     pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2749     pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2750
2751     pVideoDec->exynos_process_codecConfigData                 = &Process_Wmv_CodecConfigData;
2752
2753 #ifndef SLP_PLATFORM /* do not use ion */
2754     pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2755     if (pVideoDec->hSharedMemory == NULL) {
2756         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2757         Exynos_OSAL_Free(pWmvDec);
2758         pWmvDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2759         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2760         ret = OMX_ErrorInsufficientResources;
2761         goto EXIT;
2762     }
2763 #endif
2764     pExynosComponent->currentState = OMX_StateLoaded;
2765
2766     ret = OMX_ErrorNone;
2767
2768 EXIT:
2769     FunctionOut();
2770
2771     return ret;
2772 }
2773
2774 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
2775     OMX_HANDLETYPE hComponent)
2776 {
2777     OMX_ERRORTYPE                ret                = OMX_ErrorNone;
2778     OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
2779     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
2780     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2781     EXYNOS_WMVDEC_HANDLE        *pWmvDec            = NULL;
2782
2783     FunctionIn();
2784
2785     if (hComponent == NULL) {
2786         ret = OMX_ErrorBadParameter;
2787         goto EXIT;
2788     }
2789     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2790     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2791     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2792 #ifndef SLP_PLATFORM /* do not use ion */
2793     Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2794 #endif
2795     Exynos_OSAL_Free(pExynosComponent->componentName);
2796     pExynosComponent->componentName = NULL;
2797
2798     pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
2799     if (pWmvDec != NULL) {
2800         Exynos_OSAL_Free(pWmvDec);
2801         pWmvDec = pVideoDec->hCodecHandle = NULL;
2802     }
2803
2804     ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2805     if (ret != OMX_ErrorNone) {
2806         goto EXIT;
2807     }
2808
2809     ret = OMX_ErrorNone;
2810
2811 EXIT:
2812     FunctionOut();
2813
2814     return ret;
2815 }