UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
bs.h
Go to the documentation of this file.
1/*
2 * h264bitstream - a library for reading and writing H.264 video
3 * Copyright (C) 2005-2007 Auroras Entertainment, LLC
4 * Copyright (C) 2008-2011 Avail-TVN
5 *
6 * Written by Alex Izvorski <aizvorski@gmail.com> and Alex Giladi <alex.giladi@gmail.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef _H264_BS_H
24#define _H264_BS_H 1
25
26#include <stdint.h>
27#include <stdlib.h>
28#include <string.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34typedef struct
35{
36 uint8_t* start;
37 uint8_t* p;
38 uint8_t* end;
40} bs_t;
41
42#define _OPTIMIZE_BS_ 1
43
44#if ( _OPTIMIZE_BS_ > 0 )
45#ifndef FAST_U8
46#define FAST_U8
47#endif
48#endif
49
50
51static bs_t* bs_new(uint8_t* buf, size_t size);
52static void bs_free(bs_t* b);
53static bs_t* bs_clone( bs_t* dest, const bs_t* src );
54static bs_t* bs_init(bs_t* b, uint8_t* buf, size_t size);
55static uint32_t bs_byte_aligned(bs_t* b);
56static int bs_eof(bs_t* b);
57static int bs_overrun(bs_t* b);
58static int bs_pos(bs_t* b);
59
60static uint32_t bs_peek_u1(bs_t* b);
61static uint32_t bs_read_u1(bs_t* b);
62static uint32_t bs_read_u(bs_t* b, int n);
63static uint32_t bs_read_f(bs_t* b, int n);
64static uint32_t bs_read_u8(bs_t* b);
65static uint32_t bs_read_ue(bs_t* b);
66static int32_t bs_read_se(bs_t* b);
67
68static void bs_write_u1(bs_t* b, uint32_t v);
69static void bs_write_u(bs_t* b, int n, uint32_t v);
70static void bs_write_f(bs_t* b, int n, uint32_t v);
71static void bs_write_u8(bs_t* b, uint32_t v);
72static void bs_write_ue(bs_t* b, uint32_t v);
73static void bs_write_se(bs_t* b, int32_t v);
74
75static int bs_read_bytes(bs_t* b, uint8_t* buf, int len);
76static int bs_write_bytes(bs_t* b, uint8_t* buf, int len);
77static int bs_skip_bytes(bs_t* b, int len);
78static uint32_t bs_next_bits(bs_t* b, int nbits);
79// IMPLEMENTATION
80
81static inline bs_t* bs_init(bs_t* b, uint8_t* buf, size_t size)
82{
83 b->start = buf;
84 b->p = buf;
85 b->end = buf + size;
86 b->bits_left = 8;
87 return b;
88}
89
90static inline bs_t* bs_new(uint8_t* buf, size_t size)
91{
92 bs_t* b = (bs_t*)malloc(sizeof(bs_t));
93 bs_init(b, buf, size);
94 return b;
95}
96
97static inline void bs_free(bs_t* b)
98{
99 free(b);
100}
101
102static inline bs_t* bs_clone(bs_t* dest, const bs_t* src)
103{
104 dest->start = src->p;
105 dest->p = src->p;
106 dest->end = src->end;
107 dest->bits_left = src->bits_left;
108 return dest;
109}
110
111static inline uint32_t bs_byte_aligned(bs_t* b)
112{
113 return (b->bits_left == 8);
114}
115
116static inline int bs_eof(bs_t* b) { if (b->p >= b->end) { return 1; } else { return 0; } }
117
118static inline int bs_overrun(bs_t* b) { if (b->p > b->end) { return 1; } else { return 0; } }
119
120static inline int bs_pos(bs_t* b) { if (b->p > b->end) { return (b->end - b->start); } else { return (b->p - b->start); } }
121
122static inline int bs_bytes_left(bs_t* b) { return (b->end - b->p); }
123
124static inline uint32_t bs_read_u1(bs_t* b)
125{
126 uint32_t r = 0;
127
128 b->bits_left--;
129
130 if (! bs_eof(b))
131 {
132 r = ((*(b->p)) >> b->bits_left) & 0x01;
133 }
134
135 if (b->bits_left == 0) { b->p ++; b->bits_left = 8; }
136
137 return r;
138}
139
140static inline void bs_skip_u1(bs_t* b)
141{
142 b->bits_left--;
143 if (b->bits_left == 0) { b->p ++; b->bits_left = 8; }
144}
145
146static inline uint32_t bs_peek_u1(bs_t* b)
147{
148 uint32_t r = 0;
149
150 if (! bs_eof(b))
151 {
152 r = ((*(b->p)) >> ( b->bits_left - 1 )) & 0x01;
153 }
154 return r;
155}
156
157
158static inline uint32_t bs_read_u(bs_t* b, int n)
159{
160 uint32_t r = 0;
161 int i;
162 for (i = 0; i < n; i++)
163 {
164 r |= ( bs_read_u1(b) << ( n - i - 1 ) );
165 }
166 return r;
167}
168
169static inline void bs_skip_u(bs_t* b, int n)
170{
171 int i;
172 for ( i = 0; i < n; i++ )
173 {
174 bs_skip_u1( b );
175 }
176}
177
178static inline uint32_t bs_read_f(bs_t* b, int n) { return bs_read_u(b, n); }
179
180static inline uint32_t bs_read_u8(bs_t* b)
181{
182#ifdef FAST_U8
183 if (b->bits_left == 8 && ! bs_eof(b)) // can do fast read
184 {
185 uint32_t r = b->p[0];
186 b->p++;
187 return r;
188 }
189#endif
190 return bs_read_u(b, 8);
191}
192
193static inline uint32_t bs_read_ue(bs_t* b)
194{
195 int32_t r = 0;
196 int i = 0;
197
198 while( (bs_read_u1(b) == 0) && (i < 32) && (!bs_eof(b)) )
199 {
200 i++;
201 }
202 r = bs_read_u(b, i);
203 r += (1 << i) - 1;
204 return r;
205}
206
207static inline int32_t bs_read_se(bs_t* b)
208{
209 int32_t r = bs_read_ue(b);
210 if (r & 0x01)
211 {
212 r = (r+1)/2;
213 }
214 else
215 {
216 r = -(r/2);
217 }
218 return r;
219}
220
221
222static inline void bs_write_u1(bs_t* b, uint32_t v)
223{
224 b->bits_left--;
225
226 if (! bs_eof(b))
227 {
228 // FIXME this is slow, but we must clear bit first
229 // is it better to memset(0) the whole buffer during bs_init() instead?
230 // if we don't do either, we introduce pretty nasty bugs
231 (*(b->p)) &= ~(0x01 << b->bits_left);
232 (*(b->p)) |= ((v & 0x01) << b->bits_left);
233 }
234
235 if (b->bits_left == 0) { b->p ++; b->bits_left = 8; }
236}
237
238static inline void bs_write_u(bs_t* b, int n, uint32_t v)
239{
240 int i;
241 for (i = 0; i < n; i++)
242 {
243 bs_write_u1(b, (v >> ( n - i - 1 ))&0x01 );
244 }
245}
246
247static inline void bs_write_f(bs_t* b, int n, uint32_t v) { bs_write_u(b, n, v); }
248
249static inline void bs_write_u8(bs_t* b, uint32_t v)
250{
251#ifdef FAST_U8
252 if (b->bits_left == 8 && ! bs_eof(b)) // can do fast write
253 {
254 b->p[0] = v;
255 b->p++;
256 return;
257 }
258#endif
259 bs_write_u(b, 8, v);
260}
261
262static inline void bs_write_ue(bs_t* b, uint32_t v)
263{
264 static const int len_table[256] =
265 {
266 1,
267 1,
268 2,2,
269 3,3,3,3,
270 4,4,4,4,4,4,4,4,
271 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
272 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
273 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
274 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
275 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
276 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
277 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
278 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
279 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
280 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
281 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
282 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
283 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
284 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
285 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
286 };
287
288 int len;
289
290 if (v == 0)
291 {
292 bs_write_u1(b, 1);
293 }
294 else
295 {
296 v++;
297
298 if (v >= 0x01000000)
299 {
300 len = 24 + len_table[ v >> 24 ];
301 }
302 else if(v >= 0x00010000)
303 {
304 len = 16 + len_table[ v >> 16 ];
305 }
306 else if(v >= 0x00000100)
307 {
308 len = 8 + len_table[ v >> 8 ];
309 }
310 else
311 {
312 len = len_table[ v ];
313 }
314
315 bs_write_u(b, 2*len-1, v);
316 }
317}
318
319static inline void bs_write_se(bs_t* b, int32_t v)
320{
321 if (v <= 0)
322 {
323 bs_write_ue(b, -v*2);
324 }
325 else
326 {
327 bs_write_ue(b, v*2 - 1);
328 }
329}
330
331static inline int bs_read_bytes(bs_t* b, uint8_t* buf, int len)
332{
333 int actual_len = len;
334 if (b->end - b->p < actual_len) { actual_len = b->end - b->p; }
335 if (actual_len < 0) { actual_len = 0; }
336 memcpy(buf, b->p, actual_len);
337 if (len < 0) { len = 0; }
338 b->p += len;
339 return actual_len;
340}
341
342static inline int bs_write_bytes(bs_t* b, uint8_t* buf, int len)
343{
344 int actual_len = len;
345 if (b->end - b->p < actual_len) { actual_len = b->end - b->p; }
346 if (actual_len < 0) { actual_len = 0; }
347 memcpy(b->p, buf, actual_len);
348 if (len < 0) { len = 0; }
349 b->p += len;
350 return actual_len;
351}
352
353static inline int bs_skip_bytes(bs_t* b, int len)
354{
355 int actual_len = len;
356 if (b->end - b->p < actual_len) { actual_len = b->end - b->p; }
357 if (actual_len < 0) { actual_len = 0; }
358 if (len < 0) { len = 0; }
359 b->p += len;
360 return actual_len;
361}
362
363static inline uint32_t bs_next_bits(bs_t* bs, int nbits)
364{
365 bs_t b;
366 bs_clone(&b,bs);
367 return bs_read_u(&b, nbits);
368}
369
370static inline uint64_t bs_next_bytes(bs_t* bs, int nbytes)
371{
372 int i = 0;
373 uint64_t val = 0;
374
375 if ( (nbytes > 8) || (nbytes < 1) ) { return 0; }
376 if (bs->p + nbytes > bs->end) { return 0; }
377
378 for ( i = 0; i < nbytes; i++ ) { val = ( val << 8 ) | bs->p[i]; }
379 return val;
380}
381
382#define bs_print_state(b) fprintf( stderr, "%s:%d@%s: b->p=0x%02hhX, b->left = %d\n", __FILE__, __LINE__, __FUNCTION__, *b->p, b->bits_left )
383
384#ifdef __cplusplus
385}
386#endif
387
388#endif
int void * val
int void size_t * len
static uint32_t bs_read_u8(bs_t *b)
Definition bs.h:180
static void bs_write_u8(bs_t *b, uint32_t v)
Definition bs.h:249
static void bs_skip_u(bs_t *b, int n)
Definition bs.h:169
static uint32_t bs_read_u(bs_t *b, int n)
Definition bs.h:158
static uint32_t bs_peek_u1(bs_t *b)
Definition bs.h:146
static void bs_write_u(bs_t *b, int n, uint32_t v)
Definition bs.h:238
static bs_t * bs_clone(bs_t *dest, const bs_t *src)
Definition bs.h:102
static uint32_t bs_read_ue(bs_t *b)
Definition bs.h:193
static uint32_t bs_byte_aligned(bs_t *b)
Definition bs.h:111
static uint32_t bs_read_u1(bs_t *b)
Definition bs.h:124
static uint32_t bs_read_f(bs_t *b, int n)
Definition bs.h:178
static bs_t * bs_init(bs_t *b, uint8_t *buf, size_t size)
Definition bs.h:81
static uint32_t bs_next_bits(bs_t *b, int nbits)
Definition bs.h:363
static int32_t bs_read_se(bs_t *b)
Definition bs.h:207
static void bs_write_ue(bs_t *b, uint32_t v)
Definition bs.h:262
static void bs_write_se(bs_t *b, int32_t v)
Definition bs.h:319
static int bs_overrun(bs_t *b)
Definition bs.h:118
static int bs_pos(bs_t *b)
Definition bs.h:120
static int bs_write_bytes(bs_t *b, uint8_t *buf, int len)
Definition bs.h:342
static void bs_free(bs_t *b)
Definition bs.h:97
static uint64_t bs_next_bytes(bs_t *bs, int nbytes)
Definition bs.h:370
static void bs_skip_u1(bs_t *b)
Definition bs.h:140
static int bs_eof(bs_t *b)
Definition bs.h:116
static int bs_bytes_left(bs_t *b)
Definition bs.h:122
static int bs_read_bytes(bs_t *b, uint8_t *buf, int len)
Definition bs.h:331
static int bs_skip_bytes(bs_t *b, int len)
Definition bs.h:353
static bs_t * bs_new(uint8_t *buf, size_t size)
Definition bs.h:90
static void bs_write_f(bs_t *b, int n, uint32_t v)
Definition bs.h:247
static void bs_write_u1(bs_t *b, uint32_t v)
Definition bs.h:222
Definition bs.h:35
uint8_t * start
Definition bs.h:36
int bits_left
Definition bs.h:39
uint8_t * p
Definition bs.h:37
uint8_t * end
Definition bs.h:38