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