[FFmpeg-devel,v2,4/8] avformat/utils: Move the reference to the packet list

Submitted by Andreas Rheinhardt on Aug. 19, 2019, 9:56 p.m.

Details

Message ID 20190819215624.49795-4-andreas.rheinhardt@gmail.com
State Accepted
Commit fc20ba9e049e5dde25643bffb2565a5477e6e5f6
Headers show

Commit Message

Andreas Rheinhardt Aug. 19, 2019, 9:56 p.m.
Up until now, ff_packet_list_put had a flaw: When it moved a packet to
the list (meaning, when it ought to move the reference to the packet
list instead of creating a new one via av_packet_ref), it did not reset
the original packet, confusing the ownership of the data in the packet.
This has been done because some callers of this function were not
compatible with resetting the packet.

This commit changes these callers and fixes this flaw. In order to
indicate that the ownership of the packet has moved to the packet list,
pointers to constant AVPackets are used whenever the target of the
pointer might already be owned by the packet list.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavformat/utils.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavformat/utils.c b/libavformat/utils.c
index b93d80588d..bae2f9e0db 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -460,10 +460,7 @@  int ff_packet_list_put(AVPacketList **packet_buffer,
             return ret;
         }
     } else {
-        // TODO: Adapt callers in this file so the line below can use
-        //       av_packet_move_ref() to effectively move the reference
-        //       to the list.
-        pktl->pkt = *pkt;
+        av_packet_move_ref(&pktl->pkt, pkt);
     }
 
     if (*packet_buffer)
@@ -835,6 +832,7 @@  int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     for (;;) {
         AVPacketList *pktl = s->internal->raw_packet_buffer;
+        const AVPacket *pkt1;
 
         if (pktl) {
             st = s->streams[pktl->pkt.stream_index];
@@ -923,9 +921,10 @@  int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
             av_packet_unref(pkt);
             return err;
         }
-        s->internal->raw_packet_buffer_remaining_size -= pkt->size;
+        pkt1 = &s->internal->raw_packet_buffer_end->pkt;
+        s->internal->raw_packet_buffer_remaining_size -= pkt1->size;
 
-        if ((err = probe_codec(s, st, pkt)) < 0)
+        if ((err = probe_codec(s, st, pkt1)) < 0)
             return err;
     }
 }
@@ -3028,8 +3027,8 @@  static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
 }
 
 /* returns 1 or 0 if or if not decoded data was returned, or a negative error */
-static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
-                            AVDictionary **options)
+static int try_decode_frame(AVFormatContext *s, AVStream *st,
+                            const AVPacket *avpkt, AVDictionary **options)
 {
     AVCodecContext *avctx = st->internal->avctx;
     const AVCodec *codec;
@@ -3521,7 +3520,7 @@  fail:
     return ret;
 }
 
-static int extract_extradata(AVStream *st, AVPacket *pkt)
+static int extract_extradata(AVStream *st, const AVPacket *pkt)
 {
     AVStreamInternal *sti = st->internal;
     AVPacket *pkt_ref;
@@ -3584,7 +3583,7 @@  int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     int64_t read_size;
     AVStream *st;
     AVCodecContext *avctx;
-    AVPacket pkt1, *pkt;
+    AVPacket pkt1;
     int64_t old_offset  = avio_tell(ic->pb);
     // new streams might appear, no options for those
     int orig_nb_streams = ic->nb_streams;
@@ -3703,6 +3702,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
 
     read_size = 0;
     for (;;) {
+        const AVPacket *pkt;
         int analyzed_all_streams;
         if (ff_check_interrupt(&ic->interrupt_callback)) {
             ret = AVERROR_EXIT;
@@ -3796,14 +3796,16 @@  FF_ENABLE_DEPRECATION_WARNINGS
             break;
         }
 
-        pkt = &pkt1;
-
         if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
             ret = ff_packet_list_put(&ic->internal->packet_buffer,
                                      &ic->internal->packet_buffer_end,
-                                     pkt, 0);
+                                     &pkt1, 0);
             if (ret < 0)
                 goto find_stream_info_err;
+
+            pkt = &ic->internal->packet_buffer_end->pkt;
+        } else {
+            pkt = &pkt1;
         }
 
         st = ic->streams[pkt->stream_index];
@@ -3881,7 +3883,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
                        limit,
                        t, pkt->stream_index);
                 if (ic->flags & AVFMT_FLAG_NOBUFFER)
-                    av_packet_unref(pkt);
+                    av_packet_unref(&pkt1);
                 break;
             }
             if (pkt->duration) {
@@ -3918,7 +3920,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
                          (options && i < orig_nb_streams) ? &options[i] : NULL);
 
         if (ic->flags & AVFMT_FLAG_NOBUFFER)
-            av_packet_unref(pkt);
+            av_packet_unref(&pkt1);
 
         st->codec_info_nb_frames++;
         count++;