v4l2videodec: Fixes three H.264/HEVC ITU conformance tests

Postpone the cleanup of any consecutive sequence of lost frames
which starts at frame 0, until frame 100 is dequeued from driver.

This allows fluster tests JVT/CVWP2_TOSHIBA_E, JVC/CVWP3_TOSHIBA_E
and HEVC/POC_A_Bossen_3 that sends out-of-order frames to successfully
complete  (e.g., test of Amphion vpu driver).

Fixes #1569

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3398>
This commit is contained in:
F. Duncanh 2022-11-13 19:19:41 -05:00 committed by GStreamer Marge Bot
parent d815035e82
commit d77fe9495a

View file

@ -675,11 +675,9 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
GstVideoCodecFrame *frame; GstVideoCodecFrame *frame;
GstBuffer *buffer = NULL; GstBuffer *buffer = NULL;
GstFlowReturn ret; GstFlowReturn ret;
gint capture_configuration_change;
GST_VIDEO_DECODER_STREAM_LOCK (decoder); GST_VIDEO_DECODER_STREAM_LOCK (decoder);
if ((capture_configuration_change = if (g_atomic_int_get (&self->capture_configuration_change)) {
g_atomic_int_get (&self->capture_configuration_change))) {
gst_v4l2_object_stop (self->v4l2capture); gst_v4l2_object_stop (self->v4l2capture);
ret = gst_v4l2_video_dec_setup_capture (decoder); ret = gst_v4l2_video_dec_setup_capture (decoder);
if (ret != GST_FLOW_OK) { if (ret != GST_FLOW_OK) {
@ -761,6 +759,7 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
while ((oldest_frame = gst_video_decoder_get_oldest_frame (decoder)) && while ((oldest_frame = gst_video_decoder_get_oldest_frame (decoder)) &&
check_system_frame_number_too_old (frame->system_frame_number, check_system_frame_number_too_old (frame->system_frame_number,
oldest_frame->system_frame_number)) { oldest_frame->system_frame_number)) {
if (oldest_frame->system_frame_number > 0) {
gst_video_decoder_drop_frame (decoder, oldest_frame); gst_video_decoder_drop_frame (decoder, oldest_frame);
oldest_frame = NULL; oldest_frame = NULL;
@ -769,28 +768,29 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
GST_ELEMENT_NAME (decoder)); GST_ELEMENT_NAME (decoder));
warned = TRUE; warned = TRUE;
} }
} } else {
/* special treatment when oldest_frame->system_frame_number = 0:
/* If the initial frame triggered a Caps renegotiation, but with no actual change in * if a consecutive sequence 0, 1, 2,..., n < frame->system_frame_number
* resolution, already-correctly-decoded frames may incorrectly be dropped by the driver. * is pending, drop them all at this time. (This has been seen to occur
* This has been observed to occur in at least one driver. These frames will never dequeue. * as a driver bug when the initial frame triggered a Caps re-negotiation,
* As a workaround, drop all pending frames older than the current frame now. */ * and the driver dropped these frames) */
if (capture_configuration_change && oldest_frame guint32 counter = 0;
&& oldest_frame->system_frame_number == 0
&& frame->system_frame_number) {
gint counter = 0;
while (oldest_frame) { while (oldest_frame) {
counter++;
gst_video_decoder_drop_frame (decoder, oldest_frame); gst_video_decoder_drop_frame (decoder, oldest_frame);
counter++;
oldest_frame = gst_video_decoder_get_oldest_frame (decoder); oldest_frame = gst_video_decoder_get_oldest_frame (decoder);
if (oldest_frame->system_frame_number == frame->system_frame_number) { if (oldest_frame &&
(oldest_frame->system_frame_number > counter ||
oldest_frame->system_frame_number >=
frame->system_frame_number)) {
gst_video_codec_frame_unref (oldest_frame); gst_video_codec_frame_unref (oldest_frame);
oldest_frame = NULL; oldest_frame = NULL;
} }
} }
g_warning g_warning
("%s: %i initial frames before frame %u were not dequeued: bug in decoder -- please file a bug", ("%s: %i initial frames were not dequeued: bug in decoder -- please file a bug",
GST_ELEMENT_NAME (decoder), counter, frame->system_frame_number); GST_ELEMENT_NAME (decoder), counter);
}
} }
if (oldest_frame) if (oldest_frame)
gst_video_codec_frame_unref (oldest_frame); gst_video_codec_frame_unref (oldest_frame);