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