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