[FFmpeg-devel,04/11] avformat/utils: Try to reuse AvBufferRef

Submitted by Andreas Rheinhardt on Aug. 16, 2019, 3:05 a.m.

Details

Message ID 20190816030531.4775-4-andreas.rheinhardt@gmail.com
State New
Headers show

Commit Message

Andreas Rheinhardt Aug. 16, 2019, 3:05 a.m.
In case the parser flag PARSER_FLAG_COMPLETE_FRAMES is set, it is common
that every input packet generates exactly one output packet whose
underlying data coincides with the data of the input packet. If in this
situation the input packet buffer is reference counted (as it usually is),
the current code used to create a new reference to the underlying AVBuffer
for the output packet. The old reference would be discarded afterwards
when the input packet gets unreferenced. This has been changed: If it is
known that no more output packets result from the current input packet,
the input packet's reference is directly transferred to the last output
packet, thus saving one malloc+free.

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

Patch hide | download patch | download mbox

diff --git a/libavformat/utils.c b/libavformat/utils.c
index b57e680089..64516a6a81 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1478,10 +1478,17 @@  static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
              * 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;
+            if (size > 0) {
+                out_pkt.buf = av_buffer_ref(pkt->buf);
+                if (!out_pkt.buf) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+            } else {
+                /* flush_pkt does not have buf set, so size == 0 means
+                 * that this is the last iteration of this loop. */
+                out_pkt.buf = pkt->buf;
+                pkt->buf    = NULL;
             }
         } else {
             ret = av_packet_make_refcounted(&out_pkt);