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  int width, const char *name,
186  const int *subscripts, uint32_t *write_to)
187 {
188  int32_t value;
189 
191 
192  av_assert0(width > 0 && width <= 24);
193 
194  if (get_bits_left(gbc) < width) {
195  av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value: bitstream ended.\n");
196  return AVERROR_INVALIDDATA;
197  }
198 
199  value = get_bits_le(gbc, width);
200 
202 
203  *write_to = value;
204  return 0;
205 }
206 
207 #define HEADER(name) \
208  do { \
209  ff_cbs_trace_header(ctx, name); \
210  } while (0)
211 
212 #define CHECK(call) \
213  do { \
214  int err = (call); \
215  if (err < 0) \
216  return err; \
217  } while (0)
218 
219 #define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name
220 #define FUNC_VP8(rw, name) FUNC_NAME(rw, vp8, name)
221 #define FUNC(name) FUNC_VP8(READWRITE, name)
222 
223 #define SUBSCRIPTS(subs, ...) \
224  (subs > 0 ? ((int[subs + 1]){subs, __VA_ARGS__}) : NULL)
225 
226 #define f(width, name) xf(width, name, 0, )
227 
228 // bool [de|en]coder methods.
229 #define bc_f(width, name) bc_unsigned_subs(width, DEFAULT_PROB, true, name, 0, )
230 #define bc_s(width, name) bc_signed_subs(width, DEFAULT_PROB, name, 0, )
231 #define bc_fs(width, name, subs, ...) \
232  bc_unsigned_subs(width, DEFAULT_PROB, true, name, subs, __VA_ARGS__)
233 #define bc_ss(width, name, subs, ...) \
234  bc_signed_subs(width, DEFAULT_PROB, name, subs, __VA_ARGS__)
235 
236 // bool [de|en]coder methods for boolean value and disable tracing.
237 #define bc_b(name) bc_unsigned_subs(1, DEFAULT_PROB, false, name, 0, )
238 #define bc_b_prob(prob, name) bc_unsigned_subs(1, prob, false, name, 0, )
239 
240 #define READ
241 #define READWRITE read
242 #define RWContext GetBitContext
243 #define CBSVP8BoolCodingRW CBSVP8BoolDecoder
244 
245 #define xf(width, name, subs, ...) \
246  do { \
247  uint32_t value; \
248  CHECK(cbs_vp8_read_unsigned_le(ctx, rw, width, #name, \
249  SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
250  current->name = value; \
251  } while (0)
252 
253 #define fixed(width, name, value) \
254  do { \
255  uint32_t fixed_value; \
256  CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, 0, &fixed_value, \
257  value, value)); \
258  } while (0)
259 
260 #define bc_unsigned_subs(width, prob, enable_trace, name, subs, ...) \
261  do { \
262  uint32_t value; \
263  CHECK(cbs_vp8_bool_decoder_read_unsigned( \
264  ctx, bool_coding_rw, width, prob, #name, \
265  SUBSCRIPTS(subs, __VA_ARGS__), &value, enable_trace)); \
266  current->name = value; \
267  } while (0)
268 
269 #define bc_signed_subs(width, prob, name, subs, ...) \
270  do { \
271  int32_t value; \
272  CHECK(cbs_vp8_bool_decoder_read_signed( \
273  ctx, bool_coding_rw, width, prob, #name, \
274  SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
275  current->name = value; \
276  } while (0)
277 
278 #include "cbs_vp8_syntax_template.c"
279 
281  CodedBitstreamFragment *frag, int header)
282 {
283  int err;
284 
285  if (frag->data_size == 0)
286  return AVERROR_INVALIDDATA;
287 
288  err = ff_cbs_append_unit_data(frag, 0, frag->data, frag->data_size,
289  frag->data_ref);
290  if (err < 0)
291  return err;
292 
293  return 0;
294 }
295 
297  CodedBitstreamUnit *unit)
298 {
300  GetBitContext gbc;
301  CBSVP8BoolDecoder bool_decoder;
302  int err, pos;
303 
304  err = ff_cbs_alloc_unit_content(ctx, unit);
305  if (err < 0)
306  return err;
307  frame = unit->content;
308 
309  // Create GetBitContext for uncompressed header.
310  err = init_get_bits8_le(&gbc, unit->data, unit->data_size);
311  if (err < 0)
312  return err;
313 
314  err = cbs_vp8_read_uncompressed_header(ctx, &gbc, frame);
315  if (err < 0)
316  return err;
317 
318  pos = get_bits_count(&gbc);
319  av_assert0(pos % 8 == 0);
320 
321  // Create boolean decoder for compressed header.
322  err = cbs_vp8_bool_decoder_init(&bool_decoder, &gbc);
323  if (err < 0)
324  return err;
325 
326  err = cbs_vp8_read_compressed_header(ctx, &bool_decoder, frame);
327  if (err < 0)
328  return err;
329 
330  pos = get_bits_count(&gbc);
331  pos /= 8;
332  av_assert0(pos <= unit->data_size);
333 
334  frame->data_ref = av_buffer_ref(unit->data_ref);
335  if (!frame->data_ref)
336  return AVERROR(ENOMEM);
337 
338  frame->data = unit->data + pos;
339  frame->data_size = unit->data_size - pos;
340 
341  return 0;
342 }
343 
345  CodedBitstreamUnit *unit, PutBitContext *pbc)
346 {
347  return AVERROR_PATCHWELCOME;
348 }
349 
352 {
353  return AVERROR_PATCHWELCOME;
354 }
355 
359 };
360 
363 
364  .priv_data_size = 0,
365 
366  .unit_types = cbs_vp8_unit_types,
367 
368  .split_fragment = &cbs_vp8_split_fragment,
369  .read_unit = &cbs_vp8_read_unit,
370  .write_unit = &cbs_vp8_write_unit,
371 
372  .assemble_fragment = &cbs_vp8_assemble_fragment,
373 };
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:694
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:148
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
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
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:180
ff_cbs_type_vp8
const CodedBitstreamType ff_cbs_type_vp8
Definition: cbs_vp8.c:361
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
width
#define width
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:48
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:849
cbs_internal.h
CodedBitstreamType::codec_id
enum AVCodecID codec_id
Definition: cbs_internal.h:103
PutBitContext
Definition: put_bits.h:50
frame
static AVFrame * frame
Definition: demux_decode.c:54
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:350
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:356
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:67
split
static char * split(char *message, char delim)
Definition: af_channelmap.c:80
CodedBitstreamType
Definition: cbs_internal.h:102
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)
Definition: cbs_vp8.c:184
CodedBitstreamUnit::data_ref
AVBufferRef * data_ref
A reference to the buffer containing data.
Definition: cbs.h:98
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:296
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
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:325
pos
unsigned int pos
Definition: spdifenc.c:413
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:922
cbs_vp8_write_unit
static int cbs_vp8_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
Definition: cbs_vp8.c:344
cbs_vp8_split_fragment
static int cbs_vp8_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
Definition: cbs_vp8.c:280
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
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