diff options
author | James Almer <jamrial@gmail.com> | 2019-08-26 14:29:59 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2019-08-27 15:24:21 -0300 |
commit | d70bbdc5fa05e1c0ce381eacc6e987b5e0701d1c (patch) | |
tree | cc0a25aad251e7fe2d9cf6fb6149a510c735570f /libavcodec/qtrle.c | |
parent | 8b71cc3363b5d5b01a56f334e8b6318374192076 (diff) | |
download | ffmpeg-d70bbdc5fa05e1c0ce381eacc6e987b5e0701d1c.tar.gz |
avcodec/qtrle: call ff_reget_buffer() only when the picture data is going to change
ff_reget_buffer() will attempt to create a writable copy of the frame,
which is not needed when the decoder intends to return a reference to
the same buffer as the previous frame.
Should reduce data copy, hopefully achieving a similar speed up as
a9dacdeea6168787a142209bd19fdd74aefc9dd6 without dropping frames.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/qtrle.c')
-rw-r--r-- | libavcodec/qtrle.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 443dd88f71..2793eb91f6 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -452,15 +452,16 @@ static int qtrle_decode_frame(AVCodecContext *avctx, int header, start_line; int height, row_ptr; int has_palette = 0; + int duplicate = 0; int ret, size; bytestream2_init(&s->g, avpkt->data, avpkt->size); - if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) - return ret; /* check if this frame is even supposed to change */ - if (avpkt->size < 8) + if (avpkt->size < 8) { + duplicate = 1; goto done; + } /* start after the chunk size */ size = bytestream2_get_be32(&s->g) & 0x3FFFFFFF; @@ -473,18 +474,25 @@ static int qtrle_decode_frame(AVCodecContext *avctx, /* if a header is present, fetch additional decoding parameters */ if (header & 0x0008) { - if (avpkt->size < 14) + if (avpkt->size < 14) { + duplicate = 1; goto done; + } start_line = bytestream2_get_be16(&s->g); bytestream2_skip(&s->g, 2); height = bytestream2_get_be16(&s->g); bytestream2_skip(&s->g, 2); - if (height > s->avctx->height - start_line) + if (height > s->avctx->height - start_line) { + duplicate = 1; goto done; + } } else { start_line = 0; height = s->avctx->height; } + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) + return ret; + row_ptr = s->frame->linesize[0] * start_line; switch (avctx->bits_per_coded_sample) { @@ -546,6 +554,16 @@ static int qtrle_decode_frame(AVCodecContext *avctx, } done: + if (!s->frame->data[0]) + return AVERROR_INVALIDDATA; + if (duplicate) { + // ff_reget_buffer() isn't needed when frames don't change, so just update + // frame props. + ret = ff_decode_frame_props(avctx, s->frame); + if (ret < 0) + return ret; + } + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; |