From ff0e42eb30a5b9ebc31b57f06b1c78cd6a419002 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Wed, 14 Jul 2021 22:36:52 +0800 Subject: [PATCH] va: vp9dec: We need to check the resolution changes for every frame. The VP9 streams have the ability to change the resolution dynamically at any time point. It does not send ad KEY frame before change the resolution, even the INTER frame can change the resolution immediately. So we need to check the resolution change for each frame and do the re-negiotiation if needed. Some insaned stream may play in resolution A first and then dynamically changes to B, and after 1 or 2 frames, it use a show_existing_frame to repeat the old frame of resolution A before. So, not only new_picture(), but also duplicate_picture() need to check this. Part-of: --- sys/va/gstvavp9dec.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sys/va/gstvavp9dec.c b/sys/va/gstvavp9dec.c index a66e764bfa..606938f17f 100644 --- a/sys/va/gstvavp9dec.c +++ b/sys/va/gstvavp9dec.c @@ -188,6 +188,27 @@ gst_va_vp9_new_sequence (GstVp9Decoder * decoder, return TRUE; } +static gboolean +_check_resolution_change (GstVaVp9Dec * self, GstVp9Picture * picture) +{ + GstVaBaseDec *base = GST_VA_BASE_DEC (self); + const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr; + + if ((base->width != frame_hdr->width) || base->height != frame_hdr->height) { + base->width = frame_hdr->width; + base->height = frame_hdr->height; + + self->need_negotiation = TRUE; + if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Resolution changes, but failed to" + " negotiate with downstream"); + return FALSE; + } + } + + return TRUE; +} + static gboolean gst_va_vp9_dec_new_picture (GstVp9Decoder * decoder, GstVideoCodecFrame * frame, GstVp9Picture * picture) @@ -198,6 +219,9 @@ gst_va_vp9_dec_new_picture (GstVp9Decoder * decoder, GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); GstVaBaseDec *base = GST_VA_BASE_DEC (decoder); + if (!_check_resolution_change (self, picture)) + return FALSE; + ret = gst_video_decoder_allocate_output_frame (vdec, frame); if (ret != GST_FLOW_OK) goto error; @@ -486,6 +510,9 @@ gst_va_vp9_dec_duplicate_picture (GstVp9Decoder * decoder, GstVaDecodePicture *va_pic, *va_dup; GstVp9Picture *new_picture; + if (!_check_resolution_change (GST_VA_VP9_DEC (decoder), picture)) + return NULL; + va_pic = gst_vp9_picture_get_user_data (picture); va_dup = gst_va_decode_picture_dup (va_pic);