static GstStateChangeReturn theora_dec_change_state (GstElement * element, GstStateChange transition) { GstTheoraDec *dec = GST_THEORA_DEC (element); GstStateChangeReturn ret; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: th_info_clear (&dec->info); th_comment_clear (&dec->comment); GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE in READY->PAUSED"); dec->have_header = FALSE; dec->have_par = FALSE; gst_theora_dec_reset (dec); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } ret = parent_class->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: th_info_clear (&dec->info); th_comment_clear (&dec->comment); th_setup_free (dec->setup); dec->setup = NULL; th_decode_free (dec->decoder); dec->decoder = NULL; gst_theora_dec_reset (dec); break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return ret; }
static gboolean theora_dec_start (GstVideoDecoder * decoder) { GstTheoraDec *dec = GST_THEORA_DEC (decoder); GST_DEBUG_OBJECT (dec, "start"); th_info_clear (&dec->info); th_comment_clear (&dec->comment); GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE"); dec->have_header = FALSE; gst_theora_dec_reset (dec); return TRUE; }
static gboolean theora_dec_stop (GstVideoDecoder * decoder) { GstTheoraDec *dec = GST_THEORA_DEC (decoder); GST_DEBUG_OBJECT (dec, "stop"); th_info_clear (&dec->info); th_comment_clear (&dec->comment); th_setup_free (dec->setup); dec->setup = NULL; th_decode_free (dec->decoder); dec->decoder = NULL; gst_theora_dec_reset (dec); if (dec->input_state) { gst_video_codec_state_unref (dec->input_state); dec->input_state = NULL; } if (dec->output_state) { gst_video_codec_state_unref (dec->output_state); dec->output_state = NULL; } return TRUE; }
/* FIXME : Do we want to handle hard resets differently ? */ static gboolean theora_dec_reset (GstVideoDecoder * bdec, gboolean hard) { gst_theora_dec_reset (GST_THEORA_DEC (bdec)); return TRUE; }
static gboolean theora_dec_sink_event (GstPad * pad, GstEvent * event) { gboolean ret = FALSE; GstTheoraDec *dec; dec = GST_THEORA_DEC (gst_pad_get_parent (pad)); GST_LOG_OBJECT (dec, "handling event"); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_FLUSH_STOP: gst_theora_dec_reset (dec); ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_EOS: ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_NEWSEGMENT: { gboolean update; GstFormat format; gdouble rate, arate; gint64 start, stop, time; gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, &start, &stop, &time); /* we need TIME format */ if (format != GST_FORMAT_TIME) goto newseg_wrong_format; /* now configure the values */ gst_segment_set_newsegment_full (&dec->segment, update, rate, arate, format, start, stop, time); /* We don't forward this unless/until the decoder is initialised */ if (dec->have_header) { ret = gst_pad_push_event (dec->srcpad, event); dec->sent_newsegment = TRUE; } else { gst_event_unref (event); ret = TRUE; } break; } default: ret = gst_pad_push_event (dec->srcpad, event); break; } done: gst_object_unref (dec); return ret; /* ERRORS */ newseg_wrong_format: { GST_DEBUG_OBJECT (dec, "received non TIME newsegment"); gst_event_unref (event); goto done; } }