From 50e116c4a780ef9a0f7836867b3addf79bceb380 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 30 Mar 2021 17:24:38 +0900 Subject: [PATCH] codecs: vp9decoder: Allow decoding start with intra-only frame As per spec "7.2 Uncompressed header semantics" and "8.2 Frame order constraints", decoding can start with intra-only frame. This commit is for fixing vp90-2-16-intra-only.webm bitstream test failure. Part-of: --- gst-libs/gst/codecs/gstvp9decoder.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/codecs/gstvp9decoder.c b/gst-libs/gst/codecs/gstvp9decoder.c index e5e3959f91..94f4aeaac0 100644 --- a/gst-libs/gst/codecs/gstvp9decoder.c +++ b/gst-libs/gst/codecs/gstvp9decoder.c @@ -270,6 +270,8 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder, GstVp9ParserResult pres; GstMapInfo map; GstFlowReturn ret = GST_FLOW_OK; + gboolean intra_only = FALSE; + gboolean check_codec_change = FALSE; GST_LOG_OBJECT (self, "handle frame %" GST_PTR_FORMAT, in_buf); @@ -286,8 +288,25 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder, goto unmap_and_error; } - if (priv->wait_keyframe && (frame_hdr.frame_type != GST_VP9_KEY_FRAME - || frame_hdr.show_existing_frame)) { + if (frame_hdr.show_existing_frame) { + /* This is a non-intra, dummy frame */ + intra_only = FALSE; + } else if (frame_hdr.frame_type == GST_VP9_KEY_FRAME || frame_hdr.intra_only) { + intra_only = TRUE; + } + + if (intra_only) { + if (frame_hdr.frame_type == GST_VP9_KEY_FRAME) { + /* Always check codec change per keyframe */ + check_codec_change = TRUE; + } else if (priv->wait_keyframe) { + /* Or, if we are waiting for leading keyframe, but this is intra-only, + * try decoding this frame, it's allowed as per spec */ + check_codec_change = TRUE; + } + } + + if (priv->wait_keyframe && !intra_only) { GST_DEBUG_OBJECT (self, "Drop frame before initial keyframe"); gst_buffer_unmap (in_buf, &map); @@ -296,8 +315,7 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder, return GST_FLOW_OK; } - if (frame_hdr.frame_type == GST_VP9_KEY_FRAME && - !frame_hdr.show_existing_frame && + if (check_codec_change && !gst_vp9_decoder_check_codec_change (self, &frame_hdr)) { GST_ERROR_OBJECT (self, "codec change error"); goto unmap_and_error;