[FFmpeg-devel] [PATCH 2/4] avcodec/qtrle: return last frame even if unchanged

Marton Balint cus at passwd.hu
Fri May 31 23:28:15 EEST 2019



On Thu, 30 May 2019, Michael Niedermayer wrote:

> Fixes: Ticket7880
>
> Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> ---
> libavcodec/qtrle.c        | 42 +++++++++++++++++++++++++++++++++++----
> tests/ref/fate/qtrle-8bit |  1 +
> 2 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
> index 2c29547e5a..4add1aded6 100644
> --- a/libavcodec/qtrle.c
> +++ b/libavcodec/qtrle.c
> @@ -45,6 +45,8 @@ typedef struct QtrleContext {
>
>     GetByteContext g;
>     uint32_t pal[256];
> +    int need_flush;
> +    AVPacket flush_pkt;
> } QtrleContext;
> 
> #define CHECK_PIXEL_PTR(n)                                                            \
> @@ -444,6 +446,12 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx)
>     return 0;
> }
> 
> +static void qtrle_flush(AVCodecContext *avctx){
> +    QtrleContext *s = avctx->priv_data;
> +
> +    s->need_flush = 0;
> +}
> +
> static int qtrle_decode_frame(AVCodecContext *avctx,
>                               void *data, int *got_frame,
>                               AVPacket *avpkt)
> @@ -454,11 +462,32 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
>     int has_palette = 0;
>     int ret, size;
> 
> +    if (!avpkt->data) {
> +        if (s->need_flush) {
> +            s->need_flush = 0;
> +            if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
> +                return ret;
> +            s->frame->pkt_pos      = s->flush_pkt.pos;
> +            s->frame->pkt_duration = s->flush_pkt.duration;
> +            s->frame->pkt_dts      = s->flush_pkt.dts;
> +            s->frame->pkt_pts      =
> +            s->frame->pts          = s->flush_pkt.pts;

This does not seem to work, because the magic in decode_simple_internal in 
decode.c will overwrite these fields. Alternative approach which seems to 
work is assigning the AVPacket fields instead:

             avpkt->pos      = s->flush_pkt.pos;
             avpkt->duration = s->flush_pkt.duration;
             avpkt->dts      = s->flush_pkt.dts;
             avpkt->pts      = s->flush_pkt.pts;

Looks a bit ugly, but as far as I see we are using an internal packet, 
and not the one provided by the user, so it might be OK.

Regards,
Marton


More information about the ffmpeg-devel mailing list