[FFmpeg-cvslog] avformat/utils: use the existing packet reference when parsing complete frames

James Almer git at videolan.org
Sat Apr 14 03:19:57 EEST 2018


ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Thu Apr 12 00:06:30 2018 -0300| [23e994ca496c51f67d764ffa48be715c877883e5] | committer: James Almer

avformat/utils: use the existing packet reference when parsing complete frames

If the parser returns full frames, then the output pointer retured by
av_parser_parse2() is guaranteed to point to data contained in the
input packet's buffer.

Create a new reference to said buffer in that case, to avoid
unnecessary data copy when queueing the packet later in the function.

Reviewed-by: Michael Niedermayer <michael at niedermayer.cc>
Signed-off-by: James Almer <jamrial at gmail.com>

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

 libavformat/utils.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 733c6d65dc..f2f2cc4239 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1472,6 +1472,22 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
         if (!out_pkt.size)
             continue;
 
+        if (pkt->buf && out_pkt.data == pkt->data) {
+            /* reference pkt->buf only when out_pkt.data is guaranteed to point
+             * to data in it and not in the parser's internal buffer. */
+            /* XXX: Ensure this is the case with all parsers when st->parser->flags
+             * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
+            out_pkt.buf = av_buffer_ref(pkt->buf);
+            if (!out_pkt.buf) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+        } else {
+            ret = av_packet_make_refcounted(&out_pkt);
+            if (ret < 0)
+                goto fail;
+        }
+
         if (pkt->side_data) {
             out_pkt.side_data       = pkt->side_data;
             out_pkt.side_data_elems = pkt->side_data_elems;
@@ -1512,10 +1528,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
 
         ret = ff_packet_list_put(&s->internal->parse_queue,
                                  &s->internal->parse_queue_end,
-                                 &out_pkt, FF_PACKETLIST_FLAG_REF_PACKET);
-        av_packet_unref(&out_pkt);
-        if (ret < 0)
+                                 &out_pkt, 0);
+        if (ret < 0) {
+            av_packet_unref(&out_pkt);
             goto fail;
+        }
     }
 
     /* end of the stream => close and free the parser */



More information about the ffmpeg-cvslog mailing list