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 #include "parser_internal.h"
28 
29 static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
30 {
31  int pic_found = pc->frame_start_found;
32  uint32_t state = pc->state;
33  int cur = 0;
34 
35  if (!pic_found) {
36  for (; cur < buf_size; ++cur) {
37  state = (state << 8) | buf[cur];
38  if (AVS3_ISPIC(buf[cur])){
39  cur++;
40  pic_found = 1;
41  break;
42  }
43  }
44  }
45 
46  if (pic_found) {
47  if (!buf_size)
48  return END_NOT_FOUND;
49  for (; cur < buf_size; ++cur) {
50  state = (state << 8) | buf[cur];
51  if ((state & 0xFFFFFF00) == 0x100 && AVS3_ISUNIT(state & 0xFF)) {
52  pc->frame_start_found = 0;
53  pc->state = -1;
54  return cur - 3;
55  }
56  }
57  }
58 
59  pc->frame_start_found = pic_found;
60  pc->state = state;
61 
62  return END_NOT_FOUND;
63 }
64 
65 static void parse_avs3_nal_units(AVCodecParserContext *s, const uint8_t *buf,
66  int buf_size, AVCodecContext *avctx)
67 {
68  if (buf_size < 5) {
69  return;
70  }
71 
72  if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1) {
73  if (buf[3] == AVS3_SEQ_START_CODE) {
74  GetBitContext gb;
75  int profile, ratecode, low_delay;
76 
77  av_unused int ret = init_get_bits(&gb, buf + 4, 100);
78  av_assert1(ret >= 0);
79 
80  s->key_frame = 1;
81  s->pict_type = AV_PICTURE_TYPE_I;
82 
83  profile = get_bits(&gb, 8);
84  // Skip bits: level(8)
85  // progressive(1)
86  // field(1)
87  // library(2)
88  // resv(1)
89  // width(14)
90  // resv(1)
91  // height(14)
92  // chroma(2)
93  // sampe_precision(3)
94  skip_bits(&gb, 47);
95 
97  int sample_precision = get_bits(&gb, 3);
98  if (sample_precision == 1) {
99  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
100  } else if (sample_precision == 2) {
101  avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
102  } else {
103  avctx->pix_fmt = AV_PIX_FMT_NONE;
104  }
105  }
106 
107  // Skip bits: resv(1)
108  // aspect(4)
109  skip_bits(&gb, 5);
110 
111  ratecode = get_bits(&gb, 4);
112 
113  // Skip bits: resv(1)
114  // bitrate_low(18)
115  // resv(1)
116  // bitrate_high(12)
117  skip_bits(&gb, 32);
118 
119  low_delay = get_bits(&gb, 1);
120  avctx->has_b_frames = FFMAX(avctx->has_b_frames, !low_delay);
121 
122  avctx->framerate.num = ff_avs3_frame_rate_tab[ratecode].num;
123  avctx->framerate.den = ff_avs3_frame_rate_tab[ratecode].den;
124 
125  s->width = s->coded_width = avctx->width;
126  s->height = s->coded_height = avctx->height;
127 
128  av_log(avctx, AV_LOG_DEBUG,
129  "AVS3 parse seq HDR: profile %d; coded size: %dx%d; frame rate code: %d\n",
130  profile, avctx->width, avctx->height, ratecode);
131 
132  } else if (buf[3] == AVS3_INTRA_PIC_START_CODE) {
133  s->key_frame = 1;
134  s->pict_type = AV_PICTURE_TYPE_I;
135  } else if (buf[3] == AVS3_INTER_PIC_START_CODE){
136  s->key_frame = 0;
137  if (buf_size > 9) {
138  int pic_code_type = buf[8] & 0x3;
139  if (pic_code_type == 1 || pic_code_type == 3) {
140  s->pict_type = AV_PICTURE_TYPE_P;
141  } else {
142  s->pict_type = AV_PICTURE_TYPE_B;
143  }
144  }
145  }
146  }
147 }
148 
149 
151  const uint8_t **poutbuf, int *poutbuf_size,
152  const uint8_t *buf, int buf_size)
153 {
154  ParseContext *pc = s->priv_data;
155  int next;
156 
157  if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
158  next = buf_size;
159  } else {
160  next = avs3_find_frame_end(pc, buf, buf_size);
161  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
162  *poutbuf = NULL;
163  *poutbuf_size = 0;
164  return buf_size;
165  }
166  }
167 
168  parse_avs3_nal_units(s, buf, buf_size, avctx);
169 
170  *poutbuf = buf;
171  *poutbuf_size = buf_size;
172 
173  return next;
174 }
175 
178  .priv_data_size = sizeof(ParseContext),
179  .parse = avs3_parse,
181 };
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:150
avs3_find_frame_end
static int avs3_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
Definition: avs3_parser.c:29
ff_parse_close
av_cold void ff_parse_close(AVCodecParserContext *s)
Definition: parser.c:298
av_unused
#define av_unused
Definition: attributes.h:151
parser_internal.h
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
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
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:551
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:136
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
ParseContext
Definition: parser.h:28
GetBitContext
Definition: get_bits.h:109
AVRational::num
int num
Numerator.
Definition: rational.h:59
state
static struct @542 state
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:697
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:231
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:73
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:250
NULL
#define NULL
Definition: coverity.c:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
ParseContext::frame_start_found
int frame_start_found
Definition: parser.h:34
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: apv_parser.c:46
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:211
FFCodecParser
Definition: parser_internal.h:29
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition: avcodec.h:2609
AVS3_ISUNIT
#define AVS3_ISUNIT(x)
Definition: avs3.h:40
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
parser.h
profile
int profile
Definition: mxfenc.c:2297
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:65
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
AVCodecParserContext
Definition: avcodec.h:2575
ret
ret
Definition: filter_design.txt:187
AVS3_SEQ_START_CODE
#define AVS3_SEQ_START_CODE
Definition: avs3.h:27
ff_avs3_parser
const FFCodecParser ff_avs3_parser
Definition: avs3_parser.c:176
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:280
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
avs3.h
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
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