From 394fb56c29eee7f4f8f0334d8b5d30d3c54ac703 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 4 Feb 2014 15:58:11 +0100 Subject: [PATCH] lavf: always unref the packet passed to av_interleaved_write_frame() on error --- libavformat/avformat.h | 3 ++- libavformat/mux.c | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 71ff0fc15b..0b8fca21a7 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1589,7 +1589,8 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt); * correct values. * @endparblock * - * @return 0 on success, a negative AVERROR on error. + * @return 0 on success, a negative AVERROR on error. Libavformat will always + * take care of freeing the packet, even if this function fails. * * @see av_write_frame(), AVFormatContext.max_interleave_delta */ diff --git a/libavformat/mux.c b/libavformat/mux.c index c16d1c83a5..59f9c42cf1 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -619,22 +619,26 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) ret = check_packet(s, pkt); if (ret < 0) - return ret; + goto fail; if (pkt) { AVStream *st = s->streams[pkt->stream_index]; //FIXME/XXX/HACK drop zero sized packets - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0) - return 0; + if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0) { + ret = 0; + goto fail; + } av_dlog(s, "av_interleaved_write_frame size:%d dts:%" PRId64 " pts:%" PRId64 "\n", pkt->size, pkt->dts, pkt->pts); if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; + goto fail; - if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return AVERROR(EINVAL); + if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { + ret = AVERROR(EINVAL); + goto fail; + } } else { av_dlog(s, "av_interleaved_write_frame FLUSH\n"); flush = 1; @@ -643,6 +647,11 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) for (;; ) { AVPacket opkt; int ret = interleave_packet(s, &opkt, pkt, flush); + if (pkt) { + memset(pkt, 0, sizeof(*pkt)); + av_init_packet(pkt); + pkt = NULL; + } if (ret <= 0) //FIXME cleanup needed for ret<0 ? return ret; @@ -651,11 +660,13 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) s->streams[opkt.stream_index]->nb_frames++; av_free_packet(&opkt); - pkt = NULL; if (ret < 0) return ret; } +fail: + av_packet_unref(pkt); + return ret; } int av_write_trailer(AVFormatContext *s)