video_dec: Add ThumbnailMode decoding to WMV
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / vc1 / Exynos_OMX_Wmvdec.c
CommitLineData
9c5c94d6
SKR
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"
433e798a 38#include "Exynos_OMX_VdecControl.h"
9c5c94d6
SKR
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
70WMV_FORMAT gWvmFormat = WMV_FORMAT_UNKNOWN;
71
72const OMX_U32 wmv3 = 0x33564d57;
73const OMX_U32 wvc1 = 0x31435657;
74const OMX_U32 wmva = 0x41564d57;
75
76
77static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
78{
79 OMX_ERRORTYPE ret = OMX_ErrorNone;
80
81EXIT:
82 return ret;
83}
84
85static 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
109EXIT:
110 return ret;
111}
112
113int 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
200EXIT :
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
208static 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
246static 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
336static 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
373OMX_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
444EXIT:
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
465OMX_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
504EXIT:
505 FunctionOut();
506
507 return ret;
508}
509
510OMX_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
551EXIT:
552 FunctionOut();
553
554 return ret;
555}
556
557OMX_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
597EXIT:
598 FunctionOut();
599
600 return ret;
601}
602
603OMX_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
652EXIT:
653 FunctionOut();
654
655 return ret;
656}
657
0641ae29
TK
658OMX_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]);
0641ae29
TK
679 pBufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
680 } else {
681 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
0641ae29
TK
682 pBufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
683 }
433e798a 684 nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
0641ae29
TK
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
712EXIT:
713 FunctionOut();
714
715 return ret;
716}
717
9c5c94d6
SKR
718OMX_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)) {
9c5c94d6
SKR
754 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
755
e90eb9e8
TK
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]);
9c5c94d6
SKR
761 }
762 pOutbufOps->Clear_Queue(hMFCHandle);
763 }
764
765EXIT:
766 FunctionOut();
767
768 return ret;
769}
770
771OMX_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)) {
433e798a
EC
793 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
794 if (pBufferInfo == NULL) {
795 ret = OMX_ErrorInsufficientResources;
9c5c94d6
SKR
796 goto EXIT;
797 }
798
433e798a
EC
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);
9c5c94d6
SKR
803
804 ret = OMX_ErrorNone;
805 goto EXIT;
806 }
807
808 if (pVideoDec->bThumbnailMode == OMX_TRUE)
9f114c53 809 pDecOps->Set_IFrameDecoding(hMFCHandle);
9c5c94d6 810
c70316c7
JY
811 if ((pDecOps->Enable_DTSMode != NULL) &&
812 (pVideoDec->bDTSMode == OMX_TRUE))
813 pDecOps->Enable_DTSMode(hMFCHandle);
814
9c5c94d6
SKR
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;
9c5c94d6
SKR
844 } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
845 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
9c5c94d6 846 }
433e798a
EC
847 bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt;
848 inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
9c5c94d6
SKR
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
9c5c94d6
SKR
870 /* set output geometry */
871 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
433e798a
EC
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
9c5c94d6 907 pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
433e798a
EC
908#endif
909 bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt;
9c5c94d6
SKR
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);
433e798a
EC
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) {
9c5c94d6
SKR
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");
433e798a
EC
948 WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
949 pInbufOps->Cleanup_Buffer(hMFCHandle);
9c5c94d6
SKR
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)) {
a947bcc1
TK
965 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
966
9c5c94d6
SKR
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);
9c5c94d6
SKR
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)) {
a947bcc1
TK
987 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
988
9c5c94d6
SKR
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);
9c5c94d6
SKR
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
1013EXIT:
1014 FunctionOut();
1015
1016 return ret;
1017}
1018
1019OMX_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
433e798a
EC
1035 OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1036 OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
e02ebaac 1037
9c5c94d6
SKR
1038 FunctionIn();
1039
433e798a
EC
1040 for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++)
1041 nAllocLen[i] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[i];
e02ebaac
TK
1042
1043 pOutbufOps->Set_Shareable(hMFCHandle);
1044
9c5c94d6
SKR
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 }
9c5c94d6 1051
a38b0597
TK
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
0641ae29
TK
1060 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
1061 if (ret != OMX_ErrorNone)
1062 goto EXIT;
9c5c94d6 1063
0641ae29
TK
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++) {
9c5c94d6 1070 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
433e798a 1071 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
9c5c94d6 1072 }
98034ac0
SK
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 }
9c5c94d6 1079 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
433e798a 1080 ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0};
e02ebaac
TK
1081 int plane;
1082
a38b0597
TK
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
9c5c94d6
SKR
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++) {
433e798a 1098 for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
9c5c94d6
SKR
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
433e798a 1104 if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) {
9c5c94d6
SKR
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,
433e798a 1110 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
9c5c94d6 1111 }
98034ac0
SK
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 }
9c5c94d6
SKR
1118 } else {
1119 ret = OMX_ErrorNotImplemented;
1120 goto EXIT;
1121 }
1122#else
1123 ret = OMX_ErrorNotImplemented;
1124 goto EXIT;
1125#endif
1126 }
1127
9c5c94d6
SKR
1128 pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE;
1129
1130 ret = OMX_ErrorNone;
1131
1132EXIT:
1133 FunctionOut();
1134
1135 return ret;
1136}
1137
1138OMX_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;
9c39c5ff 1182 goto EXIT;
9c5c94d6
SKR
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 }
1233EXIT:
1234 FunctionOut();
1235
1236 return ret;
1237}
1238
1239OMX_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 }
1344EXIT:
1345 FunctionOut();
1346
1347 return ret;
1348}
1349
1350OMX_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
1386EXIT:
1387 FunctionOut();
1388
1389 return ret;
1390}
1391
1392OMX_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
1428EXIT:
1429 FunctionOut();
1430
1431 return ret;
1432}
1433
1434OMX_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
9f114c53 1468 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
9c5c94d6
SKR
1469
1470EXIT:
1471 FunctionOut();
1472
1473 return ret;
1474}
1475
1476OMX_ERRORTYPE Exynos_WmvDec_ComponentRoleEnum(
1477 OMX_HANDLETYPE hComponent,
1478 OMX_U8 *cRole,
1479 OMX_U32 nIndex)
1480{
1481 OMX_ERRORTYPE ret = OMX_ErrorNone;
1482 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1483 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1484
1485 FunctionIn();
1486
1487 if ((hComponent == NULL) || (cRole == NULL)) {
1488 ret = OMX_ErrorBadParameter;
1489 goto EXIT;
1490 }
1491 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1492 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
1493 ret = OMX_ErrorNone;
1494 } else {
1495 ret = OMX_ErrorNoMore;
1496 }
1497
1498EXIT:
1499 FunctionOut();
1500
1501 return ret;
1502}
1503
1504/* MFC Init */
1505OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1506{
1507 OMX_ERRORTYPE ret = OMX_ErrorNone;
1508 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1509 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1510 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1511 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1512 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1513 OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1514
1515 ExynosVideoDecOps *pDecOps = NULL;
1516 ExynosVideoDecBufferOps *pInbufOps = NULL;
1517 ExynosVideoDecBufferOps *pOutbufOps = NULL;
1518
1519 CSC_METHOD csc_method = CSC_METHOD_SW;
1520 int i, plane;
1521
1522 FunctionIn();
1523
1524 pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
1525 pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
1526 pExynosComponent->bUseFlagEOF = OMX_TRUE;
1527 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
e100a12d 1528 pExynosComponent->bBehaviorEOS = OMX_FALSE;
9c5c94d6
SKR
1529
1530 /* WMV Codec Open */
1531 ret = WmvCodecOpen(pWmvDec);
1532 if (ret != OMX_ErrorNone) {
1533 goto EXIT;
1534 }
1535
1536 pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1537 pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
1538 pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1539
433e798a 1540 pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE;
9c5c94d6 1541 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
433e798a 1542 OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
9c5c94d6
SKR
1543 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1544 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
0641ae29
TK
1545 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
1546 if (ret != OMX_ErrorNone)
1547 goto EXIT;
9c5c94d6 1548
0641ae29 1549 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
9c5c94d6 1550 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
9c5c94d6
SKR
1551 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1552 /*************/
1553 /* TBD */
1554 /*************/
1555 /* Does not require any actions. */
1556 }
1557
433e798a 1558 pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE;
9c5c94d6
SKR
1559 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1560 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1561 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1562 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1563 /*************/
1564 /* TBD */
1565 /*************/
1566 /* Does not require any actions. */
1567 }
1568
1569 pWmvDec->bSourceStart = OMX_FALSE;
1570 Exynos_OSAL_SignalCreate(&pWmvDec->hSourceStartEvent);
1571 pWmvDec->bDestinationStart = OMX_FALSE;
1572 Exynos_OSAL_SignalCreate(&pWmvDec->hDestinationStartEvent);
1573
1574 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1575 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1576 pWmvDec->hMFCWmvHandle.indexTimestamp = 0;
1577 pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0;
1578 /* Default WMV codec format is set as VC1*/
1579 pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_VC1;
1580
1581 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1582
433e798a
EC
1583 Exynos_OSAL_QueueCreate(&pWmvDec->bypassBufferInfoQ, QUEUE_ELEMENTS);
1584
a80c3bc5
TK
1585#ifdef USE_CSC_HW
1586 csc_method = CSC_METHOD_HW;
9c5c94d6
SKR
1587#endif
1588 pVideoDec->csc_handle = csc_init(csc_method);
1589 if (pVideoDec->csc_handle == NULL) {
1590 ret = OMX_ErrorInsufficientResources;
1591 goto EXIT;
1592 }
1593 pVideoDec->csc_set_format = OMX_FALSE;
1594
1595EXIT:
1596 FunctionOut();
1597
1598 return ret;
1599}
1600
1601/* MFC Terminate */
1602OMX_ERRORTYPE Exynos_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1603{
1604 OMX_ERRORTYPE ret = OMX_ErrorNone;
1605 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1606 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1607 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1608 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1609 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1610 OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1611
1612 ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1613 ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
1614 ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1615
1616 int i, plane;
1617
1618 FunctionIn();
1619
1620 if (pVideoDec->csc_handle != NULL) {
1621 csc_deinit(pVideoDec->csc_handle);
1622 pVideoDec->csc_handle = NULL;
1623 }
1624
433e798a
EC
1625 Exynos_OSAL_QueueTerminate(&pWmvDec->bypassBufferInfoQ);
1626
9c5c94d6
SKR
1627 Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationStartEvent);
1628 pWmvDec->hDestinationStartEvent = NULL;
1629 pWmvDec->bDestinationStart = OMX_FALSE;
1630 Exynos_OSAL_SignalTerminate(pWmvDec->hSourceStartEvent);
1631 pWmvDec->hSourceStartEvent = NULL;
1632 pWmvDec->bSourceStart = OMX_FALSE;
1633
1634 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
0641ae29 1635 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
9c5c94d6
SKR
1636 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1637 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1638 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1639 /*************/
1640 /* TBD */
1641 /*************/
1642 /* Does not require any actions. */
1643 }
1644
1645 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
0641ae29 1646 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
9c5c94d6
SKR
1647 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1648 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1649 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1650 /*************/
1651 /* TBD */
1652 /*************/
1653 /* Does not require any actions. */
1654 }
1655 WmvCodecClose(pWmvDec);
1656
e100a12d
SK
1657 Exynos_ResetAllPortConfig(pOMXComponent);
1658
9c5c94d6
SKR
1659EXIT:
1660 FunctionOut();
1661
1662 return ret;
1663}
1664
1665OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1666{
433e798a
EC
1667 OMX_ERRORTYPE ret = OMX_ErrorNone;
1668 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1669 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1670 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1671 void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1672 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1673 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1674
1675 OMX_BUFFERHEADERTYPE tempBufferHeader;
1676 void *pPrivate = NULL;
1677
9c5c94d6 1678 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
433e798a
EC
1679 OMX_BOOL bStartCode = OMX_FALSE;
1680
1681 ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1682 ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
1683 ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1684 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1685
9c5c94d6
SKR
1686 int i;
1687
1688 FunctionIn();
1689
1690 if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) {
1691 ret = WmvCodecSrcSetup(pOMXComponent, pSrcInputData);
1692 goto EXIT;
1693 }
1694 if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE) {
1695 ret = WmvCodecDstSetup(pOMXComponent);
1696 }
1697
1698 bStartCode = Check_Stream_PrefixCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
09ccc01b
TK
1699 if ((bStartCode == OMX_FALSE) &&
1700 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
9c5c94d6
SKR
1701 if (pSrcInputData->allocSize < oneFrameSize+4) {
1702 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can't attach startcode due to lack of buffer space");
1703 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1704 goto EXIT;
1705 }
1706
1707 bStartCode = Make_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
1708 if (bStartCode == OMX_FALSE) {
1709 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream Start Code");
1710 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1711 goto EXIT;
1712 }
1713 }
1714
1715 if ((bStartCode == OMX_TRUE) || ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){
1716 pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->timeStamp;
1717 pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->nFlags;
1718 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);
1719 pDecOps->Set_FrameTag(hMFCHandle, pWmvDec->hMFCWmvHandle.indexTimestamp);
1720 pWmvDec->hMFCWmvHandle.indexTimestamp++;
1721 pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP;
433e798a
EC
1722#ifdef USE_QOS_CTRL
1723 if ((pVideoDec->bQosChanged == OMX_TRUE) &&
1724 (pDecOps->Set_QosRatio != NULL)) {
1725 pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
1726 pVideoDec->bQosChanged = OMX_FALSE;
1727 }
1728#endif
9c5c94d6
SKR
1729 /* queue work for input buffer */
1730 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
433e798a
EC
1731 OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0};
1732
1733 if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
1734 tempBufferHeader.nFlags = pSrcInputData->nFlags;
1735 tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
1736 pPrivate = (void *)&tempBufferHeader;
1737 } else {
1738 pPrivate = (void *)pSrcInputData->bufferHeader;
1739 }
1740 codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
1741 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1742 (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd,
1743 (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize,
1744 pExynosInputPort->nPlaneCnt, pPrivate);
9c5c94d6
SKR
1745 if (codecReturn != VIDEO_ERROR_NONE) {
1746 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1747 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1748 goto EXIT;
1749 }
1750 WmvCodecStart(pOMXComponent, INPUT_PORT_INDEX);
1751 if (pWmvDec->bSourceStart == OMX_FALSE) {
1752 pWmvDec->bSourceStart = OMX_TRUE;
1753 Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent);
1754 Exynos_OSAL_SleepMillisec(0);
1755 }
1756 if (pWmvDec->bDestinationStart == OMX_FALSE) {
1757 pWmvDec->bDestinationStart = OMX_TRUE;
1758 Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent);
1759 Exynos_OSAL_SleepMillisec(0);
1760 }
1761 }
1762
1763 ret = OMX_ErrorNone;
1764
1765EXIT:
1766 FunctionOut();
1767
1768 return ret;
1769}
1770
1771OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1772{
1773 OMX_ERRORTYPE ret = OMX_ErrorNone;
1774 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1775 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1776 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1777 void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1778 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1779 ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1780 ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
1781 ExynosVideoBuffer *pVideoBuffer;
433e798a 1782 ExynosVideoBuffer videoBuffer;
9c5c94d6
SKR
1783
1784 FunctionIn();
1785
433e798a
EC
1786 if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
1787 pVideoBuffer = &videoBuffer;
1788 else
1789 pVideoBuffer = NULL;
9c5c94d6
SKR
1790
1791 pSrcOutputData->dataLen = 0;
1792 pSrcOutputData->usedDataLen = 0;
1793 pSrcOutputData->remainDataLen = 0;
433e798a
EC
1794 pSrcOutputData->nFlags = 0;
1795 pSrcOutputData->timeStamp = 0;
1796 pSrcOutputData->bufferHeader = NULL;
9c5c94d6
SKR
1797
1798 if (pVideoBuffer == NULL) {
1799 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1800 pSrcOutputData->allocSize = 0;
1801 pSrcOutputData->pPrivate = NULL;
1802 pSrcOutputData->bufferHeader = NULL;
1803 } else {
1804 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1805 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1806 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1807
1808 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
9c39c5ff
TK
1809 int i;
1810 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1811 if (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer ==
1812 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1813 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1814 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1815 break;
9c5c94d6 1816 }
9c5c94d6 1817 }
9c39c5ff
TK
1818
1819 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1820 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1821 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1822 goto EXIT;
1823 }
9c5c94d6
SKR
1824 }
1825
1826 /* For Share Buffer */
433e798a
EC
1827 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
1828 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
9c5c94d6
SKR
1829 }
1830
1831 ret = OMX_ErrorNone;
1832
1833EXIT:
1834 FunctionOut();
1835
1836 return ret;
1837}
1838
1839OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1840{
433e798a
EC
1841 OMX_ERRORTYPE ret = OMX_ErrorNone;
1842 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1843 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1844 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
1845 void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1846 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1847
1848 ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1849 ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1850 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1851
1852 OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1853 int i;
9c5c94d6
SKR
1854
1855 FunctionIn();
1856
1857 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1858 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1859 ret = OMX_ErrorBadParameter;
1860 goto EXIT;
1861 }
1862
433e798a
EC
1863 for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) {
1864 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[i]: 0x%x", __FUNCTION__, __LINE__, i,
1865 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]);
1866 }
9c5c94d6
SKR
1867
1868 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
433e798a 1869 (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader);
9c5c94d6
SKR
1870
1871 if (codecReturn != VIDEO_ERROR_NONE) {
1872 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1873 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1874 goto EXIT;
1875 }
1876 WmvCodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1877
1878 ret = OMX_ErrorNone;
1879
1880EXIT:
1881 FunctionOut();
1882
1883 return ret;
1884}
1885
1886OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1887{
1888 OMX_ERRORTYPE ret = OMX_ErrorNone;
1889 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1890 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1891 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1892 void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
1893 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1894 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1895 ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
1896 ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
1897 ExynosVideoBuffer *pVideoBuffer = NULL;
1898 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1899 ExynosVideoGeometry *bufferGeometry;
1900 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1901 OMX_S32 indexTimestamp = 0;
1902 int plane;
1903
1904 FunctionIn();
1905
1906 if (pWmvDec->bDestinationStart == OMX_FALSE) {
1907 ret = OMX_ErrorNone;
1908 goto EXIT;
1909 }
1910
1911 while (1) {
2a38c35a
SK
1912 pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
1913 if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
1914 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
1915 ret = OMX_ErrorHardware;
1916 goto EXIT;
1917 }
1918
1919 if (pVideoBuffer == NULL) {
9c5c94d6
SKR
1920 ret = OMX_ErrorNone;
1921 goto EXIT;
1922 }
1923 displayStatus = pVideoBuffer->displayStatus;
1924 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1925
1926 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1927 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1928 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
405399e5 1929 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
9c5c94d6
SKR
1930 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1931 ret = OMX_ErrorNone;
1932 break;
1933 }
1934 }
1935
1936 pWmvDec->hMFCWmvHandle.outputIndexTimestamp++;
1937 pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
1938
1939 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
433e798a 1940 for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
9c5c94d6
SKR
1941 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1942 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1943 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1944 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
1945 }
1946 pDstOutputData->usedDataLen = 0;
1947 pDstOutputData->pPrivate = pVideoBuffer;
e90eb9e8
TK
1948 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1949 int i = 0;
1950 pDstOutputData->pPrivate = NULL;
1951 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1952 if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] ==
1953 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
1954 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
1955 break;
1956 }
1957 }
1958
1959 if (pDstOutputData->pPrivate == NULL) {
1960 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1961 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1962 goto EXIT;
1963 }
1964 }
1965
9c5c94d6
SKR
1966 /* For Share Buffer */
1967 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1968
1969 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1970 bufferGeometry = &pWmvDec->hMFCWmvHandle.codecOutbufConf;
1971 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1972 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1973 switch (bufferGeometry->eColorFormat) {
1974 case VIDEO_COLORFORMAT_NV12:
1975 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1976 break;
433e798a
EC
1977#ifdef USE_DUALDPB_MODE
1978 case VIDEO_COLORFORMAT_I420:
1979 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar;
1980 break;
1981 case VIDEO_COLORFORMAT_YV12:
1982 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar;
1983 break;
1984 case VIDEO_COLORFORMAT_NV21:
1985 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear;
1986 break;
1987#endif
9c5c94d6
SKR
1988 case VIDEO_COLORFORMAT_NV12_TILED:
1989 default:
1990 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1991 break;
1992 }
1993
1994 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
1995 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
1996 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1997 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
1998 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
f53da333
SK
1999 if (indexTimestamp == INDEX_AFTER_EOS) {
2000 pDstOutputData->timeStamp = 0x00;
2001 pDstOutputData->nFlags = 0x00;
2002 } else {
2003 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2004 pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
2005 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2006 }
9c5c94d6
SKR
2007 } else {
2008 pDstOutputData->timeStamp = 0x00;
2009 pDstOutputData->nFlags = 0x00;
2010 }
2011 } else {
2012 /* For timestamp correction. if mfc support frametype detect */
2013 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
c70316c7
JY
2014
2015 /* NEED TIMESTAMP REORDER */
2016 if (pVideoDec->bDTSMode == OMX_TRUE) {
2017 if ((pVideoBuffer->frameType == VIDEO_FRAME_I) ||
2018 ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) &&
433e798a
EC
2019 ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
2020 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
c70316c7
JY
2021 pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp;
2022 else
2023 indexTimestamp = pWmvDec->hMFCWmvHandle.outputIndexTimestamp;
9c5c94d6 2024 }
c70316c7 2025
9c5c94d6
SKR
2026 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2027 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
c70316c7 2028
9c5c94d6
SKR
2029 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2030 }
2031
2032 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
405399e5 2033 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
9c5c94d6
SKR
2034 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2035 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2036 pDstOutputData->remainDataLen = 0;
e100a12d
SK
2037
2038 if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
2039 (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
2040 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2041 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2042 }
9c5c94d6
SKR
2043 } else {
2044 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2045 }
2046
2047 ret = OMX_ErrorNone;
2048
2049EXIT:
2050 FunctionOut();
2051
2052 return ret;
2053}
2054
2055OMX_ERRORTYPE Exynos_WmvDec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2056{
2057 OMX_ERRORTYPE ret = OMX_ErrorNone;
2058 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2059 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2060 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2061
2062 FunctionIn();
2063
2064 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2065 ret = OMX_ErrorNone;
2066 goto EXIT;
2067 }
2068 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2069 ret = OMX_ErrorNone;
2070 goto EXIT;
2071 }
2072
2073 ret = Exynos_WmvDec_SrcIn(pOMXComponent, pSrcInputData);
2074 if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
2075 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2076 pExynosComponent->callbackData,
2077 OMX_EventError, ret, 0, NULL);
2078 }
2079
2080EXIT:
2081 FunctionOut();
2082
2083 return ret;
2084}
2085
2086OMX_ERRORTYPE Exynos_WmvDec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2087{
2088 OMX_ERRORTYPE ret = OMX_ErrorNone;
2089 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2090 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2091 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2092
2093 FunctionIn();
2094
2095 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2096 ret = OMX_ErrorNone;
2097 goto EXIT;
2098 }
2099
2100 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2101 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2102 ret = OMX_ErrorNone;
2103 goto EXIT;
2104 }
2105 }
2106 if ((pWmvDec->bSourceStart == OMX_FALSE) &&
2107 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2108 Exynos_OSAL_SignalWait(pWmvDec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2109 Exynos_OSAL_SignalReset(pWmvDec->hSourceStartEvent);
2110 }
2111
2112 ret = Exynos_WmvDec_SrcOut(pOMXComponent, pSrcOutputData);
2113 if ((ret != OMX_ErrorNone) &&
2114 (pExynosComponent->currentState == OMX_StateExecuting)) {
2115 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2116 pExynosComponent->callbackData,
2117 OMX_EventError, ret, 0, NULL);
2118 }
2119
2120EXIT:
2121 FunctionOut();
2122
2123 return ret;
2124}
2125
2126OMX_ERRORTYPE Exynos_WmvDec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2127{
2128 OMX_ERRORTYPE ret = OMX_ErrorNone;
2129 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2130 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2131 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2132
2133 FunctionIn();
2134
2135 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2136 ret = OMX_ErrorNone;
2137 goto EXIT;
2138 }
2139 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2140 ret = OMX_ErrorNone;
2141 goto EXIT;
2142 }
2143 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2144 if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
2145 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2146 Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2147 Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
2148 }
433e798a
EC
2149 if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) {
2150 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ);
2151 if (pBufferInfo == NULL) {
2152 ret = OMX_ErrorUndefined;
2153 goto EXIT;
2154 }
2155
2156 pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags;
2157 pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
2158 Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
2159 Exynos_OSAL_Free(pBufferInfo);
2160
2161 ret = OMX_ErrorNone;
2162 goto EXIT;
2163 }
9c5c94d6
SKR
2164 }
2165 if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) {
2166 ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData);
2167 if (ret != OMX_ErrorNone) {
2168 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2169 pExynosComponent->callbackData,
2170 OMX_EventError, ret, 0, NULL);
2171 }
2172 }
2173
2174EXIT:
2175 FunctionOut();
2176
2177 return ret;
2178}
2179
2180OMX_ERRORTYPE Exynos_WmvDec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2181{
2182 OMX_ERRORTYPE ret = OMX_ErrorNone;
2183 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2184 EXYNOS_WMVDEC_HANDLE *pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2185 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2186
2187 FunctionIn();
2188
2189 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2190 ret = OMX_ErrorNone;
2191 goto EXIT;
2192 }
2193 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2194 ret = OMX_ErrorNone;
2195 goto EXIT;
2196 }
2197
2198 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2199 if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
2200 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2201 Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2202 Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
2203 }
433e798a
EC
2204 if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) {
2205 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
2206 OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
2207 BYPASS_BUFFER_INFO *pBufferInfo = NULL;
2208
2209 if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
2210 pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
2211 if (pOMXBuffer == NULL) {
2212 ret = OMX_ErrorUndefined;
2213 goto EXIT;
2214 }
2215 } else {
2216 pOMXBuffer = dstOutputUseBuffer->bufferHeader;
2217 }
2218
2219 pBufferInfo = Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ);
2220 if (pBufferInfo == NULL) {
2221 ret = OMX_ErrorUndefined;
2222 goto EXIT;
2223 }
2224
2225 pOMXBuffer->nFlags = pBufferInfo->nFlags;
2226 pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp;
2227 Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
2228 Exynos_OSAL_Free(pBufferInfo);
2229
2230 dstOutputUseBuffer->dataValid = OMX_FALSE;
2231
2232 ret = OMX_ErrorNone;
2233 goto EXIT;
2234 }
9c5c94d6
SKR
2235 }
2236 ret = Exynos_WmvDec_DstOut(pOMXComponent, pDstOutputData);
2237 if ((ret != OMX_ErrorNone) &&
2238 (pExynosComponent->currentState == OMX_StateExecuting)) {
2239 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2240 pExynosComponent->callbackData,
2241 OMX_EventError, ret, 0, NULL);
2242 }
2243
2244EXIT:
2245 FunctionOut();
2246
2247 return ret;
2248}
2249
2250OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2251 OMX_HANDLETYPE hComponent,
2252 OMX_STRING componentName)
2253{
2254 OMX_ERRORTYPE ret = OMX_ErrorNone;
2255 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2256 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2257 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
2258 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2259 EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
2260 OMX_S32 wmvFormat = WMV_FORMAT_UNKNOWN;
2261 int i = 0;
2262
2263 FunctionIn();
2264
2265 if ((hComponent == NULL) || (componentName == NULL)) {
2266 ret = OMX_ErrorBadParameter;
2267 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2268 goto EXIT;
2269 }
2270 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_DEC, componentName) != 0) {
2271 ret = OMX_ErrorBadParameter;
2272 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2273 goto EXIT;
2274 }
2275
2276 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2277 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2278 if (ret != OMX_ErrorNone) {
2279 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2280 goto EXIT;
2281 }
2282 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2283 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2284
2285 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2286 if (pExynosComponent->componentName == NULL) {
2287 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2288 ret = OMX_ErrorInsufficientResources;
2289 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2290 goto EXIT;
2291 }
2292 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2293
2294 pWmvDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_WMVDEC_HANDLE));
2295 if (pWmvDec == NULL) {
2296 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2297 ret = OMX_ErrorInsufficientResources;
2298 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2299 goto EXIT;
2300 }
2301 Exynos_OSAL_Memset(pWmvDec, 0, sizeof(EXYNOS_WMVDEC_HANDLE));
2302 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2303 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec;
2304 pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat;
2305
2306 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_WMV_DEC);
2307
2308 /* Set componentVersion */
2309 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2310 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2311 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2312 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2313 /* Set specVersion */
2314 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2315 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2316 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2317 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2318
2319 /* Input port */
2320 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2321 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2322 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2323 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2324 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2325 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2326 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
2327 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2328 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/wmv");
2329 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2330 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2331 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2332 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2333 //pExynosPort->bufferProcessType = BUFFER_SHARE;
2334 pExynosPort->bufferProcessType = BUFFER_COPY;
2335 pExynosPort->portWayType = WAY2_PORT;
2336
2337 /* Output port */
2338 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2339 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2340 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2341 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2342 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2343 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2344 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2345 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2346 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2347 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2348 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2349 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2350 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2351 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2352 pExynosPort->portWayType = WAY2_PORT;
2353
2354 for(i = 0; i < ALL_PORT_NUM; i++) {
2355 INIT_SET_SIZE_VERSION(&pWmvDec->WmvComponent[i], OMX_VIDEO_PARAM_WMVTYPE);
2356 pWmvDec->WmvComponent[i].nPortIndex = i;
2357 pWmvDec->WmvComponent[i].eFormat = OMX_VIDEO_WMVFormat9;
2358 }
2359
2360 pOMXComponent->GetParameter = &Exynos_WmvDec_GetParameter;
2361 pOMXComponent->SetParameter = &Exynos_WmvDec_SetParameter;
2362 pOMXComponent->GetConfig = &Exynos_WmvDec_GetConfig;
2363 pOMXComponent->SetConfig = &Exynos_WmvDec_SetConfig;
2364 pOMXComponent->GetExtensionIndex = &Exynos_WmvDec_GetExtensionIndex;
2365 pOMXComponent->ComponentRoleEnum = &Exynos_WmvDec_ComponentRoleEnum;
2366 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2367
2368 pExynosComponent->exynos_codec_componentInit = &Exynos_WmvDec_Init;
2369 pExynosComponent->exynos_codec_componentTerminate = &Exynos_WmvDec_Terminate;
2370
2371 pVideoDec->exynos_codec_srcInputProcess = &Exynos_WmvDec_srcInputBufferProcess;
2372 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_WmvDec_srcOutputBufferProcess;
2373 pVideoDec->exynos_codec_dstInputProcess = &Exynos_WmvDec_dstInputBufferProcess;
2374 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_WmvDec_dstOutputBufferProcess;
2375
2376 pVideoDec->exynos_codec_start = &WmvCodecStart;
2377 pVideoDec->exynos_codec_stop = &WmvCodecStop;
2378 pVideoDec->exynos_codec_bufferProcessRun = &WmvCodecOutputBufferProcessRun;
2379 pVideoDec->exynos_codec_enqueueAllBuffer = &WmvCodecEnQueueAllBuffer;
2380
2381 pVideoDec->exynos_checkInputFrame = &Check_Wmv_Frame;
2382 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2383 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2384
2385 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2386 if (pVideoDec->hSharedMemory == NULL) {
2387 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2388 Exynos_OSAL_Free(pWmvDec);
2389 pWmvDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2390 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2391 ret = OMX_ErrorInsufficientResources;
2392 goto EXIT;
2393 }
2394
2395 pExynosComponent->currentState = OMX_StateLoaded;
2396
2397 ret = OMX_ErrorNone;
2398
2399EXIT:
2400 FunctionOut();
2401
2402 return ret;
2403}
2404
2405OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
2406 OMX_HANDLETYPE hComponent)
2407{
2408 OMX_ERRORTYPE ret = OMX_ErrorNone;
2409 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2410 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2411 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2412 EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
2413
2414 FunctionIn();
2415
2416 if (hComponent == NULL) {
2417 ret = OMX_ErrorBadParameter;
2418 goto EXIT;
2419 }
2420 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2421 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2422 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2423
2424 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2425
2426 Exynos_OSAL_Free(pExynosComponent->componentName);
2427 pExynosComponent->componentName = NULL;
2428
2429 pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
2430 if (pWmvDec != NULL) {
2431 Exynos_OSAL_Free(pWmvDec);
2432 pWmvDec = pVideoDec->hCodecHandle = NULL;
2433 }
2434
2435 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2436 if (ret != OMX_ErrorNone) {
2437 goto EXIT;
2438 }
2439
2440 ret = OMX_ErrorNone;
2441
2442EXIT:
2443 FunctionOut();
2444
2445 return ret;
2446}