static GstStateChangeReturn vorbis_dec_change_state (GstElement * element, GstStateChange transition) { GstVorbisDec *vd = GST_VORBIS_DEC (element); GstStateChangeReturn res; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: vorbis_info_init (&vd->vi); vorbis_comment_init (&vd->vc); vd->initialized = FALSE; gst_vorbis_dec_reset (vd); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; default: break; } res = parent_class->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_DEBUG_OBJECT (vd, "PAUSED -> READY, clearing vorbis structures"); vd->initialized = FALSE; #ifndef USE_TREMOLO vorbis_block_clear (&vd->vb); #endif vorbis_dsp_clear (&vd->vd); vorbis_comment_clear (&vd->vc); vorbis_info_clear (&vd->vi); gst_vorbis_dec_reset (vd); break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return res; }
static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event) { gboolean ret = FALSE; GstVorbisDec *dec; dec = GST_VORBIS_DEC (gst_pad_get_parent (pad)); GST_LOG_OBJECT (dec, "handling event"); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: if (dec->segment.rate < 0.0) vorbis_dec_chain_reverse (dec, TRUE, NULL); ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_FLUSH_START: ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_FLUSH_STOP: /* here we must clean any state in the decoder */ #ifdef HAVE_VORBIS_SYNTHESIS_RESTART vorbis_synthesis_restart (&dec->vd); #endif gst_vorbis_dec_reset (dec); ret = gst_pad_push_event (dec->srcpad, event); break; case GST_EVENT_NEWSEGMENT: { GstFormat format; gdouble rate, arate; gint64 start, stop, time; gboolean update; gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, &start, &stop, &time); /* we need time for now */ if (format != GST_FORMAT_TIME) goto newseg_wrong_format; GST_DEBUG_OBJECT (dec, "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time)); /* now configure the values */ gst_segment_set_newsegment_full (&dec->segment, update, rate, arate, format, start, stop, time); dec->seqnum = gst_event_get_seqnum (event); if (dec->initialized) /* and forward */ ret = gst_pad_push_event (dec->srcpad, event); else { /* store it to send once we're initialized */ dec->pendingevents = g_list_append (dec->pendingevents, event); ret = TRUE; } break; } case GST_EVENT_TAG: { if (dec->initialized) /* and forward */ ret = gst_pad_push_event (dec->srcpad, event); else { /* store it to send once we're initialized */ dec->pendingevents = g_list_append (dec->pendingevents, 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"); goto done; } }