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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2427>
This commit is contained in:
He Junyan 2021-07-23 16:49:49 +08:00 committed by GStreamer Marge Bot
parent 0bde6bf750
commit e9d0d19f61

View file

@ -290,6 +290,24 @@ gst_vp9_parse_negotiate (GstVp9Parse * self, GstVp9ParseAligment in_align,
gst_clear_caps (&caps); gst_clear_caps (&caps);
} }
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 static gboolean
gst_vp9_parse_process_frame (GstVp9Parse * self, GstVp9FrameHdr * frame_hdr) gst_vp9_parse_process_frame (GstVp9Parse * self, GstVp9FrameHdr * frame_hdr)
{ {
@ -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 */ /* the resolution might be varying. Update our status per key frame */
if (frame_hdr->frame_type != GST_VP9_KEY_FRAME || if (frame_hdr->frame_type != GST_VP9_KEY_FRAME ||
frame_hdr->show_existing_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; width = frame_hdr->width;