mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
omxvideodec: fixes race condition during seeks
Acording 6.1.3 Seek Event Sequence in the OpenMAX IL 1.1.2 spec document in order to flush the component it needs to be in paused state. https://bugzilla.gnome.org/show_bug.cgi?id=726038
This commit is contained in:
parent
39ca9f980e
commit
73d83f311c
1 changed files with 46 additions and 15 deletions
|
@ -1950,6 +1950,30 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded)
|
if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* 0) Wait until the srcpad loop is stopped,
|
||||||
|
* unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks
|
||||||
|
* caused by using this lock from inside the loop function */
|
||||||
|
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
||||||
|
gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder));
|
||||||
|
GST_DEBUG_OBJECT (self, "Flushing -- task stopped");
|
||||||
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
|
/* 1) Pause the components */
|
||||||
|
if (gst_omx_component_get_state (self->dec, 0) == OMX_StateExecuting) {
|
||||||
|
gst_omx_component_set_state (self->dec, OMX_StatePause);
|
||||||
|
gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
|
||||||
|
}
|
||||||
|
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL)
|
||||||
|
if (self->eglimage) {
|
||||||
|
if (gst_omx_component_get_state (self->egl_render, 0) == OMX_StateExecuting) {
|
||||||
|
gst_omx_component_set_state (self->egl_render, OMX_StatePause);
|
||||||
|
gst_omx_component_get_state (self->egl_render, GST_CLOCK_TIME_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 2) Flush the ports */
|
||||||
|
GST_DEBUG_OBJECT (self, "flushing ports");
|
||||||
gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
|
gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
|
||||||
gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
|
gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
|
||||||
|
|
||||||
|
@ -1960,14 +1984,17 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Wait until the srcpad loop is finished,
|
/* 3) Resume components */
|
||||||
* unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks
|
gst_omx_component_set_state (self->dec, OMX_StateExecuting);
|
||||||
* caused by using this lock from inside the loop function */
|
gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL)
|
||||||
GST_PAD_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
if (self->eglimage) {
|
||||||
GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
gst_omx_component_set_state (self->egl_render, OMX_StateExecuting);
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
gst_omx_component_get_state (self->egl_render, GST_CLOCK_TIME_NONE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 4) Unset flushing to allow ports to accept data again */
|
||||||
gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
|
gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
|
||||||
gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
|
gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
|
||||||
|
|
||||||
|
@ -1976,6 +2003,7 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
gst_omx_port_set_flushing (self->egl_in_port, 5 * GST_SECOND, FALSE);
|
gst_omx_port_set_flushing (self->egl_in_port, 5 * GST_SECOND, FALSE);
|
||||||
gst_omx_port_set_flushing (self->egl_out_port, 5 * GST_SECOND, FALSE);
|
gst_omx_port_set_flushing (self->egl_out_port, 5 * GST_SECOND, FALSE);
|
||||||
err = gst_omx_port_populate (self->egl_out_port);
|
err = gst_omx_port_populate (self->egl_out_port);
|
||||||
|
gst_omx_port_mark_reconfigured (self->egl_out_port);
|
||||||
} else {
|
} else {
|
||||||
err = gst_omx_port_populate (self->dec_out_port);
|
err = gst_omx_port_populate (self->dec_out_port);
|
||||||
}
|
}
|
||||||
|
@ -1988,14 +2016,12 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
gst_omx_error_to_string (err), err);
|
gst_omx_error_to_string (err), err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Reset our state */
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->eos = FALSE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
|
self->started = FALSE;
|
||||||
(GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL);
|
GST_DEBUG_OBJECT (self, "Flush finished");
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Flush decoder");
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2025,10 +2051,15 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
return GST_FLOW_EOS;
|
return GST_FLOW_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->started && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
|
if (!self->started) {
|
||||||
|
if (!GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
|
||||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
GST_DEBUG_OBJECT (self, "Starting task");
|
||||||
|
gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
|
||||||
|
(GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
timestamp = frame->pts;
|
timestamp = frame->pts;
|
||||||
duration = frame->duration;
|
duration = frame->duration;
|
||||||
|
|
Loading…
Reference in a new issue