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 "lcevc_parse.h"
29 #include "lcevctab.h"
30 #include "parser.h"
31 #include "parser_internal.h"
32 
33 #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
34 
35 typedef struct LCEVCParserContext {
37 
39 
41  int is_lvcc;
44 
45 static int lcevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
46  int buf_size)
47 {
48  LCEVCParserContext *ctx = s->priv_data;
49  ParseContext *pc = &ctx->pc;
50 
51  for (int i = 0; i < buf_size; i++) {
52  int nut;
53 
54  pc->state = (pc->state << 8) | buf[i];
55 
56  if (((pc->state >> 8) & 0xFFFFFF) != START_CODE)
57  continue;
58 
59  nut = (pc->state >> 1) & 0x1F;
60 
61  // Beginning of access unit
62  if (nut == LCEVC_IDR_NUT || nut == LCEVC_NON_IDR_NUT) {
63  if (!pc->frame_start_found)
64  pc->frame_start_found = 1;
65  else {
66  pc->frame_start_found = 0;
67  return i - 3;
68  }
69  }
70  }
71 
72  return END_NOT_FOUND;
73 }
74 
75 static const enum AVPixelFormat pix_fmts[4][4] = {
84 };
85 
87  const H2645NAL *nal)
88 {
89  GetByteContext gbc;
90  bytestream2_init(&gbc, nal->data, nal->size);
91  bytestream2_skip(&gbc, 2);
92 
93  while (bytestream2_get_bytes_left(&gbc) > 1) {
94  GetBitContext gb;
95  uint64_t payload_size;
96  int payload_size_type, payload_type;
97  int block_size;
98 
99  int ret = init_get_bits8(&gb, gbc.buffer, bytestream2_get_bytes_left(&gbc));
100  if (ret < 0)
101  return ret;
102 
103  payload_size_type = get_bits(&gb, 3);
104  payload_type = get_bits(&gb, 5);
105  payload_size = payload_size_type;
106  if (payload_size_type == 6)
107  return AVERROR_PATCHWELCOME;
108  if (payload_size_type == 7)
109  payload_size = get_mb(&gb);
110 
111  if (payload_size > INT_MAX - (get_bits_count(&gb) >> 3))
112  return AVERROR_INVALIDDATA;
113 
114  block_size = payload_size + (get_bits_count(&gb) >> 3);
115  if (block_size >= bytestream2_get_bytes_left(&gbc))
116  return AVERROR_INVALIDDATA;
117 
118  switch (payload_type) {
120  avctx->profile = get_bits(&gb, 4);
121  avctx->level = get_bits(&gb, 4);
122  break;
124  int resolution_type, chroma_format_idc, bit_depth;
125  int processed_planes_type_flag;
126 
127  processed_planes_type_flag = get_bits1(&gb);
128  resolution_type = get_bits(&gb, 6);
129  skip_bits1(&gb);
130  chroma_format_idc = get_bits(&gb, 2);
131  skip_bits(&gb, 2);
132  bit_depth = get_bits(&gb, 2); // enhancement_depth_type
133 
134  s->format = pix_fmts[bit_depth][chroma_format_idc];
135 
136  if (resolution_type < 63) {
137  s->width = ff_lcevc_resolution_type[resolution_type].width;
138  s->height = ff_lcevc_resolution_type[resolution_type].height;
139  } else {
140  int upsample_type, tile_dimensions_type;
141  int temporal_step_width_modifier_signalled_flag, level1_filtering_signalled_flag;
142  // Skip syntax elements until we get to the custom dimension ones
143  temporal_step_width_modifier_signalled_flag = get_bits1(&gb);
144  skip_bits(&gb, 3);
145  upsample_type = get_bits(&gb, 3);
146  level1_filtering_signalled_flag = get_bits1(&gb);
147  skip_bits(&gb, 4);
148  tile_dimensions_type = get_bits(&gb, 2);
149  skip_bits(&gb, 4);
150  if (processed_planes_type_flag)
151  skip_bits(&gb, 4);
152  if (temporal_step_width_modifier_signalled_flag)
153  skip_bits(&gb, 8);
154  if (upsample_type)
155  skip_bits_long(&gb, 64);
156  if (level1_filtering_signalled_flag)
157  skip_bits(&gb, 8);
158  if (tile_dimensions_type) {
159  if (tile_dimensions_type == 3)
160  skip_bits_long(&gb, 32);
161  skip_bits(&gb, 8);
162  }
163 
164  s->width = get_bits(&gb, 16);
165  s->height = get_bits(&gb, 16);
166  }
167  break;
168  }
169  default:
170  break;
171  }
172 
173  bytestream2_skip(&gbc, block_size);
174  }
175 
176  return 0;
177 }
178 
179 static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
180  int buf_size, AVCodecContext *avctx)
181 {
182  LCEVCParserContext *ctx = s->priv_data;
183  int flags = (H2645_FLAG_IS_NALFF * !!ctx->is_lvcc) | H2645_FLAG_SMALL_PADDING;
184  int ret, i;
185 
186  /* set some sane default values */
187  s->pict_type = AV_PICTURE_TYPE_NONE;
188  s->key_frame = 0;
189  s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
190 
191  ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx,
192  ctx->nal_length_size, AV_CODEC_ID_LCEVC, flags);
193  if (ret < 0)
194  return ret;
195 
196  for (i = 0; i < ctx->pkt.nb_nals; i++) {
197  H2645NAL *nal = &ctx->pkt.nals[i];
198 
199  switch (nal->type) {
200  case LCEVC_IDR_NUT:
201  s->key_frame = 1;
202  // fall-through
203  case LCEVC_NON_IDR_NUT:
204  parse_nal_unit(s, avctx, nal);
205  break;
206  default:
207  break;
208  }
209  }
210 
211  return 0;
212 }
213 
215  AVCodecContext *avctx,
216  const uint8_t **poutbuf, int *poutbuf_size,
217  const uint8_t *buf, int buf_size)
218 {
219  LCEVCParserContext *ctx = s->priv_data;
220  ParseContext *pc = &ctx->pc;
221  int next;
222 
223  if (!ctx->parsed_extradata && avctx->extradata_size > 4) {
224  ctx->parsed_extradata = 1;
225  ctx->is_lvcc = !!avctx->extradata[0];
226 
227  if (ctx->is_lvcc)
228  ctx->nal_length_size = (avctx->extradata[4] >> 6) + 1;
229  }
230 
231  if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
232  next = buf_size;
233  } else {
234  next = lcevc_find_frame_end(s, buf, buf_size);
235  if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
236  *poutbuf = NULL;
237  *poutbuf_size = 0;
238  return buf_size;
239  }
240  }
241 
242  parse_nal_units(s, buf, buf_size, avctx);
243 
244  *poutbuf = buf;
245  *poutbuf_size = buf_size;
246  return next;
247 }
248 
250 {
251  LCEVCParserContext *ctx = s->priv_data;
252 
254 
255  av_freep(&ctx->pc.buffer);
256 }
257 
260  .priv_data_size = sizeof(LCEVCParserContext),
261  .parse = lcevc_parse,
263 };
flags
const SwsFlags flags[]
Definition: swscale.c:71
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
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
parse_nal_unit
static int parse_nal_unit(AVCodecParserContext *s, AVCodecContext *avctx, const H2645NAL *nal)
Definition: lcevc_parser.c:86
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:254
parser_internal.h
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
lcevc_parse.h
ff_lcevc_resolution_type
const struct FFLCEVCDim ff_lcevc_resolution_type[63]
Definition: lcevctab.c:21
LCEVCParserContext
Definition: lcevc_parser.c:35
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
get_mb
static uint64_t get_mb(GetBitContext *s)
Definition: lcevc_parse.h:26
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
lcevc.h
ParseContext
Definition: parser.h:28
GetBitContext
Definition: get_bits.h:109
LCEVC_NON_IDR_NUT
@ LCEVC_NON_IDR_NUT
Definition: lcevc.h:60
ff_h2645_packet_uninit
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
Definition: h2645_parse.c:685
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:542
LCEVCParserContext::pkt
H2645Packet pkt
Definition: lcevc_parser.c:38
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
LCEVCParserContext::is_lvcc
int is_lvcc
Definition: lcevc_parser.c:41
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
parse_nal_units
static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, int buf_size, AVCodecContext *avctx)
Definition: lcevc_parser.c:179
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:75
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
AV_PICTURE_TYPE_NONE
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition: avutil.h:277
START_CODE
#define START_CODE
start_code_prefix_one_3bytes
Definition: lcevc_parser.c:33
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
FFLCEVCDim::height
uint16_t height
Definition: lcevctab.h:28
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
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:657
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:214
ff_lcevc_parser
const FFCodecParser ff_lcevc_parser
Definition: lcevc_parser.c:258
LCEVCParserContext::nal_length_size
int nal_length_size
Definition: lcevc_parser.c:42
parser.h
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition: parser_internal.h:76
FFLCEVCDim::width
uint16_t width
Definition: lcevctab.h:27
avcodec.h
AVCodecParserContext
Definition: avcodec.h:2593
lcevc_find_frame_end
static int lcevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, int buf_size)
Definition: lcevc_parser.c:45
ret
ret
Definition: filter_design.txt:187
lcevctab.h
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:249
AVCodecContext
main external API structure.
Definition: avcodec.h:439
LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
@ LCEVC_PAYLOAD_TYPE_SEQUENCE_CONFIG
Definition: lcevc.h:70
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1630
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
LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
@ LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG
Definition: lcevc.h:71
LCEVCParserContext::pc
ParseContext pc
Definition: lcevc_parser.c:36
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
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:520
LCEVC_IDR_NUT
@ LCEVC_IDR_NUT
Definition: lcevc.h:61
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:40