diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-10-31 08:53:18 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2013-03-08 07:33:45 +0100 |
commit | 1afddbe59e96af75f1c07605afc95615569f388f (patch) | |
tree | 0e8223d9813de6976ec50dc1a5a7c7bf9a099450 /libavformat | |
parent | 1cec0624d0e6f48590283a57169b58b9fe8449d3 (diff) | |
download | ffmpeg-1afddbe59e96af75f1c07605afc95615569f388f.tar.gz |
avpacket: use AVBuffer to allow refcounting the packets.
This will allow us to avoid copying the packets in many cases.
This breaks ABI.
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/asfdec.c | 16 | ||||
-rw-r--r-- | libavformat/avformat.h | 14 | ||||
-rw-r--r-- | libavformat/avidec.c | 8 | ||||
-rw-r--r-- | libavformat/flacdec.c | 13 | ||||
-rw-r--r-- | libavformat/id3v2.c | 16 | ||||
-rw-r--r-- | libavformat/id3v2.h | 3 | ||||
-rw-r--r-- | libavformat/matroskadec.c | 14 | ||||
-rw-r--r-- | libavformat/matroskaenc.c | 28 | ||||
-rw-r--r-- | libavformat/mp3enc.c | 6 | ||||
-rw-r--r-- | libavformat/mpegts.c | 18 | ||||
-rw-r--r-- | libavformat/mux.c | 3 | ||||
-rw-r--r-- | libavformat/mxg.c | 6 | ||||
-rw-r--r-- | libavformat/psxstr.c | 4 | ||||
-rw-r--r-- | libavformat/rmdec.c | 4 | ||||
-rw-r--r-- | libavformat/rtpdec.c | 8 | ||||
-rw-r--r-- | libavformat/rtpdec_qt.c | 6 | ||||
-rw-r--r-- | libavformat/utils.c | 19 |
17 files changed, 112 insertions, 74 deletions
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index d4694310fc..a30bf1aadf 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -1232,9 +1232,10 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->ds_span); } else { /* packet descrambling */ - uint8_t *newdata = av_malloc(asf_st->pkt.size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (newdata) { + AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size + + FF_INPUT_BUFFER_PADDING_SIZE); + if (buf) { + uint8_t *newdata = buf->data; int offset = 0; memset(newdata + asf_st->pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); @@ -1250,13 +1251,18 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk asf_st->ds_chunk_size); offset += asf_st->ds_chunk_size; } - av_free(asf_st->pkt.data); - asf_st->pkt.data = newdata; + av_buffer_unref(&asf_st->pkt.buf); + asf_st->pkt.buf = buf; + asf_st->pkt.data = buf->data; } } } asf_st->frag_offset = 0; *pkt = asf_st->pkt; +#if FF_API_DESTRUCT_PACKET + asf_st->pkt.destruct = NULL; +#endif + asf_st->pkt.buf = 0; asf_st->pkt.size = 0; asf_st->pkt.data = 0; asf_st->pkt.side_data_elems = 0; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 149b66f1c9..097d506a82 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -158,9 +158,9 @@ * information will be in AVStream.time_base units, i.e. it has to be * multiplied by the timebase to convert them to seconds. * - * If AVPacket.destruct is set on the returned packet, then the packet is + * If AVPacket.buf is set on the returned packet, then the packet is * allocated dynamically and the user may keep it indefinitely. - * Otherwise, if AVPacket.destruct is NULL, the packet data is backed by a + * Otherwise, if AVPacket.buf is NULL, the packet data is backed by a * static storage somewhere inside the demuxer and the packet is only valid * until the next av_read_frame() call or closing the file. If the caller * requires a longer lifetime, av_dup_packet() will make an av_malloc()ed copy @@ -1313,7 +1313,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt); * omit invalid data between valid frames so as to give the decoder the maximum * information possible for decoding. * - * If pkt->destruct is NULL, then the packet is valid until the next + * If pkt->buf is NULL, then the packet is valid until the next * av_read_frame() or until av_close_input_file(). Otherwise the packet is valid * indefinitely. In both cases the packet must be freed with * av_free_packet when it is no longer needed. For video, the packet contains @@ -1461,10 +1461,10 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt); * demuxer level. * * @param s media file handle - * @param pkt The packet containing the data to be written. Libavformat takes - * ownership of the data and will free it when it sees fit using the packet's - * @ref AVPacket.destruct "destruct" field. The caller must not access the data - * after this function returns, as it may already be freed. + * @param pkt The packet containing the data to be written. pkt->buf must be set + * to a valid AVBufferRef describing the packet data. Libavformat takes + * ownership of this reference and will unref it when it sees fit. The caller + * must not access the data through this reference after this function returns. * This can be NULL (at any time, not just at the end), to flush the * interleaving queues. * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 2277ef00bf..b235875c53 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -980,7 +980,9 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; int err; +#if FF_API_DESTRUCT_PACKET void* dstr; +#endif if (CONFIG_DV_DEMUXER && avi->dv_demux) { int size = avpriv_dv_get_packet(avi->dv_demux, pkt); @@ -1081,10 +1083,16 @@ resync: } if (CONFIG_DV_DEMUXER && avi->dv_demux) { + AVBufferRef *avbuf = pkt->buf; +#if FF_API_DESTRUCT_PACKET dstr = pkt->destruct; +#endif size = avpriv_dv_produce_packet(avi->dv_demux, pkt, pkt->data, pkt->size); +#if FF_API_DESTRUCT_PACKET pkt->destruct = dstr; +#endif + pkt->buf = avbuf; pkt->flags |= AV_PKT_FLAG_KEY; if (size < 0) av_free_packet(pkt); diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index f19f95d901..7aaec9eb26 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -32,7 +32,8 @@ static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) { const CodecMime *mime = ff_id3v2_mime_tags; enum AVCodecID id = AV_CODEC_ID_NONE; - uint8_t mimetype[64], *desc = NULL, *data = NULL; + AVBufferRef *data = NULL; + uint8_t mimetype[64], *desc = NULL; AVIOContext *pb = NULL; AVStream *st; int type, width, height; @@ -110,11 +111,11 @@ static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) ret = AVERROR_INVALIDDATA; goto fail; } - if (!(data = av_malloc(len))) { + if (!(data = av_buffer_alloc(len))) { ret = AVERROR(ENOMEM); goto fail; } - if (avio_read(pb, data, len) != len) { + if (avio_read(pb, data->data, len) != len) { av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n"); if (s->error_recognition & AV_EF_EXPLODE) ret = AVERROR(EIO); @@ -128,9 +129,9 @@ static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) } av_init_packet(&st->attached_pic); - st->attached_pic.data = data; + st->attached_pic.buf = data; + st->attached_pic.data = data->data; st->attached_pic.size = len; - st->attached_pic.destruct = av_destruct_packet; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; @@ -148,8 +149,8 @@ static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) return 0; fail: + av_buffer_unref(&data); av_freep(&desc); - av_freep(&data); av_freep(&pb); return ret; diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 4516ac74ef..204ea745d4 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -420,7 +420,7 @@ finish: static void free_apic(void *obj) { ID3v2ExtraMetaAPIC *apic = obj; - av_freep(&apic->data); + av_buffer_unref(&apic->buf); av_freep(&apic->description); av_freep(&apic); } @@ -476,9 +476,8 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag goto fail; } - apic->len = taglen; - apic->data = av_malloc(taglen); - if (!apic->data || avio_read(pb, apic->data, taglen) != taglen) + apic->buf = av_buffer_alloc(taglen); + if (!apic->buf || avio_read(pb, apic->buf->data, taglen) != taglen) goto fail; new_extra->tag = "APIC"; @@ -734,14 +733,13 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta) av_dict_set(&st->metadata, "comment", apic->type, 0); av_init_packet(&st->attached_pic); - st->attached_pic.data = apic->data; - st->attached_pic.size = apic->len; - st->attached_pic.destruct = av_destruct_packet; + st->attached_pic.buf = apic->buf; + st->attached_pic.data = apic->buf->data; + st->attached_pic.size = apic->buf->size; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; - apic->data = NULL; - apic->len = 0; + apic->buf = NULL; } return 0; diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h index cb2fb02093..7cb4296f11 100644 --- a/libavformat/id3v2.h +++ b/libavformat/id3v2.h @@ -67,8 +67,7 @@ typedef struct ID3v2ExtraMetaGEOB { } ID3v2ExtraMetaGEOB; typedef struct ID3v2ExtraMetaAPIC { - uint8_t *data; - int len; + AVBufferRef *buf; const char *type; uint8_t *description; enum AVCodecID id; diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 86ff477d85..a01e2c4f57 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1107,7 +1107,8 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size, static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, AVPacket *pkt, uint64_t display_duration) { - char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size; + AVBufferRef *line; + char *layer, *ptr = pkt->data, *end = ptr+pkt->size; for (; *ptr!=',' && ptr<end-1; ptr++); if (*ptr == ',') layer = ++ptr; @@ -1125,13 +1126,14 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, es = ec/ 100; ec -= 100*es; *ptr++ = '\0'; len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE; - if (!(line = av_malloc(len))) + if (!(line = av_buffer_alloc(len))) return; - snprintf(line,len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", + snprintf(line->data, len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", layer, sh, sm, ss, sc, eh, em, es, ec, ptr); - av_free(pkt->data); - pkt->data = line; - pkt->size = strlen(line); + av_buffer_unref(&pkt->buf); + pkt->buf = line; + pkt->data = line->data; + pkt->size = strlen(line->data); } } diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index b37d10cba1..b1e4a1e146 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -90,7 +90,6 @@ typedef struct MatroskaMuxContext { mkv_cues *cues; mkv_track *tracks; - unsigned int audio_buffer_size; AVPacket cur_audio_pkt; int have_attachments; @@ -969,7 +968,6 @@ static int mkv_write_header(AVFormatContext *s) av_init_packet(&mkv->cur_audio_pkt); mkv->cur_audio_pkt.size = 0; - mkv->audio_buffer_size = 0; avio_flush(pb); return 0; @@ -1180,19 +1178,6 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) return 0; } -static int mkv_copy_packet(MatroskaMuxContext *mkv, const AVPacket *pkt) -{ - uint8_t *data = mkv->cur_audio_pkt.data; - mkv->cur_audio_pkt = *pkt; - mkv->cur_audio_pkt.data = av_fast_realloc(data, &mkv->audio_buffer_size, pkt->size); - if (!mkv->cur_audio_pkt.data) - return AVERROR(ENOMEM); - - memcpy(mkv->cur_audio_pkt.data, pkt->data, pkt->size); - mkv->cur_audio_pkt.size = pkt->size; - return 0; -} - static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) { MatroskaMuxContext *mkv = s->priv_data; @@ -1219,7 +1204,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // check if we have an audio packet cached if (mkv->cur_audio_pkt.size > 0) { ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); - mkv->cur_audio_pkt.size = 0; + av_free_packet(&mkv->cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); return ret; @@ -1228,9 +1213,11 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) // buffer an audio packet to ensure the packet containing the video // keyframe's timecode is contained in the same cluster for WebM - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - ret = mkv_copy_packet(mkv, pkt); - else + if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { + mkv->cur_audio_pkt = *pkt; + mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf); + ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM); + } else ret = mkv_write_packet_internal(s, pkt); return ret; } @@ -1245,7 +1232,7 @@ static int mkv_write_trailer(AVFormatContext *s) // check if we have an audio packet cached if (mkv->cur_audio_pkt.size > 0) { ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); - mkv->cur_audio_pkt.size = 0; + av_free_packet(&mkv->cur_audio_pkt); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); return ret; @@ -1282,7 +1269,6 @@ static int mkv_write_trailer(AVFormatContext *s) av_free(mkv->tracks); av_freep(&mkv->cues->entries); av_freep(&mkv->cues); - av_destruct_packet(&mkv->cur_audio_pkt); return 0; } diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index c969777255..4d7c798c95 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -343,7 +343,11 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(ENOMEM); pktl->pkt = *pkt; - pkt->destruct = NULL; + pktl->pkt.buf = av_buffer_ref(pkt->buf); + if (!pktl->pkt.buf) { + av_freep(&pktl); + return AVERROR(ENOMEM); + } if (mp3->queue_end) mp3->queue_end->next = pktl; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 399b0743ce..61b8b55c42 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/buffer.h" #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" #include "libavutil/log.h" @@ -173,7 +174,7 @@ typedef struct PESContext { int64_t pts, dts; int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ uint8_t header[MAX_PES_HEADER_SIZE]; - uint8_t *buffer; + AVBufferRef *buffer; SLConfigDescr sl; } PESContext; @@ -364,7 +365,7 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) av_freep(&filter->u.section_filter.section_buf); else if (filter->type == MPEGTS_PES) { PESContext *pes = filter->u.pes_filter.opaque; - av_freep(&pes->buffer); + av_buffer_unref(&pes->buffer); /* referenced private data will be freed later in * avformat_close_input */ if (!((PESContext *)filter->u.pes_filter.opaque)->st) { @@ -635,8 +636,8 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) { av_init_packet(pkt); - pkt->destruct = av_destruct_packet; - pkt->data = pes->buffer; + pkt->buf = pes->buffer; + pkt->data = pes->buffer->data; pkt->size = pes->data_index; if(pes->total_size != MAX_PES_PAYLOAD && @@ -793,7 +794,8 @@ static int mpegts_push_data(MpegTSFilter *filter, pes->total_size = MAX_PES_PAYLOAD; /* allocate pes buffer */ - pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); + pes->buffer = av_buffer_alloc(pes->total_size + + FF_INPUT_BUFFER_PADDING_SIZE); if (!pes->buffer) return AVERROR(ENOMEM); @@ -895,7 +897,7 @@ static int mpegts_push_data(MpegTSFilter *filter, if (pes->data_index > 0 && pes->data_index+buf_size > pes->total_size) { new_pes_packet(pes, ts->pkt); pes->total_size = MAX_PES_PAYLOAD; - pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); + pes->buffer = av_buffer_alloc(pes->total_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!pes->buffer) return AVERROR(ENOMEM); ts->stop_parse = 1; @@ -904,7 +906,7 @@ static int mpegts_push_data(MpegTSFilter *filter, // not sure if this is legal in ts but see issue #2392 buf_size = pes->total_size; } - memcpy(pes->buffer+pes->data_index, p, buf_size); + memcpy(pes->buffer->data + pes->data_index, p, buf_size); pes->data_index += buf_size; } buf_size = 0; @@ -1781,7 +1783,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets) if (ts->pids[i]) { if (ts->pids[i]->type == MPEGTS_PES) { PESContext *pes = ts->pids[i]->u.pes_filter.opaque; - av_freep(&pes->buffer); + av_buffer_unref(&pes->buffer); pes->data_index = 0; pes->state = MPEGTS_SKIP; /* skip until pes header */ } diff --git a/libavformat/mux.c b/libavformat/mux.c index f7a7f3a2c9..cb3c297a6b 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -420,7 +420,10 @@ void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, this_pktl = av_mallocz(sizeof(AVPacketList)); this_pktl->pkt = *pkt; +#if FF_API_DESTRUCT_PACKET pkt->destruct = NULL; // do not free original but only the copy +#endif + pkt->buf = NULL; av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory if (s->streams[pkt->stream_index]->last_in_packet_buffer) { diff --git a/libavformat/mxg.c b/libavformat/mxg.c index 8959134769..ea54fe2277 100644 --- a/libavformat/mxg.c +++ b/libavformat/mxg.c @@ -168,7 +168,10 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->pts = pkt->dts = mxg->dts; pkt->stream_index = 0; +#if FF_API_DESTRUCT_PACKET pkt->destruct = NULL; +#endif + pkt->buf = NULL; pkt->size = mxg->buffer_ptr - mxg->soi_ptr; pkt->data = mxg->soi_ptr; @@ -206,7 +209,10 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt) /* time (GMT) of first sample in usec since 1970, little-endian */ pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8); pkt->stream_index = 1; +#if FF_API_DESTRUCT_PACKET pkt->destruct = NULL; +#endif + pkt->buf = NULL; pkt->size = size - 14; pkt->data = startmarker_ptr + 16; diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c index 633d61dd44..313a1d8fe7 100644 --- a/libavformat/psxstr.c +++ b/libavformat/psxstr.c @@ -201,6 +201,10 @@ static int str_read_packet(AVFormatContext *s, *ret_pkt = *pkt; pkt->data= NULL; pkt->size= -1; + pkt->buf = NULL; +#if FF_API_DESTRUCT_PACKET + pkt->destruct = NULL; +#endif return 0; } diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 3cf2c97fe4..7746740df6 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -678,6 +678,10 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, *pkt= vst->pkt; vst->pkt.data= NULL; vst->pkt.size= 0; + vst->pkt.buf = NULL; +#if FF_API_DESTRUCT_PACKET + vst->pkt.destruct = NULL; +#endif if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, vst->videobufpos - 1 - 8*vst->slices); diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index f734b91cbe..6652842441 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -864,11 +864,15 @@ int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p, int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx) { + int ret; av_init_packet(pkt); pkt->size = avio_close_dyn_buf(*dyn_buf, &pkt->data); pkt->stream_index = stream_idx; - pkt->destruct = av_destruct_packet; - *dyn_buf = NULL; + *dyn_buf = NULL; + if ((ret = av_packet_from_data(pkt, pkt->data, pkt->size)) < 0) { + av_freep(&pkt->data); + return ret; + } return pkt->size; } diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c index 6350507fc2..1222b4590d 100644 --- a/libavformat/rtpdec_qt.c +++ b/libavformat/rtpdec_qt.c @@ -186,12 +186,14 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt, memcpy(qt->pkt.data + qt->pkt.size, buf + avio_tell(&pb), alen); qt->pkt.size += alen; if (has_marker_bit) { - *pkt = qt->pkt; + int ret = av_packet_from_data(pkt, qt->pkt.data, qt->pkt.size); + if (ret < 0) + return ret; + qt->pkt.size = 0; qt->pkt.data = NULL; pkt->flags = flags & RTP_FLAG_KEY ? AV_PKT_FLAG_KEY : 0; pkt->stream_index = st->index; - pkt->destruct = av_destruct_packet; memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); return 0; } diff --git a/libavformat/utils.c b/libavformat/utils.c index a89e956d8d..61802a82e6 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -464,16 +464,20 @@ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, return &pktl->pkt; } -static void queue_attached_pictures(AVFormatContext *s) +static int queue_attached_pictures(AVFormatContext *s) { int i; for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC && s->streams[i]->discard < AVDISCARD_ALL) { AVPacket copy = s->streams[i]->attached_pic; - copy.destruct = NULL; + copy.buf = av_buffer_ref(copy.buf); + if (!copy.buf) + return AVERROR(ENOMEM); + add_to_pktbuf(&s->raw_packet_buffer, ©, &s->raw_packet_buffer_end); } + return 0; } int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) @@ -535,7 +539,8 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma goto fail; ff_id3v2_free_extra_meta(&id3v2_extra_meta); - queue_attached_pictures(s); + if ((ret = queue_attached_pictures(s)) < 0) + goto fail; if (s->pb && !s->data_offset) s->data_offset = avio_tell(s->pb); @@ -1074,8 +1079,12 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) } if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) { + out_pkt.buf = pkt->buf; + pkt->buf = NULL; +#if FF_API_DESTRUCT_PACKET out_pkt.destruct = pkt->destruct; pkt->destruct = NULL; +#endif } if ((ret = av_dup_packet(&out_pkt)) < 0) goto fail; @@ -1735,7 +1744,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f int ret = seek_frame_internal(s, stream_index, timestamp, flags); if (ret >= 0) - queue_attached_pictures(s); + ret = queue_attached_pictures(s); return ret; } @@ -1751,7 +1760,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags); if (ret >= 0) - queue_attached_pictures(s); + ret = queue_attached_pictures(s); return ret; } |