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