static void gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) { GstAmcAudioDec *self; self = GST_AMC_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Resetting decoder"); if (!self->started) { GST_DEBUG_OBJECT (self, "Codec not started yet"); return; } self->flushing = TRUE; gst_amc_codec_flush (self->codec); /* Wait until the srcpad loop is finished, * 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_STREAM_LOCK (GST_AUDIO_DECODER_SRC_PAD (self)); GST_PAD_STREAM_UNLOCK (GST_AUDIO_DECODER_SRC_PAD (self)); GST_AUDIO_DECODER_STREAM_LOCK (self); self->flushing = FALSE; /* Start the srcpad loop again */ self->last_upstream_ts = 0; self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); GST_DEBUG_OBJECT (self, "Reset decoder"); }
static gboolean gst_amc_video_dec_stop (GstVideoDecoder * decoder) { GstAmcVideoDec *self; GError *err = NULL; self = GST_AMC_VIDEO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping decoder"); self->flushing = TRUE; if (self->started) { gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_amc_codec_stop (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); self->started = FALSE; } gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder)); self->downstream_flow_ret = GST_FLOW_FLUSHING; self->drained = TRUE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); g_free (self->codec_data); self->codec_data_size = 0; if (self->input_state) gst_video_codec_state_unref (self->input_state); self->input_state = NULL; GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; }
static GstStateChangeReturn gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition) { GstAmcAudioDec *self; GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GError *err = NULL; g_return_val_if_fail (GST_IS_AMC_AUDIO_DEC (element), GST_STATE_CHANGE_FAILURE); self = GST_AMC_AUDIO_DEC (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: self->downstream_flow_ret = GST_FLOW_OK; self->draining = FALSE; self->started = FALSE; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; case GST_STATE_CHANGE_PAUSED_TO_READY: self->flushing = TRUE; gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); break; default: break; } if (ret == GST_STATE_CHANGE_FAILURE) return ret; ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; }
static gboolean gst_amc_video_enc_flush (GstVideoEncoder * encoder) { GstAmcVideoEnc *self; GError *err = NULL; self = GST_AMC_VIDEO_ENC (encoder); GST_DEBUG_OBJECT (self, "Flushing encoder"); if (!self->started) { GST_DEBUG_OBJECT (self, "Codec not started yet"); return TRUE; } self->flushing = TRUE; gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); /* Wait until the srcpad loop is finished, * unlock GST_VIDEO_ENCODER_STREAM_LOCK to prevent deadlocks * caused by using this lock from inside the loop function */ GST_VIDEO_ENCODER_STREAM_UNLOCK (self); GST_PAD_STREAM_LOCK (GST_VIDEO_ENCODER_SRC_PAD (self)); GST_PAD_STREAM_UNLOCK (GST_VIDEO_ENCODER_SRC_PAD (self)); GST_VIDEO_ENCODER_STREAM_LOCK (self); self->flushing = FALSE; /* Start the srcpad loop again */ self->last_upstream_ts = 0; self->drained = TRUE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self), (GstTaskFunction) gst_amc_video_enc_loop, encoder, NULL); GST_DEBUG_OBJECT (self, "Flush encoder"); return TRUE; }
static gboolean gst_amc_audio_dec_stop (GstAudioDecoder * decoder) { GstAmcAudioDec *self; GError *err = NULL; self = GST_AMC_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping decoder"); self->flushing = TRUE; if (self->started) { gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_amc_codec_stop (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); self->started = FALSE; } gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); memset (self->positions, 0, sizeof (self->positions)); gst_adapter_flush (self->output_adapter, gst_adapter_available (self->output_adapter)); g_list_foreach (self->codec_datas, (GFunc) g_free, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; self->downstream_flow_ret = GST_FLOW_FLUSHING; self->drained = TRUE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; }
static gboolean gst_amc_audio_dec_stop (GstAudioDecoder * decoder) { GstAmcAudioDec *self; self = GST_AMC_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Stopping decoder"); self->flushing = TRUE; if (self->started) { gst_amc_codec_flush (self->codec); gst_amc_codec_stop (self->codec); self->started = FALSE; if (self->input_buffers) gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); self->input_buffers = NULL; if (self->output_buffers) gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); self->output_buffers = NULL; } gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); memset (self->positions, 0, sizeof (self->positions)); g_list_foreach (self->codec_datas, (GFunc) g_free, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; self->downstream_flow_ret = GST_FLOW_FLUSHING; self->eos = FALSE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); g_mutex_unlock (&self->drain_lock); GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; }