[FFmpeg-cvslog] lavf: always unref the packet passed to av_interleaved_write_frame() on error

Anton Khirnov git at videolan.org
Mon Feb 10 20:32:11 CET 2014


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue Feb  4 15:58:11 2014 +0100| [394fb56c29eee7f4f8f0334d8b5d30d3c54ac703] | committer: Anton Khirnov

lavf: always unref the packet passed to av_interleaved_write_frame() on error

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=394fb56c29eee7f4f8f0334d8b5d30d3c54ac703
---

 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 71ff0fc..0b8fca2 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 c16d1c8..59f9c42 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)



More information about the ffmpeg-cvslog mailing list