put_bits.h
Go to the documentation of this file.
1 /*
2  * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
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 writer API
24  */
25 
26 #ifndef AVCODEC_PUT_BITS_H
27 #define AVCODEC_PUT_BITS_H
28 
29 #include <stdint.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 
33 #include "libavutil/bswap.h"
34 #include "libavutil/common.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/log.h"
37 #include "libavutil/avassert.h"
38 #include "mathops.h"
39 #include "config.h"
40 
41 typedef struct PutBitContext {
42  uint32_t bit_buf;
43  int bit_left;
47 
48 /**
49  * Initialize the PutBitContext s.
50  *
51  * @param buffer the buffer where to put bits
52  * @param buffer_size the size in bytes of buffer
53  */
54 static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
55  int buffer_size)
56 {
57  if (buffer_size < 0) {
58  buffer_size = 0;
59  buffer = NULL;
60  }
61 
62  s->size_in_bits = 8 * buffer_size;
63  s->buf = buffer;
64  s->buf_end = s->buf + buffer_size;
65  s->buf_ptr = s->buf;
66  s->bit_left = 32;
67  s->bit_buf = 0;
68 }
69 
70 /**
71  * @return the total number of bits written to the bitstream.
72  */
73 static inline int put_bits_count(PutBitContext *s)
74 {
75  return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
76 }
77 
78 /**
79  * Pad the end of the output stream with zeros.
80  */
81 static inline void flush_put_bits(PutBitContext *s)
82 {
83 #ifndef BITSTREAM_WRITER_LE
84  if (s->bit_left < 32)
85  s->bit_buf <<= s->bit_left;
86 #endif
87  while (s->bit_left < 32) {
88  /* XXX: should test end of buffer */
89 #ifdef BITSTREAM_WRITER_LE
90  *s->buf_ptr++ = s->bit_buf;
91  s->bit_buf >>= 8;
92 #else
93  *s->buf_ptr++ = s->bit_buf >> 24;
94  s->bit_buf <<= 8;
95 #endif
96  s->bit_left += 8;
97  }
98  s->bit_left = 32;
99  s->bit_buf = 0;
100 }
101 
102 #ifdef BITSTREAM_WRITER_LE
103 #define avpriv_align_put_bits align_put_bits_unsupported_here
104 #define avpriv_put_string ff_put_string_unsupported_here
105 #define avpriv_copy_bits avpriv_copy_bits_unsupported_here
106 #else
107 /**
108  * Pad the bitstream with zeros up to the next byte boundary.
109  */
111 
112 /**
113  * Put the string string in the bitstream.
114  *
115  * @param terminate_string 0-terminates the written string if value is 1
116  */
117 void avpriv_put_string(PutBitContext *pb, const char *string,
118  int terminate_string);
119 
120 /**
121  * Copy the content of src to the bitstream.
122  *
123  * @param length the number of bits of src to copy
124  */
125 void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
126 #endif
127 
128 /**
129  * Write up to 31 bits into a bitstream.
130  * Use put_bits32 to write 32 bits.
131  */
132 static inline void put_bits(PutBitContext *s, int n, unsigned int value)
133 {
134  unsigned int bit_buf;
135  int bit_left;
136 
137  av_assert2(n <= 31 && value < (1U << n));
138 
139  bit_buf = s->bit_buf;
140  bit_left = s->bit_left;
141 
142  /* XXX: optimize */
143 #ifdef BITSTREAM_WRITER_LE
144  bit_buf |= value << (32 - bit_left);
145  if (n >= bit_left) {
146  av_assert2(s->buf_ptr+3<s->buf_end);
147  AV_WL32(s->buf_ptr, bit_buf);
148  s->buf_ptr += 4;
149  bit_buf = (bit_left == 32) ? 0 : value >> bit_left;
150  bit_left += 32;
151  }
152  bit_left -= n;
153 #else
154  if (n < bit_left) {
155  bit_buf = (bit_buf << n) | value;
156  bit_left -= n;
157  } else {
158  bit_buf <<= bit_left;
159  bit_buf |= value >> (n - bit_left);
160  av_assert2(s->buf_ptr+3<s->buf_end);
161  AV_WB32(s->buf_ptr, bit_buf);
162  s->buf_ptr += 4;
163  bit_left += 32 - n;
164  bit_buf = value;
165  }
166 #endif
167 
168  s->bit_buf = bit_buf;
169  s->bit_left = bit_left;
170 }
171 
172 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
173 {
174  av_assert2(n >= 0 && n <= 31);
175 
176  put_bits(pb, n, value & ((1 << n) - 1));
177 }
178 
179 /**
180  * Write exactly 32 bits into a bitstream.
181  */
182 static void av_unused put_bits32(PutBitContext *s, uint32_t value)
183 {
184  int lo = value & 0xffff;
185  int hi = value >> 16;
186 #ifdef BITSTREAM_WRITER_LE
187  put_bits(s, 16, lo);
188  put_bits(s, 16, hi);
189 #else
190  put_bits(s, 16, hi);
191  put_bits(s, 16, lo);
192 #endif
193 }
194 
195 /**
196  * Return the pointer to the byte where the bitstream writer will put
197  * the next bit.
198  */
200 {
201  return s->buf_ptr;
202 }
203 
204 /**
205  * Skip the given number of bytes.
206  * PutBitContext must be flushed & aligned to a byte boundary before calling this.
207  */
208 static inline void skip_put_bytes(PutBitContext *s, int n)
209 {
210  av_assert2((put_bits_count(s) & 7) == 0);
211  av_assert2(s->bit_left == 32);
212  s->buf_ptr += n;
213 }
214 
215 /**
216  * Skip the given number of bits.
217  * Must only be used if the actual values in the bitstream do not matter.
218  * If n is 0 the behavior is undefined.
219  */
220 static inline void skip_put_bits(PutBitContext *s, int n)
221 {
222  s->bit_left -= n;
223  s->buf_ptr -= 4 * (s->bit_left >> 5);
224  s->bit_left &= 31;
225 }
226 
227 /**
228  * Change the end of the buffer.
229  *
230  * @param size the new size in bytes of the buffer where to put bits
231  */
232 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
233 {
234  s->buf_end = s->buf + size;
235 }
236 
237 #endif /* AVCODEC_PUT_BITS_H */
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:182
void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string)
Put the string string in the bitstream.
Definition: bitstream.c:51
const char * s
Definition: avisynth_c.h:668
static void put_sbits(PutBitContext *pb, int n, int32_t value)
Definition: put_bits.h:172
static void skip_put_bits(PutBitContext *s, int n)
Skip the given number of bits.
Definition: put_bits.h:220
struct PutBitContext PutBitContext
#define AV_WB32(p, darg)
Definition: intreadwrite.h:265
#define AV_WL32(p, darg)
Definition: intreadwrite.h:282
uint8_t
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
#define U(x)
int size_in_bits
Definition: put_bits.h:45
static uint8_t * put_bits_ptr(PutBitContext *s)
Return the pointer to the byte where the bitstream writer will put the next bit.
Definition: put_bits.h:199
uint8_t * buf
Definition: put_bits.h:44
simple assert() macros that are a bit more flexible than ISO C assert().
static void put_bits(PutBitContext *s, int n, unsigned int value)
Write up to 31 bits into a bitstream.
Definition: put_bits.h:132
int size
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:73
static void skip_put_bytes(PutBitContext *s, int n)
Skip the given number of bytes.
Definition: put_bits.h:208
int32_t
static void set_put_bits_buffer_size(PutBitContext *s, int size)
Change the end of the buffer.
Definition: put_bits.h:232
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
int bit_left
Definition: put_bits.h:43
uint8_t * buf_end
Definition: put_bits.h:44
double value
Definition: eval.c:82
uint8_t * buf_ptr
Definition: put_bits.h:44
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
Copy the content of src to the bitstream.
Definition: bitstream.c:61
byte swapping routines
void avpriv_align_put_bits(PutBitContext *s)
Pad the bitstream with zeros up to the next byte boundary.
Definition: bitstream.c:46
uint32_t bit_buf
Definition: put_bits.h:42
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:81
common internal and external API header
the buffer and buffer reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFilterBuffer structures They must not be accessed but through references stored in AVFilterBufferRef structures Several references can point to the same buffer
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:54
const char int length
Definition: avisynth_c.h:668
#define av_unused
Definition: attributes.h:114