FFmpeg
bitstream.c
Go to the documentation of this file.
1 /*
2  * Common bit i/o utils
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5  * Copyright (c) 2010 Loren Merritt
6  *
7  * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
8  *
9  * This file is part of FFmpeg.
10  *
11  * FFmpeg is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * FFmpeg is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with FFmpeg; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 /**
27  * @file
28  * bitstream api.
29  */
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/qsort.h"
33 #include "avcodec.h"
34 #include "internal.h"
35 #include "mathops.h"
36 #include "put_bits.h"
37 #include "vlc.h"
38 
39 const uint8_t ff_log2_run[41]={
40  0, 0, 0, 0, 1, 1, 1, 1,
41  2, 2, 2, 2, 3, 3, 3, 3,
42  4, 4, 5, 5, 6, 6, 7, 7,
43  8, 9,10,11,12,13,14,15,
44 16,17,18,19,20,21,22,23,
45 24,
46 };
47 
48 void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
49 {
50  while (*string) {
51  put_bits(pb, 8, *string);
52  string++;
53  }
54  if (terminate_string)
55  put_bits(pb, 8, 0);
56 }
57 
58 void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
59 {
60  int words = length >> 4;
61  int bits = length & 15;
62  int i;
63 
64  if (length == 0)
65  return;
66 
67  av_assert0(length <= put_bits_left(pb));
68 
69  if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) {
70  for (i = 0; i < words; i++)
71  put_bits(pb, 16, AV_RB16(src + 2 * i));
72  } else {
73  for (i = 0; put_bits_count(pb) & 31; i++)
74  put_bits(pb, 8, src[i]);
75  flush_put_bits(pb);
76  memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
77  skip_put_bytes(pb, 2 * words - i);
78  }
79 
80  put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
81 }
82 
83 /* VLC decoding */
84 
85 #define GET_DATA(v, table, i, wrap, size) \
86 { \
87  const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
88  switch(size) { \
89  case 1: \
90  v = *(const uint8_t *)ptr; \
91  break; \
92  case 2: \
93  v = *(const uint16_t *)ptr; \
94  break; \
95  case 4: \
96  default: \
97  av_assert1(size == 4); \
98  v = *(const uint32_t *)ptr; \
99  break; \
100  } \
101 }
102 
103 
104 static int alloc_table(VLC *vlc, int size, int use_static)
105 {
106  int index = vlc->table_size;
107 
108  vlc->table_size += size;
109  if (vlc->table_size > vlc->table_allocated) {
110  if (use_static)
111  abort(); // cannot do anything, init_vlc() is used with too little memory
112  vlc->table_allocated += (1 << vlc->bits);
113  vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
114  if (!vlc->table) {
115  vlc->table_allocated = 0;
116  vlc->table_size = 0;
117  return AVERROR(ENOMEM);
118  }
119  memset(vlc->table + vlc->table_allocated - (1 << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits);
120  }
121  return index;
122 }
123 
124 #define LOCALBUF_ELEMS 1500 // the maximum currently needed is 1296 by rv34
125 
126 typedef struct VLCcode {
127  uint8_t bits;
129  /** codeword, with the first bit-to-be-read in the msb
130  * (even if intended for a little-endian bitstream reader) */
131  uint32_t code;
132 } VLCcode;
133 
134 static int vlc_common_init(VLC *vlc_arg, int nb_bits, int nb_codes,
135  VLC **vlc, VLC *localvlc, VLCcode **buf,
136  int flags)
137 {
138  *vlc = vlc_arg;
139  (*vlc)->bits = nb_bits;
141  av_assert0(nb_codes <= LOCALBUF_ELEMS);
142  *localvlc = *vlc_arg;
143  *vlc = localvlc;
144  (*vlc)->table_size = 0;
145  } else {
146  (*vlc)->table = NULL;
147  (*vlc)->table_allocated = 0;
148  (*vlc)->table_size = 0;
149  }
150  if (nb_codes > LOCALBUF_ELEMS) {
151  *buf = av_malloc_array(nb_codes, sizeof(VLCcode));
152  if (!*buf)
153  return AVERROR(ENOMEM);
154  }
155 
156  return 0;
157 }
158 
159 static int compare_vlcspec(const void *a, const void *b)
160 {
161  const VLCcode *sa = a, *sb = b;
162  return (sa->code >> 1) - (sb->code >> 1);
163 }
164 /**
165  * Build VLC decoding tables suitable for use with get_vlc().
166  *
167  * @param vlc the context to be initialized
168  *
169  * @param table_nb_bits max length of vlc codes to store directly in this table
170  * (Longer codes are delegated to subtables.)
171  *
172  * @param nb_codes number of elements in codes[]
173  *
174  * @param codes descriptions of the vlc codes
175  * These must be ordered such that codes going into the same subtable are contiguous.
176  * Sorting by VLCcode.code is sufficient, though not necessary.
177  */
178 static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
179  VLCcode *codes, int flags)
180 {
181  int table_size, table_index, index, code_prefix, symbol, subtable_bits;
182  int i, j, k, n, nb, inc;
183  uint32_t code;
184  volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent an internal compiler error in gcc 4.2
185 
186  if (table_nb_bits > 30)
187  return AVERROR(EINVAL);
188  table_size = 1 << table_nb_bits;
189  table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
190  ff_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
191  if (table_index < 0)
192  return table_index;
193  table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
194 
195  /* first pass: map codes and compute auxiliary table sizes */
196  for (i = 0; i < nb_codes; i++) {
197  n = codes[i].bits;
198  code = codes[i].code;
199  symbol = codes[i].symbol;
200  ff_dlog(NULL, "i=%d n=%d code=0x%"PRIx32"\n", i, n, code);
201  if (n <= table_nb_bits) {
202  /* no need to add another table */
203  j = code >> (32 - table_nb_bits);
204  nb = 1 << (table_nb_bits - n);
205  inc = 1;
206  if (flags & INIT_VLC_OUTPUT_LE) {
207  j = bitswap_32(code);
208  inc = 1 << n;
209  }
210  for (k = 0; k < nb; k++) {
211  int bits = table[j][1];
212  int oldsym = table[j][0];
213  ff_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
214  if ((bits || oldsym) && (bits != n || oldsym != symbol)) {
215  av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
216  return AVERROR_INVALIDDATA;
217  }
218  table[j][1] = n; //bits
219  table[j][0] = symbol;
220  j += inc;
221  }
222  } else {
223  /* fill auxiliary table recursively */
224  n -= table_nb_bits;
225  code_prefix = code >> (32 - table_nb_bits);
226  subtable_bits = n;
227  codes[i].bits = n;
228  codes[i].code = code << table_nb_bits;
229  for (k = i+1; k < nb_codes; k++) {
230  n = codes[k].bits - table_nb_bits;
231  if (n <= 0)
232  break;
233  code = codes[k].code;
234  if (code >> (32 - table_nb_bits) != code_prefix)
235  break;
236  codes[k].bits = n;
237  codes[k].code = code << table_nb_bits;
238  subtable_bits = FFMAX(subtable_bits, n);
239  }
240  subtable_bits = FFMIN(subtable_bits, table_nb_bits);
241  j = (flags & INIT_VLC_OUTPUT_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
242  table[j][1] = -subtable_bits;
243  ff_dlog(NULL, "%4x: n=%d (subtable)\n",
244  j, codes[i].bits + table_nb_bits);
245  index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
246  if (index < 0)
247  return index;
248  /* note: realloc has been done, so reload tables */
249  table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
250  table[j][0] = index; //code
251  if (table[j][0] != index) {
252  avpriv_request_sample(NULL, "strange codes");
253  return AVERROR_PATCHWELCOME;
254  }
255  i = k-1;
256  }
257  }
258 
259  for (i = 0; i < table_size; i++) {
260  if (table[i][1] == 0) //bits
261  table[i][0] = -1; //codes
262  }
263 
264  return table_index;
265 }
266 
267 static int vlc_common_end(VLC *vlc, int nb_bits, int nb_codes, VLCcode *codes,
268  int flags, VLC *vlc_arg, VLCcode localbuf[LOCALBUF_ELEMS])
269 {
270  int ret = build_table(vlc, nb_bits, nb_codes, codes, flags);
271 
273  if (vlc->table_size != vlc->table_allocated &&
275  av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
276  av_assert0(ret >= 0);
277  *vlc_arg = *vlc;
278  } else {
279  if (codes != localbuf)
280  av_free(codes);
281  if (ret < 0) {
282  av_freep(&vlc->table);
283  return ret;
284  }
285  }
286  return 0;
287 }
288 
289 /* Build VLC decoding tables suitable for use with get_vlc().
290 
291  'nb_bits' sets the decoding table size (2^nb_bits) entries. The
292  bigger it is, the faster is the decoding. But it should not be too
293  big to save memory and L1 cache. '9' is a good compromise.
294 
295  'nb_codes' : number of vlcs codes
296 
297  'bits' : table which gives the size (in bits) of each vlc code.
298 
299  'codes' : table which gives the bit pattern of of each vlc code.
300 
301  'symbols' : table which gives the values to be returned from get_vlc().
302 
303  'xxx_wrap' : give the number of bytes between each entry of the
304  'bits' or 'codes' tables.
305 
306  'xxx_size' : gives the number of bytes of each entry of the 'bits'
307  or 'codes' tables. Currently 1,2 and 4 are supported.
308 
309  'wrap' and 'size' make it possible to use any memory configuration and types
310  (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
311 */
312 int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
313  const void *bits, int bits_wrap, int bits_size,
314  const void *codes, int codes_wrap, int codes_size,
315  const void *symbols, int symbols_wrap, int symbols_size,
316  int flags)
317 {
318  VLCcode localbuf[LOCALBUF_ELEMS], *buf = localbuf;
319  int i, j, ret;
320  VLC localvlc, *vlc;
321 
322  ret = vlc_common_init(vlc_arg, nb_bits, nb_codes, &vlc, &localvlc,
323  &buf, flags);
324  if (ret < 0)
325  return ret;
326 
327  av_assert0(symbols_size <= 2 || !symbols);
328  j = 0;
329 #define COPY(condition)\
330  for (i = 0; i < nb_codes; i++) { \
331  unsigned len; \
332  GET_DATA(len, bits, i, bits_wrap, bits_size); \
333  if (!(condition)) \
334  continue; \
335  if (len > 3*nb_bits || len > 32) { \
336  av_log(NULL, AV_LOG_ERROR, "Too long VLC (%u) in init_vlc\n", len);\
337  if (buf != localbuf) \
338  av_free(buf); \
339  return AVERROR(EINVAL); \
340  } \
341  buf[j].bits = len; \
342  GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
343  if (buf[j].code >= (1LL<<buf[j].bits)) { \
344  av_log(NULL, AV_LOG_ERROR, "Invalid code %"PRIx32" for %d in " \
345  "init_vlc\n", buf[j].code, i); \
346  if (buf != localbuf) \
347  av_free(buf); \
348  return AVERROR(EINVAL); \
349  } \
350  if (flags & INIT_VLC_INPUT_LE) \
351  buf[j].code = bitswap_32(buf[j].code); \
352  else \
353  buf[j].code <<= 32 - buf[j].bits; \
354  if (symbols) \
355  GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
356  else \
357  buf[j].symbol = i; \
358  j++; \
359  }
360  COPY(len > nb_bits);
361  // qsort is the slowest part of init_vlc, and could probably be improved or avoided
362  AV_QSORT(buf, j, struct VLCcode, compare_vlcspec);
363  COPY(len && len <= nb_bits);
364  nb_codes = j;
365 
366  return vlc_common_end(vlc, nb_bits, nb_codes, buf,
367  flags, vlc_arg, localbuf);
368 }
369 
370 int ff_init_vlc_from_lengths(VLC *vlc_arg, int nb_bits, int nb_codes,
371  const int8_t *lens, int lens_wrap,
372  const void *symbols, int symbols_wrap, int symbols_size,
373  int offset, int flags, void *logctx)
374 {
375  VLCcode localbuf[LOCALBUF_ELEMS], *buf = localbuf;
376  VLC localvlc, *vlc;
377  uint64_t code;
378  int ret, j, len_max = FFMIN(32, 3 * nb_bits);
379 
380  ret = vlc_common_init(vlc_arg, nb_bits, nb_codes, &vlc, &localvlc,
381  &buf, flags);
382  if (ret < 0)
383  return ret;
384 
385  j = code = 0;
386  for (int i = 0; i < nb_codes; i++, lens += lens_wrap) {
387  int len = *lens;
388  if (len > 0) {
389  unsigned sym;
390 
391  buf[j].bits = len;
392  if (symbols)
393  GET_DATA(sym, symbols, i, symbols_wrap, symbols_size)
394  else
395  sym = i;
396  buf[j].symbol = sym + offset;
397  buf[j++].code = code;
398  } else if (len < 0) {
399  len = -len;
400  } else
401  continue;
402  if (len > len_max || code & ((1U << (32 - len)) - 1)) {
403  av_log(logctx, AV_LOG_ERROR, "Invalid VLC (length %u)\n", len);
404  goto fail;
405  }
406  code += 1U << (32 - len);
407  if (code > UINT32_MAX + 1ULL) {
408  av_log(logctx, AV_LOG_ERROR, "Overdetermined VLC tree\n");
409  goto fail;
410  }
411  }
412  return vlc_common_end(vlc, nb_bits, j, buf,
413  flags, vlc_arg, localbuf);
414 fail:
415  if (buf != localbuf)
416  av_free(buf);
417  return AVERROR_INVALIDDATA;
418 }
419 
420 void ff_free_vlc(VLC *vlc)
421 {
422  av_freep(&vlc->table);
423 }
build_table
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, VLCcode *codes, int flags)
Build VLC decoding tables suitable for use with get_vlc().
Definition: bitstream.c:178
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
bitswap_32
static av_always_inline uint32_t bitswap_32(uint32_t x)
Definition: mathops.h:243
INIT_VLC_OUTPUT_LE
#define INIT_VLC_OUTPUT_LE
Definition: vlc.h:93
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:218
index
fg index
Definition: ffmpeg_filter.c:168
internal.h
b
#define b
Definition: input.c:41
table
static const uint16_t table[]
Definition: prosumer.c:206
COPY
#define COPY(condition)
ff_copy_bits
void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
Copy the content of src to the bitstream.
Definition: bitstream.c:58
VLC_TYPE
#define VLC_TYPE
Definition: vlc.h:24
U
#define U(x)
Definition: vp56_arith.h:37
fail
#define fail()
Definition: checkasm.h:134
put_bits_left
static int put_bits_left(PutBitContext *s)
Definition: put_bits.h:124
ff_init_vlc_from_lengths
int ff_init_vlc_from_lengths(VLC *vlc_arg, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
Definition: bitstream.c:370
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
bits
uint8_t bits
Definition: vp3data.h:141
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
ff_put_string
void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
Put the string string in the bitstream.
Definition: bitstream.c:48
ff_free_vlc
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:420
LOCALBUF_ELEMS
#define LOCALBUF_ELEMS
Definition: bitstream.c:124
PutBitContext
Definition: put_bits.h:49
if
if(ret)
Definition: filter_design.txt:179
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
ff_log2_run
const uint8_t ff_log2_run[41]
Definition: bitstream.c:39
vlc_common_end
static int vlc_common_end(VLC *vlc, int nb_bits, int nb_codes, VLCcode *codes, int flags, VLC *vlc_arg, VLCcode localbuf[LOCALBUF_ELEMS])
Definition: bitstream.c:267
src
#define src
Definition: vp8dsp.c:255
mathops.h
INIT_VLC_USE_NEW_STATIC
#define INIT_VLC_USE_NEW_STATIC
Definition: vlc.h:95
ff_init_vlc_sparse
int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, int flags)
Definition: bitstream.c:312
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
vlc_common_init
static int vlc_common_init(VLC *vlc_arg, int nb_bits, int nb_codes, VLC **vlc, VLC *localvlc, VLCcode **buf, int flags)
Definition: bitstream.c:134
VLCcode
Definition: bitstream.c:126
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
VLC::table_allocated
int table_allocated
Definition: vlc.h:29
qsort.h
GET_DATA
#define GET_DATA(v, table, i, wrap, size)
Definition: bitstream.c:85
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
size
int size
Definition: twinvq_data.h:10344
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
code_prefix
static const unsigned code_prefix[]
Definition: qdmc.c:76
offset
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 offset
Definition: writing_filters.txt:86
i
int i
Definition: input.c:407
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
put_bits_count
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:79
AV_QSORT
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition: qsort.h:33
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
VLCcode::bits
uint8_t bits
Definition: bitstream.c:127
VLCcode::code
uint32_t code
codeword, with the first bit-to-be-read in the msb (even if intended for a little-endian bitstream re...
Definition: bitstream.c:131
len
int len
Definition: vorbis_enc_data.h:452
avcodec.h
VLC::bits
int bits
Definition: vlc.h:27
alloc_table
static int alloc_table(VLC *vlc, int size, int use_static)
Definition: bitstream.c:104
ret
ret
Definition: filter_design.txt:187
INIT_VLC_STATIC_OVERLONG
#define INIT_VLC_STATIC_OVERLONG
Definition: vlc.h:96
put_bits_ptr
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:369
VLC
Definition: vlc.h:26
skip_put_bytes
static void skip_put_bytes(PutBitContext *s, int n)
Skip the given number of bytes.
Definition: put_bits.h:378
VLC::table_size
int table_size
Definition: vlc.h:29
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:39
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:142
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
compare_vlcspec
static int compare_vlcspec(const void *a, const void *b)
Definition: bitstream.c:159
vlc.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
VLCcode::symbol
VLC_TYPE symbol
Definition: bitstream.c:128
put_bits.h
VLC::table
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98