FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 
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 
142  av_buffer_default_free, NULL, 0);
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 */
183 static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup)
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  if (pkt->side_data_elems && dup)
200  pkt->side_data = src->side_data;
201  if (pkt->side_data_elems && !dup) {
202  return av_copy_packet_side_data(pkt, src);
203  }
204  return 0;
205 
206 failed_alloc:
207  av_destruct_packet(pkt);
208  return AVERROR(ENOMEM);
209 }
210 
212 {
213  if (src->side_data_elems) {
214  int i;
215  DUP_DATA(pkt->side_data, src->side_data,
216  src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
217  memset(pkt->side_data, 0,
218  src->side_data_elems * sizeof(*src->side_data));
219  for (i = 0; i < src->side_data_elems; i++) {
220  DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
221  src->side_data[i].size, 1, ALLOC_MALLOC);
222  pkt->side_data[i].size = src->side_data[i].size;
223  pkt->side_data[i].type = src->side_data[i].type;
224  }
225  }
226  return 0;
227 
228 failed_alloc:
229  av_destruct_packet(pkt);
230  return AVERROR(ENOMEM);
231 }
232 
234 {
235  AVPacket tmp_pkt;
236 
237  if (!pkt->buf && pkt->data
239  && !pkt->destruct
240 #endif
241  ) {
242  tmp_pkt = *pkt;
243  return copy_packet_data(pkt, &tmp_pkt, 1);
244  }
245  return 0;
246 }
247 
249 {
250  *dst = *src;
251  return copy_packet_data(dst, src, 0);
252 }
253 
255 {
256  if (pkt) {
257  int i;
258 
259  if (pkt->buf)
260  av_buffer_unref(&pkt->buf);
261 #if FF_API_DESTRUCT_PACKET
262  else if (pkt->destruct)
263  pkt->destruct(pkt);
264  pkt->destruct = NULL;
265 #endif
266  pkt->data = NULL;
267  pkt->size = 0;
268 
269  for (i = 0; i < pkt->side_data_elems; i++)
270  av_free(pkt->side_data[i].data);
271  av_freep(&pkt->side_data);
272  pkt->side_data_elems = 0;
273  }
274 }
275 
277  int size)
278 {
279  int elems = pkt->side_data_elems;
280 
281  if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
282  return NULL;
283  if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
284  return NULL;
285 
286  pkt->side_data = av_realloc(pkt->side_data,
287  (elems + 1) * sizeof(*pkt->side_data));
288  if (!pkt->side_data)
289  return NULL;
290 
292  if (!pkt->side_data[elems].data)
293  return NULL;
294  pkt->side_data[elems].size = size;
295  pkt->side_data[elems].type = type;
296  pkt->side_data_elems++;
297 
298  return pkt->side_data[elems].data;
299 }
300 
302  int *size)
303 {
304  int i;
305 
306  for (i = 0; i < pkt->side_data_elems; i++) {
307  if (pkt->side_data[i].type == type) {
308  if (size)
309  *size = pkt->side_data[i].size;
310  return pkt->side_data[i].data;
311  }
312  }
313  return NULL;
314 }
315 
316 #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
317 
319  if(pkt->side_data_elems){
320  AVBufferRef *buf;
321  int i;
322  uint8_t *p;
323  uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE;
324  AVPacket old= *pkt;
325  for (i=0; i<old.side_data_elems; i++) {
326  size += old.side_data[i].size + 5LL;
327  }
328  if (size > INT_MAX)
329  return AVERROR(EINVAL);
330  buf = av_buffer_alloc(size);
331  if (!buf)
332  return AVERROR(ENOMEM);
333  pkt->buf = buf;
334  pkt->data = p = buf->data;
335 #if FF_API_DESTRUCT_PACKET
336  pkt->destruct = dummy_destruct_packet;
337 #endif
338  pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
339  bytestream_put_buffer(&p, old.data, old.size);
340  for (i=old.side_data_elems-1; i>=0; i--) {
341  bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
342  bytestream_put_be32(&p, old.side_data[i].size);
343  *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
344  }
345  bytestream_put_be64(&p, FF_MERGE_MARKER);
346  av_assert0(p-pkt->data == pkt->size);
347  memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
348  av_free_packet(&old);
349  pkt->side_data_elems = 0;
350  pkt->side_data = NULL;
351  return 1;
352  }
353  return 0;
354 }
355 
357  if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
358  int i;
359  unsigned int size, orig_pktsize = pkt->size;
360  uint8_t *p;
361 
362  p = pkt->data + pkt->size - 8 - 5;
363  for (i=1; ; i++){
364  size = AV_RB32(p);
365  if (size>INT_MAX || p - pkt->data < size)
366  return 0;
367  if (p[4]&128)
368  break;
369  p-= size+5;
370  }
371 
372  pkt->side_data = av_malloc(i * sizeof(*pkt->side_data));
373  if (!pkt->side_data)
374  return AVERROR(ENOMEM);
375 
376  p= pkt->data + pkt->size - 8 - 5;
377  for (i=0; ; i++){
378  size= AV_RB32(p);
379  av_assert0(size<=INT_MAX && p - pkt->data >= size);
381  pkt->side_data[i].size = size;
382  pkt->side_data[i].type = p[4]&127;
383  if (!pkt->side_data[i].data)
384  return AVERROR(ENOMEM);
385  memcpy(pkt->side_data[i].data, p-size, size);
386  pkt->size -= size + 5;
387  if(p[4]&128)
388  break;
389  p-= size+5;
390  }
391  pkt->size -= 8;
392  /* FFMIN() prevents overflow in case the packet wasn't allocated with
393  * proper padding.
394  * If the side data is smaller than the buffer padding size, the
395  * remaining bytes should have already been filled with zeros by the
396  * original packet allocation anyway. */
397  memset(pkt->data + pkt->size, 0,
398  FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE));
399  pkt->side_data_elems = i+1;
400  return 1;
401  }
402  return 0;
403 }
404 
406  int size)
407 {
408  int i;
409 
410  for (i = 0; i < pkt->side_data_elems; i++) {
411  if (pkt->side_data[i].type == type) {
412  if (size > pkt->side_data[i].size)
413  return AVERROR(ENOMEM);
414  pkt->side_data[i].size = size;
415  return 0;
416  }
417  }
418  return AVERROR(ENOENT);
419 }