FFmpeg
lcevc_parser.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdint.h>
20 
21 #include "libavutil/mem.h"
22 
23 #include "avcodec.h"
24 #include "bytestream.h"
25 #include "get_bits.h"
26 #include "h2645_parse.h"
27 #include "lcevc.h"
28 #include "parser.h"
29 #include "parser_internal.h"
30 
31 #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
32 
33 typedef struct LCEVCParserContext {
35 
37 
39  int is_lvcc;
42 
43 static int lcevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
44  int buf_size)
45 {
46  LCEVCParserContext *ctx = s->priv_data;
47  ParseContext *pc = &ctx->pc;
48 
49  for (int i = 0; i < buf_size; i++) {
50  int nut;
51 
52  pc->state = (pc->state << 8) | buf[i];
53 
54  if (((pc->state >> 8) & 0xFFFFFF) != START_CODE)
55  continue;
56 
57  nut = (pc->state >> 1) & 0x1F;
58 
59  // Beginning of access unit
60  if (nut == LCEVC_IDR_NUT || nut == LCEVC_NON_IDR_NUT) {
61  if (!pc->frame_start_found)
62  pc->frame_start_found = 1;
63  else {
64  pc->frame_start_found = 0;
65  return i - 3;
66  }
67  }
68  }
69 
70  return END_NOT_FOUND;
71 }
72 
73 static const enum AVPixelFormat pix_fmts[4][4] = {
82 };
83 
84 static const struct {
85  int width;
86  int height;
87 } resolution_type_lut[63] = {
88  { 0, 0},
89  { 360, 200 }, { 400, 240 }, { 480, 320 }, { 640, 360 },
90  { 640, 480 }, { 768, 480 }, { 800, 600 }, { 852, 480 },
91  { 854, 480 }, { 856, 480 }, { 960, 540 }, { 960, 640 },
92  { 1024, 576 }, { 1024, 600 }, { 1024, 768 }, { 1152, 864 },
93  { 1280, 720 }, { 1280, 800 }, { 1280, 1024 }, { 1360, 768 },
94  { 1366, 768 }, { 1920, 1200 }, { 2048, 1080 }, { 2048, 1152 },
95  { 2048, 1536 }, { 2160, 1440 }, { 2560, 1440 }, { 2560, 1600 },
96  { 2560, 2048 }, { 3200, 1800 }, { 3200, 2048 }, { 3200, 2400 },
97  { 3440, 1440 }, { 3840, 1600 }, { 3840, 2160 }, { 3840, 2400 },
98  { 4096, 2160 }, { 4096, 3072 }, { 5120, 2880 }, { 5120, 3200 },
99  { 5120, 4096 }, { 6400, 4096 }, { 6400, 4800 }, { 7680, 4320 },
100  { 7680, 4800 },
101 };
102 
103 static inline uint64_t get_mb(GetBitContext *s) {
104  int more, i = 0;
105  uint64_t mb = 0;
106 
107  do {
108  int byte = get_bits(s, 8);
109  unsigned bits = byte & 0x7f;
110  more = byte & 0x80;
111  mb = (mb << 7) | bits;
112  if (++i == 10)
113  break;
114  } while (more);
115 
116  return mb;
117 }
118 
120  const H2645NAL *nal)
121 {
122  GetByteContext gbc;
123  bytestream2_init(&gbc, nal->data, nal->size);
124  bytestream2_skip(&gbc, 2);
125 
126  while (bytestream2_get_bytes_left(&gbc) > 1) {
127  GetBitContext gb;
128  int payload_size_type, payload_type, payload_size;
129  int block_size;
130 
132 
133  payload_size_type = get_bits(&gb, 3);
134  payload_type = get_bits(&gb, 5);
135  payload_size = payload_size_type;
136  if (payload_size_type == 6)
137  return AVERROR_PATCHWELCOME;
138  if (payload_size_type == 7)
139  payload_size = get_mb(&gb);
140 
141  block_size = payload_size + (get_bits_count(&gb) >> 3);
142  if (block_size >= bytestream2_get_bytes_left(&gbc))
143  return AVERROR_INVALIDDATA;
144 
145  switch (payload_type) {
147  avctx->profile = get_bits(&gb, 4);
148  avctx->level = get_bits(&gb, 4);
149  break;
151  int resolution_type, chroma_format_idc, bit_depth;
152  int processed_planes_type_flag;
153 
154  processed_planes_type_flag = get_bits1(&gb);
155  resolution_type = get_bits(&gb, 6);
156  skip_bits1(&gb);
157  chroma_format_idc = get_bits(&gb, 2);
158  skip_bits(&gb, 2);
159  bit_depth = get_bits(&gb, 2); // enhancement_depth_type
160 
161  s->format = pix_fmts[bit_depth][chroma_format_idc];
162 
163  if (resolution_type < 63) {
164  s->width = resolution_type_lut[resolution_type].width;
165  s->height = resolution_type_lut[resolution_type].height;
166  } else {
167  int upsample_type, tile_dimensions_type;
168  int temporal_step_width_modifier_signalled_flag, level1_filtering_signalled_flag;
169  // Skip syntax elements until we get to the custom dimension ones
170  temporal_step_width_modifier_signalled_flag = get_bits1(&gb);
171  skip_bits(&gb, 3);
172  upsample_type = get_bits(&gb, 3);
173  level1_filtering_signalled_flag = get_bits1(&gb);
174  skip_bits(&gb, 4);
175  tile_dimensions_type = get_bits(&gb, 2);
176  skip_bits(&gb, 4);
177  if (processed_planes_type_flag)
178  skip_bits(&gb, 4);
179  if (temporal_step_width_modifier_signalled_flag)
180  skip_bits(&gb, 8);
181  if (upsample_type)
182  skip_bits_long(&gb, 64);
183  if (level1_filtering_signalled_flag)
184  skip_bits(&gb, 8);
185  if (tile_dimensions_type) {
186  if (tile_dimensions_type == 3)
187  skip_bits_long(&gb, 32);
188  skip_bits(&gb, 8);
189  }
190 
191  s->width = get_bits(&gb, 16);
192  s->height = get_bits(&gb, 16);
193  }
194  break;
195  }
196  default:
197  break;
198  }
199 
200  bytestream2_skip(&gbc, block_size);
201  }
202 
203  return 0;
204 }
205 
206 static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
207  int buf_size, AVCodecContext *avctx)
208 {
209  LCEVCParserContext *ctx = s->priv_data;
210  int flags = (H2645_FLAG_IS_NALFF * !!ctx->is_lvcc) | H2645_FLAG_SMALL_PADDING;
211  int ret, i;
212 
213  /* set some sane default values */
214  s->pict_type = AV_PICTURE_TYPE_NONE;
215  s->key_frame = 0;
216  s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
217 
218  ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx,
219  ctx->nal_length_size, AV_CODEC_ID_LCEVC, flags);
220  if (ret < 0)
221  return ret;
222 
223  for (i = 0; i < ctx->pkt.nb_nals; i++) {
224  H2645NAL *nal = &ctx->pkt.nals[i];
225 
226  switch (nal->type) {
227  case LCEVC_IDR_NUT:
228  s->key_frame = 1;
229  // fall-through
230  case LCEVC_NON_IDR_NUT:
231  parse_nal_unit(s, avctx, nal);
232  break;
233  default:
234  break;
235  }
236  }
237 
238  return 0;
239 }
240 
242  AVCodecContext *avctx,
243  const uint8_t **poutbuf, int *poutbuf_size,
244  const uint8_t *buf, int buf_size)
245 {
246  LCEVCParserContext *ctx = s->priv_data;
247  ParseContext *pc = &ctx->pc;
248  int next;
249 
250  if (!ctx->parsed_extradata && avctx->extradata_size > 4) {
251  ctx->parsed_extradata = 1;
252  ctx->is_lvcc = !!avctx->extradata[0];
253 
254  if (ctx->is_lvcc)
255  ctx->nal_length_size = (avctx->extradata[4] >> 6) + 1;
256  }
257 
258  if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
259  next = buf_size;
260  } else {
261  next = lcevc_find_frame_end(s, buf, buf_size);
262  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
263  *poutbuf = NULL;
264  *poutbuf_size = 0;
265  return buf_size;
266  }
267  }
268 
269  parse_nal_units(s, buf, buf_size, avctx);
270 
271  *poutbuf = buf;
272  *poutbuf_size = buf_size;
273  return next;
274 }
275 
277 {
278  LCEVCParserContext *ctx = s->priv_data;
279 
281 
282  av_freep(&ctx->pc.buffer);
283 }
284 
287  .priv_data_size = sizeof(LCEVCParserContext),
288  .parse = lcevc_parse,
290 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
h2645_parse.h
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
GetByteContext
Definition: bytestream.h:33
AV_PICTURE_STRUCTURE_UNKNOWN
@ AV_PICTURE_STRUCTURE_UNKNOWN
unknown
Definition: avcodec.h:2587
parse_nal_unit
static int parse_nal_unit(AVCodecParserContext *s, AVCodecContext *avctx, const H2645NAL *nal)
Definition: lcevc_parser.c:119
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:254
parser_internal.h
ff_h2645_packet_uninit
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
Definition: h2645_parse.c:667
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
LCEVCParserContext
Definition: lcevc_parser.c:33
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
ParseContext::state
uint32_t state
contains the last few bytes in MSB order
Definition: parser.h:33
resolution_type_lut
static const struct @177 resolution_type_lut[63]
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
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
LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
@ LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
Definition: lcevc.h:70
GetBitContext
Definition: get_bits.h:109
get_mb
static uint64_t get_mb(GetBitContext *s)
Definition: lcevc_parser.c:103
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:542
LCEVCParserContext::pkt
H2645Packet pkt
Definition: lcevc_parser.c:36
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:523
s
#define s(width, name)
Definition: cbs_vp9.c:198
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
bits
uint8_t bits
Definition: vp3data.h:128
LCEVCParserContext::is_lvcc
int is_lvcc
Definition: lcevc_parser.c:39
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
get_bits.h
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:521
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_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:519
LCEVC_IDR_NUT
@ LCEVC_IDR_NUT
Definition: lcevc.h:61
parse_nal_units
static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, int buf_size, AVCodecContext *avctx)
Definition: lcevc_parser.c:206
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
ParseContext::frame_start_found
int frame_start_found
Definition: parser.h:34
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
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:92
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1640
pix_fmts
static enum AVPixelFormat pix_fmts[4][4]
Definition: lcevc_parser.c:73
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:544
H2645NAL
Definition: h2645_parse.h:34
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:546
mb
#define mb(name)
Definition: cbs_lcevc.c:95
AV_PICTURE_TYPE_NONE
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition: avutil.h:277
LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
@ LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
Definition: lcevc.h:71
START_CODE
#define START_CODE
start_code_prefix_one_3bytes
Definition: lcevc_parser.c:31
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
skip_bits1
static void skip_bits1(GetBitContext *s)
Definition: get_bits.h:416
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:217
FFCodecParser
Definition: parser_internal.h:29
height
int height
Definition: lcevc_parser.c:86
H2645_FLAG_SMALL_PADDING
@ H2645_FLAG_SMALL_PADDING
Definition: h2645_parse.h:98
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition: avcodec.h:2627
nal
static int FUNC() nal(CodedBitstreamContext *ctx, RWContext *rw, LCEVCRawNAL *current, int nal_unit_type)
Definition: cbs_lcevc_syntax_template.c:655
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:522
lcevc_parse
static int lcevc_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition: lcevc_parser.c:241
ff_lcevc_parser
const FFCodecParser ff_lcevc_parser
Definition: lcevc_parser.c:285
LCEVCParserContext::nal_length_size
int nal_length_size
Definition: lcevc_parser.c:40
parser.h
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
avcodec.h
AVCodecParserContext
Definition: avcodec.h:2593
width
int width
Definition: lcevc_parser.c:85
lcevc_find_frame_end
static int lcevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, int buf_size)
Definition: lcevc_parser.c:43
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:543
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:548
lcevc_parser_close
static void lcevc_parser_close(AVCodecParserContext *s)
Definition: lcevc_parser.c:276
AVCodecContext
main external API structure.
Definition: avcodec.h:439
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1630
lcevc.h
LCEVC_NON_IDR_NUT
@ LCEVC_NON_IDR_NUT
Definition: lcevc.h:60
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
mem.h
END_NOT_FOUND
#define END_NOT_FOUND
Definition: parser.h:40
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
LCEVCParserContext::pc
ParseContext pc
Definition: lcevc_parser.c:34
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
H2645_FLAG_IS_NALFF
@ H2645_FLAG_IS_NALFF
Definition: h2645_parse.h:97
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:549
ff_h2645_packet_split
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int nal_length_size, enum AVCodecID codec_id, int flags)
Split an input packet into NAL units.
Definition: h2645_parse.c:527
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:520
H2645Packet
Definition: h2645_parse.h:82
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:547
LCEVCParserContext::parsed_extradata
int parsed_extradata
Definition: lcevc_parser.c:38