History

lavc: add standalone cached bitstream reader

The cached bitstream reader was originally written by Alexandra Hájková for Libav, with significant input from Kostya Shishkov and Luca Barbato. It was then committed to FFmpeg in ca079b09549, by merging it with the implementation of the current bitstream reader. This merge makes the code of get_bits.h significantly harder to read, since it now contains two different bitstream readers interleaved with #ifdefs. Additionally, the code was committed without proper authorship attribution. This commit re-adds the cached bitstream reader as a standalone header, as it was originally developed. It will be made useful in following commits. Integration by Anton Khirnov.

Alexandra Hájková committed 10 years ago

Commit 8fe551e1 parent 4b2b9a61 file · +529 −0Browse files

Unified · Split

libavcodec/bitstream.h+529−0
@@ -0,0 +1,529 @@
1+/*
2+ * Copyright (c) 2016 Alexandra Hájková
3+ *
4+ * This file is part of FFmpeg.
5+ *
6+ * FFmpeg is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * FFmpeg is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with FFmpeg; if not, write to the Free Software
18+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+ */
20+
21+/**
22+ * @file
23+ * bitstream reader API header.
24+ */
25+
26+#ifndef AVCODEC_BITSTREAM_H
27+#define AVCODEC_BITSTREAM_H
28+
29+#include <stdint.h>
30+
31+#include "config.h"
32+
33+#include "libavutil/avassert.h"
34+#include "libavutil/common.h"
35+#include "libavutil/intreadwrite.h"
36+#include "libavutil/log.h"
37+
38+#include "mathops.h"
39+#include "vlc.h"
40+
41+#ifndef UNCHECKED_BITSTREAM_READER
42+#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
43+#endif
44+
45+typedef struct BitstreamContext {
46+ uint64_t bits; // stores bits read from the buffer
47+ const uint8_t *buffer, *buffer_end;
48+ const uint8_t *ptr; // pointer to the position inside a buffer
49+ unsigned bits_valid; // number of bits left in bits field
50+ unsigned size_in_bits;
51+} BitstreamContext;
52+
53+/**
54+ * @return
55+ * - 0 on successful refill
56+ * - a negative number when bitstream end is hit
57+ *
58+ * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled.
59+ */
60+static inline int bits_priv_refill_64(BitstreamContext *bc)
61+{
62+#if !UNCHECKED_BITSTREAM_READER
63+ if (bc->ptr >= bc->buffer_end)
64+ return -1;
65+#endif
66+
67+#ifdef BITSTREAM_READER_LE
68+ bc->bits = AV_RL64(bc->ptr);
69+#else
70+ bc->bits = AV_RB64(bc->ptr);
71+#endif
72+ bc->ptr += 8;
73+ bc->bits_valid = 64;
74+
75+ return 0;
76+}
77+
78+/**
79+ * @return
80+ * - 0 on successful refill
81+ * - a negative number when bitstream end is hit
82+ *
83+ * Always succeeds when UNCHECKED_BITSTREAM_READER is enabled.
84+ */
85+static inline int bits_priv_refill_32(BitstreamContext *bc)
86+{
87+#if !UNCHECKED_BITSTREAM_READER
88+ if (bc->ptr >= bc->buffer_end)
89+ return -1;
90+#endif
91+
92+#ifdef BITSTREAM_READER_LE
93+ bc->bits |= (uint64_t)AV_RL32(bc->ptr) << bc->bits_valid;
94+#else
95+ bc->bits |= (uint64_t)AV_RB32(bc->ptr) << (32 - bc->bits_valid);
96+#endif
97+ bc->ptr += 4;
98+ bc->bits_valid += 32;
99+
100+ return 0;
101+}
102+
103+/**
104+ * Initialize BitstreamContext.
105+ * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
106+ * larger than the actual read bits because some optimized bitstream
107+ * readers read 32 or 64 bits at once and could read over the end
108+ * @param bit_size the size of the buffer in bits
109+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
110+ */
111+static inline int bits_init(BitstreamContext *bc, const uint8_t *buffer,
112+ unsigned int bit_size)
113+{
114+ unsigned int buffer_size;
115+
116+ if (bit_size > INT_MAX - 7 || !buffer) {
117+ bc->buffer = NULL;
118+ bc->ptr = NULL;
119+ bc->bits_valid = 0;
120+ return AVERROR_INVALIDDATA;
121+ }
122+
123+ buffer_size = (bit_size + 7) >> 3;
124+
125+ bc->buffer = buffer;
126+ bc->buffer_end = buffer + buffer_size;
127+ bc->ptr = bc->buffer;
128+ bc->size_in_bits = bit_size;
129+ bc->bits_valid = 0;
130+ bc->bits = 0;
131+
132+ bits_priv_refill_64(bc);
133+
134+ return 0;
135+}
136+
137+/**
138+ * Initialize BitstreamContext.
139+ * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
140+ * larger than the actual read bits because some optimized bitstream
141+ * readers read 32 or 64 bits at once and could read over the end
142+ * @param byte_size the size of the buffer in bytes
143+ * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow
144+ */
145+static inline int bits_init8(BitstreamContext *bc, const uint8_t *buffer,
146+ unsigned int byte_size)
147+{
148+ if (byte_size > INT_MAX / 8)
149+ return AVERROR_INVALIDDATA;
150+ return bits_init(bc, buffer, byte_size * 8);
151+}
152+
153+/**
154+ * Return number of bits already read.
155+ */
156+static inline int bits_tell(const BitstreamContext *bc)
157+{
158+ return (bc->ptr - bc->buffer) * 8 - bc->bits_valid;
159+}
160+
161+/**
162+ * Return buffer size in bits.
163+ */
164+static inline int bits_size(const BitstreamContext *bc)
165+{
166+ return bc->size_in_bits;
167+}
168+
169+/**
170+ * Return the number of the bits left in a buffer.
171+ */
172+static inline int bits_left(const BitstreamContext *bc)
173+{
174+ return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_valid;
175+}
176+
177+static inline uint64_t bits_priv_val_show(BitstreamContext *bc, unsigned int n)
178+{
179+ av_assert2(n > 0 && n <= 64);
180+
181+#ifdef BITSTREAM_READER_LE
182+ return bc->bits & (UINT64_MAX >> (64 - n));
183+#else
184+ return bc->bits >> (64 - n);
185+#endif
186+}
187+
188+static inline void bits_priv_skip_remaining(BitstreamContext *bc, unsigned int n)
189+{
190+#ifdef BITSTREAM_READER_LE
191+ bc->bits >>= n;
192+#else
193+ bc->bits <<= n;
194+#endif
195+ bc->bits_valid -= n;
196+}
197+
198+static inline uint64_t bits_priv_val_get(BitstreamContext *bc, unsigned int n)
199+{
200+ uint64_t ret;
201+
202+ av_assert2(n > 0 && n < 64);
203+
204+ ret = bits_priv_val_show(bc, n);
205+ bits_priv_skip_remaining(bc, n);
206+
207+ return ret;
208+}
209+
210+/**
211+ * Return one bit from the buffer.
212+ */
213+static inline unsigned int bits_read_bit(BitstreamContext *bc)
214+{
215+ if (!bc->bits_valid && bits_priv_refill_64(bc) < 0)
216+ return 0;
217+
218+ return bits_priv_val_get(bc, 1);
219+}
220+
221+/**
222+ * Return n bits from the buffer, n has to be in the 1-32 range.
223+ * May be faster than bits_read() when n is not a compile-time constant and is
224+ * known to be non-zero;
225+ */
226+static inline uint32_t bits_read_nz(BitstreamContext *bc, unsigned int n)
227+{
228+ av_assert2(n > 0 && n <= 32);
229+
230+ if (n > bc->bits_valid) {
231+ if (bits_priv_refill_32(bc) < 0)
232+ bc->bits_valid = n;
233+ }
234+
235+ return bits_priv_val_get(bc, n);
236+}
237+
238+/**
239+ * Return n bits from the buffer, n has to be in the 0-32 range.
240+ */
241+static inline uint32_t bits_read(BitstreamContext *bc, unsigned int n)
242+{
243+ av_assert2(n <= 32);
244+
245+ if (!n)
246+ return 0;
247+
248+ return bits_read_nz(bc, n);
249+}
250+
251+/**
252+ * Return n bits from the buffer, n has to be in the 0-63 range.
253+ */
254+static inline uint64_t bits_read_63(BitstreamContext *bc, unsigned int n)
255+{
256+ uint64_t ret = 0;
257+ unsigned left = 0;
258+
259+ av_assert2(n <= 63);
260+
261+ if (!n)
262+ return 0;
263+
264+ if (n > bc->bits_valid) {
265+ left = bc->bits_valid;
266+ n -= left;
267+
268+ if (left)
269+ ret = bits_priv_val_get(bc, left);
270+
271+ if (bits_priv_refill_64(bc) < 0)
272+ bc->bits_valid = n;
273+
274+ }
275+
276+#ifdef BITSTREAM_READER_LE
277+ ret = bits_priv_val_get(bc, n) << left | ret;
278+#else
279+ ret = bits_priv_val_get(bc, n) | ret << n;
280+#endif
281+
282+ return ret;
283+}
284+
285+/**
286+ * Return n bits from the buffer, n has to be in the 0-64 range.
287+ */
288+static inline uint64_t bits_read_64(BitstreamContext *bc, unsigned int n)
289+{
290+ av_assert2(n <= 64);
291+
292+ if (n == 64) {
293+ uint64_t ret = bits_read_63(bc, 63);
294+#ifdef BITSTREAM_READER_LE
295+ return ret | ((uint64_t)bits_read_bit(bc) << 63);
296+#else
297+ return (ret << 1) | (uint64_t)bits_read_bit(bc);
298+#endif
299+ }
300+ return bits_read_63(bc, n);
301+}
302+
303+/**
304+ * Return n bits from the buffer as a signed integer.
305+ * n has to be in the 0-32 range.
306+ */
307+static inline int32_t bits_read_signed(BitstreamContext *bc, unsigned int n)
308+{
309+ return sign_extend(bits_read(bc, n), n);
310+}
311+
312+/**
313+ * Return n bits from the buffer but do not change the buffer state.
314+ * n has to be in the 1-32 range. May
315+ */
316+static inline uint32_t bits_peek_nz(BitstreamContext *bc, unsigned int n)
317+{
318+ av_assert2(n > 0 && n <= 32);
319+
320+ if (n > bc->bits_valid)
321+ bits_priv_refill_32(bc);
322+
323+ return bits_priv_val_show(bc, n);
324+}
325+
326+/**
327+ * Return n bits from the buffer but do not change the buffer state.
328+ * n has to be in the 0-32 range.
329+ */
330+static inline uint32_t bits_peek(BitstreamContext *bc, unsigned int n)
331+{
332+ av_assert2(n <= 32);
333+
334+ if (!n)
335+ return 0;
336+
337+ return bits_peek_nz(bc, n);
338+}
339+
340+/**
341+ * Return n bits from the buffer as a signed integer,
342+ * do not change the buffer state.
343+ * n has to be in the 0-32 range.
344+ */
345+static inline int bits_peek_signed(BitstreamContext *bc, unsigned int n)
346+{
347+ return sign_extend(bits_peek(bc, n), n);
348+}
349+
350+/**
351+ * Skip n bits in the buffer.
352+ */
353+static inline void bits_skip(BitstreamContext *bc, unsigned int n)
354+{
355+ if (n < bc->bits_valid)
356+ bits_priv_skip_remaining(bc, n);
357+ else {
358+ n -= bc->bits_valid;
359+ bc->bits = 0;
360+ bc->bits_valid = 0;
361+
362+ if (n >= 64) {
363+ unsigned int skip = n / 8;
364+
365+ n -= skip * 8;
366+ bc->ptr += skip;
367+ }
368+ bits_priv_refill_64(bc);
369+ if (n)
370+ bits_priv_skip_remaining(bc, n);
371+ }
372+}
373+
374+/**
375+ * Seek to the given bit position.
376+ */
377+static inline void bits_seek(BitstreamContext *bc, unsigned pos)
378+{
379+ bc->ptr = bc->buffer;
380+ bc->bits = 0;
381+ bc->bits_valid = 0;
382+
383+ bits_skip(bc, pos);
384+}
385+
386+/**
387+ * Skip bits to a byte boundary.
388+ */
389+static inline const uint8_t *bits_align(BitstreamContext *bc)
390+{
391+ unsigned int n = -bits_tell(bc) & 7;
392+ if (n)
393+ bits_skip(bc, n);
394+ return bc->buffer + (bits_tell(bc) >> 3);
395+}
396+
397+/**
398+ * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB).
399+ * If MSB not set it is negative.
400+ * @param n length in bits
401+ */
402+static inline int bits_read_xbits(BitstreamContext *bc, unsigned int n)
403+{
404+ int32_t cache = bits_peek(bc, 32);
405+ int sign = ~cache >> 31;
406+ bits_priv_skip_remaining(bc, n);
407+
408+ return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign;
409+}
410+
411+/**
412+ * Return decoded truncated unary code for the values 0, 1, 2.
413+ */
414+static inline int bits_decode012(BitstreamContext *bc)
415+{
416+ if (!bits_read_bit(bc))
417+ return 0;
418+ else
419+ return bits_read_bit(bc) + 1;
420+}
421+
422+/**
423+ * Return decoded truncated unary code for the values 2, 1, 0.
424+ */
425+static inline int bits_decode210(BitstreamContext *bc)
426+{
427+ if (bits_read_bit(bc))
428+ return 0;
429+ else
430+ return 2 - bits_read_bit(bc);
431+}
432+
433+/* Read sign bit and flip the sign of the provided value accordingly. */
434+static inline int bits_apply_sign(BitstreamContext *bc, int val)
435+{
436+ int sign = bits_read_signed(bc, 1);
437+ return (val ^ sign) - sign;
438+}
439+
440+static inline int bits_skip_1stop_8data(BitstreamContext *s)
441+{
442+ if (bits_left(s) <= 0)
443+ return AVERROR_INVALIDDATA;
444+
445+ while (bits_read_bit(s)) {
446+ bits_skip(s, 8);
447+ if (bits_left(s) <= 0)
448+ return AVERROR_INVALIDDATA;
449+ }
450+
451+ return 0;
452+}
453+
454+/**
455+ * Return the LUT element for the given bitstream configuration.
456+ */
457+static inline int bits_priv_set_idx(BitstreamContext *bc, int code, int *n, int *nb_bits,
458+ const VLCElem *table)
459+{
460+ unsigned idx;
461+
462+ *nb_bits = -*n;
463+ idx = bits_peek(bc, *nb_bits) + code;
464+ *n = table[idx].len;
465+
466+ return table[idx].sym;
467+}
468+
469+/**
470+ * Parse a vlc code.
471+ * @param bits is the number of bits which will be read at once, must be
472+ * identical to nb_bits in init_vlc()
473+ * @param max_depth is the number of times bits bits must be read to completely
474+ * read the longest vlc code
475+ * = (max_vlc_length + bits - 1) / bits
476+ * If the vlc code is invalid and max_depth=1, then no bits will be removed.
477+ * If the vlc code is invalid and max_depth>1, then the number of bits removed
478+ * is undefined.
479+ */
480+static inline int bits_read_vlc(BitstreamContext *bc, const VLCElem *table,
481+ int bits, int max_depth)
482+{
483+ int nb_bits;
484+ unsigned idx = bits_peek(bc, bits);
485+ int code = table[idx].sym;
486+ int n = table[idx].len;
487+
488+ if (max_depth > 1 && n < 0) {
489+ bits_priv_skip_remaining(bc, bits);
490+ code = bits_priv_set_idx(bc, code, &n, &nb_bits, table);
491+ if (max_depth > 2 && n < 0) {
492+ bits_priv_skip_remaining(bc, nb_bits);
493+ code = bits_priv_set_idx(bc, code, &n, &nb_bits, table);
494+ }
495+ }
496+ bits_priv_skip_remaining(bc, n);
497+
498+ return code;
499+}
500+
501+#define BITS_RL_VLC(level, run, bc, table, bits, max_depth) \
502+ do { \
503+ int n, nb_bits; \
504+ unsigned int index = bits_peek(bc, bits); \
505+ level = table[index].level; \
506+ n = table[index].len; \
507+ \
508+ if (max_depth > 1 && n < 0) { \
509+ bits_skip(bc, bits); \
510+ \
511+ nb_bits = -n; \
512+ \
513+ index = bits_peek(bc, nb_bits) + level; \
514+ level = table[index].level; \
515+ n = table[index].len; \
516+ if (max_depth > 2 && n < 0) { \
517+ bits_skip(bc, nb_bits); \
518+ nb_bits = -n; \
519+ \
520+ index = bits_peek(bc, nb_bits) + level; \
521+ level = table[index].level; \
522+ n = table[index].len; \
523+ } \
524+ } \
525+ run = table[index].run; \
526+ bits_skip(bc, n); \
527+ } while (0)
528+
529+#endif /* AVCODEC_BITSTREAM_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t