1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
/*
* Copyright (c) 2016 Alexandra Hájková
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream reader API header.
*/
#ifndef AVCODEC_BITSTREAM_H
#define AVCODEC_BITSTREAM_H
#include <stdint.h>
#include "config.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "mathops.h"
#include "vlc.h"
#ifndef UNCHECKED_BITSTREAM_READER
#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
#endif
typedef struct BitstreamContext {
uint64_t bits; // stores bits read from the buffer
const uint8_t *buffer, *buffer_end;
const uint8_t *ptr; // pointer to the position inside a buffer
unsigned bits_left; // number of bits left in bits field
unsigned size_in_bits;
} BitstreamContext;
/**
* Return number of bits already read.
*/
static inline int bitstream_tell(const BitstreamContext *bc)
{
return (bc->ptr - bc->buffer) * 8 - bc->bits_left;
}
/**
* Return buffer size in bits.
*/
static inline int bitstream_tell_size(const BitstreamContext *bc)
{
return bc->size_in_bits;
}
/**
* Return the number of the bits left in a buffer.
*/
static inline int bitstream_bits_left(const BitstreamContext *bc)
{
return (bc->buffer - bc->ptr) * 8 + bc->size_in_bits + bc->bits_left;
}
/* Unwind the cache so a refill_32 can fill it again. */
static inline void bitstream_unwind(BitstreamContext *bc)
{
int unwind = 4;
int unwind_bits = unwind * 8;
if (bc->bits_left < unwind_bits)
return;
bc->bits >>= unwind_bits;
bc->bits <<= unwind_bits;
bc->bits_left -= unwind_bits;
bc->ptr -= unwind;
}
/* Unget up to 32 bits. */
static inline void bitstream_unget(BitstreamContext *bc, uint64_t value,
size_t amount)
{
size_t cache_size = sizeof(bc->bits) * 8;
if (bc->bits_left + amount > cache_size)
bitstream_unwind(bc);
bc->bits = (bc->bits >> amount) | (value << (cache_size - amount));
bc->bits_left += amount;
}
#define BITSTREAM_LE
#include "bitstream_template.h"
#undef BITSTREAM_LE
#include "bitstream_template.h"
#define bitstream_init bitstream_init_be
#define bitstream_init8 bitstream_init8_be
#define bitstream_read_bit bitstream_read_bit_be
#define bitstream_read_63 bitstream_read_63_be
#define bitstream_read bitstream_read_be
#define bitstream_read_signed bitstream_read_signed_be
#define bitstream_peek bitstream_peek_be
#define bitstream_peek_signed bitstream_peek_signed_be
#define bitstream_skip bitstream_skip_be
#define bitstream_skip_cache bitstream_skip_cache_be
#define bitstream_seek bitstream_seek_be
#define bitstream_align bitstream_align_be
#define bitstream_read_xbits bitstream_read_xbits_be
#define bitstream_decode012 bitstream_decode012_be
#define bitstream_decode210 bitstream_decode210_be
#define bitstream_apply_sign bitstream_apply_sign_be
#define bitstream_read_vlc bitstream_read_vlc_be
#define BITSTREAM_RL_VLC(level, run, bc, table, bits, max_depth) \
do { \
int n, nb_bits; \
unsigned int index = bitstream_peek(bc, bits); \
level = table[index].level; \
n = table[index].len; \
\
if (max_depth > 1 && n < 0) { \
bitstream_skip(bc, bits); \
\
nb_bits = -n; \
\
index = bitstream_peek(bc, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
if (max_depth > 2 && n < 0) { \
bitstream_skip(bc, nb_bits); \
nb_bits = -n; \
\
index = bitstream_peek(bc, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
} \
} \
run = table[index].run; \
bitstream_skip(bc, n); \
} while (0)
#endif /* AVCODEC_BITSTREAM_H */
|