annotate ffmpeg/libavcodec/avpacket.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * AVPacket functions for libavcodec
yading@10 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 #include <string.h>
yading@10 23
yading@10 24 #include "libavutil/avassert.h"
yading@10 25 #include "libavutil/common.h"
yading@10 26 #include "libavutil/mem.h"
yading@10 27 #include "avcodec.h"
yading@10 28 #include "bytestream.h"
yading@10 29 #include "internal.h"
yading@10 30
yading@10 31 void ff_packet_free_side_data(AVPacket *pkt)
yading@10 32 {
yading@10 33 int i;
yading@10 34 for (i = 0; i < pkt->side_data_elems; i++)
yading@10 35 av_free(pkt->side_data[i].data);
yading@10 36 av_freep(&pkt->side_data);
yading@10 37 pkt->side_data_elems = 0;
yading@10 38 }
yading@10 39
yading@10 40 #if FF_API_DESTRUCT_PACKET
yading@10 41 void av_destruct_packet(AVPacket *pkt)
yading@10 42 {
yading@10 43 av_free(pkt->data);
yading@10 44 pkt->data = NULL;
yading@10 45 pkt->size = 0;
yading@10 46 }
yading@10 47
yading@10 48 /* a dummy destruct callback for the callers that assume AVPacket.destruct ==
yading@10 49 * NULL => static data */
yading@10 50 static void dummy_destruct_packet(AVPacket *pkt)
yading@10 51 {
yading@10 52 av_assert0(0);
yading@10 53 }
yading@10 54 #endif
yading@10 55
yading@10 56 void av_init_packet(AVPacket *pkt)
yading@10 57 {
yading@10 58 pkt->pts = AV_NOPTS_VALUE;
yading@10 59 pkt->dts = AV_NOPTS_VALUE;
yading@10 60 pkt->pos = -1;
yading@10 61 pkt->duration = 0;
yading@10 62 pkt->convergence_duration = 0;
yading@10 63 pkt->flags = 0;
yading@10 64 pkt->stream_index = 0;
yading@10 65 #if FF_API_DESTRUCT_PACKET
yading@10 66 pkt->destruct = NULL;
yading@10 67 #endif
yading@10 68 pkt->buf = NULL;
yading@10 69 pkt->side_data = NULL;
yading@10 70 pkt->side_data_elems = 0;
yading@10 71 }
yading@10 72
yading@10 73 int av_new_packet(AVPacket *pkt, int size)
yading@10 74 {
yading@10 75 AVBufferRef *buf = NULL;
yading@10 76
yading@10 77 if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
yading@10 78 return AVERROR(EINVAL);
yading@10 79
yading@10 80 av_buffer_realloc(&buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 81 if (!buf)
yading@10 82 return AVERROR(ENOMEM);
yading@10 83
yading@10 84 memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 85
yading@10 86 av_init_packet(pkt);
yading@10 87 pkt->buf = buf;
yading@10 88 pkt->data = buf->data;
yading@10 89 pkt->size = size;
yading@10 90 #if FF_API_DESTRUCT_PACKET
yading@10 91 pkt->destruct = dummy_destruct_packet;
yading@10 92 #endif
yading@10 93
yading@10 94 return 0;
yading@10 95 }
yading@10 96
yading@10 97 void av_shrink_packet(AVPacket *pkt, int size)
yading@10 98 {
yading@10 99 if (pkt->size <= size)
yading@10 100 return;
yading@10 101 pkt->size = size;
yading@10 102 memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 103 }
yading@10 104
yading@10 105 int av_grow_packet(AVPacket *pkt, int grow_by)
yading@10 106 {
yading@10 107 int new_size;
yading@10 108 av_assert0((unsigned)pkt->size <= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 109 if (!pkt->size)
yading@10 110 return av_new_packet(pkt, grow_by);
yading@10 111 if ((unsigned)grow_by >
yading@10 112 INT_MAX - (pkt->size + FF_INPUT_BUFFER_PADDING_SIZE))
yading@10 113 return -1;
yading@10 114
yading@10 115 new_size = pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE;
yading@10 116 if (pkt->buf) {
yading@10 117 int ret = av_buffer_realloc(&pkt->buf, new_size);
yading@10 118 if (ret < 0)
yading@10 119 return ret;
yading@10 120 } else {
yading@10 121 pkt->buf = av_buffer_alloc(new_size);
yading@10 122 if (!pkt->buf)
yading@10 123 return AVERROR(ENOMEM);
yading@10 124 memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
yading@10 125 #if FF_API_DESTRUCT_PACKET
yading@10 126 pkt->destruct = dummy_destruct_packet;
yading@10 127 #endif
yading@10 128 }
yading@10 129 pkt->data = pkt->buf->data;
yading@10 130 pkt->size += grow_by;
yading@10 131 memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 132
yading@10 133 return 0;
yading@10 134 }
yading@10 135
yading@10 136 int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
yading@10 137 {
yading@10 138 if (size >= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
yading@10 139 return AVERROR(EINVAL);
yading@10 140
yading@10 141 pkt->buf = av_buffer_create(data, size + FF_INPUT_BUFFER_PADDING_SIZE,
yading@10 142 av_buffer_default_free, NULL, 0);
yading@10 143 if (!pkt->buf)
yading@10 144 return AVERROR(ENOMEM);
yading@10 145
yading@10 146 pkt->data = data;
yading@10 147 pkt->size = size;
yading@10 148 #if FF_API_DESTRUCT_PACKET
yading@10 149 pkt->destruct = dummy_destruct_packet;
yading@10 150 #endif
yading@10 151
yading@10 152 return 0;
yading@10 153 }
yading@10 154
yading@10 155 #define ALLOC_MALLOC(data, size) data = av_malloc(size)
yading@10 156 #define ALLOC_BUF(data, size) \
yading@10 157 do { \
yading@10 158 av_buffer_realloc(&pkt->buf, size); \
yading@10 159 data = pkt->buf ? pkt->buf->data : NULL; \
yading@10 160 } while (0)
yading@10 161
yading@10 162 #define DUP_DATA(dst, src, size, padding, ALLOC) \
yading@10 163 do { \
yading@10 164 void *data; \
yading@10 165 if (padding) { \
yading@10 166 if ((unsigned)(size) > \
yading@10 167 (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
yading@10 168 goto failed_alloc; \
yading@10 169 ALLOC(data, size + FF_INPUT_BUFFER_PADDING_SIZE); \
yading@10 170 } else { \
yading@10 171 ALLOC(data, size); \
yading@10 172 } \
yading@10 173 if (!data) \
yading@10 174 goto failed_alloc; \
yading@10 175 memcpy(data, src, size); \
yading@10 176 if (padding) \
yading@10 177 memset((uint8_t *)data + size, 0, \
yading@10 178 FF_INPUT_BUFFER_PADDING_SIZE); \
yading@10 179 dst = data; \
yading@10 180 } while (0)
yading@10 181
yading@10 182 /* Makes duplicates of data, side_data, but does not copy any other fields */
yading@10 183 static int copy_packet_data(AVPacket *pkt, AVPacket *src)
yading@10 184 {
yading@10 185 pkt->data = NULL;
yading@10 186 pkt->side_data = NULL;
yading@10 187 if (pkt->buf) {
yading@10 188 AVBufferRef *ref = av_buffer_ref(src->buf);
yading@10 189 if (!ref)
yading@10 190 return AVERROR(ENOMEM);
yading@10 191 pkt->buf = ref;
yading@10 192 pkt->data = ref->data;
yading@10 193 } else {
yading@10 194 DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
yading@10 195 }
yading@10 196 #if FF_API_DESTRUCT_PACKET
yading@10 197 pkt->destruct = dummy_destruct_packet;
yading@10 198 #endif
yading@10 199
yading@10 200 if (pkt->side_data_elems) {
yading@10 201 int i;
yading@10 202
yading@10 203 DUP_DATA(pkt->side_data, src->side_data,
yading@10 204 pkt->side_data_elems * sizeof(*pkt->side_data), 0, ALLOC_MALLOC);
yading@10 205 memset(pkt->side_data, 0,
yading@10 206 pkt->side_data_elems * sizeof(*pkt->side_data));
yading@10 207 for (i = 0; i < pkt->side_data_elems; i++) {
yading@10 208 DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
yading@10 209 src->side_data[i].size, 1, ALLOC_MALLOC);
yading@10 210 pkt->side_data[i].size = src->side_data[i].size;
yading@10 211 pkt->side_data[i].type = src->side_data[i].type;
yading@10 212 }
yading@10 213 }
yading@10 214 return 0;
yading@10 215
yading@10 216 failed_alloc:
yading@10 217 av_destruct_packet(pkt);
yading@10 218 return AVERROR(ENOMEM);
yading@10 219 }
yading@10 220
yading@10 221 int av_dup_packet(AVPacket *pkt)
yading@10 222 {
yading@10 223 AVPacket tmp_pkt;
yading@10 224
yading@10 225 if (!pkt->buf && pkt->data
yading@10 226 #if FF_API_DESTRUCT_PACKET
yading@10 227 && !pkt->destruct
yading@10 228 #endif
yading@10 229 ) {
yading@10 230 tmp_pkt = *pkt;
yading@10 231 return copy_packet_data(pkt, &tmp_pkt);
yading@10 232 }
yading@10 233 return 0;
yading@10 234 }
yading@10 235
yading@10 236 int av_copy_packet(AVPacket *dst, AVPacket *src)
yading@10 237 {
yading@10 238 *dst = *src;
yading@10 239 return copy_packet_data(dst, src);
yading@10 240 }
yading@10 241
yading@10 242 void av_free_packet(AVPacket *pkt)
yading@10 243 {
yading@10 244 if (pkt) {
yading@10 245 int i;
yading@10 246
yading@10 247 if (pkt->buf)
yading@10 248 av_buffer_unref(&pkt->buf);
yading@10 249 #if FF_API_DESTRUCT_PACKET
yading@10 250 else if (pkt->destruct)
yading@10 251 pkt->destruct(pkt);
yading@10 252 pkt->destruct = NULL;
yading@10 253 #endif
yading@10 254 pkt->data = NULL;
yading@10 255 pkt->size = 0;
yading@10 256
yading@10 257 for (i = 0; i < pkt->side_data_elems; i++)
yading@10 258 av_free(pkt->side_data[i].data);
yading@10 259 av_freep(&pkt->side_data);
yading@10 260 pkt->side_data_elems = 0;
yading@10 261 }
yading@10 262 }
yading@10 263
yading@10 264 uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
yading@10 265 int size)
yading@10 266 {
yading@10 267 int elems = pkt->side_data_elems;
yading@10 268
yading@10 269 if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
yading@10 270 return NULL;
yading@10 271 if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
yading@10 272 return NULL;
yading@10 273
yading@10 274 pkt->side_data = av_realloc(pkt->side_data,
yading@10 275 (elems + 1) * sizeof(*pkt->side_data));
yading@10 276 if (!pkt->side_data)
yading@10 277 return NULL;
yading@10 278
yading@10 279 pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 280 if (!pkt->side_data[elems].data)
yading@10 281 return NULL;
yading@10 282 pkt->side_data[elems].size = size;
yading@10 283 pkt->side_data[elems].type = type;
yading@10 284 pkt->side_data_elems++;
yading@10 285
yading@10 286 return pkt->side_data[elems].data;
yading@10 287 }
yading@10 288
yading@10 289 uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
yading@10 290 int *size)
yading@10 291 {
yading@10 292 int i;
yading@10 293
yading@10 294 for (i = 0; i < pkt->side_data_elems; i++) {
yading@10 295 if (pkt->side_data[i].type == type) {
yading@10 296 if (size)
yading@10 297 *size = pkt->side_data[i].size;
yading@10 298 return pkt->side_data[i].data;
yading@10 299 }
yading@10 300 }
yading@10 301 return NULL;
yading@10 302 }
yading@10 303
yading@10 304 #define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
yading@10 305
yading@10 306 int av_packet_merge_side_data(AVPacket *pkt){
yading@10 307 if(pkt->side_data_elems){
yading@10 308 AVBufferRef *buf;
yading@10 309 int i;
yading@10 310 uint8_t *p;
yading@10 311 uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE;
yading@10 312 AVPacket old= *pkt;
yading@10 313 for (i=0; i<old.side_data_elems; i++) {
yading@10 314 size += old.side_data[i].size + 5LL;
yading@10 315 }
yading@10 316 if (size > INT_MAX)
yading@10 317 return AVERROR(EINVAL);
yading@10 318 buf = av_buffer_alloc(size);
yading@10 319 if (!buf)
yading@10 320 return AVERROR(ENOMEM);
yading@10 321 pkt->buf = buf;
yading@10 322 pkt->data = p = buf->data;
yading@10 323 #if FF_API_DESTRUCT_PACKET
yading@10 324 pkt->destruct = dummy_destruct_packet;
yading@10 325 #endif
yading@10 326 pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
yading@10 327 bytestream_put_buffer(&p, old.data, old.size);
yading@10 328 for (i=old.side_data_elems-1; i>=0; i--) {
yading@10 329 bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
yading@10 330 bytestream_put_be32(&p, old.side_data[i].size);
yading@10 331 *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
yading@10 332 }
yading@10 333 bytestream_put_be64(&p, FF_MERGE_MARKER);
yading@10 334 av_assert0(p-pkt->data == pkt->size);
yading@10 335 memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 336 av_free_packet(&old);
yading@10 337 pkt->side_data_elems = 0;
yading@10 338 pkt->side_data = NULL;
yading@10 339 return 1;
yading@10 340 }
yading@10 341 return 0;
yading@10 342 }
yading@10 343
yading@10 344 int av_packet_split_side_data(AVPacket *pkt){
yading@10 345 if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
yading@10 346 int i;
yading@10 347 unsigned int size;
yading@10 348 uint8_t *p;
yading@10 349
yading@10 350 p = pkt->data + pkt->size - 8 - 5;
yading@10 351 for (i=1; ; i++){
yading@10 352 size = AV_RB32(p);
yading@10 353 if (size>INT_MAX || p - pkt->data < size)
yading@10 354 return 0;
yading@10 355 if (p[4]&128)
yading@10 356 break;
yading@10 357 p-= size+5;
yading@10 358 }
yading@10 359
yading@10 360 pkt->side_data = av_malloc(i * sizeof(*pkt->side_data));
yading@10 361 if (!pkt->side_data)
yading@10 362 return AVERROR(ENOMEM);
yading@10 363
yading@10 364 p= pkt->data + pkt->size - 8 - 5;
yading@10 365 for (i=0; ; i++){
yading@10 366 size= AV_RB32(p);
yading@10 367 av_assert0(size<=INT_MAX && p - pkt->data >= size);
yading@10 368 pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 369 pkt->side_data[i].size = size;
yading@10 370 pkt->side_data[i].type = p[4]&127;
yading@10 371 if (!pkt->side_data[i].data)
yading@10 372 return AVERROR(ENOMEM);
yading@10 373 memcpy(pkt->side_data[i].data, p-size, size);
yading@10 374 pkt->size -= size + 5;
yading@10 375 if(p[4]&128)
yading@10 376 break;
yading@10 377 p-= size+5;
yading@10 378 }
yading@10 379 pkt->size -= 8;
yading@10 380 pkt->side_data_elems = i+1;
yading@10 381 return 1;
yading@10 382 }
yading@10 383 return 0;
yading@10 384 }
yading@10 385
yading@10 386 int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
yading@10 387 int size)
yading@10 388 {
yading@10 389 int i;
yading@10 390
yading@10 391 for (i = 0; i < pkt->side_data_elems; i++) {
yading@10 392 if (pkt->side_data[i].type == type) {
yading@10 393 if (size > pkt->side_data[i].size)
yading@10 394 return AVERROR(ENOMEM);
yading@10 395 pkt->side_data[i].size = size;
yading@10 396 return 0;
yading@10 397 }
yading@10 398 }
yading@10 399 return AVERROR(ENOENT);
yading@10 400 }