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