9acaebf3ce3db8bcbcbb7a0af8cff0e01d53ed57
[platform/adaptation/nexell/nx-video-api.git] / src / nx_video_dec.c
1 /*
2  *      Copyright (C) 2016 Nexell Co. All Rights Reserved
3  *      Nexell Co. Proprietary & Confidential
4  *
5  *      NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE
6  *  AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING
7  *  BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
8  *  FOR A PARTICULAR PURPOSE.
9  *
10  *      File            : nx_video_api.c
11  *      Brief           : V4L2 Video Decoder
12  *      Author          : SungWon Jo (doriya@nexell.co.kr)
13  *      History         : 2016.04.25 : Create
14  */
15
16 #include <stdio.h>
17 #include <stdbool.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 #include <sys/stat.h>
24 #include <sys/ioctl.h>
25
26 #include <linux/videodev2.h>
27 #include <linux/videodev2_nxp_media.h>
28
29 #include <nx_video_alloc.h>
30 #include <nx_video_api.h>
31 #include "nx_video_log.h"
32
33
34 /*----------------------------------------------------------------------------*/
35 #define NX_V4L2_DEC_NAME                "nx-vpu-dec"
36 #define VIDEODEV_MINOR_MAX              63
37 #define STREAM_BUFFER_NUM               1
38
39
40 struct NX_V4L2DEC_INFO
41 {
42   int fd;
43   uint32_t codecType;
44   int32_t width;
45   int32_t height;
46
47   int32_t useExternalFrameBuffer;
48   int32_t numFrameBuffers;
49   NX_VID_MEMORY_HANDLE hImage[MAX_FRAME_BUFFER_NUM];
50
51   NX_MEMORY_HANDLE hStream[STREAM_BUFFER_NUM];
52
53   /* Initialize Output Information        */
54   uint8_t pSeqData[1024];       /* SPS PPS (H.264) or Decoder Specific Information(for MPEG4) */
55   int32_t seqDataSize;
56
57   IMG_DISP_INFO dispInfo;
58
59   int32_t planesNum;
60
61   int32_t frameCnt;
62
63   /* For MPEG4 */
64   int vopTimeBits;
65
66   /* For VC1 */
67   int32_t iInterlace;
68
69 #ifdef TIZEN_FEATURE_ARTIK530
70   /* buffer manager */
71   void *bufmgr;
72 #endif
73 };
74
75
76 /*
77  *              Find Device Node
78  */
79
80 /*----------------------------------------------------------------------------*/
81 static int32_t
82 V4l2DecOpen (void)
83 {
84   int fd = -1;
85
86   bool found = false;
87   struct stat s;
88   FILE *stream_fd;
89   char filename[64], name[64];
90   int32_t i = 0;
91
92   while (!found && (i <= VIDEODEV_MINOR_MAX)) {
93     /* video device node */
94     snprintf (filename, 64, "/dev/video%d", i);
95
96     /* if the node is video device */
97     if ((lstat (filename, &s) == 0) && S_ISCHR (s.st_mode)
98         && ((int) ((unsigned short) (s.st_rdev) >> 8) == 81)) {
99       /* open sysfs entry */
100       snprintf (filename, 64, "/sys/class/video4linux/video%d/name", i);
101       stream_fd = fopen (filename, "r");
102       if (stream_fd == NULL) {
103         _D ("failed to open sysfs entry for videodev \n");
104         i++;
105         continue;
106       }
107
108       /* read sysfs entry for device name */
109       if (fgets (name, sizeof (name), stream_fd) == 0) {
110         _D ("failed to read sysfs entry for videodev\n");
111       } else {
112         if (strncmp (name, NX_V4L2_DEC_NAME, strlen (NX_V4L2_DEC_NAME)) == 0) {
113           _D ("node found for device %s: /dev/video%d \n", NX_V4L2_DEC_NAME,
114               i);
115           found = true;
116         }
117       }
118
119       fclose (stream_fd);
120     }
121
122     i++;
123   }
124
125   if (found) {
126     snprintf (filename, 64, "/dev/video%d", i - 1);
127     fd = open (filename, O_RDWR);
128   }
129
130   return fd;
131 }
132
133
134 #ifndef MKTAG
135 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
136 #endif
137
138 #ifndef PUT_LE32
139 #define PUT_LE32(_p, _var) \
140         *_p++ = (uint8_t)((_var) >> 0); \
141         *_p++ = (uint8_t)((_var) >> 8); \
142         *_p++ = (uint8_t)((_var) >> 16); \
143         *_p++ = (uint8_t)((_var) >> 24);
144 #endif
145
146 #ifndef PUT_BE32
147 #define PUT_BE32(_p, _var) \
148         *_p++ = (uint8_t)((_var) >> 24); \
149         *_p++ = (uint8_t)((_var) >> 16); \
150         *_p++ = (uint8_t)((_var) >> 8); \
151         *_p++ = (uint8_t)((_var) >> 0);
152 #endif
153
154 #ifndef PUT_LE16
155 #define PUT_LE16(_p, _var) \
156         *_p++ = (uint8_t)((_var) >> 0); \
157         *_p++ = (uint8_t)((_var) >> 8);
158 #endif
159
160 #ifndef PUT_BE16
161 #define PUT_BE16(_p, _var) \
162         *_p++ = (uint8_t)((_var) >> 8); \
163         *_p++ = (uint8_t)((_var) >> 0);
164 #endif
165
166
167 typedef struct
168 {
169   uint32_t dwUsedBits;
170   uint8_t *pbyStart;
171   uint32_t dwPktSize;
172 } VLD_STREAM;
173
174 static int32_t
175 vld_count_leading_zero (uint32_t dwWord)
176 {
177   int32_t iLZ = 0;
178
179   if ((dwWord >> (32 - 16)) == 0)
180     iLZ = 16;
181   if ((dwWord >> (32 - 8 - iLZ)) == 0)
182     iLZ += 8;
183   if ((dwWord >> (32 - 4 - iLZ)) == 0)
184     iLZ += 4;
185   if ((dwWord >> (32 - 2 - iLZ)) == 0)
186     iLZ += 2;
187   if ((dwWord >> (32 - 1 - iLZ)) == 0)
188     iLZ += 1;
189
190   return iLZ;
191 }
192
193 static uint32_t
194 vld_show_bits (VLD_STREAM * pstVldStm, int32_t iBits)
195 {
196   uint32_t dwUsedBits = pstVldStm->dwUsedBits;
197   int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
198   uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
199   uint32_t dwRead;
200
201   dwRead = *pbyRead++ << 24;
202   if (iBits > iBitCnt) {
203     dwRead += *pbyRead++ << 16;
204     if (iBits > iBitCnt + 8) {
205       dwRead += *pbyRead++ << 8;
206       if (iBits > iBitCnt + 16)
207         dwRead += *pbyRead++;
208     }
209   }
210
211   return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
212 }
213
214 static uint32_t
215 vld_get_bits (VLD_STREAM * pstVldStm, int32_t iBits)
216 {
217   uint32_t dwUsedBits = pstVldStm->dwUsedBits;
218   int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
219   uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
220   uint32_t dwRead;
221
222   pstVldStm->dwUsedBits += iBits;
223
224   dwRead = *pbyRead++ << 24;
225   if (iBits > iBitCnt) {
226     dwRead += *pbyRead++ << 16;
227     if (iBits > iBitCnt + 8) {
228       dwRead += *pbyRead++ << 8;
229       if (iBits > iBitCnt + 16)
230         dwRead += *pbyRead++;
231     }
232   }
233
234   return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
235 }
236
237 static void
238 vld_flush_bits (VLD_STREAM * pstVldStm, int iBits)
239 {
240   pstVldStm->dwUsedBits += iBits;
241 }
242
243 static uint32_t
244 vld_get_uev (VLD_STREAM * pstVldStm)
245 {
246   int32_t iLZ = vld_count_leading_zero (vld_show_bits (pstVldStm, 32));
247
248   vld_flush_bits (pstVldStm, iLZ);
249   return (vld_get_bits (pstVldStm, iLZ + 1) - 1);
250 }
251
252 static void
253 Mp4DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
254     int32_t iStreamSize)
255 {
256   uint8_t *pbyStrm = pbyStream;
257   uint32_t uPreFourByte = (uint32_t) - 1;
258
259   hDec->vopTimeBits = 0;
260
261   do {
262     if (pbyStrm >= (pbyStream + iStreamSize))
263       break;
264
265     uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
266
267     if (uPreFourByte >= 0x00000120 && uPreFourByte <= 0x0000012F) {
268       VLD_STREAM stStrm = { 0, pbyStrm, iStreamSize };
269       int32_t i;
270
271       vld_flush_bits (&stStrm, 1 + 8);  /* random_accessible_vol, video_object_type_indication */
272       if (vld_get_bits (&stStrm, 1))    /* is_object_layer_identifier */
273         vld_flush_bits (&stStrm, 4 + 3);        /* video_object_layer_verid, video_object_layer_priority */
274
275       if (vld_get_bits (&stStrm, 4) == 0xF)     /* aspect_ratio_info */
276         vld_flush_bits (&stStrm, 8 + 8);        /* par_width, par_height */
277
278       if (vld_get_bits (&stStrm, 1)) {  /* vol_control_parameters */
279         if (vld_get_bits (&stStrm, 2 + 1 + 1) & 1) {    /* chroma_format, low_delay, vbv_parameters */
280           vld_flush_bits (&stStrm, 15 + 1);     /* first_half_bit_rate, marker_bit */
281           vld_flush_bits (&stStrm, 15 + 1);     /* latter_half_bit_rate, marker_bit */
282           vld_flush_bits (&stStrm, 15 + 1);     /* first_half_vbv_buffer_size, marker_bit */
283           vld_flush_bits (&stStrm, 3 + 11 + 1); /* latter_half_vbv_buffer_size, first_half_vbv_occupancy, marker_bit */
284           vld_flush_bits (&stStrm, 15 + 1);     /* latter_half_vbv_occupancy, marker_bit */
285         }
286       }
287
288       vld_flush_bits (&stStrm, 2 + 1);  /* video_object_layer_shape, marker_bit */
289
290       for (i = 0; i < 16; i++)  /* vop_time_increment_resolution */
291         if (vld_get_bits (&stStrm, 1))
292           break;
293       hDec->vopTimeBits = 16 - i;
294       break;
295     }
296   } while (1);
297 }
298
299 static int32_t
300 Mp4DecParseFrameHeader (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
301     int32_t iStreamSize)
302 {
303   VLD_STREAM stStrm = { 0, pbyStream, iStreamSize };
304   int32_t iSize = iStreamSize;
305
306   if (vld_get_bits (&stStrm, 32) == 0x000001B6) {
307     vld_flush_bits (&stStrm, 2);        /* vop_coding_type */
308
309     do {
310       if (vld_get_bits (&stStrm, 1) == 0)
311         break;
312     } while (stStrm.dwUsedBits < ((uint32_t) iStreamSize << 3));
313
314     vld_flush_bits (&stStrm, 1 + hDec->vopTimeBits + 1);        /* marker_bits, vop_time_increment, marker_bits */
315
316     if (vld_get_bits (&stStrm, 1) == 0) /* vop_coded */
317       iSize = 0;
318   }
319
320   return iSize;
321 }
322
323 static int32_t
324 GetSequenceHeader (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
325 {
326   uint8_t *pbySrc = pSeqIn->seqBuf;
327   uint8_t *pbyDst = (uint8_t *) hDec->hStream[0]->pBuffer;
328   int32_t iSize = pSeqIn->seqSize;
329
330   switch (hDec->codecType) {
331     case V4L2_PIX_FMT_H264:
332       if (pSeqIn->seqSize > 0) {
333         memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
334
335         if ((pbySrc[2] == 0) && (pbySrc[7] > 51))
336           pbyDst[7] = 51;
337         else if ((pbySrc[2] == 1) && (pbySrc[6] > 51))
338           pbyDst[6] = 51;
339         break;
340       } else
341         return -1;
342
343     case V4L2_PIX_FMT_DIV3:
344       if (pSeqIn->seqSize == 0) {
345         if ((pSeqIn->width > 0) && (pSeqIn->height > 0)) {
346           PUT_LE32 (pbyDst, MKTAG ('C', 'N', 'M', 'V'));
347           PUT_LE16 (pbyDst, 0x00);      /* version */
348           PUT_LE16 (pbyDst, 0x20);      /* length of header in bytes */
349           PUT_LE32 (pbyDst, MKTAG ('D', 'I', 'V', '3'));        /* codec FourCC */
350           PUT_LE16 (pbyDst, pSeqIn->width);
351           PUT_LE16 (pbyDst, pSeqIn->height);
352           PUT_LE32 (pbyDst, 0); /* frame rate */
353           PUT_LE32 (pbyDst, 0); /* time scale(?) */
354           PUT_LE32 (pbyDst, 0); /* number of frames in file */
355           PUT_LE32 (pbyDst, 0); /* unused */
356           iSize += 32;
357         } else
358           return -1;
359       } else {
360         PUT_BE32 (pbyDst, pSeqIn->seqSize);
361         iSize += 4;
362         memcpy (pbyDst, pbyDst, pSeqIn->seqSize);
363       }
364       break;
365
366     case V4L2_PIX_FMT_WMV9:
367       if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
368 #ifdef RCV_V2
369         PUT_LE32 (pbyDst, (0xC5 << 24) | 0x00); /* version */
370 #else
371         /* RCV_V1 */
372         PUT_LE32 (pbyDst, (0x85 << 24) | 0x00);
373 #endif
374
375         PUT_LE32 (pbyDst, pSeqIn->seqSize);
376         memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
377         pbyDst += pSeqIn->seqSize;
378         PUT_LE32 (pbyDst, pSeqIn->height);
379         PUT_LE32 (pbyDst, pSeqIn->width);
380         iSize += 16;
381 #ifdef RCV_V2
382         PUT_LE32 (pbyDst, 12);
383         /* STRUCT_B_FRIST (LEVEL:3|CBR:1:RESERVE:4:HRD_BUFFER|24) */
384         PUT_LE32 (pbyDst, 2 << 29 | 1 << 28 | 0x80 << 24 | 1 << 0);
385         PUT_LE32 (pbyDst, 0);   /* bitrate */
386         PUT_LE32 (pbyDst, 0);   /* framerate */
387         iSize += 16;
388 #endif
389         break;
390       } else
391         return -1;
392
393     case V4L2_PIX_FMT_RV8:
394     case V4L2_PIX_FMT_RV9:
395       if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
396         iSize += 26;
397
398         PUT_BE32 (pbyDst, iSize);       /* Length */
399         PUT_LE32 (pbyDst, MKTAG ('V', 'I', 'D', 'O'));  /* MOFTag */
400
401         if (hDec->codecType == V4L2_PIX_FMT_RV8) {
402           PUT_LE32 (pbyDst, MKTAG ('R', 'V', '3', '0'));
403         } else {
404           PUT_LE32 (pbyDst, MKTAG ('R', 'V', '4', '0'));
405         }
406
407         PUT_BE16 (pbyDst, pSeqIn->width);
408         PUT_BE16 (pbyDst, pSeqIn->height);
409         PUT_BE16 (pbyDst, 0x0c);        /* BitCount */
410         PUT_BE16 (pbyDst, 0x00);        /* PadWidth */
411         PUT_BE16 (pbyDst, 0x00);        /* PadHeight */
412         PUT_LE32 (pbyDst, 0);   /* framerate */
413         memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
414         break;
415       } else
416         return -1;
417
418     case V4L2_PIX_FMT_VP8:
419       if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
420         PUT_LE32 (pbyDst, MKTAG ('D', 'K', 'I', 'F'));  /* signature 'DKIF' */
421         PUT_LE16 (pbyDst, 0x00);        /* version */
422         PUT_LE16 (pbyDst, 0x20);        /* length of header in bytes */
423         PUT_LE32 (pbyDst, MKTAG ('V', 'P', '8', '0'));  /* codec FourCC */
424         PUT_LE16 (pbyDst, pSeqIn->width);       /* width */
425         PUT_LE16 (pbyDst, pSeqIn->height);      /* height */
426         PUT_LE32 (pbyDst, 0);   /* frame rate */
427         PUT_LE32 (pbyDst, 0);   /* time scale(?) */
428         PUT_LE32 (pbyDst, 0);   /* number of frames in file */
429         PUT_LE32 (pbyDst, 0);   /* unused */
430         iSize += 32;
431
432         PUT_LE32 (pbyDst, pSeqIn->seqSize);
433         PUT_LE32 (pbyDst, 0);
434         PUT_LE32 (pbyDst, 0);
435         memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
436         iSize += 12;
437         break;
438       } else
439         return -1;
440
441     case V4L2_PIX_FMT_XVID:
442     case V4L2_PIX_FMT_DIVX:
443     case V4L2_PIX_FMT_DIV4:
444     case V4L2_PIX_FMT_DIV5:
445     case V4L2_PIX_FMT_DIV6:
446     case V4L2_PIX_FMT_MPEG4:
447       Mp4DecParseVideoCfg (hDec, pbySrc, pSeqIn->seqSize);
448
449     default:
450       if (pSeqIn->seqSize > 0)
451         memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
452       else
453         return -1;
454   }
455
456   return iSize;
457 }
458
459 static int32_t
460 GetFrameStream (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn, int32_t * idx)
461 {
462   int32_t iSize = pDecIn->strmSize;
463   uint8_t *pbySrc = pDecIn->strmBuf;
464   uint8_t *pbyDst;
465
466   if (iSize <= 0)
467     return 0;
468
469   *idx = hDec->frameCnt % STREAM_BUFFER_NUM;
470   pbyDst = (uint8_t *) hDec->hStream[*idx]->pBuffer;
471
472   switch (hDec->codecType) {
473     case V4L2_PIX_FMT_H264:
474       memcpy (pbyDst, pbySrc, iSize);
475       if (iSize > 8) {
476         if ((pbySrc[2] == 0) && ((pbySrc[4] & 0x1F) == 7) && (pbySrc[7] > 51))
477           pbyDst[7] = 51;
478         else if ((pbySrc[2] == 1) && ((pbySrc[3] & 0x1F) == 7)
479             && (pbySrc[6] > 51))
480           pbyDst[6] = 51;
481       }
482       break;
483
484     case V4L2_PIX_FMT_WVC1:
485       /* check start code as prefix (0x00, 0x00, 0x01) */
486       if (pbySrc[0] != 0 || pbySrc[1] != 0 || pbySrc[2] != 1) {
487         *pbyDst++ = 0x00;
488         *pbyDst++ = 0x00;
489         *pbyDst++ = 0x01;
490         *pbyDst++ = 0x0D;
491         memcpy (pbyDst, pbySrc, iSize);
492         iSize += 4;
493       } else {
494         /* no extra header size, there is start code in input stream */
495         memcpy (pbyDst, pbySrc, iSize);
496       }
497       break;
498
499     case V4L2_PIX_FMT_WMV9:
500       PUT_LE32 (pbyDst, iSize | 0);     /* Key Frame = 0x80000000 */
501       iSize += 4;
502
503 #ifdef RCV_V2
504       PUT_LE32 (pbyDst, 0);
505       iSize += 4;
506 #endif
507
508       memcpy (pbyDst, pbySrc, pDecIn->strmSize);
509       break;
510
511     case V4L2_PIX_FMT_RV8:
512     case V4L2_PIX_FMT_RV9:
513     {
514       int32_t cSlice, nSlice;
515       int32_t i, val, offset;
516
517       cSlice = pbySrc[0] + 1;
518       nSlice = iSize - 1 - (cSlice * 8);
519
520       PUT_BE32 (pbyDst, nSlice);
521       PUT_LE32 (pbyDst, 0);
522       PUT_BE16 (pbyDst, 0);     /* frame number */
523       PUT_BE16 (pbyDst, 0x02);  /* Flags */
524       PUT_BE32 (pbyDst, 0x00);  /* LastPacket */
525       PUT_BE32 (pbyDst, cSlice);        /* NumSegments */
526
527       offset = 1;
528       for (i = 0; i < cSlice; i++) {
529         val =
530             (pbySrc[offset + 3] << 24) | (pbySrc[offset +
531                 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
532         PUT_BE32 (pbyDst, val); /* isValid */
533         offset += 4;
534         val =
535             (pbySrc[offset + 3] << 24) | (pbySrc[offset +
536                 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
537         PUT_BE32 (pbyDst, val); /* Offset */
538         offset += 4;
539       }
540
541       memcpy (pbyDst, pbySrc + (1 + (cSlice * 8)), nSlice);
542       iSize = 20 + (cSlice * 8) + nSlice;
543     }
544       break;
545
546     case V4L2_PIX_FMT_DIV3:
547     case V4L2_PIX_FMT_VP8:
548       PUT_LE32 (pbyDst, iSize);
549       PUT_LE32 (pbyDst, 0);
550       PUT_LE32 (pbyDst, 0);
551       memcpy (pbyDst, pbySrc, iSize);
552       iSize += 12;
553       break;
554
555     case V4L2_PIX_FMT_XVID:
556     case V4L2_PIX_FMT_DIVX:
557     case V4L2_PIX_FMT_DIV4:
558     case V4L2_PIX_FMT_DIV5:
559     case V4L2_PIX_FMT_DIV6:
560     case V4L2_PIX_FMT_MPEG4:
561       /* For PB Frame */
562       if (hDec->vopTimeBits > 0) {
563         iSize = Mp4DecParseFrameHeader (hDec, pbySrc, iSize);
564       }
565
566     default:
567       memcpy ((void *) pbyDst, (void *) pbySrc, iSize);
568   }
569
570   return iSize;
571 }
572
573
574 /*
575  *              V4L2 Decoder
576  */
577
578 /*----------------------------------------------------------------------------*/
579 NX_V4L2DEC_HANDLE
580 NX_V4l2DecOpen (uint32_t codecType)
581 {
582   NX_V4L2DEC_HANDLE hDec =
583       (NX_V4L2DEC_HANDLE) malloc (sizeof (struct NX_V4L2DEC_INFO));
584
585   memset (hDec, 0, sizeof (struct NX_V4L2DEC_INFO));
586
587   hDec->fd = V4l2DecOpen ();
588   if (hDec->fd <= 0) {
589     _E ("Failed to open video decoder device\n");
590     goto ERROR_EXIT;
591   }
592
593   /* Query capabilities of Device */
594   {
595     struct v4l2_capability cap;
596
597     memset (&cap, 0, sizeof (cap));
598
599     if (ioctl (hDec->fd, VIDIOC_QUERYCAP, &cap) != 0) {
600       _E ("failed to ioctl: VIDIOC_QUERYCAP\n");
601       goto ERROR_EXIT;
602     }
603   }
604
605   hDec->codecType = codecType;
606
607   return hDec;
608
609 ERROR_EXIT:
610   free (hDec);
611
612   return NULL;
613 }
614
615 /*----------------------------------------------------------------------------*/
616 int32_t
617 NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec)
618 {
619   int32_t ret = 0, i;
620
621   if (NULL == hDec) {
622     _E ("Fail, Invalid Handle.\n");
623     return -1;
624   }
625
626   {
627     enum v4l2_buf_type type;
628
629     type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
630     if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
631       _E ("failed to ioctl: VIDIOC_STREAMOFF(Stream)\n");
632       return -1;
633     }
634
635     type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
636     if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
637       _E ("failed to ioctl: VIDIOC_STREAMOFF(Image)\n");
638       return -1;
639     }
640
641     for (i = 0; i < STREAM_BUFFER_NUM; i++)
642       NX_FreeMemory (hDec->hStream[i]);
643
644     close (hDec->fd);
645   }
646
647   if (hDec->useExternalFrameBuffer == 0) {
648     for (i = 0; i < hDec->numFrameBuffers; i++) {
649       if (hDec->hImage[i]) {
650         NX_FreeVideoMemory (hDec->hImage[i]);
651         hDec->hImage[i] = NULL;
652       }
653     }
654   }
655 #ifdef TIZEN_FEATURE_ARTIK530
656     if (hDec->bufmgr)
657       tbm_bufmgr_deinit (hDec->bufmgr);
658 #endif
659
660   free (hDec);
661
662   return ret;
663 }
664
665 /*----------------------------------------------------------------------------*/
666 int32_t
667 NX_V4l2DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn,
668     NX_V4L2DEC_SEQ_OUT * pSeqOut)
669 {
670   int32_t imgWidth = pSeqIn->width;
671   int32_t imgHeight = pSeqIn->height;
672
673   memset (pSeqOut, 0, sizeof (NX_V4L2DEC_SEQ_OUT));
674
675   if (NULL == hDec) {
676     _E ("Fail, Invalid Handle.\n");
677     return -1;
678   }
679
680   hDec->seqDataSize = (pSeqIn->seqSize < 1024) ? (pSeqIn->seqSize) : (1024);
681   memcpy (hDec->pSeqData, pSeqIn->seqBuf, hDec->seqDataSize);
682
683   /* Set Stream Formet */
684   {
685     struct v4l2_format fmt;
686
687     memset (&fmt, 0, sizeof (fmt));
688
689     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
690     fmt.fmt.pix_mp.pixelformat = hDec->codecType;
691
692     if ((imgWidth == 0) || (imgHeight == 0))
693       fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
694           MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4;
695     else
696       fmt.fmt.pix_mp.plane_fmt[0].sizeimage = imgWidth * imgHeight * 3 / 4;
697
698     fmt.fmt.pix_mp.width = imgWidth;
699     fmt.fmt.pix_mp.height = imgHeight;
700     fmt.fmt.pix_mp.num_planes = 1;
701
702     if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
703       _E ("Failed to ioctx : VIDIOC_S_FMT(Input Stream)\n");
704       return -1;
705     }
706   }
707
708   /* Malloc Stream Buffer */
709   {
710     struct v4l2_requestbuffers req;
711     int32_t i, buffCnt = STREAM_BUFFER_NUM;
712
713     /* IOCTL : VIDIOC_REQBUFS For Input Stream */
714     memset (&req, 0, sizeof (req));
715     req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
716     req.count = buffCnt;
717     req.memory = V4L2_MEMORY_DMABUF;
718
719     if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
720       _E ("failed to ioctl: VIDIOC_REQBUFS(Input Stream)\n");
721       return -1;
722     }
723
724     for (i = 0; i < buffCnt; i++) {
725       hDec->hStream[i] =
726           NX_AllocateMemory (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4, 4096);
727       if (hDec->hStream[i] == NULL) {
728         _E ("Failed to allocate stream buffer(%d, %d)\n", i,
729             MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4);
730         return -1;
731       }
732
733       if (NX_MapMemory (hDec->hStream[i]) != 0) {
734         _E ("Stream memory Mapping Failed\n");
735         return -1;
736       }
737     }
738   }
739
740   /* Set Parameter */
741   {
742     if (hDec->codecType == V4L2_PIX_FMT_MJPEG) {
743       struct v4l2_control ctrl;
744
745       ctrl.id = V4L2_CID_MPEG_VIDEO_THUMBNAIL_MODE;
746       ctrl.value = pSeqIn->thumbnailMode;
747
748       if (ioctl (hDec->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
749         _E ("failed to ioctl: Set Thumbnail Mode\n");
750         return -1;
751       }
752     }
753   }
754
755   /* Parser Sequence Header */
756   {
757     struct v4l2_plane planes[1];
758     struct v4l2_buffer buf;
759     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
760     int32_t iSeqSize = GetSequenceHeader (hDec, pSeqIn);
761
762     if (iSeqSize <= 0) {
763       _E ("Fail, input data has error!!");
764       return -1;
765     }
766
767     memset (&buf, 0, sizeof (buf));
768     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
769     buf.m.planes = planes;
770     buf.length = 1;
771     buf.memory = V4L2_MEMORY_DMABUF;
772     buf.index = 0;
773
774     buf.m.planes[0].m.userptr = (unsigned long) hDec->hStream[0]->pBuffer;
775     buf.m.planes[0].m.fd = hDec->hStream[0]->dmaFd;
776     buf.m.planes[0].length = hDec->hStream[0]->size;
777     buf.m.planes[0].bytesused = iSeqSize;
778     buf.m.planes[0].data_offset = 0;
779
780     buf.timestamp.tv_sec = pSeqIn->timeStamp / 1000;
781     buf.timestamp.tv_usec = (pSeqIn->timeStamp % 1000) * 1000;
782
783     if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
784       _E ("failed to ioctl: VIDIOC_QBUF(Header Stream)\n");
785       return -1;
786     }
787
788     if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
789       _E ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
790       return -1;
791     }
792
793     memset (&buf, 0, sizeof (buf));
794     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
795     buf.m.planes = planes;
796     buf.length = 1;
797     buf.memory = V4L2_MEMORY_DMABUF;
798
799     if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
800       _E ("failed to ioctl: VIDIOC_DQBUF(Header Stream)\n");
801       return -1;
802     }
803
804     pSeqOut->usedByte = buf.bytesused;
805
806     if (buf.field == V4L2_FIELD_NONE)
807       pSeqOut->interlace = NONE_FIELD;
808     else if (V4L2_FIELD_INTERLACED)
809       pSeqOut->interlace = FIELD_INTERLACED;
810
811     hDec->iInterlace = pSeqOut->interlace;
812   }
813
814   /* Get Image Information */
815   {
816     struct v4l2_format fmt;
817     struct v4l2_crop crop;
818
819     memset (&fmt, 0, sizeof (fmt));
820     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
821
822     if (ioctl (hDec->fd, VIDIOC_G_FMT, &fmt) != 0) {
823       _E ("Fail, ioctl(): VIDIOC_G_FMT.\n");
824       return -1;
825     }
826
827     pSeqOut->imgFourCC = fmt.fmt.pix_mp.pixelformat;
828     pSeqOut->width = fmt.fmt.pix_mp.width;
829     pSeqOut->height = fmt.fmt.pix_mp.height;
830     pSeqOut->minBuffers = fmt.fmt.pix_mp.reserved[1];
831     hDec->numFrameBuffers = pSeqOut->minBuffers;
832
833     memset (&crop, 0, sizeof (crop));
834     crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
835
836     if (ioctl (hDec->fd, VIDIOC_G_CROP, &crop) != 0) {
837       _E ("Fail, ioctl(): VIDIOC_G_CROP\n");
838       return -1;
839     }
840
841     pSeqOut->dispInfo.dispLeft = crop.c.left;
842     pSeqOut->dispInfo.dispTop = crop.c.top;
843     pSeqOut->dispInfo.dispRight = crop.c.left + crop.c.width;
844     pSeqOut->dispInfo.dispBottom = crop.c.top + crop.c.height;
845   }
846
847   return 0;
848 }
849
850 /*----------------------------------------------------------------------------*/
851 int32_t
852 NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
853 {
854   /* Set Output Image */
855   {
856     struct v4l2_format fmt;
857
858     memset (&fmt, 0, sizeof (fmt));
859     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
860     fmt.fmt.pix_mp.pixelformat = pSeqIn->imgFormat;
861     fmt.fmt.pix_mp.width = pSeqIn->width;
862     fmt.fmt.pix_mp.height = pSeqIn->height;
863     fmt.fmt.pix_mp.num_planes = pSeqIn->imgPlaneNum;
864
865     if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
866       _E ("failed to ioctl: VIDIOC_S_FMT(Output Yuv)\n");
867       return -1;
868     }
869
870     hDec->planesNum = pSeqIn->imgPlaneNum;
871   }
872
873   /* Malloc Output Image */
874   {
875     struct v4l2_requestbuffers req;
876     struct v4l2_plane planes[3];
877     struct v4l2_buffer buf;
878     enum v4l2_buf_type type;
879     int32_t imgBuffCnt, i, j;
880
881     /* Calculate Buffer Number */
882     if (pSeqIn->pMemHandle == NULL) {
883       hDec->useExternalFrameBuffer = false;
884       imgBuffCnt = hDec->numFrameBuffers + pSeqIn->numBuffers;
885     } else {
886       hDec->useExternalFrameBuffer = true;
887       if (2 > pSeqIn->numBuffers - hDec->numFrameBuffers)
888         _D ("External Buffer too small.(min=%d, buffers=%d)\n",
889             hDec->numFrameBuffers, pSeqIn->numBuffers);
890
891       imgBuffCnt = pSeqIn->numBuffers;
892     }
893     hDec->numFrameBuffers = imgBuffCnt;
894
895     /* Request Output Buffer */
896     memset (&req, 0, sizeof (req));
897     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
898     req.count = imgBuffCnt;
899     req.memory = V4L2_MEMORY_DMABUF;
900
901     if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
902       _E ("failed to ioctl: VIDIOC_REQBUFS(Output YUV)\n");
903       return -1;
904     }
905
906     memset (&buf, 0, sizeof (buf));
907     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
908     buf.m.planes = planes;
909     buf.length = pSeqIn->imgPlaneNum;
910     buf.memory = V4L2_MEMORY_DMABUF;
911
912 #ifdef TIZEN_FEATURE_ARTIK530
913   hDec->bufmgr = tbm_bufmgr_init (-1);
914   _D ("bufmgr = %p", hDec->bufmgr);
915   if (!hDec->bufmgr) {
916     _E ("failed to initialize tbm_init");
917     return -1;
918   }
919 #endif
920     /* Allocate Buffer(Internal or External) */
921     for (i = 0; i < imgBuffCnt; i++) {
922       if (true == hDec->useExternalFrameBuffer) {
923         hDec->hImage[i] = pSeqIn->pMemHandle[i];
924       } else {
925         hDec->hImage[i] =
926             NX_AllocateVideoMemory (hDec->bufmgr, pSeqIn->width, pSeqIn->height,
927             pSeqIn->imgPlaneNum, pSeqIn->imgFormat, 4096);
928         if (hDec->hImage[i] == NULL) {
929           _E ("Failed to allocate image buffer(%d, %d, %d)\n", i,
930               pSeqIn->width, pSeqIn->height);
931           return -1;
932         }
933
934         if (NX_MapVideoMemory (hDec->hImage[i]) != 0) {
935           _E ("Video Memory Mapping Failed\n");
936           return -1;
937         }
938       }
939
940       buf.index = i;
941
942       for (j = 0; j < (int32_t) pSeqIn->imgPlaneNum; j++) {
943         buf.m.planes[j].m.fd = hDec->hImage[i]->dmaFd[j];
944         buf.m.planes[j].length = hDec->hImage[i]->size[j];
945       }
946
947       if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
948         _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
949         return -1;
950       }
951     }
952
953     type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
954     if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
955       _E ("failed to ioctl: VIDIOC_STREAMON\n");
956       return -1;
957     }
958   }
959
960   return 0;
961 }
962
963 /*----------------------------------------------------------------------------*/
964 int32_t
965 NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
966     NX_V4L2DEC_OUT * pDecOut)
967 {
968   struct v4l2_buffer buf;
969   struct v4l2_plane planes[3];
970   int idx;
971   int32_t iStrmSize;
972   int32_t frameType;
973
974   if (NULL == hDec) {
975     _E ("Fail, Invalid Handle.\n");
976     return -1;
977   }
978
979   iStrmSize = GetFrameStream (hDec, pDecIn, &idx);
980
981   /* Queue Input Buffer */
982   memset (&buf, 0, sizeof (buf));
983   buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
984   buf.m.planes = planes;
985   buf.length = 1;
986   buf.memory = V4L2_MEMORY_DMABUF;
987   buf.index = idx;
988   buf.timestamp.tv_sec = pDecIn->timeStamp / 1000;
989   buf.timestamp.tv_usec = (pDecIn->timeStamp % 1000) * 1000;
990   buf.flags = pDecIn->eos ? 1 : 0;
991
992   /* buf.m.planes[0].m.userptr = (unsigned long)hStream->pBuffer; */
993   buf.m.planes[0].m.fd = hDec->hStream[idx]->dmaFd;
994   buf.m.planes[0].length = hDec->hStream[idx]->size;
995   buf.m.planes[0].bytesused = iStrmSize;
996   buf.m.planes[0].data_offset = 0;
997
998   if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
999     _E ("Fail, ioctl(): VIDIOC_QBUF.(Input)\n");
1000     return -1;
1001   }
1002
1003   if (iStrmSize > 0) {
1004     /* Dequeue Input ES Buffer -> Get Decoded Order Result */
1005     memset (&buf, 0, sizeof (buf));
1006     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1007     buf.m.planes = planes;
1008     buf.length = 1;
1009     buf.memory = V4L2_MEMORY_DMABUF;
1010
1011     if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1012       _E ("Fail, ioctl(): VIDIOC_DQBUF.(Input)\n");
1013       return -1;
1014     }
1015
1016     pDecOut->decIdx = buf.index;
1017     pDecOut->usedByte = buf.bytesused;
1018     pDecOut->outFrmReliable_0_100[DECODED_FRAME] = buf.reserved;
1019     pDecOut->timeStamp[DECODED_FRAME] =
1020         ((uint64_t) buf.timestamp.tv_sec) * 1000 + buf.timestamp.tv_usec / 1000;
1021     frameType = buf.flags;
1022
1023     if (frameType & V4L2_BUF_FLAG_KEYFRAME)
1024       pDecOut->picType[DECODED_FRAME] = PIC_TYPE_I;
1025     else if (frameType & V4L2_BUF_FLAG_PFRAME)
1026       pDecOut->picType[DECODED_FRAME] = PIC_TYPE_P;
1027     else if (frameType & V4L2_BUF_FLAG_BFRAME)
1028       pDecOut->picType[DECODED_FRAME] = PIC_TYPE_B;
1029     else
1030       pDecOut->picType[DECODED_FRAME] = PIC_TYPE_UNKNOWN;
1031
1032     if (buf.field == V4L2_FIELD_NONE)
1033       pDecOut->interlace[DECODED_FRAME] = NONE_FIELD;
1034     else if (buf.field == V4L2_FIELD_SEQ_TB)
1035       pDecOut->interlace[DECODED_FRAME] = TOP_FIELD_FIRST;
1036     else if (buf.field == V4L2_FIELD_SEQ_BT)
1037       pDecOut->interlace[DECODED_FRAME] = BOTTOM_FIELD_FIRST;
1038   } else if (pDecIn->strmSize > 0) {
1039     pDecOut->usedByte = pDecIn->strmSize;
1040   }
1041
1042   /* Dequeue Output YUV Buffer -> Get Display Order Result */
1043   memset (&buf, 0, sizeof (buf));
1044   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1045   buf.m.planes = planes;
1046   buf.length = hDec->planesNum;
1047   buf.memory = V4L2_MEMORY_DMABUF;
1048
1049   if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1050     _E ("Fail, ioctl(): VIDIOC_DQBUF(Output)\n");
1051     return -100;
1052   }
1053
1054   pDecOut->dispIdx = buf.index;
1055   // pDecOut->dispInfo = &hDec->dispInfo;         // TBD.
1056
1057   if (pDecOut->dispIdx >= 0) {
1058     pDecOut->hImg = *hDec->hImage[buf.index];
1059     pDecOut->timeStamp[DISPLAY_FRAME] =
1060         ((uint64_t) buf.timestamp.tv_sec) * 1000 + buf.timestamp.tv_usec / 1000;
1061     pDecOut->outFrmReliable_0_100[DISPLAY_FRAME] = buf.reserved;
1062     frameType = buf.flags;
1063
1064     if (frameType & V4L2_BUF_FLAG_KEYFRAME)
1065       pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_I;
1066     else if (frameType & V4L2_BUF_FLAG_PFRAME)
1067       pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_P;
1068     else if (frameType & V4L2_BUF_FLAG_BFRAME)
1069       pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_B;
1070     else
1071       pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_UNKNOWN;
1072
1073     if (buf.field == V4L2_FIELD_NONE)
1074       pDecOut->interlace[DISPLAY_FRAME] = NONE_FIELD;
1075     else if (buf.field == V4L2_FIELD_SEQ_TB)
1076       pDecOut->interlace[DISPLAY_FRAME] = TOP_FIELD_FIRST;
1077     else if (buf.field == V4L2_FIELD_SEQ_BT)
1078       pDecOut->interlace[DISPLAY_FRAME] = BOTTOM_FIELD_FIRST;
1079   }
1080
1081   hDec->frameCnt++;
1082
1083   if (pDecOut->dispIdx == -1)
1084     return -1;
1085
1086   return 0;
1087 }
1088
1089 /*----------------------------------------------------------------------------*/
1090 int32_t
1091 NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
1092     int32_t iFrameIdx)
1093 {
1094   struct v4l2_buffer buf;
1095   struct v4l2_plane planes[3];
1096   int32_t index = -1;
1097   int32_t i;
1098
1099   if (NULL == hDec) {
1100     _E ("Fail, Invalid Handle.\n");
1101     return -1;
1102   }
1103
1104   if (iFrameIdx >= 0) {
1105     index = iFrameIdx;
1106   } else {
1107     /* Search Buffer Index */
1108     if (hFrameBuf != NULL) {
1109       for (i = 0; i < hDec->numFrameBuffers; i++) {
1110         if (hFrameBuf == hDec->hImage[i]) {
1111           index = i;
1112           break;
1113         }
1114       }
1115     }
1116   }
1117
1118   if (index < 0) {
1119     _E ("Fail, Invalid FrameBuffer or FrameIndex.\n");
1120     return -1;
1121   }
1122
1123   memset (&buf, 0, sizeof (buf));
1124   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1125   buf.index = index;
1126   buf.m.planes = planes;
1127   buf.length = hDec->planesNum;
1128   buf.memory = V4L2_MEMORY_DMABUF;
1129
1130   for (i = 0; i < hDec->planesNum; i++) {
1131     buf.m.planes[i].m.fd = hDec->hImage[index]->dmaFd[i];
1132     buf.m.planes[i].length = hDec->hImage[index]->size[i];
1133   }
1134
1135   /* Queue Output Buffer */
1136   if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
1137     _E ("Fail, ioctl(): VIDIOC_QBUF.(Clear Display Index, index = %d)\n",
1138         index);
1139     return -1;
1140   }
1141
1142   return 0;
1143 }
1144
1145 /*----------------------------------------------------------------------------*/
1146 int32_t
1147 NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
1148 {
1149   enum v4l2_buf_type type;
1150
1151   if (NULL == hDec) {
1152     _E ("Fail, Invalid Handle.\n");
1153     return -1;
1154   }
1155
1156   type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1157   if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
1158     _E ("failed to ioctl: VIDIOC_STREAMOFF(Stream)\n");
1159     return -1;
1160   }
1161
1162   type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1163   if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
1164     _E ("failed to ioctl: VIDIOC_STREAMOFF(Image)\n");
1165     return -1;
1166   }
1167
1168   type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1169   if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
1170     _E ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
1171     return -1;
1172   }
1173
1174   type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1175   if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
1176     _E ("failed to ioctl: VIDIOC_STREAMON\n");
1177     return -1;
1178   }
1179
1180   {
1181     struct v4l2_plane planes[3];
1182     struct v4l2_buffer buf;
1183     int32_t i, j;
1184
1185     memset (&buf, 0, sizeof (buf));
1186     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1187     buf.m.planes = planes;
1188     buf.length = hDec->planesNum;
1189     buf.memory = V4L2_MEMORY_DMABUF;
1190
1191     for (i = 0; i < hDec->numFrameBuffers; i++) {
1192       buf.index = i;
1193
1194       for (j = 0; j < (int32_t) hDec->planesNum; j++) {
1195         buf.m.planes[j].m.fd = hDec->hImage[i]->dmaFd[j];
1196         buf.m.planes[j].length = hDec->hImage[i]->size[j];
1197       }
1198
1199       if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
1200         _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
1201         return -1;
1202       }
1203     }
1204   }
1205
1206   return 0;
1207 }
1208
1209 /* Optional Function */
1210 int32_t
1211 NX_DecGetFrameType (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
1212     uint32_t codecType, int32_t * piFrameType)
1213 {
1214   uint8_t *pbyStrm = pDecIn->strmBuf;
1215   uint32_t uPreFourByte = (uint32_t) - 1;
1216   int32_t iFrmType = PIC_TYPE_UNKNOWN;
1217
1218   if ((pbyStrm == NULL) || (piFrameType == NULL))
1219     return -1;
1220
1221   if (!codecType)
1222     codecType = hDec->codecType;
1223
1224   switch (codecType) {
1225     case V4L2_PIX_FMT_H264:
1226       do {
1227         if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1228           return -1;
1229
1230         uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1231
1232         if ((uPreFourByte == 0x00000001) || (uPreFourByte << 8 == 0x00000100)) {
1233           int32_t iNaluType = pbyStrm[0] & 0x1F;
1234
1235           /* Slice start code */
1236           if (iNaluType == 5) {
1237             iFrmType = PIC_TYPE_IDR;
1238             break;
1239           } else if (iNaluType == 1) {
1240             VLD_STREAM stStrm = { 8, pbyStrm, pDecIn->strmSize };
1241
1242             vld_get_uev (&stStrm);      /* First_mb_in_slice */
1243             iFrmType = vld_get_uev (&stStrm);   /* Slice type */
1244
1245             if (iFrmType == 0 || iFrmType == 5)
1246               iFrmType = PIC_TYPE_P;
1247             else if (iFrmType == 1 || iFrmType == 6)
1248               iFrmType = PIC_TYPE_B;
1249             else if (iFrmType == 2 || iFrmType == 7)
1250               iFrmType = PIC_TYPE_I;
1251             break;
1252           }
1253         }
1254       } while (1);
1255       break;
1256
1257     case V4L2_PIX_FMT_MPEG2:
1258       do {
1259         if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1260           return -1;
1261
1262         uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1263
1264         /* Picture start code */
1265         if (uPreFourByte == 0x00000100) {
1266           VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1267
1268           vld_flush_bits (&stStrm, 10); /* temporal_reference */
1269           iFrmType = vld_get_bits (&stStrm, 3); /* picture_coding_type */
1270
1271           if (iFrmType == 1)
1272             iFrmType = PIC_TYPE_I;
1273           else if (iFrmType == 2)
1274             iFrmType = PIC_TYPE_P;
1275           else if (iFrmType == 3)
1276             iFrmType = PIC_TYPE_B;
1277           break;
1278         }
1279       } while (1);
1280       break;
1281
1282     case V4L2_PIX_FMT_WVC1:
1283       if (hDec == NULL || hDec->seqDataSize == 0)
1284         return -1;
1285
1286       {
1287         VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1288
1289         if (hDec->iInterlace != NONE_FIELD) {
1290           /* FCM */
1291           if (vld_get_bits (&stStrm, 1) == 1)
1292             vld_flush_bits (&stStrm, 1);
1293         }
1294
1295         iFrmType = vld_get_bits (&stStrm, 1);
1296         if (iFrmType == 0) {
1297           iFrmType = PIC_TYPE_P;
1298         } else {
1299           iFrmType = vld_get_bits (&stStrm, 1);
1300           if (iFrmType == 0) {
1301             iFrmType = PIC_TYPE_B;
1302           } else {
1303             iFrmType = vld_get_bits (&stStrm, 1);
1304             if (iFrmType == 0) {
1305               iFrmType = PIC_TYPE_I;
1306             } else {
1307               iFrmType = vld_get_bits (&stStrm, 1);
1308               if (iFrmType == 0)
1309                 iFrmType = PIC_TYPE_VC1_BI;
1310               else
1311                 iFrmType = PIC_TYPE_SKIP;
1312             }
1313           }
1314         }
1315       }
1316       break;
1317
1318     case V4L2_PIX_FMT_WMV9:
1319       if (hDec == NULL || hDec->seqDataSize == 0)
1320         return -1;
1321
1322       {
1323         int32_t rangeRed;
1324         int32_t fInterPFlag;
1325         int32_t maxBframes;
1326         VLD_STREAM stStrm = { 24, hDec->pSeqData, hDec->seqDataSize };
1327
1328         /* Parse Sequece Header */
1329         rangeRed = vld_get_bits (&stStrm, 1);
1330         maxBframes = vld_get_bits (&stStrm, 3);
1331         vld_flush_bits (&stStrm, 2);
1332         fInterPFlag = vld_get_bits (&stStrm, 1);
1333
1334         /* Parse Frame Header */
1335         stStrm.dwUsedBits = 0;
1336         stStrm.pbyStart = pbyStrm;
1337         stStrm.dwPktSize = pDecIn->strmSize;
1338
1339         if (fInterPFlag == 1)
1340           vld_flush_bits (&stStrm, 1);  /* INTERPFRM */
1341
1342         vld_flush_bits (&stStrm, 2);    /* FRMCNT */
1343
1344         if (rangeRed == 1)
1345           vld_flush_bits (&stStrm, 1);  /* RANGEREDFRM */
1346
1347         iFrmType = vld_get_bits (&stStrm, 1);
1348         if (maxBframes > 0) {
1349           if (iFrmType == 1) {
1350             iFrmType = PIC_TYPE_P;
1351           } else {
1352             iFrmType = vld_get_bits (&stStrm, 1);
1353             if (iFrmType == 1)
1354               iFrmType = PIC_TYPE_I;
1355             else if (iFrmType == 0)
1356               iFrmType = PIC_TYPE_B;    /* or BI */
1357           }
1358         } else {
1359           if (iFrmType == 0)
1360             iFrmType = PIC_TYPE_I;
1361           else if (iFrmType == 1)
1362             iFrmType = PIC_TYPE_P;
1363         }
1364
1365       }
1366       break;
1367
1368     default:
1369       return -1;
1370   }
1371
1372   *piFrameType = iFrmType;
1373
1374   return 0;
1375 }