mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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)
|
||||
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_out_port, 5 * GST_SECOND, TRUE);
|
||||
|
||||
|
@ -1960,14 +1984,17 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Wait until the srcpad loop is finished,
|
||||
* 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_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||
GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||
/* 3) Resume components */
|
||||
gst_omx_component_set_state (self->dec, OMX_StateExecuting);
|
||||
gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
|
||||
#if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL)
|
||||
if (self->eglimage) {
|
||||
gst_omx_component_set_state (self->egl_render, OMX_StateExecuting);
|
||||
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_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_out_port, 5 * GST_SECOND, FALSE);
|
||||
err = gst_omx_port_populate (self->egl_out_port);
|
||||
gst_omx_port_mark_reconfigured (self->egl_out_port);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
/* Start the srcpad loop again */
|
||||
/* Reset our state */
|
||||
self->last_upstream_ts = 0;
|
||||
self->eos = FALSE;
|
||||
self->downstream_flow_ret = GST_FLOW_OK;
|
||||
gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
|
||||
(GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Flush decoder");
|
||||
self->started = FALSE;
|
||||
GST_DEBUG_OBJECT (self, "Flush finished");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -2025,10 +2051,15 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
|
|||
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);
|
||||
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;
|
||||
duration = frame->duration;
|
||||
|
|
Loading…
Reference in a new issue