summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2018-04-12 00:06:30 -0300
committerJames Almer <jamrial@gmail.com>2018-04-13 21:19:22 -0300
commit23e994ca496c51f67d764ffa48be715c877883e5 (patch)
treecdd95a010ce50b837f867f142a7338a72162312c /libavformat
parentb14761d1f8372dfe558193b8b754b9f1a858077d (diff)
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')
-rw-r--r--libavformat/utils.c23
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 */