2 * Copyright (C) 2016 Nexell Co. All Rights Reserved
3 * Nexell Co. Proprietary & Confidential
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.
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
24 #include <sys/ioctl.h>
26 #include <linux/videodev2.h>
27 #include <linux/videodev2_nxp_media.h>
29 #include <nx_video_alloc.h>
30 #include <nx_video_api.h>
31 #include "nx_video_log.h"
34 /*----------------------------------------------------------------------------*/
35 #define NX_V4L2_DEC_NAME "nx-vpu-dec"
36 #define VIDEODEV_MINOR_MAX 63
37 #define STREAM_BUFFER_NUM 1
40 struct NX_V4L2DEC_INFO
47 int32_t useExternalFrameBuffer;
48 int32_t numFrameBuffers;
49 NX_VID_MEMORY_HANDLE hImage[MAX_FRAME_BUFFER_NUM];
51 NX_MEMORY_HANDLE hStream[STREAM_BUFFER_NUM];
53 /* Initialize Output Information */
54 uint8_t pSeqData[1024]; /* SPS PPS (H.264) or Decoder Specific Information(for MPEG4) */
57 IMG_DISP_INFO dispInfo;
69 #ifdef TIZEN_FEATURE_ARTIK530
80 /*----------------------------------------------------------------------------*/
89 char filename[64], name[64];
92 while (!found && (i <= VIDEODEV_MINOR_MAX)) {
93 /* video device node */
94 snprintf (filename, 64, "/dev/video%d", i);
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");
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");
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,
126 snprintf (filename, 64, "/dev/video%d", i - 1);
127 fd = open (filename, O_RDWR);
135 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
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);
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);
155 #define PUT_LE16(_p, _var) \
156 *_p++ = (uint8_t)((_var) >> 0); \
157 *_p++ = (uint8_t)((_var) >> 8);
161 #define PUT_BE16(_p, _var) \
162 *_p++ = (uint8_t)((_var) >> 8); \
163 *_p++ = (uint8_t)((_var) >> 0);
175 vld_count_leading_zero (uint32_t dwWord)
179 if ((dwWord >> (32 - 16)) == 0)
181 if ((dwWord >> (32 - 8 - iLZ)) == 0)
183 if ((dwWord >> (32 - 4 - iLZ)) == 0)
185 if ((dwWord >> (32 - 2 - iLZ)) == 0)
187 if ((dwWord >> (32 - 1 - iLZ)) == 0)
194 vld_show_bits (VLD_STREAM * pstVldStm, int32_t iBits)
196 uint32_t dwUsedBits = pstVldStm->dwUsedBits;
197 int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
198 uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
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++;
211 return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
215 vld_get_bits (VLD_STREAM * pstVldStm, int32_t iBits)
217 uint32_t dwUsedBits = pstVldStm->dwUsedBits;
218 int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
219 uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
222 pstVldStm->dwUsedBits += iBits;
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++;
234 return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
238 vld_flush_bits (VLD_STREAM * pstVldStm, int iBits)
240 pstVldStm->dwUsedBits += iBits;
244 vld_get_uev (VLD_STREAM * pstVldStm)
246 int32_t iLZ = vld_count_leading_zero (vld_show_bits (pstVldStm, 32));
248 vld_flush_bits (pstVldStm, iLZ);
249 return (vld_get_bits (pstVldStm, iLZ + 1) - 1);
253 Mp4DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
256 uint8_t *pbyStrm = pbyStream;
257 uint32_t uPreFourByte = (uint32_t) - 1;
259 hDec->vopTimeBits = 0;
262 if (pbyStrm >= (pbyStream + iStreamSize))
265 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
267 if (uPreFourByte >= 0x00000120 && uPreFourByte <= 0x0000012F) {
268 VLD_STREAM stStrm = { 0, pbyStrm, iStreamSize };
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 */
275 if (vld_get_bits (&stStrm, 4) == 0xF) /* aspect_ratio_info */
276 vld_flush_bits (&stStrm, 8 + 8); /* par_width, par_height */
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 */
288 vld_flush_bits (&stStrm, 2 + 1); /* video_object_layer_shape, marker_bit */
290 for (i = 0; i < 16; i++) /* vop_time_increment_resolution */
291 if (vld_get_bits (&stStrm, 1))
293 hDec->vopTimeBits = 16 - i;
300 Mp4DecParseFrameHeader (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
303 VLD_STREAM stStrm = { 0, pbyStream, iStreamSize };
304 int32_t iSize = iStreamSize;
306 if (vld_get_bits (&stStrm, 32) == 0x000001B6) {
307 vld_flush_bits (&stStrm, 2); /* vop_coding_type */
310 if (vld_get_bits (&stStrm, 1) == 0)
312 } while (stStrm.dwUsedBits < ((uint32_t) iStreamSize << 3));
314 vld_flush_bits (&stStrm, 1 + hDec->vopTimeBits + 1); /* marker_bits, vop_time_increment, marker_bits */
316 if (vld_get_bits (&stStrm, 1) == 0) /* vop_coded */
324 GetSequenceHeader (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
326 uint8_t *pbySrc = pSeqIn->seqBuf;
327 uint8_t *pbyDst = (uint8_t *) hDec->hStream[0]->pBuffer;
328 int32_t iSize = pSeqIn->seqSize;
330 switch (hDec->codecType) {
331 case V4L2_PIX_FMT_H264:
332 if (pSeqIn->seqSize > 0) {
333 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
335 if ((pbySrc[2] == 0) && (pbySrc[7] > 51))
337 else if ((pbySrc[2] == 1) && (pbySrc[6] > 51))
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 */
360 PUT_BE32 (pbyDst, pSeqIn->seqSize);
362 memcpy (pbyDst, pbyDst, pSeqIn->seqSize);
366 case V4L2_PIX_FMT_WMV9:
367 if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
369 PUT_LE32 (pbyDst, (0xC5 << 24) | 0x00); /* version */
372 PUT_LE32 (pbyDst, (0x85 << 24) | 0x00);
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);
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 */
393 case V4L2_PIX_FMT_RV8:
394 case V4L2_PIX_FMT_RV9:
395 if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
398 PUT_BE32 (pbyDst, iSize); /* Length */
399 PUT_LE32 (pbyDst, MKTAG ('V', 'I', 'D', 'O')); /* MOFTag */
401 if (hDec->codecType == V4L2_PIX_FMT_RV8) {
402 PUT_LE32 (pbyDst, MKTAG ('R', 'V', '3', '0'));
404 PUT_LE32 (pbyDst, MKTAG ('R', 'V', '4', '0'));
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);
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 */
432 PUT_LE32 (pbyDst, pSeqIn->seqSize);
433 PUT_LE32 (pbyDst, 0);
434 PUT_LE32 (pbyDst, 0);
435 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
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);
450 if (pSeqIn->seqSize > 0)
451 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
460 GetFrameStream (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn, int32_t * idx)
462 int32_t iSize = pDecIn->strmSize;
463 uint8_t *pbySrc = pDecIn->strmBuf;
469 *idx = hDec->frameCnt % STREAM_BUFFER_NUM;
470 pbyDst = (uint8_t *) hDec->hStream[*idx]->pBuffer;
472 switch (hDec->codecType) {
473 case V4L2_PIX_FMT_H264:
474 memcpy (pbyDst, pbySrc, iSize);
476 if ((pbySrc[2] == 0) && ((pbySrc[4] & 0x1F) == 7) && (pbySrc[7] > 51))
478 else if ((pbySrc[2] == 1) && ((pbySrc[3] & 0x1F) == 7)
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) {
491 memcpy (pbyDst, pbySrc, iSize);
494 /* no extra header size, there is start code in input stream */
495 memcpy (pbyDst, pbySrc, iSize);
499 case V4L2_PIX_FMT_WMV9:
500 PUT_LE32 (pbyDst, iSize | 0); /* Key Frame = 0x80000000 */
504 PUT_LE32 (pbyDst, 0);
508 memcpy (pbyDst, pbySrc, pDecIn->strmSize);
511 case V4L2_PIX_FMT_RV8:
512 case V4L2_PIX_FMT_RV9:
514 int32_t cSlice, nSlice;
515 int32_t i, val, offset;
517 cSlice = pbySrc[0] + 1;
518 nSlice = iSize - 1 - (cSlice * 8);
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 */
528 for (i = 0; i < cSlice; i++) {
530 (pbySrc[offset + 3] << 24) | (pbySrc[offset +
531 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
532 PUT_BE32 (pbyDst, val); /* isValid */
535 (pbySrc[offset + 3] << 24) | (pbySrc[offset +
536 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
537 PUT_BE32 (pbyDst, val); /* Offset */
541 memcpy (pbyDst, pbySrc + (1 + (cSlice * 8)), nSlice);
542 iSize = 20 + (cSlice * 8) + nSlice;
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);
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:
562 if (hDec->vopTimeBits > 0) {
563 iSize = Mp4DecParseFrameHeader (hDec, pbySrc, iSize);
567 memcpy ((void *) pbyDst, (void *) pbySrc, iSize);
578 /*----------------------------------------------------------------------------*/
580 NX_V4l2DecOpen (uint32_t codecType)
582 NX_V4L2DEC_HANDLE hDec =
583 (NX_V4L2DEC_HANDLE) malloc (sizeof (struct NX_V4L2DEC_INFO));
585 memset (hDec, 0, sizeof (struct NX_V4L2DEC_INFO));
587 hDec->fd = V4l2DecOpen ();
589 _E ("Failed to open video decoder device\n");
593 /* Query capabilities of Device */
595 struct v4l2_capability cap;
597 memset (&cap, 0, sizeof (cap));
599 if (ioctl (hDec->fd, VIDIOC_QUERYCAP, &cap) != 0) {
600 _E ("failed to ioctl: VIDIOC_QUERYCAP\n");
605 hDec->codecType = codecType;
615 /*----------------------------------------------------------------------------*/
617 NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec)
622 _E ("Fail, Invalid Handle.\n");
627 enum v4l2_buf_type type;
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");
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");
641 for (i = 0; i < STREAM_BUFFER_NUM; i++)
642 NX_FreeMemory (hDec->hStream[i]);
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;
655 #ifdef TIZEN_FEATURE_ARTIK530
657 tbm_bufmgr_deinit (hDec->bufmgr);
665 /*----------------------------------------------------------------------------*/
667 NX_V4l2DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn,
668 NX_V4L2DEC_SEQ_OUT * pSeqOut)
670 int32_t imgWidth = pSeqIn->width;
671 int32_t imgHeight = pSeqIn->height;
673 memset (pSeqOut, 0, sizeof (NX_V4L2DEC_SEQ_OUT));
676 _E ("Fail, Invalid Handle.\n");
680 hDec->seqDataSize = (pSeqIn->seqSize < 1024) ? (pSeqIn->seqSize) : (1024);
681 memcpy (hDec->pSeqData, pSeqIn->seqBuf, hDec->seqDataSize);
683 /* Set Stream Formet */
685 struct v4l2_format fmt;
687 memset (&fmt, 0, sizeof (fmt));
689 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
690 fmt.fmt.pix_mp.pixelformat = hDec->codecType;
692 if ((imgWidth == 0) || (imgHeight == 0))
693 fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
694 MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4;
696 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = imgWidth * imgHeight * 3 / 4;
698 fmt.fmt.pix_mp.width = imgWidth;
699 fmt.fmt.pix_mp.height = imgHeight;
700 fmt.fmt.pix_mp.num_planes = 1;
702 if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
703 _E ("Failed to ioctx : VIDIOC_S_FMT(Input Stream)\n");
708 /* Malloc Stream Buffer */
710 struct v4l2_requestbuffers req;
711 int32_t i, buffCnt = STREAM_BUFFER_NUM;
713 /* IOCTL : VIDIOC_REQBUFS For Input Stream */
714 memset (&req, 0, sizeof (req));
715 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
717 req.memory = V4L2_MEMORY_DMABUF;
719 if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
720 _E ("failed to ioctl: VIDIOC_REQBUFS(Input Stream)\n");
724 for (i = 0; i < buffCnt; 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);
733 if (NX_MapMemory (hDec->hStream[i]) != 0) {
734 _E ("Stream memory Mapping Failed\n");
742 if (hDec->codecType == V4L2_PIX_FMT_MJPEG) {
743 struct v4l2_control ctrl;
745 ctrl.id = V4L2_CID_MPEG_VIDEO_THUMBNAIL_MODE;
746 ctrl.value = pSeqIn->thumbnailMode;
748 if (ioctl (hDec->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
749 _E ("failed to ioctl: Set Thumbnail Mode\n");
755 /* Parser Sequence Header */
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);
763 _E ("Fail, input data has error!!");
767 memset (&buf, 0, sizeof (buf));
768 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
769 buf.m.planes = planes;
771 buf.memory = V4L2_MEMORY_DMABUF;
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;
780 buf.timestamp.tv_sec = pSeqIn->timeStamp / 1000;
781 buf.timestamp.tv_usec = (pSeqIn->timeStamp % 1000) * 1000;
783 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
784 _E ("failed to ioctl: VIDIOC_QBUF(Header Stream)\n");
788 if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
789 _E ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
793 memset (&buf, 0, sizeof (buf));
794 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
795 buf.m.planes = planes;
797 buf.memory = V4L2_MEMORY_DMABUF;
799 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
800 _E ("failed to ioctl: VIDIOC_DQBUF(Header Stream)\n");
804 pSeqOut->usedByte = buf.bytesused;
806 if (buf.field == V4L2_FIELD_NONE)
807 pSeqOut->interlace = NONE_FIELD;
808 else if (V4L2_FIELD_INTERLACED)
809 pSeqOut->interlace = FIELD_INTERLACED;
811 hDec->iInterlace = pSeqOut->interlace;
814 /* Get Image Information */
816 struct v4l2_format fmt;
817 struct v4l2_crop crop;
819 memset (&fmt, 0, sizeof (fmt));
820 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
822 if (ioctl (hDec->fd, VIDIOC_G_FMT, &fmt) != 0) {
823 _E ("Fail, ioctl(): VIDIOC_G_FMT.\n");
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;
833 memset (&crop, 0, sizeof (crop));
834 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
836 if (ioctl (hDec->fd, VIDIOC_G_CROP, &crop) != 0) {
837 _E ("Fail, ioctl(): VIDIOC_G_CROP\n");
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;
850 /*----------------------------------------------------------------------------*/
852 NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
854 /* Set Output Image */
856 struct v4l2_format fmt;
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;
865 if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
866 _E ("failed to ioctl: VIDIOC_S_FMT(Output Yuv)\n");
870 hDec->planesNum = pSeqIn->imgPlaneNum;
873 /* Malloc Output Image */
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;
881 /* Calculate Buffer Number */
882 if (pSeqIn->pMemHandle == NULL) {
883 hDec->useExternalFrameBuffer = false;
884 imgBuffCnt = hDec->numFrameBuffers + pSeqIn->numBuffers;
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);
891 imgBuffCnt = pSeqIn->numBuffers;
893 hDec->numFrameBuffers = imgBuffCnt;
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;
901 if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
902 _E ("failed to ioctl: VIDIOC_REQBUFS(Output YUV)\n");
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;
912 #ifdef TIZEN_FEATURE_ARTIK530
913 hDec->bufmgr = tbm_bufmgr_init (-1);
914 _D ("bufmgr = %p", hDec->bufmgr);
916 _E ("failed to initialize tbm_init");
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];
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);
934 if (NX_MapVideoMemory (hDec->hImage[i]) != 0) {
935 _E ("Video Memory Mapping Failed\n");
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];
947 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
948 _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
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");
963 /*----------------------------------------------------------------------------*/
965 NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
966 NX_V4L2DEC_OUT * pDecOut)
968 struct v4l2_buffer buf;
969 struct v4l2_plane planes[3];
975 _E ("Fail, Invalid Handle.\n");
979 iStrmSize = GetFrameStream (hDec, pDecIn, &idx);
981 /* Queue Input Buffer */
982 memset (&buf, 0, sizeof (buf));
983 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
984 buf.m.planes = planes;
986 buf.memory = V4L2_MEMORY_DMABUF;
988 buf.timestamp.tv_sec = pDecIn->timeStamp / 1000;
989 buf.timestamp.tv_usec = (pDecIn->timeStamp % 1000) * 1000;
990 buf.flags = pDecIn->eos ? 1 : 0;
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;
998 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
999 _E ("Fail, ioctl(): VIDIOC_QBUF.(Input)\n");
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;
1009 buf.memory = V4L2_MEMORY_DMABUF;
1011 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1012 _E ("Fail, ioctl(): VIDIOC_DQBUF.(Input)\n");
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;
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;
1030 pDecOut->picType[DECODED_FRAME] = PIC_TYPE_UNKNOWN;
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;
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;
1049 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1050 _E ("Fail, ioctl(): VIDIOC_DQBUF(Output)\n");
1054 pDecOut->dispIdx = buf.index;
1055 // pDecOut->dispInfo = &hDec->dispInfo; // TBD.
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;
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;
1071 pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_UNKNOWN;
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;
1083 if (pDecOut->dispIdx == -1)
1089 /*----------------------------------------------------------------------------*/
1091 NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
1094 struct v4l2_buffer buf;
1095 struct v4l2_plane planes[3];
1100 _E ("Fail, Invalid Handle.\n");
1104 if (iFrameIdx >= 0) {
1107 /* Search Buffer Index */
1108 if (hFrameBuf != NULL) {
1109 for (i = 0; i < hDec->numFrameBuffers; i++) {
1110 if (hFrameBuf == hDec->hImage[i]) {
1119 _E ("Fail, Invalid FrameBuffer or FrameIndex.\n");
1123 memset (&buf, 0, sizeof (buf));
1124 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1126 buf.m.planes = planes;
1127 buf.length = hDec->planesNum;
1128 buf.memory = V4L2_MEMORY_DMABUF;
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];
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",
1145 /*----------------------------------------------------------------------------*/
1147 NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
1149 enum v4l2_buf_type type;
1152 _E ("Fail, Invalid Handle.\n");
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");
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");
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");
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");
1181 struct v4l2_plane planes[3];
1182 struct v4l2_buffer buf;
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;
1191 for (i = 0; i < hDec->numFrameBuffers; i++) {
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];
1199 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
1200 _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
1209 /* Optional Function */
1211 NX_DecGetFrameType (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
1212 uint32_t codecType, int32_t * piFrameType)
1214 uint8_t *pbyStrm = pDecIn->strmBuf;
1215 uint32_t uPreFourByte = (uint32_t) - 1;
1216 int32_t iFrmType = PIC_TYPE_UNKNOWN;
1218 if ((pbyStrm == NULL) || (piFrameType == NULL))
1222 codecType = hDec->codecType;
1224 switch (codecType) {
1225 case V4L2_PIX_FMT_H264:
1227 if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1230 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1232 if ((uPreFourByte == 0x00000001) || (uPreFourByte << 8 == 0x00000100)) {
1233 int32_t iNaluType = pbyStrm[0] & 0x1F;
1235 /* Slice start code */
1236 if (iNaluType == 5) {
1237 iFrmType = PIC_TYPE_IDR;
1239 } else if (iNaluType == 1) {
1240 VLD_STREAM stStrm = { 8, pbyStrm, pDecIn->strmSize };
1242 vld_get_uev (&stStrm); /* First_mb_in_slice */
1243 iFrmType = vld_get_uev (&stStrm); /* Slice type */
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;
1257 case V4L2_PIX_FMT_MPEG2:
1259 if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1262 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1264 /* Picture start code */
1265 if (uPreFourByte == 0x00000100) {
1266 VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1268 vld_flush_bits (&stStrm, 10); /* temporal_reference */
1269 iFrmType = vld_get_bits (&stStrm, 3); /* picture_coding_type */
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;
1282 case V4L2_PIX_FMT_WVC1:
1283 if (hDec == NULL || hDec->seqDataSize == 0)
1287 VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1289 if (hDec->iInterlace != NONE_FIELD) {
1291 if (vld_get_bits (&stStrm, 1) == 1)
1292 vld_flush_bits (&stStrm, 1);
1295 iFrmType = vld_get_bits (&stStrm, 1);
1296 if (iFrmType == 0) {
1297 iFrmType = PIC_TYPE_P;
1299 iFrmType = vld_get_bits (&stStrm, 1);
1300 if (iFrmType == 0) {
1301 iFrmType = PIC_TYPE_B;
1303 iFrmType = vld_get_bits (&stStrm, 1);
1304 if (iFrmType == 0) {
1305 iFrmType = PIC_TYPE_I;
1307 iFrmType = vld_get_bits (&stStrm, 1);
1309 iFrmType = PIC_TYPE_VC1_BI;
1311 iFrmType = PIC_TYPE_SKIP;
1318 case V4L2_PIX_FMT_WMV9:
1319 if (hDec == NULL || hDec->seqDataSize == 0)
1324 int32_t fInterPFlag;
1326 VLD_STREAM stStrm = { 24, hDec->pSeqData, hDec->seqDataSize };
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);
1334 /* Parse Frame Header */
1335 stStrm.dwUsedBits = 0;
1336 stStrm.pbyStart = pbyStrm;
1337 stStrm.dwPktSize = pDecIn->strmSize;
1339 if (fInterPFlag == 1)
1340 vld_flush_bits (&stStrm, 1); /* INTERPFRM */
1342 vld_flush_bits (&stStrm, 2); /* FRMCNT */
1345 vld_flush_bits (&stStrm, 1); /* RANGEREDFRM */
1347 iFrmType = vld_get_bits (&stStrm, 1);
1348 if (maxBframes > 0) {
1349 if (iFrmType == 1) {
1350 iFrmType = PIC_TYPE_P;
1352 iFrmType = vld_get_bits (&stStrm, 1);
1354 iFrmType = PIC_TYPE_I;
1355 else if (iFrmType == 0)
1356 iFrmType = PIC_TYPE_B; /* or BI */
1360 iFrmType = PIC_TYPE_I;
1361 else if (iFrmType == 1)
1362 iFrmType = PIC_TYPE_P;
1372 *piFrameType = iFrmType;