mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
nvenc: Early terminate handle_frame if the last flow was not GST_FLOW_OK
If the last flow was not GST_FLOW_OK, the encoding thread is not running and there is nothing to pop from GAsyncQueue (this causes deadlock). To prevent deadlock, just return the handle_frame without further encoding process if the last flow was not GST_FLOW_OK. Note that the last flow will be cleared per FLUSH_STOP and STREAM_START event.
This commit is contained in:
parent
68a51abdcd
commit
52dfbbe5da
1 changed files with 34 additions and 4 deletions
|
@ -34,10 +34,6 @@
|
|||
#include <gst/gl/gl.h>
|
||||
#endif
|
||||
|
||||
/* TODO:
|
||||
* - reset last_flow on FLUSH_STOP (seeking)
|
||||
*/
|
||||
|
||||
/* This currently supports both 5.x and 6.x versions of the NvEncodeAPI.h
|
||||
* header which are mostly API compatible. */
|
||||
|
||||
|
@ -234,6 +230,8 @@ static void gst_nv_base_enc_set_context (GstElement * element,
|
|||
GstContext * context);
|
||||
static gboolean gst_nv_base_enc_sink_query (GstVideoEncoder * enc,
|
||||
GstQuery * query);
|
||||
static gboolean gst_nv_base_enc_sink_event (GstVideoEncoder * enc,
|
||||
GstEvent * event);
|
||||
static gboolean gst_nv_base_enc_set_format (GstVideoEncoder * enc,
|
||||
GstVideoCodecState * state);
|
||||
static GstFlowReturn gst_nv_base_enc_handle_frame (GstVideoEncoder * enc,
|
||||
|
@ -276,6 +274,7 @@ gst_nv_base_enc_class_init (GstNvBaseEncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_nv_base_enc_handle_frame);
|
||||
videoenc_class->finish = GST_DEBUG_FUNCPTR (gst_nv_base_enc_finish);
|
||||
videoenc_class->sink_query = GST_DEBUG_FUNCPTR (gst_nv_base_enc_sink_query);
|
||||
videoenc_class->sink_event = GST_DEBUG_FUNCPTR (gst_nv_base_enc_sink_event);
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE_ID,
|
||||
g_param_spec_uint ("cuda-device-id",
|
||||
|
@ -560,6 +559,26 @@ gst_nv_base_enc_sink_query (GstVideoEncoder * enc, GstQuery * query)
|
|||
return GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (enc, query);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_nv_base_enc_sink_event (GstVideoEncoder * enc, GstEvent * event)
|
||||
{
|
||||
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc);
|
||||
gboolean ret;
|
||||
|
||||
ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event (enc, event);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_STREAM_START:
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
nvenc->last_flow = GST_FLOW_OK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_nv_base_enc_start (GstVideoEncoder * enc)
|
||||
{
|
||||
|
@ -2240,6 +2259,17 @@ gst_nv_base_enc_handle_frame (GstVideoEncoder * enc, GstVideoCodecFrame * frame)
|
|||
|
||||
g_assert (nvenc->encoder != NULL);
|
||||
|
||||
/* check last flow and if it's not OK, just return the last flow,
|
||||
* non-OK flow means that encoding thread was terminated */
|
||||
flow = g_atomic_int_get (&nvenc->last_flow);
|
||||
if (flow != GST_FLOW_OK) {
|
||||
GST_DEBUG_OBJECT (nvenc, "last flow was %s", gst_flow_get_name (flow));
|
||||
/* just drop this frame */
|
||||
gst_video_encoder_finish_frame (enc, frame);
|
||||
|
||||
return flow;
|
||||
}
|
||||
|
||||
if (g_atomic_int_compare_and_exchange (&nvenc->reconfig, TRUE, FALSE)) {
|
||||
if (!gst_nv_base_enc_set_format (enc, nvenc->input_state)) {
|
||||
flow = GST_FLOW_NOT_NEGOTIATED;
|
||||
|
|
Loading…
Reference in a new issue