mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
vaapidecode: drop decode timeout, always wait for a free surface.
vaapidecode used to wait up to one second past the expected time of presentation for the last decoded frame. This is not realistic in practice when it comes to video pause/resume. Changed behaviour to unconditionnally wait for a free VA surface prior to continuing the decoding. The decode task will continue pushing the output frames to the downstream element while also reporting errors at the same time to the main thread. https://bugzilla.gnome.org/show_bug.cgi?id=707108 Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
7e8470e1ec
commit
367944ba32
2 changed files with 17 additions and 49 deletions
|
@ -237,46 +237,32 @@ gst_vaapidecode_decode_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame)
|
|||
GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstFlowReturn ret;
|
||||
gint64 end_time;
|
||||
|
||||
if (decode->render_time_base)
|
||||
end_time = decode->render_time_base;
|
||||
else
|
||||
end_time = g_get_monotonic_time();
|
||||
end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time);
|
||||
end_time += G_TIME_SPAN_SECOND;
|
||||
ret = g_atomic_int_get(&decode->decoder_loop_status);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
/* Decode current frame */
|
||||
for (;;) {
|
||||
status = gst_vaapi_decoder_decode(decode->decoder, frame);
|
||||
if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
|
||||
gboolean was_signalled;
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
|
||||
g_mutex_lock(&decode->decoder_mutex);
|
||||
was_signalled = g_cond_wait_until(
|
||||
&decode->decoder_ready,
|
||||
&decode->decoder_mutex,
|
||||
end_time
|
||||
);
|
||||
g_cond_wait(&decode->decoder_ready, &decode->decoder_mutex);
|
||||
g_mutex_unlock(&decode->decoder_mutex);
|
||||
GST_VIDEO_DECODER_STREAM_LOCK(vdec);
|
||||
if (was_signalled)
|
||||
continue;
|
||||
goto error_decode_timeout;
|
||||
}
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
goto error_decode;
|
||||
break;
|
||||
}
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* Try to report back early any error that occured in the decode task */
|
||||
ret = g_atomic_int_get(&decode->decoder_loop_status);
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
error_decode_timeout:
|
||||
{
|
||||
GST_WARNING("decode timeout. Decoder required a VA surface but none "
|
||||
"got available within one second");
|
||||
return GST_FLOW_EOS;
|
||||
}
|
||||
error_decode:
|
||||
{
|
||||
GST_ERROR("decode error %d", status);
|
||||
|
@ -287,7 +273,7 @@ error_decode:
|
|||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
break;
|
||||
default:
|
||||
ret = GST_FLOW_EOS;
|
||||
ret = GST_FLOW_ERROR;
|
||||
break;
|
||||
}
|
||||
gst_video_decoder_drop_frame(vdec, frame);
|
||||
|
@ -370,22 +356,6 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec)
|
|||
if (ret != GST_FLOW_OK)
|
||||
goto error_commit_buffer;
|
||||
|
||||
/* Estimate when this frame would no longer be needed for rendering */
|
||||
if (GST_CLOCK_TIME_IS_VALID(out_frame->pts)) {
|
||||
if (!decode->render_time_base)
|
||||
decode->render_time_base = g_get_monotonic_time() -
|
||||
GST_TIME_AS_USECONDS(out_frame->pts);
|
||||
decode->last_buffer_time = out_frame->pts;
|
||||
if (GST_CLOCK_TIME_IS_VALID(out_frame->duration))
|
||||
decode->last_buffer_time += out_frame->duration;
|
||||
else
|
||||
decode->last_buffer_time += GST_SECOND;
|
||||
}
|
||||
else {
|
||||
decode->render_time_base = 0;
|
||||
decode->last_buffer_time = 0;
|
||||
}
|
||||
|
||||
gst_video_codec_frame_unref(out_frame);
|
||||
return GST_FLOW_OK;
|
||||
|
||||
|
@ -400,7 +370,7 @@ error_create_buffer:
|
|||
GST_VAAPI_ID_ARGS(surface_id));
|
||||
gst_video_decoder_drop_frame(vdec, out_frame);
|
||||
gst_video_codec_frame_unref(out_frame);
|
||||
return GST_FLOW_EOS;
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
error_get_meta:
|
||||
|
@ -408,7 +378,7 @@ error_get_meta:
|
|||
GST_ERROR("failed to get vaapi video meta attached to video buffer");
|
||||
gst_video_decoder_drop_frame(vdec, out_frame);
|
||||
gst_video_codec_frame_unref(out_frame);
|
||||
return GST_FLOW_EOS;
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
#endif
|
||||
error_commit_buffer:
|
||||
|
@ -416,7 +386,7 @@ error_commit_buffer:
|
|||
if (ret != GST_FLOW_FLUSHING)
|
||||
GST_ERROR("video sink rejected the video buffer (error %d)", ret);
|
||||
gst_video_codec_frame_unref(out_frame);
|
||||
return GST_FLOW_EOS;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,6 +412,8 @@ gst_vaapidecode_decode_loop(GstVaapiDecode *decode)
|
|||
ret = gst_vaapidecode_push_decoded_frame(vdec);
|
||||
if (ret == GST_FLOW_OK)
|
||||
return;
|
||||
g_atomic_int_compare_and_exchange(&decode->decoder_loop_status,
|
||||
GST_FLOW_OK, ret);
|
||||
|
||||
/* If invoked from gst_vaapidecode_finish(), then return right
|
||||
away no matter the errors, or the GstVaapiDecoder needs further
|
||||
|
@ -667,8 +639,6 @@ gst_vaapidecode_reset_full(GstVaapiDecode *decode, GstCaps *caps, gboolean hard)
|
|||
|
||||
/* Reset timers if hard reset was requested (e.g. seek) */
|
||||
if (hard) {
|
||||
decode->render_time_base = 0;
|
||||
decode->last_buffer_time = 0;
|
||||
}
|
||||
|
||||
/* Only reset decoder if codec type changed */
|
||||
|
@ -960,8 +930,7 @@ gst_vaapidecode_init(GstVaapiDecode *decode)
|
|||
decode->decoder = NULL;
|
||||
decode->decoder_caps = NULL;
|
||||
decode->allowed_caps = NULL;
|
||||
decode->render_time_base = 0;
|
||||
decode->last_buffer_time = 0;
|
||||
decode->decoder_loop_status = GST_FLOW_OK;
|
||||
|
||||
g_mutex_init(&decode->decoder_mutex);
|
||||
g_cond_init(&decode->decoder_ready);
|
||||
|
|
|
@ -72,12 +72,11 @@ struct _GstVaapiDecode {
|
|||
GstVaapiDecoder *decoder;
|
||||
GMutex decoder_mutex;
|
||||
GCond decoder_ready;
|
||||
volatile gint decoder_loop_status;
|
||||
volatile gboolean decoder_finish;
|
||||
GCond decoder_finish_done;
|
||||
GstCaps *decoder_caps;
|
||||
GstCaps *allowed_caps;
|
||||
gint64 render_time_base;
|
||||
GstClockTime last_buffer_time;
|
||||
guint current_frame_size;
|
||||
guint has_texture_upload_meta : 1;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue