static GstEvent * gst_wildmidi_get_new_segment_event (GstWildmidi * wildmidi, GstFormat format) { gint64 start = 0, stop = -1, time = 0; GstSegment *segment, newseg; GstEvent *event; GstFormat src_format; segment = wildmidi->o_segment; src_format = segment->format; newseg = *segment; /* convert the segment values to the target format */ gst_wildmidi_src_convert (wildmidi, src_format, segment->start, &format, &start); gst_wildmidi_src_convert (wildmidi, src_format, segment->stop, &format, &stop); gst_wildmidi_src_convert (wildmidi, src_format, segment->time, &format, &time); newseg.format = format; newseg.start = start; newseg.stop = stop; newseg.time = time; event = gst_event_new_segment (&newseg); return event; }
static gboolean gst_wildmidi_src_query (GstPad * pad, GstQuery * query) { gboolean res = TRUE; GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad)); GstFormat src_format, dst_format; gint64 src_value, dst_value; if (!wildmidi->song) { gst_object_unref (wildmidi); return FALSE; } switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_segment->last_stop, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_CONVERT: gst_query_parse_convert (query, &src_format, &src_value, &dst_format, NULL); res = gst_wildmidi_src_convert (wildmidi, src_format, src_value, &dst_format, &dst_value); if (res) gst_query_set_convert (query, src_format, src_value, dst_format, dst_value); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT); break; case GST_QUERY_SEGMENT: gst_query_set_segment (query, wildmidi->o_segment->rate, wildmidi->o_segment->format, wildmidi->o_segment->start, wildmidi->o_segment->stop); break; case GST_QUERY_SEEKING: gst_query_set_seeking (query, wildmidi->o_segment->format, TRUE, 0, wildmidi->o_len); break; default: res = FALSE; break; } gst_object_unref (wildmidi); return res; }
static GstEvent * gst_wildmidi_get_new_segment_event (GstWildmidi * wildmidi, GstFormat format) { gint64 start, stop, time; GstSegment *segment; GstEvent *event; GstFormat src_format; segment = wildmidi->o_segment; src_format = segment->format; /* convert the segment values to the target format */ gst_wildmidi_src_convert (wildmidi, src_format, segment->start, &format, &start); gst_wildmidi_src_convert (wildmidi, src_format, segment->stop, &format, &stop); gst_wildmidi_src_convert (wildmidi, src_format, segment->time, &format, &time); event = gst_event_new_new_segment_full (FALSE, segment->rate, segment->applied_rate, format, start, stop, time); return event; }
static gboolean gst_wildmidi_do_seek (GstWildmidi * wildmidi, GstEvent * event) { gdouble rate; GstFormat src_format, dst_format; GstSeekFlags flags; GstSeekType start_type, stop_type; gint64 start, stop; gboolean flush, update; #ifdef HAVE_WILDMIDI_0_2_2 gboolean accurate; #endif gboolean res; unsigned long int sample; GstSegment *segment; if (!wildmidi->song) return FALSE; gst_event_parse_seek (event, &rate, &src_format, &flags, &start_type, &start, &stop_type, &stop); /* convert the input format to samples */ dst_format = GST_FORMAT_DEFAULT; res = TRUE; if (start_type != GST_SEEK_TYPE_NONE) { res = gst_wildmidi_src_convert (wildmidi, src_format, start, &dst_format, &start); } if (res && stop_type != GST_SEEK_TYPE_NONE) { res = gst_wildmidi_src_convert (wildmidi, src_format, stop, &dst_format, &stop); } /* unsupported format */ if (!res) return res; flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH); #ifdef HAVE_WILDMIDI_0_2_2 accurate = ((flags & GST_SEEK_FLAG_ACCURATE) == GST_SEEK_FLAG_ACCURATE); #endif if (flush) { GST_DEBUG ("performing flush"); gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_start ()); } else { gst_pad_stop_task (wildmidi->sinkpad); } segment = wildmidi->o_segment; GST_PAD_STREAM_LOCK (wildmidi->sinkpad); if (flush) { gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_stop (TRUE)); } /* update the segment now */ gst_segment_do_seek (segment, rate, dst_format, flags, start_type, start, stop_type, stop, &update); /* we need to seek to position in the segment now, sample will be updated */ sample = segment->position; GST_OBJECT_LOCK (wildmidi); #ifdef HAVE_WILDMIDI_0_2_2 if (accurate) { WildMidi_SampledSeek (wildmidi->song, &sample); } else { WildMidi_FastSeek (wildmidi->song, &sample); } #else WildMidi_FastSeek (wildmidi->song, &sample); #endif GST_OBJECT_UNLOCK (wildmidi); segment->start = segment->time = segment->position = sample; gst_pad_push_event (wildmidi->srcpad, gst_wildmidi_get_new_segment_event (wildmidi, GST_FORMAT_TIME)); gst_pad_start_task (wildmidi->sinkpad, (GstTaskFunction) gst_wildmidi_loop, wildmidi->sinkpad, NULL); wildmidi->discont = TRUE; GST_PAD_STREAM_UNLOCK (wildmidi->sinkpad); GST_DEBUG ("seek done"); return TRUE; }
static gboolean gst_wildmidi_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean res = TRUE; GstWildmidi *wildmidi = GST_WILDMIDI (parent); GstFormat src_format, dst_format; gint64 src_value, dst_value; if (!wildmidi->song) return FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_set_duration (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_POSITION: gst_query_set_position (query, GST_FORMAT_TIME, gst_util_uint64_scale_int (wildmidi->o_segment->position, GST_SECOND, WILDMIDI_RATE)); break; case GST_QUERY_CONVERT: gst_query_parse_convert (query, &src_format, &src_value, &dst_format, NULL); res = gst_wildmidi_src_convert (wildmidi, src_format, src_value, &dst_format, &dst_value); if (res) gst_query_set_convert (query, src_format, src_value, dst_format, dst_value); break; case GST_QUERY_FORMATS: gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT); break; case GST_QUERY_SEGMENT:{ GstFormat format; gint64 start, stop; format = wildmidi->o_segment->format; start = gst_segment_to_stream_time (wildmidi->o_segment, format, wildmidi->o_segment->start); if ((stop = wildmidi->o_segment->stop) == -1) stop = wildmidi->o_segment->duration; else stop = gst_segment_to_stream_time (wildmidi->o_segment, format, stop); gst_query_set_segment (query, wildmidi->o_segment->rate, format, start, stop); res = TRUE; break; } case GST_QUERY_SEEKING: gst_query_set_seeking (query, wildmidi->o_segment->format, TRUE, 0, wildmidi->o_len); break; default: res = gst_pad_query_default (pad, parent, query); break; } return res; }