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"
32 #ifdef TIZEN_FEATURE_ARTIK530
37 /*----------------------------------------------------------------------------*/
38 #define NX_V4L2_DEC_NAME "nx-vpu-dec"
39 #define VIDEODEV_MINOR_MAX 63
40 #define STREAM_BUFFER_NUM 1
43 struct NX_V4L2DEC_INFO
50 int32_t useExternalFrameBuffer;
51 int32_t numFrameBuffers;
52 NX_VID_MEMORY_HANDLE hImage[MAX_FRAME_BUFFER_NUM];
54 NX_MEMORY_HANDLE hStream[STREAM_BUFFER_NUM];
56 /* Initialize Output Information */
57 uint8_t pSeqData[1024]; /* SPS PPS (H.264) or Decoder Specific Information(for MPEG4) */
60 IMG_DISP_INFO dispInfo;
72 #ifdef TIZEN_FEATURE_ARTIK530
76 pthread_mutex_t bufferLock;
85 /*----------------------------------------------------------------------------*/
94 char filename[64], name[64];
97 while (!found && (i <= VIDEODEV_MINOR_MAX)) {
98 /* video device node */
99 snprintf (filename, 64, "/dev/video%d", i);
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");
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");
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,
131 snprintf (filename, 64, "/dev/video%d", i - 1);
132 fd = open (filename, O_RDWR);
140 #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
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);
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);
160 #define PUT_LE16(_p, _var) \
161 *_p++ = (uint8_t)((_var) >> 0); \
162 *_p++ = (uint8_t)((_var) >> 8);
166 #define PUT_BE16(_p, _var) \
167 *_p++ = (uint8_t)((_var) >> 8); \
168 *_p++ = (uint8_t)((_var) >> 0);
180 vld_count_leading_zero (uint32_t dwWord)
184 if ((dwWord >> (32 - 16)) == 0)
186 if ((dwWord >> (32 - 8 - iLZ)) == 0)
188 if ((dwWord >> (32 - 4 - iLZ)) == 0)
190 if ((dwWord >> (32 - 2 - iLZ)) == 0)
192 if ((dwWord >> (32 - 1 - iLZ)) == 0)
199 vld_show_bits (VLD_STREAM * pstVldStm, int32_t iBits)
201 uint32_t dwUsedBits = pstVldStm->dwUsedBits;
202 int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
203 uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
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++;
216 return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
220 vld_get_bits (VLD_STREAM * pstVldStm, int32_t iBits)
222 uint32_t dwUsedBits = pstVldStm->dwUsedBits;
223 int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
224 uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
227 pstVldStm->dwUsedBits += iBits;
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++;
239 return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
243 vld_flush_bits (VLD_STREAM * pstVldStm, int iBits)
245 pstVldStm->dwUsedBits += iBits;
249 vld_get_uev (VLD_STREAM * pstVldStm)
251 int32_t iLZ = vld_count_leading_zero (vld_show_bits (pstVldStm, 32));
253 vld_flush_bits (pstVldStm, iLZ);
254 return (vld_get_bits (pstVldStm, iLZ + 1) - 1);
258 Mp4DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
261 uint8_t *pbyStrm = pbyStream;
262 uint32_t uPreFourByte = (uint32_t) - 1;
264 hDec->vopTimeBits = 0;
267 if (pbyStrm >= (pbyStream + iStreamSize))
270 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
272 if (uPreFourByte >= 0x00000120 && uPreFourByte <= 0x0000012F) {
273 VLD_STREAM stStrm = { 0, pbyStrm, iStreamSize };
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 */
280 if (vld_get_bits (&stStrm, 4) == 0xF) /* aspect_ratio_info */
281 vld_flush_bits (&stStrm, 8 + 8); /* par_width, par_height */
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 */
293 vld_flush_bits (&stStrm, 2 + 1); /* video_object_layer_shape, marker_bit */
295 for (i = 0; i < 16; i++) /* vop_time_increment_resolution */
296 if (vld_get_bits (&stStrm, 1))
298 hDec->vopTimeBits = 16 - i;
305 Mp4DecParseFrameHeader (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
308 VLD_STREAM stStrm = { 0, pbyStream, iStreamSize };
309 int32_t iSize = iStreamSize;
311 if (vld_get_bits (&stStrm, 32) == 0x000001B6) {
312 vld_flush_bits (&stStrm, 2); /* vop_coding_type */
315 if (vld_get_bits (&stStrm, 1) == 0)
317 } while (stStrm.dwUsedBits < ((uint32_t) iStreamSize << 3));
319 vld_flush_bits (&stStrm, 1 + hDec->vopTimeBits + 1); /* marker_bits, vop_time_increment, marker_bits */
321 if (vld_get_bits (&stStrm, 1) == 0) /* vop_coded */
329 GetSequenceHeader (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
331 uint8_t *pbySrc = pSeqIn->seqBuf;
332 uint8_t *pbyDst = (uint8_t *) hDec->hStream[0]->pBuffer;
333 int32_t iSize = pSeqIn->seqSize;
335 switch (hDec->codecType) {
336 case V4L2_PIX_FMT_H264:
337 if (pSeqIn->seqSize > 0) {
338 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
340 if ((pbySrc[2] == 0) && (pbySrc[7] > 51))
342 else if ((pbySrc[2] == 1) && (pbySrc[6] > 51))
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 */
365 PUT_BE32 (pbyDst, pSeqIn->seqSize);
367 memcpy (pbyDst, pbyDst, pSeqIn->seqSize);
371 case V4L2_PIX_FMT_WMV9:
372 if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
374 PUT_LE32 (pbyDst, (0xC5 << 24) | 0x00); /* version */
377 PUT_LE32 (pbyDst, (0x85 << 24) | 0x00);
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);
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 */
398 case V4L2_PIX_FMT_RV8:
399 case V4L2_PIX_FMT_RV9:
400 if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
403 PUT_BE32 (pbyDst, iSize); /* Length */
404 PUT_LE32 (pbyDst, MKTAG ('V', 'I', 'D', 'O')); /* MOFTag */
406 if (hDec->codecType == V4L2_PIX_FMT_RV8) {
407 PUT_LE32 (pbyDst, MKTAG ('R', 'V', '3', '0'));
409 PUT_LE32 (pbyDst, MKTAG ('R', 'V', '4', '0'));
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);
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 */
437 PUT_LE32 (pbyDst, pSeqIn->seqSize);
438 PUT_LE32 (pbyDst, 0);
439 PUT_LE32 (pbyDst, 0);
440 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
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);
455 if (pSeqIn->seqSize > 0)
456 memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
465 GetFrameStream (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn, int32_t * idx)
467 int32_t iSize = pDecIn->strmSize;
468 uint8_t *pbySrc = pDecIn->strmBuf;
474 *idx = hDec->frameCnt % STREAM_BUFFER_NUM;
475 pbyDst = (uint8_t *) hDec->hStream[*idx]->pBuffer;
477 switch (hDec->codecType) {
478 case V4L2_PIX_FMT_H264:
479 memcpy (pbyDst, pbySrc, iSize);
481 if ((pbySrc[2] == 0) && ((pbySrc[4] & 0x1F) == 7) && (pbySrc[7] > 51))
483 else if ((pbySrc[2] == 1) && ((pbySrc[3] & 0x1F) == 7)
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) {
496 memcpy (pbyDst, pbySrc, iSize);
499 /* no extra header size, there is start code in input stream */
500 memcpy (pbyDst, pbySrc, iSize);
504 case V4L2_PIX_FMT_WMV9:
505 PUT_LE32 (pbyDst, iSize | 0); /* Key Frame = 0x80000000 */
509 PUT_LE32 (pbyDst, 0);
513 memcpy (pbyDst, pbySrc, pDecIn->strmSize);
516 case V4L2_PIX_FMT_RV8:
517 case V4L2_PIX_FMT_RV9:
519 int32_t cSlice, nSlice;
520 int32_t i, val, offset;
522 cSlice = pbySrc[0] + 1;
523 nSlice = iSize - 1 - (cSlice * 8);
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 */
533 for (i = 0; i < cSlice; i++) {
535 (pbySrc[offset + 3] << 24) | (pbySrc[offset +
536 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
537 PUT_BE32 (pbyDst, val); /* isValid */
540 (pbySrc[offset + 3] << 24) | (pbySrc[offset +
541 2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
542 PUT_BE32 (pbyDst, val); /* Offset */
546 memcpy (pbyDst, pbySrc + (1 + (cSlice * 8)), nSlice);
547 iSize = 20 + (cSlice * 8) + nSlice;
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);
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:
567 if (hDec->vopTimeBits > 0) {
568 iSize = Mp4DecParseFrameHeader (hDec, pbySrc, iSize);
572 memcpy ((void *) pbyDst, (void *) pbySrc, iSize);
583 /*----------------------------------------------------------------------------*/
585 NX_V4l2DecOpen (uint32_t codecType)
587 NX_V4L2DEC_HANDLE hDec =
588 (NX_V4L2DEC_HANDLE) malloc (sizeof (struct NX_V4L2DEC_INFO));
590 memset (hDec, 0, sizeof (struct NX_V4L2DEC_INFO));
592 hDec->fd = V4l2DecOpen ();
594 _E ("Failed to open video decoder device\n");
598 /* Query capabilities of Device */
600 struct v4l2_capability cap;
602 memset (&cap, 0, sizeof (cap));
604 if (ioctl (hDec->fd, VIDIOC_QUERYCAP, &cap) != 0) {
605 _E ("failed to ioctl: VIDIOC_QUERYCAP\n");
610 hDec->codecType = codecType;
611 #ifdef TIZEN_FEATURE_ARTIK530
612 pthread_mutex_init(&hDec->bufferLock, NULL);
623 /*----------------------------------------------------------------------------*/
625 NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec)
630 _E ("Fail, Invalid Handle.\n");
635 enum v4l2_buf_type type;
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");
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");
649 for (i = 0; i < STREAM_BUFFER_NUM; i++)
650 NX_FreeMemory (hDec->hStream[i]);
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;
663 #ifdef TIZEN_FEATURE_ARTIK530
664 pthread_mutex_destroy(&hDec->bufferLock);
666 tbm_bufmgr_deinit (hDec->bufmgr);
674 /*----------------------------------------------------------------------------*/
676 NX_V4l2DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn,
677 NX_V4L2DEC_SEQ_OUT * pSeqOut)
679 int32_t imgWidth = pSeqIn->width;
680 int32_t imgHeight = pSeqIn->height;
682 memset (pSeqOut, 0, sizeof (NX_V4L2DEC_SEQ_OUT));
685 _E ("Fail, Invalid Handle.\n");
689 hDec->seqDataSize = (pSeqIn->seqSize < 1024) ? (pSeqIn->seqSize) : (1024);
690 memcpy (hDec->pSeqData, pSeqIn->seqBuf, hDec->seqDataSize);
692 /* Set Stream Formet */
694 struct v4l2_format fmt;
696 memset (&fmt, 0, sizeof (fmt));
698 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
699 fmt.fmt.pix_mp.pixelformat = hDec->codecType;
701 if ((imgWidth == 0) || (imgHeight == 0))
702 fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
703 MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4;
705 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = imgWidth * imgHeight * 3 / 4;
707 fmt.fmt.pix_mp.width = imgWidth;
708 fmt.fmt.pix_mp.height = imgHeight;
709 fmt.fmt.pix_mp.num_planes = 1;
711 if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
712 _E ("Failed to ioctx : VIDIOC_S_FMT(Input Stream)\n");
717 /* Malloc Stream Buffer */
719 struct v4l2_requestbuffers req;
720 int32_t i, buffCnt = STREAM_BUFFER_NUM;
722 /* IOCTL : VIDIOC_REQBUFS For Input Stream */
723 memset (&req, 0, sizeof (req));
724 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
726 req.memory = V4L2_MEMORY_DMABUF;
728 if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
729 _E ("failed to ioctl: VIDIOC_REQBUFS(Input Stream)\n");
733 for (i = 0; i < buffCnt; 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);
742 if (NX_MapMemory (hDec->hStream[i]) != 0) {
743 _E ("Stream memory Mapping Failed\n");
751 if (hDec->codecType == V4L2_PIX_FMT_MJPEG) {
752 struct v4l2_control ctrl;
754 ctrl.id = V4L2_CID_MPEG_VIDEO_THUMBNAIL_MODE;
755 ctrl.value = pSeqIn->thumbnailMode;
757 if (ioctl (hDec->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
758 _E ("failed to ioctl: Set Thumbnail Mode\n");
764 /* Parser Sequence Header */
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);
772 _E ("Fail, input data has error!!");
776 memset (&buf, 0, sizeof (buf));
777 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
778 buf.m.planes = planes;
780 buf.memory = V4L2_MEMORY_DMABUF;
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;
789 buf.timestamp.tv_sec = pSeqIn->timeStamp / 1000;
790 buf.timestamp.tv_usec = (pSeqIn->timeStamp % 1000) * 1000;
792 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
793 _E ("failed to ioctl: VIDIOC_QBUF(Header Stream)\n");
797 if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
798 _E ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
802 memset (&buf, 0, sizeof (buf));
803 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
804 buf.m.planes = planes;
806 buf.memory = V4L2_MEMORY_DMABUF;
808 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
809 _E ("failed to ioctl: VIDIOC_DQBUF(Header Stream)\n");
813 pSeqOut->usedByte = buf.bytesused;
815 if (buf.field == V4L2_FIELD_NONE)
816 pSeqOut->interlace = NONE_FIELD;
817 else if (V4L2_FIELD_INTERLACED)
818 pSeqOut->interlace = FIELD_INTERLACED;
820 hDec->iInterlace = pSeqOut->interlace;
823 /* Get Image Information */
825 struct v4l2_format fmt;
826 struct v4l2_crop crop;
828 memset (&fmt, 0, sizeof (fmt));
829 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
831 if (ioctl (hDec->fd, VIDIOC_G_FMT, &fmt) != 0) {
832 _E ("Fail, ioctl(): VIDIOC_G_FMT.\n");
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;
842 memset (&crop, 0, sizeof (crop));
843 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
845 if (ioctl (hDec->fd, VIDIOC_G_CROP, &crop) != 0) {
846 _E ("Fail, ioctl(): VIDIOC_G_CROP\n");
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;
859 /*----------------------------------------------------------------------------*/
861 NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
863 /* Set Output Image */
865 struct v4l2_format fmt;
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;
874 if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
875 _E ("failed to ioctl: VIDIOC_S_FMT(Output Yuv)\n");
879 hDec->planesNum = pSeqIn->imgPlaneNum;
882 /* Malloc Output Image */
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;
890 /* Calculate Buffer Number */
891 if (pSeqIn->pMemHandle == NULL) {
892 hDec->useExternalFrameBuffer = false;
893 imgBuffCnt = hDec->numFrameBuffers + pSeqIn->numBuffers;
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);
900 imgBuffCnt = pSeqIn->numBuffers;
902 hDec->numFrameBuffers = imgBuffCnt;
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;
910 if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
911 _E ("failed to ioctl: VIDIOC_REQBUFS(Output YUV)\n");
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;
921 #ifdef TIZEN_FEATURE_ARTIK530
922 hDec->bufmgr = tbm_bufmgr_init (-1);
923 _D ("bufmgr = %p", hDec->bufmgr);
925 _E ("failed to initialize tbm_init");
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];
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);
943 if (NX_MapVideoMemory (hDec->hImage[i]) != 0) {
944 _E ("Video Memory Mapping Failed\n");
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];
956 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
957 _E ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
960 #ifdef TIZEN_FEATURE_ARTIK530
961 hDec->hImage[i]->isQueued = 1;
963 _D ("INIT QBUF [%2d] %p (%d)", i, hDec->hImage[i], hDec->queuedCnt);
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");
977 /*----------------------------------------------------------------------------*/
979 NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
980 NX_V4L2DEC_OUT * pDecOut)
982 struct v4l2_buffer buf;
983 struct v4l2_plane planes[3];
989 _E ("Fail, Invalid Handle.\n");
993 iStrmSize = GetFrameStream (hDec, pDecIn, &idx);
995 /* Queue Input Buffer */
996 memset (&buf, 0, sizeof (buf));
997 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
998 buf.m.planes = planes;
1000 buf.memory = V4L2_MEMORY_DMABUF;
1002 buf.timestamp.tv_sec = pDecIn->timeStamp / 1000;
1003 buf.timestamp.tv_usec = (pDecIn->timeStamp % 1000) * 1000;
1004 buf.flags = pDecIn->eos ? 1 : 0;
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;
1012 if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
1013 _E ("Fail, ioctl(): VIDIOC_QBUF.(Input)\n");
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;
1023 buf.memory = V4L2_MEMORY_DMABUF;
1025 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1026 _E ("Fail, ioctl(): VIDIOC_DQBUF.(Input)\n");
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;
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;
1044 pDecOut->picType[DECODED_FRAME] = PIC_TYPE_UNKNOWN;
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;
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;
1063 if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
1064 _E ("Fail, ioctl(): VIDIOC_DQBUF(Output)\n");
1068 pDecOut->dispIdx = buf.index;
1069 // pDecOut->dispInfo = &hDec->dispInfo; // TBD.
1071 if (pDecOut->dispIdx >= 0) {
1072 pDecOut->hImg = *hDec->hImage[buf.index];
1073 #ifdef TIZEN_FEATURE_ARTIK530
1074 pthread_mutex_lock(&hDec->bufferLock);
1076 hDec->hImage[buf.index]->isQueued = 0;
1078 /*_D ("DQBUF [%2d] %p (%d)", buf.index, hDec->hImage[buf.index], hDec->queuedCnt);*/
1080 pthread_mutex_unlock(&hDec->bufferLock);
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;
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;
1094 pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_UNKNOWN;
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;
1106 if (pDecOut->dispIdx == -1)
1112 /*----------------------------------------------------------------------------*/
1114 NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
1117 struct v4l2_buffer buf;
1118 struct v4l2_plane planes[3];
1123 _E ("Fail, Invalid Handle.\n");
1127 if (iFrameIdx >= 0) {
1129 #ifdef TIZEN_FEATURE_ARTIK530
1130 hFrameBuf = hDec->hImage[index];
1133 /* Search Buffer Index */
1134 if (hFrameBuf != NULL) {
1135 for (i = 0; i < hDec->numFrameBuffers; i++) {
1136 if (hFrameBuf == hDec->hImage[i]) {
1145 _E ("Fail, Invalid FrameBuffer or FrameIndex.\n");
1148 #ifdef TIZEN_FEATURE_ARTIK530
1150 _E ("No frame buffer for index %d", index);
1154 pthread_mutex_lock(&hDec->bufferLock);
1156 if (hFrameBuf->isQueued) {
1157 _E ("This buffer[%2d] is already queued, skip QBUF", index);
1158 pthread_mutex_unlock(&hDec->bufferLock);
1163 memset (&buf, 0, sizeof (buf));
1164 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1166 buf.m.planes = planes;
1167 buf.length = hDec->planesNum;
1168 buf.memory = V4L2_MEMORY_DMABUF;
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];
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",
1179 #ifdef TIZEN_FEATURE_ARTIK530
1180 pthread_mutex_unlock(&hDec->bufferLock);
1185 #ifdef TIZEN_FEATURE_ARTIK530
1186 hFrameBuf->isQueued = 1;
1188 /*_D ("QBUF [%2d] %p (%d)", index, hFrameBuf, hDec->queuedCnt);*/
1190 pthread_mutex_unlock(&hDec->bufferLock);
1195 /*----------------------------------------------------------------------------*/
1197 NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
1199 enum v4l2_buf_type type;
1202 _E ("Fail, Invalid Handle.\n");
1205 #ifdef TIZEN_FEATURE_ARTIK530
1206 pthread_mutex_lock(&hDec->bufferLock);
1207 hDec->queuedCnt = 0;
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);
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);
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);
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);
1245 struct v4l2_plane planes[3];
1246 struct v4l2_buffer buf;
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;
1255 for (i = 0; i < hDec->numFrameBuffers; i++) {
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];
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);
1270 #ifdef TIZEN_FEATURE_ARTIK530
1271 hDec->hImage[i]->isQueued = 1;
1273 _D ("FLUSH QBUF [%2d] %p (%d)", i, hDec->hImage[i], hDec->queuedCnt);
1277 #ifdef TIZEN_FEATURE_ARTIK530
1278 pthread_mutex_unlock(&hDec->bufferLock);
1284 /* Optional Function */
1286 NX_DecGetFrameType (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
1287 uint32_t codecType, int32_t * piFrameType)
1289 uint8_t *pbyStrm = pDecIn->strmBuf;
1290 uint32_t uPreFourByte = (uint32_t) - 1;
1291 int32_t iFrmType = PIC_TYPE_UNKNOWN;
1293 if ((pbyStrm == NULL) || (piFrameType == NULL))
1297 codecType = hDec->codecType;
1299 switch (codecType) {
1300 case V4L2_PIX_FMT_H264:
1302 if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1305 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1307 if ((uPreFourByte == 0x00000001) || (uPreFourByte << 8 == 0x00000100)) {
1308 int32_t iNaluType = pbyStrm[0] & 0x1F;
1310 /* Slice start code */
1311 if (iNaluType == 5) {
1312 iFrmType = PIC_TYPE_IDR;
1314 } else if (iNaluType == 1) {
1315 VLD_STREAM stStrm = { 8, pbyStrm, pDecIn->strmSize };
1317 vld_get_uev (&stStrm); /* First_mb_in_slice */
1318 iFrmType = vld_get_uev (&stStrm); /* Slice type */
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;
1332 case V4L2_PIX_FMT_MPEG2:
1334 if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
1337 uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
1339 /* Picture start code */
1340 if (uPreFourByte == 0x00000100) {
1341 VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1343 vld_flush_bits (&stStrm, 10); /* temporal_reference */
1344 iFrmType = vld_get_bits (&stStrm, 3); /* picture_coding_type */
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;
1357 case V4L2_PIX_FMT_WVC1:
1358 if (hDec == NULL || hDec->seqDataSize == 0)
1362 VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
1364 if (hDec->iInterlace != NONE_FIELD) {
1366 if (vld_get_bits (&stStrm, 1) == 1)
1367 vld_flush_bits (&stStrm, 1);
1370 iFrmType = vld_get_bits (&stStrm, 1);
1371 if (iFrmType == 0) {
1372 iFrmType = PIC_TYPE_P;
1374 iFrmType = vld_get_bits (&stStrm, 1);
1375 if (iFrmType == 0) {
1376 iFrmType = PIC_TYPE_B;
1378 iFrmType = vld_get_bits (&stStrm, 1);
1379 if (iFrmType == 0) {
1380 iFrmType = PIC_TYPE_I;
1382 iFrmType = vld_get_bits (&stStrm, 1);
1384 iFrmType = PIC_TYPE_VC1_BI;
1386 iFrmType = PIC_TYPE_SKIP;
1393 case V4L2_PIX_FMT_WMV9:
1394 if (hDec == NULL || hDec->seqDataSize == 0)
1399 int32_t fInterPFlag;
1401 VLD_STREAM stStrm = { 24, hDec->pSeqData, hDec->seqDataSize };
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);
1409 /* Parse Frame Header */
1410 stStrm.dwUsedBits = 0;
1411 stStrm.pbyStart = pbyStrm;
1412 stStrm.dwPktSize = pDecIn->strmSize;
1414 if (fInterPFlag == 1)
1415 vld_flush_bits (&stStrm, 1); /* INTERPFRM */
1417 vld_flush_bits (&stStrm, 2); /* FRMCNT */
1420 vld_flush_bits (&stStrm, 1); /* RANGEREDFRM */
1422 iFrmType = vld_get_bits (&stStrm, 1);
1423 if (maxBframes > 0) {
1424 if (iFrmType == 1) {
1425 iFrmType = PIC_TYPE_P;
1427 iFrmType = vld_get_bits (&stStrm, 1);
1429 iFrmType = PIC_TYPE_I;
1430 else if (iFrmType == 0)
1431 iFrmType = PIC_TYPE_B; /* or BI */
1435 iFrmType = PIC_TYPE_I;
1436 else if (iFrmType == 1)
1437 iFrmType = PIC_TYPE_P;
1447 *piFrameType = iFrmType;