diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 8a46d40c11..682ac8fe41 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -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,9 +2051,14 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, return GST_FLOW_EOS; } - if (!self->started && !GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) { - gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); - return GST_FLOW_OK; + 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;