diff options
author | James Almer <jamrial@gmail.com> | 2018-04-12 00:06:30 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2018-04-13 21:19:22 -0300 |
commit | 23e994ca496c51f67d764ffa48be715c877883e5 (patch) | |
tree | cdd95a010ce50b837f867f142a7338a72162312c /libavformat/utils.c | |
parent | b14761d1f8372dfe558193b8b754b9f1a858077d (diff) | |
download | ffmpeg-23e994ca496c51f67d764ffa48be715c877883e5.tar.gz |
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@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 23 |
1 files 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 */ |