mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-27 18:02:11 +00:00
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
a9dacdeea6
without dropping frames.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
8b71cc3363
commit
d70bbdc5fa
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user