FFmpeg
avs3_parser.c
Go to the documentation of this file.
1 /*
2  * AVS3-P2/IEEE1857.10 video parser.
3  * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
4  * Bingjie Han <hanbj@pkusz.edu.cn>
5  * Huiwen Ren <hwrenx@gmail.com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "avs3.h"
25 #include "get_bits.h"
26 #include "parser.h"
27 
28 static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
29 {
30  int pic_found = pc->frame_start_found;
31  uint32_t state = pc->state;
32  int cur = 0;
33 
34  if (!pic_found) {
35  for (; cur < buf_size; ++cur) {
36  state = (state << 8) | buf[cur];
37  if (AVS3_ISPIC(buf[cur])){
38  cur++;
39  pic_found = 1;
40  break;
41  }
42  }
43  }
44 
45  if (pic_found) {
46  if (!buf_size)
47  return END_NOT_FOUND;
48  for (; cur < buf_size; ++cur) {
49  state = (state << 8) | buf[cur];
50  if ((state & 0xFFFFFF00) == 0x100 && AVS3_ISUNIT(state & 0xFF)) {
51  pc->frame_start_found = 0;
52  pc->state = -1;
53  return cur - 3;
54  }
55  }
56  }
57 
58  pc->frame_start_found = pic_found;
59  pc->state = state;
60 
61  return END_NOT_FOUND;
62 }
63 
64 static void parse_avs3_nal_units(AVCodecParserContext *s, const uint8_t *buf,
65  int buf_size, AVCodecContext *avctx)
66 {
67  if (buf_size < 5) {
68  return;
69  }
70 
71  if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1) {
72  if (buf[3] == AVS3_SEQ_START_CODE) {
73  GetBitContext gb;
74  int profile, ratecode, low_delay;
75 
76  init_get_bits8(&gb, buf + 4, buf_size - 4);
77 
78  s->key_frame = 1;
79  s->pict_type = AV_PICTURE_TYPE_I;
80 
81  profile = get_bits(&gb, 8);
82  // Skip bits: level(8)
83  // progressive(1)
84  // field(1)
85  // library(2)
86  // resv(1)
87  // width(14)
88  // resv(1)
89  // height(14)
90  // chroma(2)
91  // sampe_precision(3)
92  skip_bits(&gb, 47);
93 
95  int sample_precision = get_bits(&gb, 3);
96  if (sample_precision == 1) {
97  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
98  } else if (sample_precision == 2) {
100  } else {
101  avctx->pix_fmt = AV_PIX_FMT_NONE;
102  }
103  }
104 
105  // Skip bits: resv(1)
106  // aspect(4)
107  skip_bits(&gb, 5);
108 
109  ratecode = get_bits(&gb, 4);
110 
111  // Skip bits: resv(1)
112  // bitrate_low(18)
113  // resv(1)
114  // bitrate_high(12)
115  skip_bits(&gb, 32);
116 
117  low_delay = get_bits(&gb, 1);
118  avctx->has_b_frames = FFMAX(avctx->has_b_frames, !low_delay);
119 
120  avctx->framerate.num = ff_avs3_frame_rate_tab[ratecode].num;
121  avctx->framerate.den = ff_avs3_frame_rate_tab[ratecode].den;
122 
123  s->width = s->coded_width = avctx->width;
124  s->height = s->coded_height = avctx->height;
125 
126  av_log(avctx, AV_LOG_DEBUG,
127  "AVS3 parse seq HDR: profile %d; coded size: %dx%d; frame rate code: %d\n",
128  profile, avctx->width, avctx->height, ratecode);
129 
130  } else if (buf[3] == AVS3_INTRA_PIC_START_CODE) {
131  s->key_frame = 1;
132  s->pict_type = AV_PICTURE_TYPE_I;
133  } else if (buf[3] == AVS3_INTER_PIC_START_CODE){
134  s->key_frame = 0;
135  if (buf_size > 9) {
136  int pic_code_type = buf[8] & 0x3;
137  if (pic_code_type == 1 || pic_code_type == 3) {
138  s->pict_type = AV_PICTURE_TYPE_P;
139  } else {
140  s->pict_type = AV_PICTURE_TYPE_B;
141  }
142  }
143  }
144  }
145 }
146 
147 
149  const uint8_t **poutbuf, int *poutbuf_size,
150  const uint8_t *buf, int buf_size)
151 {
152  ParseContext *pc = s->priv_data;
153  int next;
154 
155  if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
156  next = buf_size;
157  } else {
158  next = avs3_find_frame_end(pc, buf, buf_size);
159  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
160  *poutbuf = NULL;
161  *poutbuf_size = 0;
162  return buf_size;
163  }
164  }
165 
166  parse_avs3_nal_units(s, buf, buf_size, avctx);
167 
168  *poutbuf = buf;
169  *poutbuf_size = buf_size;
170 
171  return next;
172 }
173 
176  .priv_data_size = sizeof(ParseContext),
177  .parser_parse = avs3_parse,
178  .parser_close = ff_parse_close,
179 };
avs3_parse
static int avs3_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: avs3_parser.c:148
avs3_find_frame_end
static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
Definition: avs3_parser.c:28
ff_parse_close
void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:288
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ParseContext::state
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:381
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1803
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
ff_avs3_parser
const AVCodecParser ff_avs3_parser
Definition: avs3_parser.c:174
ParseContext
Definition: parser.h:28
GetBitContext
Definition: get_bits.h:108
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_PIX_FMT_YUV420P10LE
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:149
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:744
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVS3_INTRA_PIC_START_CODE
#define AVS3_INTRA_PIC_START_CODE
Definition: avs3.h:30
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
get_bits.h
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:248
NULL
#define NULL
Definition: coverity.c:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
ParseContext::frame_start_found
int frame_start_found
Definition: parser.h:34
AVCodecParser::codec_ids
int codec_ids[7]
Definition: avcodec.h:2934
ff_avs3_frame_rate_tab
static const AVRational ff_avs3_frame_rate_tab[16]
Definition: avs3.h:46
ff_combine_frame
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
Combine the (truncated) bitstream to a complete frame.
Definition: parser.c:203
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition: avcodec.h:2808
AVS3_ISUNIT
#define AVS3_ISUNIT(x)
Definition: avs3.h:40
parser.h
profile
int profile
Definition: mxfenc.c:2115
parse_avs3_nal_units
static void parse_avs3_nal_units(AVCodecParserContext *s, const uint8_t *buf, int buf_size, AVCodecContext *avctx)
Definition: avs3_parser.c:64
AVCodecContext::height
int height
Definition: avcodec.h:621
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:658
AVCodecParserContext
Definition: avcodec.h:2774
AVS3_SEQ_START_CODE
#define AVS3_SEQ_START_CODE
Definition: avs3.h:27
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:281
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
avs3.h
state
static struct @362 state
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
AVCodecParser
Definition: avcodec.h:2933
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVS3_INTER_PIC_START_CODE
#define AVS3_INTER_PIC_START_CODE
Definition: avs3.h:33
AVS3_ISPIC
#define AVS3_ISPIC(x)
Definition: avs3.h:39
AVS3_PROFILE_BASELINE_MAIN10
#define AVS3_PROFILE_BASELINE_MAIN10
Definition: avs3.h:37