diff mbox

[FFmpeg-devel,4/3,v2,RFC] avcodec/qtrle: call ff_reget_buffer() only when the picture data is going to change

Message ID 20190826190214.5791-1-jamrial@gmail.com
State New
Headers show

Commit Message

James Almer Aug. 26, 2019, 7:02 p.m. UTC
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.

Signed-off-by: James Almer <jamrial@gmail.com>
---
Now ensuring there's a previous frame available to reuse.

 libavcodec/qtrle.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer Aug. 27, 2019, 3:51 p.m. UTC | #1
On Mon, Aug 26, 2019 at 04:02:14PM -0300, James Almer wrote:
> 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.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Now ensuring there's a previous frame available to reuse.
> 
>  libavcodec/qtrle.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)

would a function like ff_reget_buffer() but that returns a read only frame
simplify this ?

Such function could then later also set any flag or UID

either way patch LGTM

thx

[...]
James Almer Aug. 27, 2019, 5:48 p.m. UTC | #2
On 8/27/2019 12:51 PM, Michael Niedermayer wrote:
> On Mon, Aug 26, 2019 at 04:02:14PM -0300, James Almer wrote:
>> 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.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Now ensuring there's a previous frame available to reuse.
>>
>>  libavcodec/qtrle.c | 14 ++++++++++++--
>>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> would a function like ff_reget_buffer() but that returns a read only frame
> simplify this ?

Yeah, either that, or maybe adding a new parameter to ff_reget_buffer().

> 
> Such function could then later also set any flag or UID

Frames are meant to be independent, so i don't think tying them to some
decoder instance id is a good idea, if that's what you meant in the
other thread.

> 
> either way patch LGTM

Will push, thanks.

> 
> thx
> 
> [...]
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
diff mbox

Patch

diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index bf3daf26e1..edfbef7f28 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -456,8 +456,6 @@  static int qtrle_decode_frame(AVCodecContext *avctx,
     int drop = 0;
 
     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) {
@@ -492,6 +490,9 @@  static int qtrle_decode_frame(AVCodecContext *avctx,
         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) {
@@ -553,6 +554,15 @@  static int qtrle_decode_frame(AVCodecContext *avctx,
     }
 
 done:
+    if (!s->frame->data[0])
+        return AVERROR_INVALIDDATA;
+    if (drop) {
+        // 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;
     if (drop)