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