FFmpeg
bytestream.h
Go to the documentation of this file.
1 /*
2  * Bytestream functions
3  * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
4  * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #ifndef AVCODEC_BYTESTREAM_H
24 #define AVCODEC_BYTESTREAM_H
25 
26 #include <stdint.h>
27 #include <string.h>
28 
29 #include "libavutil/avassert.h"
30 #include "libavutil/common.h"
31 #include "libavutil/intreadwrite.h"
32 
33 typedef struct GetByteContext {
36 
37 typedef struct PutByteContext {
39  int eof;
41 
42 #define DEF(type, name, bytes, read, write) \
43 static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \
44 { \
45  (*b) += bytes; \
46  return read(*b - bytes); \
47 } \
48 static av_always_inline void bytestream_put_ ## name(uint8_t **b, \
49  const type value) \
50 { \
51  write(*b, value); \
52  (*b) += bytes; \
53 } \
54 static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \
55  const type value) \
56 { \
57  bytestream_put_ ## name(&p->buffer, value); \
58 } \
59 static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \
60  const type value) \
61 { \
62  if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \
63  write(p->buffer, value); \
64  p->buffer += bytes; \
65  } else \
66  p->eof = 1; \
67 } \
68 static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \
69 { \
70  return bytestream_get_ ## name(&g->buffer); \
71 } \
72 static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \
73 { \
74  if (g->buffer_end - g->buffer < bytes) { \
75  g->buffer = g->buffer_end; \
76  return 0; \
77  } \
78  return bytestream2_get_ ## name ## u(g); \
79 } \
80 static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \
81 { \
82  if (g->buffer_end - g->buffer < bytes) \
83  return 0; \
84  return read(g->buffer); \
85 }
86 
87 DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
88 DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
89 DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
90 DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
91 DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
92 DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
93 DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
94 DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
95 DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
96 
97 #if AV_HAVE_BIGENDIAN
98 # define bytestream2_get_ne16 bytestream2_get_be16
99 # define bytestream2_get_ne24 bytestream2_get_be24
100 # define bytestream2_get_ne32 bytestream2_get_be32
101 # define bytestream2_get_ne64 bytestream2_get_be64
102 # define bytestream2_get_ne16u bytestream2_get_be16u
103 # define bytestream2_get_ne24u bytestream2_get_be24u
104 # define bytestream2_get_ne32u bytestream2_get_be32u
105 # define bytestream2_get_ne64u bytestream2_get_be64u
106 # define bytestream2_put_ne16 bytestream2_put_be16
107 # define bytestream2_put_ne24 bytestream2_put_be24
108 # define bytestream2_put_ne32 bytestream2_put_be32
109 # define bytestream2_put_ne64 bytestream2_put_be64
110 # define bytestream2_peek_ne16 bytestream2_peek_be16
111 # define bytestream2_peek_ne24 bytestream2_peek_be24
112 # define bytestream2_peek_ne32 bytestream2_peek_be32
113 # define bytestream2_peek_ne64 bytestream2_peek_be64
114 #else
115 # define bytestream2_get_ne16 bytestream2_get_le16
116 # define bytestream2_get_ne24 bytestream2_get_le24
117 # define bytestream2_get_ne32 bytestream2_get_le32
118 # define bytestream2_get_ne64 bytestream2_get_le64
119 # define bytestream2_get_ne16u bytestream2_get_le16u
120 # define bytestream2_get_ne24u bytestream2_get_le24u
121 # define bytestream2_get_ne32u bytestream2_get_le32u
122 # define bytestream2_get_ne64u bytestream2_get_le64u
123 # define bytestream2_put_ne16 bytestream2_put_le16
124 # define bytestream2_put_ne24 bytestream2_put_le24
125 # define bytestream2_put_ne32 bytestream2_put_le32
126 # define bytestream2_put_ne64 bytestream2_put_le64
127 # define bytestream2_peek_ne16 bytestream2_peek_le16
128 # define bytestream2_peek_ne24 bytestream2_peek_le24
129 # define bytestream2_peek_ne32 bytestream2_peek_le32
130 # define bytestream2_peek_ne64 bytestream2_peek_le64
131 #endif
132 
134  const uint8_t *buf,
135  int buf_size)
136 {
137  av_assert0(buf_size >= 0);
138  g->buffer = buf;
139  g->buffer_start = buf;
140  g->buffer_end = buf + buf_size;
141 }
142 
144  uint8_t *buf,
145  int buf_size)
146 {
147  av_assert0(buf_size >= 0);
148  p->buffer = buf;
149  p->buffer_start = buf;
150  p->buffer_end = buf + buf_size;
151  p->eof = 0;
152 }
153 
155 {
156  return g->buffer_end - g->buffer;
157 }
158 
160 {
161  return p->buffer_end - p->buffer;
162 }
163 
165  unsigned int size)
166 {
167  g->buffer += FFMIN(g->buffer_end - g->buffer, size);
168 }
169 
171  unsigned int size)
172 {
173  g->buffer += size;
174 }
175 
177  unsigned int size)
178 {
179  int size2;
180  if (p->eof)
181  return;
182  size2 = FFMIN(p->buffer_end - p->buffer, size);
183  if (size2 != size)
184  p->eof = 1;
185  p->buffer += size2;
186 }
187 
189 {
190  return (int)(g->buffer - g->buffer_start);
191 }
192 
194 {
195  return (int)(p->buffer - p->buffer_start);
196 }
197 
199 {
200  return (int)(g->buffer_end - g->buffer_start);
201 }
202 
204 {
205  return (int)(p->buffer_end - p->buffer_start);
206 }
207 
209  int offset,
210  int whence)
211 {
212  switch (whence) {
213  case SEEK_CUR:
214  offset = av_clip(offset, -(g->buffer - g->buffer_start),
215  g->buffer_end - g->buffer);
216  g->buffer += offset;
217  break;
218  case SEEK_END:
219  offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
220  g->buffer = g->buffer_end + offset;
221  break;
222  case SEEK_SET:
223  offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
224  g->buffer = g->buffer_start + offset;
225  break;
226  default:
227  return AVERROR(EINVAL);
228  }
229  return bytestream2_tell(g);
230 }
231 
233  int offset,
234  int whence)
235 {
236  p->eof = 0;
237  switch (whence) {
238  case SEEK_CUR:
239  if (p->buffer_end - p->buffer < offset)
240  p->eof = 1;
241  offset = av_clip(offset, -(p->buffer - p->buffer_start),
242  p->buffer_end - p->buffer);
243  p->buffer += offset;
244  break;
245  case SEEK_END:
246  if (offset > 0)
247  p->eof = 1;
248  offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
249  p->buffer = p->buffer_end + offset;
250  break;
251  case SEEK_SET:
252  if (p->buffer_end - p->buffer_start < offset)
253  p->eof = 1;
254  offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
255  p->buffer = p->buffer_start + offset;
256  break;
257  default:
258  return AVERROR(EINVAL);
259  }
260  return bytestream2_tell_p(p);
261 }
262 
264  uint8_t *dst,
265  unsigned int size)
266 {
267  int size2 = FFMIN(g->buffer_end - g->buffer, size);
268  memcpy(dst, g->buffer, size2);
269  g->buffer += size2;
270  return size2;
271 }
272 
274  uint8_t *dst,
275  unsigned int size)
276 {
277  memcpy(dst, g->buffer, size);
278  g->buffer += size;
279  return size;
280 }
281 
283  const uint8_t *src,
284  unsigned int size)
285 {
286  int size2;
287  if (p->eof)
288  return 0;
289  size2 = FFMIN(p->buffer_end - p->buffer, size);
290  if (size2 != size)
291  p->eof = 1;
292  memcpy(p->buffer, src, size2);
293  p->buffer += size2;
294  return size2;
295 }
296 
298  const uint8_t *src,
299  unsigned int size)
300 {
301  memcpy(p->buffer, src, size);
302  p->buffer += size;
303  return size;
304 }
305 
307  const uint8_t c,
308  unsigned int size)
309 {
310  int size2;
311  if (p->eof)
312  return;
313  size2 = FFMIN(p->buffer_end - p->buffer, size);
314  if (size2 != size)
315  p->eof = 1;
316  memset(p->buffer, c, size2);
317  p->buffer += size2;
318 }
319 
321  const uint8_t c,
322  unsigned int size)
323 {
324  memset(p->buffer, c, size);
325  p->buffer += size;
326 }
327 
329 {
330  return p->eof;
331 }
332 
334  GetByteContext *g,
335  unsigned int size)
336 {
337  memcpy(p->buffer, g->buffer, size);
338  p->buffer += size;
339  g->buffer += size;
340  return size;
341 }
342 
344  GetByteContext *g,
345  unsigned int size)
346 {
347  int size2;
348 
349  if (p->eof)
350  return 0;
351  size = FFMIN(g->buffer_end - g->buffer, size);
352  size2 = FFMIN(p->buffer_end - p->buffer, size);
353  if (size2 != size)
354  p->eof = 1;
355 
356  return bytestream2_copy_bufferu(p, g, size2);
357 }
358 
359 static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
360  uint8_t *dst,
361  unsigned int size)
362 {
363  memcpy(dst, *b, size);
364  (*b) += size;
365  return size;
366 }
367 
369  const uint8_t *src,
370  unsigned int size)
371 {
372  memcpy(*b, src, size);
373  (*b) += size;
374 }
375 
376 #endif /* AVCODEC_BYTESTREAM_H */
le32
uint64_t_TMPL AV_WL64 unsigned int_TMPL le32
Definition: bytestream.h:88
bytestream2_get_eof
static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
Definition: bytestream.h:328
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
GetByteContext::buffer_start
const uint8_t * buffer_start
Definition: bytestream.h:34
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
GetByteContext
Definition: bytestream.h:33
AV_RL64
uint64_t_TMPL AV_RL64
Definition: bytestream.h:87
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:170
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
b
#define b
Definition: input.c:41
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:193
bytestream2_size_p
static av_always_inline int bytestream2_size_p(PutByteContext *p)
Definition: bytestream.h:203
bytestream2_get_bytes_left_p
static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
Definition: bytestream.h:159
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
bytestream2_get_bytes_left
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
be24
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 be24
Definition: bytestream.h:93
le24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL le24
Definition: bytestream.h:89
src
#define src
Definition: vp8dsp.c:254
avassert.h
buf
void * buf
Definition: avisynth_c.h:766
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
intreadwrite.h
g
const char * g
Definition: vf_curves.c:115
bytestream2_put_buffer
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:282
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:90
bytestream2_copy_bufferu
static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p, GetByteContext *g, unsigned int size)
Definition: bytestream.h:333
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
PutByteContext::eof
int eof
Definition: bytestream.h:39
PutByteContext::buffer_start
uint8_t * buffer_start
Definition: bytestream.h:38
AV_WL24
#define AV_WL24(p, d)
Definition: intreadwrite.h:464
be64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL be64
Definition: bytestream.h:91
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
be32
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 be32
Definition: bytestream.h:92
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
PutByteContext
Definition: bytestream.h:37
bytestream2_size
static av_always_inline int bytestream2_size(GetByteContext *g)
Definition: bytestream.h:198
DEF
#define DEF(type, name, bytes, read, write)
Definition: bytestream.h:42
PutByteContext::buffer
uint8_t * buffer
Definition: bytestream.h:38
size
int size
Definition: twinvq_data.h:11134
AV_RB32
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_RB32
Definition: bytestream.h:92
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
AV_RL24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:89
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
AV_WL64
#define AV_WL64(p, v)
Definition: intreadwrite.h:440
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
bytestream_put_buffer
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:368
bytestream2_skip_p
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition: bytestream.h:176
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:43
bytestream2_set_bufferu
static av_always_inline void bytestream2_set_bufferu(PutByteContext *p, const uint8_t c, unsigned int size)
Definition: bytestream.h:320
uint8_t
uint8_t
Definition: audio_convert.c:194
bytestream2_set_buffer
static av_always_inline void bytestream2_set_buffer(PutByteContext *p, const uint8_t c, unsigned int size)
Definition: bytestream.h:306
le64
uint64_t_TMPL le64
Definition: bytestream.h:87
GetByteContext::buffer_end
const uint8_t * buffer_end
Definition: bytestream.h:34
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:396
bytestream_get_buffer
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
Definition: bytestream.h:359
bytestream2_copy_buffer
static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p, GetByteContext *g, unsigned int size)
Definition: bytestream.h:343
be16
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 be16
Definition: bytestream.h:94
le16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL le16
Definition: bytestream.h:90
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
PutByteContext::buffer_end
uint8_t * buffer_end
Definition: bytestream.h:38
bytestream2_seek_p
static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset, int whence)
Definition: bytestream.h:232
AV_RB8
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_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:95
bytestream2_get_bufferu
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:273
bytestream2_put_bufferu
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:297
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
AV_RB24
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_RB24
Definition: bytestream.h:93
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:91
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:94