avpacket.c
Go to the documentation of this file.
1 /*
2  * AVPacket functions for libavcodec
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <string.h>
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/mem.h"
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "internal.h"
30 
32 {
33  int i;
34  for (i = 0; i < pkt->side_data_elems; i++)
35  av_free(pkt->side_data[i].data);
36  av_freep(&pkt->side_data);
37  pkt->side_data_elems = 0;
38 }
39 
40 #if FF_API_DESTRUCT_PACKET
41 void av_destruct_packet(AVPacket *pkt)
42 {
43  av_free(pkt->data);
44  pkt->data = NULL;
45  pkt->size = 0;
46 }
47 
48 /* a dummy destruct callback for the callers that assume AVPacket.destruct ==
49  * NULL => static data */
50 static void dummy_destruct_packet(AVPacket *pkt)
51 {
52  av_assert0(0);
53 }
54 #endif
55 
57 {
58  pkt->pts = AV_NOPTS_VALUE;
59  pkt->dts = AV_NOPTS_VALUE;
60  pkt->pos = -1;
61  pkt->duration = 0;
62  pkt->convergence_duration = 0;
63  pkt->flags = 0;
64  pkt->stream_index = 0;
65 #if FF_API_DESTRUCT_PACKET
66  pkt->destruct = NULL;
67 #endif
68  pkt->buf = NULL;
69  pkt->side_data = NULL;
70  pkt->side_data_elems = 0;
71 }
72 
73 int av_new_packet(AVPacket *pkt, int size)
74 {
75  AVBufferRef *buf = NULL;
76 
77  if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
78  return AVERROR(EINVAL);
79 
81  if (!buf)
82  return AVERROR(ENOMEM);
83 
84  memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
85 
86  av_init_packet(pkt);
87  pkt->buf = buf;
88  pkt->data = buf->data;
89  pkt->size = size;
90 #if FF_API_DESTRUCT_PACKET
91  pkt->destruct = dummy_destruct_packet;
92 #endif
93 
94  return 0;
95 }
96 
98 {
99  if (pkt->size <= size)
100  return;
101  pkt->size = size;
102  memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
103 }
104 
105 int av_grow_packet(AVPacket *pkt, int grow_by)
106 {
107  int new_size;
108  av_assert0((unsigned)pkt->size <= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
109  if (!pkt->size)
110  return av_new_packet(pkt, grow_by);
111  if ((unsigned)grow_by >
112  INT_MAX - (pkt->size + FF_INPUT_BUFFER_PADDING_SIZE))
113  return -1;
114 
115  new_size = pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE;
116  if (pkt->buf) {
117  int ret = av_buffer_realloc(&pkt->buf, new_size);
118  if (ret < 0)
119  return ret;
120  } else {
121  pkt->buf = av_buffer_alloc(new_size);
122  if (!pkt->buf)
123  return AVERROR(ENOMEM);
124  memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
125 #if FF_API_DESTRUCT_PACKET
126  pkt->destruct = dummy_destruct_packet;
127 #endif
128  }
129  pkt->data = pkt->buf->data;
130  pkt->size += grow_by;
131  memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
132 
133  return 0;
134 }
135 
137 {
138  if (size >= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
139  return AVERROR(EINVAL);
140 
143  if (!pkt->buf)
144  return AVERROR(ENOMEM);
145 
146  pkt->data = data;
147  pkt->size = size;
148 #if FF_API_DESTRUCT_PACKET
149  pkt->destruct = dummy_destruct_packet;
150 #endif
151 
152  return 0;
153 }
154 
155 #define ALLOC_MALLOC(data, size) data = av_malloc(size)
156 #define ALLOC_BUF(data, size) \
157 do { \
158  av_buffer_realloc(&pkt->buf, size); \
159  data = pkt->buf ? pkt->buf->data : NULL; \
160 } while (0)
161 
162 #define DUP_DATA(dst, src, size, padding, ALLOC) \
163  do { \
164  void *data; \
165  if (padding) { \
166  if ((unsigned)(size) > \
167  (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
168  goto failed_alloc; \
169  ALLOC(data, size + FF_INPUT_BUFFER_PADDING_SIZE); \
170  } else { \
171  ALLOC(data, size); \
172  } \
173  if (!data) \
174  goto failed_alloc; \
175  memcpy(data, src, size); \
176  if (padding) \
177  memset((uint8_t *)data + size, 0, \
178  FF_INPUT_BUFFER_PADDING_SIZE); \
179  dst = data; \
180  } while (0)
181 
182 /* Makes duplicates of data, side_data, but does not copy any other fields */
184 {
185  pkt->data = NULL;
186  pkt->side_data = NULL;
187  if (pkt->buf) {
188  AVBufferRef *ref = av_buffer_ref(src->buf);
189  if (!ref)
190  return AVERROR(ENOMEM);
191  pkt->buf = ref;
192  pkt->data = ref->data;
193  } else {
194  DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
195  }
196 #if FF_API_DESTRUCT_PACKET
197  pkt->destruct = dummy_destruct_packet;
198 #endif
199 
200  if (pkt->side_data_elems) {
201  int i;
202 
203  DUP_DATA(pkt->side_data, src->side_data,
204  pkt->side_data_elems * sizeof(*pkt->side_data), 0, ALLOC_MALLOC);
205  memset(pkt->side_data, 0,
206  pkt->side_data_elems * sizeof(*pkt->side_data));
207  for (i = 0; i < pkt->side_data_elems; i++) {
208  DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
209  src->side_data[i].size, 1, ALLOC_MALLOC);
210  pkt->side_data[i].size = src->side_data[i].size;
211  pkt->side_data[i].type = src->side_data[i].type;
212  }
213  }
214  return 0;
215 
216 failed_alloc:
217  av_destruct_packet(pkt);
218  return AVERROR(ENOMEM);
219 }
220 
222 {
223  AVPacket tmp_pkt;
224 
225  if (!pkt->buf && pkt->data
227  && !pkt->destruct
228 #endif
229  ) {
230  tmp_pkt = *pkt;
231  return copy_packet_data(pkt, &tmp_pkt);
232  }
233  return 0;
234 }
235 
237 {
238  *dst = *src;
239  return copy_packet_data(dst, src);
240 }
241 
243 {
244  if (pkt) {
245  int i;
246 
247  if (pkt->buf)
248  av_buffer_unref(&pkt->buf);
249 #if FF_API_DESTRUCT_PACKET
250  else if (pkt->destruct)
251  pkt->destruct(pkt);
252  pkt->destruct = NULL;
253 #endif
254  pkt->data = NULL;
255  pkt->size = 0;
256 
257  for (i = 0; i < pkt->side_data_elems; i++)
258  av_free(pkt->side_data[i].data);
259  av_freep(&pkt->side_data);
260  pkt->side_data_elems = 0;
261  }
262 }
263 
265  int size)
266 {
267  int elems = pkt->side_data_elems;
268 
269  if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
270  return NULL;
271  if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
272  return NULL;
273 
274  pkt->side_data = av_realloc(pkt->side_data,
275  (elems + 1) * sizeof(*pkt->side_data));
276  if (!pkt->side_data)
277  return NULL;
278 
280  if (!pkt->side_data[elems].data)
281  return NULL;
282  pkt->side_data[elems].size = size;
283  pkt->side_data[elems].type = type;
284  pkt->side_data_elems++;
285 
286  return pkt->side_data[elems].data;
287 }
288 
290  int *size)
291 {
292  int i;
293 
294  for (i = 0; i < pkt->side_data_elems; i++) {
295  if (pkt->side_data[i].type == type) {
296  if (size)
297  *size = pkt->side_data[i].size;
298  return pkt->side_data[i].data;
299  }
300  }
301  return NULL;
302 }
303 
304 #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
305 
307  if(pkt->side_data_elems){
308  AVBufferRef *buf;
309  int i;
310  uint8_t *p;
311  uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE;
312  AVPacket old= *pkt;
313  for (i=0; i<old.side_data_elems; i++) {
314  size += old.side_data[i].size + 5LL;
315  }
316  if (size > INT_MAX)
317  return AVERROR(EINVAL);
318  buf = av_buffer_alloc(size);
319  if (!buf)
320  return AVERROR(ENOMEM);
321  pkt->buf = buf;
322  pkt->data = p = buf->data;
323 #if FF_API_DESTRUCT_PACKET
324  pkt->destruct = dummy_destruct_packet;
325 #endif
326  pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
327  bytestream_put_buffer(&p, old.data, old.size);
328  for (i=old.side_data_elems-1; i>=0; i--) {
329  bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
330  bytestream_put_be32(&p, old.side_data[i].size);
331  *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
332  }
333  bytestream_put_be64(&p, FF_MERGE_MARKER);
334  av_assert0(p-pkt->data == pkt->size);
335  memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
336  av_free_packet(&old);
337  pkt->side_data_elems = 0;
338  pkt->side_data = NULL;
339  return 1;
340  }
341  return 0;
342 }
343 
345  if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
346  int i;
347  unsigned int size;
348  uint8_t *p;
349 
350  p = pkt->data + pkt->size - 8 - 5;
351  for (i=1; ; i++){
352  size = AV_RB32(p);
353  if (size>INT_MAX || p - pkt->data < size)
354  return 0;
355  if (p[4]&128)
356  break;
357  p-= size+5;
358  }
359 
360  pkt->side_data = av_malloc(i * sizeof(*pkt->side_data));
361  if (!pkt->side_data)
362  return AVERROR(ENOMEM);
363 
364  p= pkt->data + pkt->size - 8 - 5;
365  for (i=0; ; i++){
366  size= AV_RB32(p);
367  av_assert0(size<=INT_MAX && p - pkt->data >= size);
369  pkt->side_data[i].size = size;
370  pkt->side_data[i].type = p[4]&127;
371  if (!pkt->side_data[i].data)
372  return AVERROR(ENOMEM);
373  memcpy(pkt->side_data[i].data, p-size, size);
374  pkt->size -= size + 5;
375  if(p[4]&128)
376  break;
377  p-= size+5;
378  }
379  pkt->size -= 8;
380  pkt->side_data_elems = i+1;
381  return 1;
382  }
383  return 0;
384 }
385 
387  int size)
388 {
389  int i;
390 
391  for (i = 0; i < pkt->side_data_elems; i++) {
392  if (pkt->side_data[i].type == type) {
393  if (size > pkt->side_data[i].size)
394  return AVERROR(ENOMEM);
395  pkt->side_data[i].size = size;
396  return 0;
397  }
398  }
399  return AVERROR(ENOENT);
400 }
#define DUP_DATA(dst, src, size, padding, ALLOC)
Definition: avpacket.c:162
AVPacketSideDataType
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
FIXME Range Coding of cr are ref
Definition: snow.txt:367
memory handling functions
int64_t pos
byte position in stream, -1 if unknown
#define AV_RB64
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
Definition: avpacket.c:97
#define ALLOC_MALLOC(data, size)
Definition: avpacket.c:155
int av_copy_packet(AVPacket *dst, AVPacket *src)
Copy packet, including contents.
Definition: avpacket.c:236
#define ALLOC_BUF(data, size)
Definition: avpacket.c:156
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
int av_dup_packet(AVPacket *pkt)
Definition: avpacket.c:221
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
#define AV_RB32
static AVPacket pkt
Definition: demuxing.c:56
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
Initialize a reference-counted packet from av_malloc()ed data.
Definition: avpacket.c:136
uint8_t * data
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
void av_buffer_default_free(void *opaque, uint8_t *data)
Default free callback, which calls av_free() on the buffer data.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
Spectrum Plot time data
int64_t convergence_duration
Time difference in AVStream->time_base units from the pts of this packet to the point at which the ou...
static int copy_packet_data(AVPacket *pkt, AVPacket *src)
Definition: avpacket.c:183
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
simple assert() macros that are a bit more flexible than ISO C assert().
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Shrink the already allocated side data buffer.
Definition: avpacket.c:386
int av_buffer_realloc(AVBufferRef **pbuf, int size)
Reallocate a given buffer.
external API header
int size
int flags
A combination of AV_PKT_FLAG values.
int av_packet_merge_side_data(AVPacket *pkt)
Definition: avpacket.c:306
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
#define FF_API_DESTRUCT_PACKET
int av_packet_split_side_data(AVPacket *pkt)
Definition: avpacket.c:344
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
uint8_t * data
The data buffer.
Definition: buffer.h:89
void * buf
Definition: avisynth_c.h:594
void ff_packet_free_side_data(AVPacket *pkt)
Remove and free all side data from packet.
Definition: avpacket.c:31
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define type
#define FF_MERGE_MARKER
Definition: avpacket.c:304
A reference to a data buffer.
Definition: buffer.h:81
common internal api header.
common internal and external API header
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition: avpacket.c:105
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:56
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
struct AVPacket::@35 * side_data
Additional packet data that can be provided by the container.
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
uint8_t * av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:289
enum AVPacketSideDataType type
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:264
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190