static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; GstVorbisDec *dec; dec = GST_VORBIS_DEC (gst_pad_get_parent (pad)); if (G_UNLIKELY (dec == NULL)) { gst_event_unref (event); return FALSE; } switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { GstFormat format, tformat; gdouble rate; GstEvent *real_seek; GstSeekFlags flags; GstSeekType cur_type, stop_type; gint64 cur, stop; gint64 tcur, tstop; guint32 seqnum; gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop); seqnum = gst_event_get_seqnum (event); gst_event_unref (event); /* First bring the requested format to time */ tformat = GST_FORMAT_TIME; if (!(res = vorbis_dec_convert (pad, format, cur, &tformat, &tcur))) goto convert_error; if (!(res = vorbis_dec_convert (pad, format, stop, &tformat, &tstop))) goto convert_error; /* then seek with time on the peer */ real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, cur_type, tcur, stop_type, tstop); gst_event_set_seqnum (real_seek, seqnum); res = gst_pad_push_event (dec->sinkpad, real_seek); break; } default: res = gst_pad_push_event (dec->sinkpad, event); break; } done: gst_object_unref (dec); return res; /* ERRORS */ convert_error: { GST_DEBUG_OBJECT (dec, "cannot convert start/stop for seek"); goto done; } }
static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query) { GstVorbisDec *dec; gboolean res; dec = GST_VORBIS_DEC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); if (!(res = vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val))) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (dec); return res; /* ERRORS */ error: { GST_DEBUG_OBJECT (dec, "error converting value"); goto done; } }
static gboolean vorbis_dec_src_query (GstPad * pad, GstQuery * query) { GstVorbisDec *dec; gboolean res = FALSE; dec = GST_VORBIS_DEC (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { gint64 value; GstFormat format; gint64 time; gst_query_parse_position (query, &format, NULL); /* we start from the last seen time */ time = dec->last_timestamp; /* correct for the segment values */ time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); GST_LOG_OBJECT (dec, "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time)); /* and convert to the final format */ if (!(res = vorbis_dec_convert (pad, GST_FORMAT_TIME, time, &format, &value))) goto error; gst_query_set_position (query, format, value); GST_LOG_OBJECT (dec, "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value, format); break; } case GST_QUERY_DURATION: { res = gst_pad_peer_query (dec->sinkpad, query); if (!res) goto error; break; } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); if (!(res = vorbis_dec_convert (pad, src_fmt, src_val, &dest_fmt, &dest_val))) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } default: res = gst_pad_query_default (pad, query); break; } done: gst_object_unref (dec); return res; /* ERRORS */ error: { GST_WARNING_OBJECT (dec, "error handling query"); goto done; } }