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 {
34  const uint8_t *buffer, *buffer_end, *buffer_start;
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 ## u(GetByteContext *g) \
81 { \
82  return read(g->buffer); \
83 } \
84 static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \
85 { \
86  if (g->buffer_end - g->buffer < bytes) \
87  return 0; \
88  return bytestream2_peek_ ## name ## u(g); \
89 }
90 
91 DEF(uint64_t, le64, 8, AV_RL64, AV_WL64)
92 DEF(unsigned int, le32, 4, AV_RL32, AV_WL32)
93 DEF(unsigned int, le24, 3, AV_RL24, AV_WL24)
94 DEF(unsigned int, le16, 2, AV_RL16, AV_WL16)
95 DEF(uint64_t, be64, 8, AV_RB64, AV_WB64)
96 DEF(unsigned int, be32, 4, AV_RB32, AV_WB32)
97 DEF(unsigned int, be24, 3, AV_RB24, AV_WB24)
98 DEF(unsigned int, be16, 2, AV_RB16, AV_WB16)
99 DEF(unsigned int, byte, 1, AV_RB8 , AV_WB8)
100 
101 #if AV_HAVE_BIGENDIAN
102 # define bytestream2_get_ne16 bytestream2_get_be16
103 # define bytestream2_get_ne24 bytestream2_get_be24
104 # define bytestream2_get_ne32 bytestream2_get_be32
105 # define bytestream2_get_ne64 bytestream2_get_be64
106 # define bytestream2_get_ne16u bytestream2_get_be16u
107 # define bytestream2_get_ne24u bytestream2_get_be24u
108 # define bytestream2_get_ne32u bytestream2_get_be32u
109 # define bytestream2_get_ne64u bytestream2_get_be64u
110 # define bytestream2_put_ne16 bytestream2_put_be16
111 # define bytestream2_put_ne24 bytestream2_put_be24
112 # define bytestream2_put_ne32 bytestream2_put_be32
113 # define bytestream2_put_ne64 bytestream2_put_be64
114 # define bytestream2_peek_ne16 bytestream2_peek_be16
115 # define bytestream2_peek_ne24 bytestream2_peek_be24
116 # define bytestream2_peek_ne32 bytestream2_peek_be32
117 # define bytestream2_peek_ne64 bytestream2_peek_be64
118 #else
119 # define bytestream2_get_ne16 bytestream2_get_le16
120 # define bytestream2_get_ne24 bytestream2_get_le24
121 # define bytestream2_get_ne32 bytestream2_get_le32
122 # define bytestream2_get_ne64 bytestream2_get_le64
123 # define bytestream2_get_ne16u bytestream2_get_le16u
124 # define bytestream2_get_ne24u bytestream2_get_le24u
125 # define bytestream2_get_ne32u bytestream2_get_le32u
126 # define bytestream2_get_ne64u bytestream2_get_le64u
127 # define bytestream2_put_ne16 bytestream2_put_le16
128 # define bytestream2_put_ne24 bytestream2_put_le24
129 # define bytestream2_put_ne32 bytestream2_put_le32
130 # define bytestream2_put_ne64 bytestream2_put_le64
131 # define bytestream2_peek_ne16 bytestream2_peek_le16
132 # define bytestream2_peek_ne24 bytestream2_peek_le24
133 # define bytestream2_peek_ne32 bytestream2_peek_le32
134 # define bytestream2_peek_ne64 bytestream2_peek_le64
135 #endif
136 
138  const uint8_t *buf,
139  int buf_size)
140 {
141  av_assert0(buf_size >= 0);
142  g->buffer = buf;
143  g->buffer_start = buf;
144  g->buffer_end = buf + buf_size;
145 }
146 
148  uint8_t *buf,
149  int buf_size)
150 {
151  av_assert0(buf_size >= 0);
152  p->buffer = buf;
153  p->buffer_start = buf;
154  p->buffer_end = buf + buf_size;
155  p->eof = 0;
156 }
157 
159 {
160  return g->buffer_end - g->buffer;
161 }
162 
164 {
165  return p->buffer_end - p->buffer;
166 }
167 
169  unsigned int size)
170 {
171  g->buffer += FFMIN(g->buffer_end - g->buffer, size);
172 }
173 
175  unsigned int size)
176 {
177  g->buffer += size;
178 }
179 
181  unsigned int size)
182 {
183  int size2;
184  if (p->eof)
185  return;
186  size2 = FFMIN(p->buffer_end - p->buffer, size);
187  if (size2 != size)
188  p->eof = 1;
189  p->buffer += size2;
190 }
191 
193 {
194  return (int)(g->buffer - g->buffer_start);
195 }
196 
198 {
199  return (int)(p->buffer - p->buffer_start);
200 }
201 
203 {
204  return (int)(g->buffer_end - g->buffer_start);
205 }
206 
208 {
209  return (int)(p->buffer_end - p->buffer_start);
210 }
211 
213  int offset,
214  int whence)
215 {
216  switch (whence) {
217  case SEEK_CUR:
218  offset = av_clip(offset, -(g->buffer - g->buffer_start),
219  g->buffer_end - g->buffer);
220  g->buffer += offset;
221  break;
222  case SEEK_END:
223  offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0);
224  g->buffer = g->buffer_end + offset;
225  break;
226  case SEEK_SET:
227  offset = av_clip(offset, 0, g->buffer_end - g->buffer_start);
228  g->buffer = g->buffer_start + offset;
229  break;
230  default:
231  return AVERROR(EINVAL);
232  }
233  return bytestream2_tell(g);
234 }
235 
237  int offset,
238  int whence)
239 {
240  p->eof = 0;
241  switch (whence) {
242  case SEEK_CUR:
243  if (p->buffer_end - p->buffer < offset)
244  p->eof = 1;
245  offset = av_clip(offset, -(p->buffer - p->buffer_start),
246  p->buffer_end - p->buffer);
247  p->buffer += offset;
248  break;
249  case SEEK_END:
250  if (offset > 0)
251  p->eof = 1;
252  offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
253  p->buffer = p->buffer_end + offset;
254  break;
255  case SEEK_SET:
256  if (p->buffer_end - p->buffer_start < offset)
257  p->eof = 1;
259  p->buffer = p->buffer_start + offset;
260  break;
261  default:
262  return AVERROR(EINVAL);
263  }
264  return bytestream2_tell_p(p);
265 }
266 
268  uint8_t *dst,
269  unsigned int size)
270 {
271  int size2 = FFMIN(g->buffer_end - g->buffer, size);
272  memcpy(dst, g->buffer, size2);
273  g->buffer += size2;
274  return size2;
275 }
276 
278  uint8_t *dst,
279  unsigned int size)
280 {
281  memcpy(dst, g->buffer, size);
282  g->buffer += size;
283  return size;
284 }
285 
287  const uint8_t *src,
288  unsigned int size)
289 {
290  int size2;
291  if (p->eof)
292  return 0;
293  size2 = FFMIN(p->buffer_end - p->buffer, size);
294  if (size2 != size)
295  p->eof = 1;
296  memcpy(p->buffer, src, size2);
297  p->buffer += size2;
298  return size2;
299 }
300 
302  const uint8_t *src,
303  unsigned int size)
304 {
305  memcpy(p->buffer, src, size);
306  p->buffer += size;
307  return size;
308 }
309 
311  const uint8_t c,
312  unsigned int size)
313 {
314  int size2;
315  if (p->eof)
316  return;
317  size2 = FFMIN(p->buffer_end - p->buffer, size);
318  if (size2 != size)
319  p->eof = 1;
320  memset(p->buffer, c, size2);
321  p->buffer += size2;
322 }
323 
325  const uint8_t c,
326  unsigned int size)
327 {
328  memset(p->buffer, c, size);
329  p->buffer += size;
330 }
331 
333 {
334  return p->eof;
335 }
336 
338  GetByteContext *g,
339  unsigned int size)
340 {
341  memcpy(p->buffer, g->buffer, size);
342  p->buffer += size;
343  g->buffer += size;
344  return size;
345 }
346 
348  GetByteContext *g,
349  unsigned int size)
350 {
351  int size2;
352 
353  if (p->eof)
354  return 0;
355  size = FFMIN(g->buffer_end - g->buffer, size);
356  size2 = FFMIN(p->buffer_end - p->buffer, size);
357  if (size2 != size)
358  p->eof = 1;
359 
360  return bytestream2_copy_bufferu(p, g, size2);
361 }
362 
363 static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b,
364  uint8_t *dst,
365  unsigned int size)
366 {
367  memcpy(dst, *b, size);
368  (*b) += size;
369  return size;
370 }
371 
373  const uint8_t *src,
374  unsigned int size)
375 {
376  memcpy(*b, src, size);
377  (*b) += size;
378 }
379 
380 #endif /* AVCODEC_BYTESTREAM_H */
le32
uint64_t_TMPL AV_WL64 unsigned int_TMPL le32
Definition: bytestream.h:92
av_clip
#define av_clip
Definition: common.h:96
bytestream2_get_eof
static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
Definition: bytestream.h:332
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:91
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
bytestream2_seek
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:212
b
#define b
Definition: input.c:40
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:197
bytestream2_size_p
static av_always_inline int bytestream2_size_p(PutByteContext *p)
Definition: bytestream.h:207
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
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:97
le24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL le24
Definition: bytestream.h:93
avassert.h
bytestream2_get_bytes_left_p
static av_always_inline int bytestream2_get_bytes_left_p(PutByteContext *p)
Definition: bytestream.h:163
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
intreadwrite.h
g
const char * g
Definition: vf_curves.c:117
bytestream2_put_buffer
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:286
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:94
bytestream2_copy_bufferu
static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p, GetByteContext *g, unsigned int size)
Definition: bytestream.h:337
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
src
#define src
Definition: vp8dsp.c:255
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:95
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
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:96
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_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
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:202
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:10344
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:96
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:93
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
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:372
bytestream2_skip_p
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition: bytestream.h:180
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
bytestream2_set_bufferu
static av_always_inline void bytestream2_set_bufferu(PutByteContext *p, const uint8_t c, unsigned int size)
Definition: bytestream.h:324
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
bytestream2_set_buffer
static av_always_inline void bytestream2_set_buffer(PutByteContext *p, const uint8_t c, unsigned int size)
Definition: bytestream.h:310
le64
uint64_t_TMPL le64
Definition: bytestream.h:91
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:363
bytestream2_copy_buffer
static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p, GetByteContext *g, unsigned int size)
Definition: bytestream.h:347
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:98
le16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL le16
Definition: bytestream.h:94
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
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:236
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:99
bytestream2_get_bufferu
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:277
bytestream2_put_bufferu
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:301
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
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:97
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:95
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