diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2014-08-14 17:33:07 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2014-08-14 17:33:07 +0300 |
commit | 19d77004d2f5bd2ef76a7262c7a26cdaacc5c018 (patch) | |
tree | 8c52b0200457400a7df9ef34b5986a1d45485e28 | |
parent | b4c7c726ef443cf8a89df26026706e391846bb4a (diff) |
omxaudiodec: Fix flushing logic and make it more similar to the video decoder
-rw-r--r-- | omx/gstomxaudiodec.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/omx/gstomxaudiodec.c b/omx/gstomxaudiodec.c index f894086..8b6440d 100644 --- a/omx/gstomxaudiodec.c +++ b/omx/gstomxaudiodec.c @@ -920,11 +920,7 @@ gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) return FALSE; } - /* Start the srcpad loop again */ - GST_DEBUG_OBJECT (self, "Starting task again"); self->downstream_flow_ret = GST_FLOW_OK; - gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL); return TRUE; } @@ -933,28 +929,53 @@ static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) { GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder); + OMX_ERRORTYPE err = OMX_ErrorNone; - GST_DEBUG_OBJECT (self, "Resetting decoder"); + GST_DEBUG_OBJECT (self, "Flushing decoder"); + if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded) + return; + + /* 0) 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); + } + + /* 1) Wait until the srcpad loop is stopped, + * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks + * caused by using this lock from inside the loop function */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); + GST_DEBUG_OBJECT (self, "Flushing -- task stopped"); + GST_AUDIO_DECODER_STREAM_LOCK (self); + + /* 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); - /* Wait until the srcpad loop is finished */ - GST_AUDIO_ENCODER_STREAM_UNLOCK (self); - GST_PAD_STREAM_LOCK (GST_AUDIO_ENCODER_SRC_PAD (self)); - GST_PAD_STREAM_UNLOCK (GST_AUDIO_ENCODER_SRC_PAD (self)); - GST_AUDIO_ENCODER_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); + /* 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); - gst_omx_port_populate (self->dec_out_port); - /* Start the srcpad loop again */ + err = gst_omx_port_populate (self->dec_out_port); + + if (err != OMX_ErrorNone) { + GST_WARNING_OBJECT (self, "Failed to populate output port: %s (0x%08x)", + gst_omx_error_to_string (err), err); + } + + /* Reset our state */ self->last_upstream_ts = 0; - self->downstream_flow_ret = GST_FLOW_OK; self->eos = FALSE; - gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL); + self->downstream_flow_ret = GST_FLOW_OK; + self->started = FALSE; + GST_DEBUG_OBJECT (self, "Flush finished"); } static GstFlowReturn @@ -993,6 +1014,12 @@ gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) return self->downstream_flow_ret; } + if (!self->started) { + GST_DEBUG_OBJECT (self, "Starting task"); + gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL); + } + if (inbuf == NULL) return gst_omx_audio_dec_drain (self, TRUE); |