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