FFmpeg
cbs_vp8.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 "libavutil/avassert.h"
20 
21 #include "cbs.h"
22 #include "cbs_internal.h"
23 #include "cbs_vp8.h"
24 
25 #include <stdbool.h>
26 
27 #define DEFAULT_PROB 0x80
28 
29 // The probability table is defined in 'vp8data.c'.
30 extern const uint8_t ff_vp8_token_update_probs[4][8][3][11];
31 
32 // Implements VP8 boolean decoder using GetBitContext to read the bitstream.
33 typedef struct CBSVP8BoolDecoder {
35 
36  uint8_t value;
37  uint8_t range;
38 
39  uint8_t count; // Store the number of bits in the `value` buffer.
40 
42 
44 {
46  av_assert0(gbc);
47 
48  decoder->gbc = gbc;
49  decoder->value = 0;
50  decoder->range = 255;
51 
52  decoder->count = 0;
53 
54  return 0;
55 }
56 
58 {
59  int bits = 8 - decoder->count;
60 
61  av_assert0(decoder->count <= 8);
62  if (decoder->count == 8) {
63  return true;
64  }
65 
66  if (get_bits_left(decoder->gbc) >= bits) {
67  decoder->value |= get_bits(decoder->gbc, bits);
68  decoder->count += bits;
69  }
70 
71  return (decoder->count == 8);
72 }
73 
75  const uint8_t prob, uint8_t *output)
76 {
77  uint8_t split = 1 + (((decoder->range - 1) * prob) >> 8);
78 
80  return AVERROR_INVALIDDATA;
81  }
82 
83  av_assert0(decoder->count == 8);
84  if (decoder->value >= split) {
85  *output = 1;
86  decoder->range -= split;
87  decoder->value -= split;
88  } else {
89  *output = 0;
90  decoder->range = split;
91  }
92 
93  while (decoder->range < 128) {
94  decoder->value <<= 1;
95  decoder->range <<= 1;
96  --decoder->count;
97  }
98 
99  return 0;
100 }
101 
103  const uint8_t prob,
104  uint32_t num_bits,
105  uint32_t *output)
106 {
107  int ret = 0;
108 
109  av_assert0(num_bits <= 32);
110 
111  *output = 0;
112  for (; num_bits > 0; --num_bits) {
113  uint8_t bit_output = 0;
115  &bit_output)) != 0) {
116  return ret;
117  }
118 
119  *output = (*output << 1) | bit_output;
120  }
121 
122  return 0;
123 }
124 
126  CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width,
127  uint8_t prob, const char *name, const int *subscripts, uint32_t *write_to,
128  bool trace_enable)
129 {
130  int ret = 0;
131  GetBitContext *gbc = bool_decoder->gbc;
132  uint32_t value;
133 
135 
136  av_assert0(width >= 0 && width <= 8);
137 
139  if (ret != 0) {
140  return ret;
141  }
142 
143  if (trace_enable) {
145  }
146 
147  *write_to = value;
148  return 0;
149 }
150 
152  CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width,
153  uint8_t prob, const char *name, const int *subscripts, int32_t *write_to)
154 {
155  int ret = 0;
156  GetBitContext *gbc = bool_decoder->gbc;
157  int32_t value;
158  uint8_t sign = 0;
159 
161 
162  av_assert0(width >= 0 && width <= 8);
163 
165  if (ret != 0) {
166  return ret;
167  }
168 
169  ret = cbs_vp8_bool_decoder_read_bool(bool_decoder, prob, &sign);
170  if (ret != 0) {
171  return ret;
172  }
173 
174  if (sign) {
175  value = -value;
176  }
177 
179 
180  *write_to = value;
181  return 0;
182 }
183 
185  GetBitContext *gbc, int width,
186  const char *name, const int *subscripts,
187  uint32_t *write_to, uint32_t range_min,
188  uint32_t range_max)
189 {
190  int32_t value;
191 
193 
194  av_assert0(width > 0 && width <= 24);
195 
196  if (get_bits_left(gbc) < width) {
197  av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value: bitstream ended.\n");
198  return AVERROR_INVALIDDATA;
199  }
200 
201  value = get_bits_le(gbc, width);
202 
204 
205  if (value < range_min || value > range_max) {
206  av_log(ctx->log_ctx, AV_LOG_ERROR,
207  "%s out of range: "
208  "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n",
209  name, value, range_min, range_max);
210  return AVERROR_INVALIDDATA;
211  }
212 
213  *write_to = value;
214  return 0;
215 }
216 
217 #define HEADER(name) \
218  do { \
219  ff_cbs_trace_header(ctx, name); \
220  } while (0)
221 
222 #define CHECK(call) \
223  do { \
224  int err = (call); \
225  if (err < 0) \
226  return err; \
227  } while (0)
228 
229 #define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name
230 #define FUNC_VP8(rw, name) FUNC_NAME(rw, vp8, name)
231 #define FUNC(name) FUNC_VP8(READWRITE, name)
232 
233 #define SUBSCRIPTS(subs, ...) \
234  (subs > 0 ? ((int[subs + 1]){subs, __VA_ARGS__}) : NULL)
235 
236 #define f(width, name) xf(width, name, 0, )
237 
238 // bool [de|en]coder methods.
239 #define bc_f(width, name) bc_unsigned_subs(width, DEFAULT_PROB, true, name, 0, )
240 #define bc_s(width, name) bc_signed_subs(width, DEFAULT_PROB, name, 0, )
241 #define bc_fs(width, name, subs, ...) \
242  bc_unsigned_subs(width, DEFAULT_PROB, true, name, subs, __VA_ARGS__)
243 #define bc_ss(width, name, subs, ...) \
244  bc_signed_subs(width, DEFAULT_PROB, name, subs, __VA_ARGS__)
245 
246 // bool [de|en]coder methods for boolean value and disable tracing.
247 #define bc_b(name) bc_unsigned_subs(1, DEFAULT_PROB, false, name, 0, )
248 #define bc_b_prob(prob, name) bc_unsigned_subs(1, prob, false, name, 0, )
249 
250 #define READ
251 #define READWRITE read
252 #define RWContext GetBitContext
253 #define CBSVP8BoolCodingRW CBSVP8BoolDecoder
254 
255 #define xf(width, name, subs, ...) \
256  do { \
257  uint32_t value; \
258  CHECK(cbs_vp8_read_unsigned_le(ctx, rw, width, #name, \
259  SUBSCRIPTS(subs, __VA_ARGS__), &value, \
260  0, MAX_UINT_BITS(width))); \
261  current->name = value; \
262  } while (0)
263 
264 #define fixed(width, name, value) \
265  do { \
266  uint32_t fixed_value; \
267  CHECK(cbs_vp8_read_unsigned_le(ctx, rw, width, #name, 0, &fixed_value, \
268  value, value)); \
269  } while (0)
270 
271 #define bc_unsigned_subs(width, prob, enable_trace, name, subs, ...) \
272  do { \
273  uint32_t value; \
274  CHECK(cbs_vp8_bool_decoder_read_unsigned( \
275  ctx, bool_coding_rw, width, prob, #name, \
276  SUBSCRIPTS(subs, __VA_ARGS__), &value, enable_trace)); \
277  current->name = value; \
278  } while (0)
279 
280 #define bc_signed_subs(width, prob, name, subs, ...) \
281  do { \
282  int32_t value; \
283  CHECK(cbs_vp8_bool_decoder_read_signed( \
284  ctx, bool_coding_rw, width, prob, #name, \
285  SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
286  current->name = value; \
287  } while (0)
288 
289 #include "cbs_vp8_syntax_template.c"
290 
292  CodedBitstreamFragment *frag, int header)
293 {
294  int err;
295 
296  if (frag->data_size == 0)
297  return AVERROR_INVALIDDATA;
298 
299  err = ff_cbs_append_unit_data(frag, 0, frag->data, frag->data_size,
300  frag->data_ref);
301  if (err < 0)
302  return err;
303 
304  return 0;
305 }
306 
308  CodedBitstreamUnit *unit)
309 {
311  GetBitContext gbc;
312  CBSVP8BoolDecoder bool_decoder;
313  int err, pos;
314 
315  err = ff_cbs_alloc_unit_content(ctx, unit);
316  if (err < 0)
317  return err;
318  frame = unit->content;
319 
320  // Create GetBitContext for uncompressed header.
321  err = init_get_bits8_le(&gbc, unit->data, unit->data_size);
322  if (err < 0)
323  return err;
324 
325  err = cbs_vp8_read_uncompressed_header(ctx, &gbc, frame);
326  if (err < 0)
327  return err;
328 
329  pos = get_bits_count(&gbc);
330  av_assert0(pos % 8 == 0);
331 
332  // Create boolean decoder for compressed header.
333  err = cbs_vp8_bool_decoder_init(&bool_decoder, &gbc);
334  if (err < 0)
335  return err;
336 
337  err = cbs_vp8_read_compressed_header(ctx, &bool_decoder, frame);
338  if (err < 0)
339  return err;
340 
341  pos = get_bits_count(&gbc);
342  // Position may not be byte-aligned after compressed header; Round up byte
343  // count for accurate data positioning.
344  pos = (pos + 7) / 8;
345  av_assert0(pos <= unit->data_size);
346 
347  frame->data_ref = av_buffer_ref(unit->data_ref);
348  if (!frame->data_ref)
349  return AVERROR(ENOMEM);
350 
351  frame->data = unit->data + pos;
352  frame->data_size = unit->data_size - pos;
353 
354  return 0;
355 }
356 
358  CodedBitstreamUnit *unit, PutBitContext *pbc)
359 {
360  return AVERROR_PATCHWELCOME;
361 }
362 
365 {
366  return AVERROR_PATCHWELCOME;
367 }
368 
372 };
373 
376 
377  .priv_data_size = 0,
378 
379  .unit_types = cbs_vp8_unit_types,
380 
381  .split_fragment = &cbs_vp8_split_fragment,
382  .read_unit = &cbs_vp8_read_unit,
383  .write_unit = &cbs_vp8_write_unit,
384 
385  .assemble_fragment = &cbs_vp8_assemble_fragment,
386 };
cbs_vp8_bool_decoder_read_unsigned
static int cbs_vp8_bool_decoder_read_unsigned(CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width, uint8_t prob, const char *name, const int *subscripts, uint32_t *write_to, bool trace_enable)
Definition: cbs_vp8.c:125
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:695
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
CBSVP8BoolDecoder::range
uint8_t range
Definition: cbs_vp8.c:37
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:107
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
ff_vp8_token_update_probs
const uint8_t ff_vp8_token_update_probs[4][8][3][11]
Definition: vp8data.c:43
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:219
data
const char data[16]
Definition: mxf.c:149
cbs.h
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
cbs_vp8_bool_decoder_read_bool
static int cbs_vp8_bool_decoder_read_bool(CBSVP8BoolDecoder *decoder, const uint8_t prob, uint8_t *output)
Definition: cbs_vp8.c:74
CBSVP8BoolDecoder::gbc
GetBitContext * gbc
Definition: cbs_vp8.c:34
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:70
cbs_vp8_bool_decoder_read_signed
static int cbs_vp8_bool_decoder_read_signed(CodedBitstreamContext *ctx, CBSVP8BoolDecoder *bool_decoder, int width, uint8_t prob, const char *name, const int *subscripts, int32_t *write_to)
Definition: cbs_vp8.c:151
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:331
CBS_UNIT_TYPE_INTERNAL_REF
#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field)
Definition: cbs_internal.h:312
GetBitContext
Definition: get_bits.h:108
CodedBitstreamUnit::data
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
Definition: cbs.h:81
cbs_vp8_bool_decoder_init
static int cbs_vp8_bool_decoder_init(CBSVP8BoolDecoder *decoder, GetBitContext *gbc)
Definition: cbs_vp8.c:43
avassert.h
CodedBitstreamUnitTypeDescriptor
Definition: cbs_internal.h:56
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
ff_cbs_type_vp8
const CodedBitstreamType ff_cbs_type_vp8
Definition: cbs_vp8.c:374
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
CodedBitstreamFragment::data_size
size_t data_size
The number of bytes in the bitstream.
Definition: cbs.h:135
bits
uint8_t bits
Definition: vp3data.h:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
CBSVP8BoolDecoder
Definition: cbs_vp8.c:33
get_bits_le
static unsigned int get_bits_le(GetBitContext *s, int n)
Definition: get_bits.h:356
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ff_cbs_append_unit_data
int ff_cbs_append_unit_data(CodedBitstreamFragment *frag, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, AVBufferRef *data_buf)
Add a new unit to a fragment with the given data bitstream.
Definition: cbs.c:850
cbs_internal.h
CodedBitstreamType::codec_id
enum AVCodecID codec_id
Definition: cbs_internal.h:103
PutBitContext
Definition: put_bits.h:50
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
cbs_vp8_assemble_fragment
static int cbs_vp8_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Definition: cbs_vp8.c:363
CodedBitstreamUnit::data_size
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).
Definition: cbs.h:86
cbs_vp8_unit_types
static const CodedBitstreamUnitTypeDescriptor cbs_vp8_unit_types[]
Definition: cbs_vp8.c:369
VP8RawFrame
Definition: cbs_vp8.h:125
CodedBitstreamFragment::data
uint8_t * data
Pointer to the bitstream form of this fragment.
Definition: cbs.h:128
header
static const uint8_t header[24]
Definition: sdr2.c:68
split
static char * split(char *message, char delim)
Definition: af_channelmap.c:89
CodedBitstreamType
Definition: cbs_internal.h:102
CodedBitstreamUnit::data_ref
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition: cbs.h:98
cbs_vp8_read_unsigned_le
static int cbs_vp8_read_unsigned_le(CodedBitstreamContext *ctx, GetBitContext *gbc, int width, const char *name, const int *subscripts, uint32_t *write_to, uint32_t range_min, uint32_t range_max)
Definition: cbs_vp8.c:184
cbs_vp8.h
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
cbs_vp8_read_unit
static int cbs_vp8_read_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Definition: cbs_vp8.c:307
CBS_UNIT_TYPE_END_OF_LIST
#define CBS_UNIT_TYPE_END_OF_LIST
Definition: cbs_internal.h:335
CBSVP8BoolDecoder::count
uint8_t count
Definition: cbs_vp8.c:39
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:325
pos
unsigned int pos
Definition: spdifenc.c:414
ff_cbs_alloc_unit_content
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
Allocate a new internal content buffer matching the type of the unit.
Definition: cbs.c:923
cbs_vp8_write_unit
static int cbs_vp8_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
Definition: cbs_vp8.c:357
cbs_vp8_split_fragment
static int cbs_vp8_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
Definition: cbs_vp8.c:291
cbs_vp8_bool_decoder_read_literal
static int cbs_vp8_bool_decoder_read_literal(CBSVP8BoolDecoder *decoder, const uint8_t prob, uint32_t num_bits, uint32_t *output)
Definition: cbs_vp8.c:102
init_get_bits8_le
static int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer, int byte_size)
Definition: get_bits.h:553
cbs_vp8_bool_decoder_fill_value
static bool cbs_vp8_bool_decoder_fill_value(CBSVP8BoolDecoder *decoder)
Definition: cbs_vp8.c:57
cbs_vp8_syntax_template.c
int32_t
int32_t
Definition: audioconvert.c:56
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
CodedBitstreamFragment::data_ref
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition: cbs.h:145
width
#define width
Definition: dsp.h:85
CBSVP8BoolDecoder::value
uint8_t value
Definition: cbs_vp8.c:36
CBS_TRACE_READ_START
#define CBS_TRACE_READ_START()
Definition: cbs_internal.h:208
CBS_TRACE_READ_END
#define CBS_TRACE_READ_END()
Definition: cbs_internal.h:216