From e9d0d19f61ee9ec2eb5d3c29fc68a08b23539f72 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 23 Jul 2021 16:49:49 +0800 Subject: [PATCH] videoparsers: vp9: Need to process the first frame even not key. Some cut VP9 streams begin with a non key frame. The current code just bail out the parse_process_frame() if not a key frame. Because of this, we do not set the valid caps before we push the data of the first frame(even this first frame will be discarded by the downstream decoder because it is not a key frame). The pipeline such as: gst-launch-1.0 filesrc location=some.ivf ! ivfparse ! vp9parse ! vavp9dec ! fakesink will get a negotiation error and the pipeline can not continue. The correct behaviour should be: the decoder discard the first frame and continue to decode later frames successfully. So, when the parse does not have valid stream info(should be the first frame case), we should continue and report caps. Part-of: --- gst/videoparsers/gstvp9parse.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gst/videoparsers/gstvp9parse.c b/gst/videoparsers/gstvp9parse.c index a8d2d1e..81b2879 100644 --- a/gst/videoparsers/gstvp9parse.c +++ b/gst/videoparsers/gstvp9parse.c @@ -291,6 +291,24 @@ gst_vp9_parse_negotiate (GstVp9Parse * self, GstVp9ParseAligment in_align, } static gboolean +gst_vp9_parse_is_info_valid (GstVp9Parse * self) +{ + if (self->width <= 0 || self->height <= 0) + return FALSE; + + if (self->subsampling_x < 0 || self->subsampling_y < 0) + return FALSE; + + if (self->profile == GST_VP9_PROFILE_UNDEFINED) + return FALSE; + + if (self->bit_depth < (GstVp9BitDepth) GST_VP9_BIT_DEPTH_8) + return FALSE; + + return TRUE; +} + +static gboolean gst_vp9_parse_process_frame (GstVp9Parse * self, GstVp9FrameHdr * frame_hdr) { GstVp9Parser *parser = self->parser; @@ -299,7 +317,9 @@ gst_vp9_parse_process_frame (GstVp9Parse * self, GstVp9FrameHdr * frame_hdr) /* the resolution might be varying. Update our status per key frame */ if (frame_hdr->frame_type != GST_VP9_KEY_FRAME || frame_hdr->show_existing_frame) { - return TRUE; + /* Need to continue to get some valid info. */ + if (gst_vp9_parse_is_info_valid (self)) + return TRUE; } width = frame_hdr->width; -- 2.7.4