summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2005-02-15 11:05:35 +0000
committerTim-Philipp Müller <tim@centricular.net>2005-02-15 11:05:35 +0000
commit8bc146d759aedcb3e102840df978b296b667ced0 (patch)
tree85d605f150b73cdb182ade7b29798df8cc152d07 /gst
parent3d40ce29002cdd03687198d819a23becdd2e0e84 (diff)
downloadgst-plugins-bad-8bc146d759aedcb3e102840df978b296b667ced0.tar.gz
gst-plugins-bad-8bc146d759aedcb3e102840df978b296b667ced0.tar.bz2
gst-plugins-bad-8bc146d759aedcb3e102840df978b296b667ced0.zip
Add query function to GstSpeed, so that the stream length and current position get adjusted when queried (note that c...
Original commit message from CVS: Add query function to GstSpeed, so that the stream length and current position get adjusted when queried (note that current position queries may still be wrong if the audio sink returns values based on buffer timestamps instead of passing on the query
Diffstat (limited to 'gst')
-rw-r--r--gst/speed/demo-mp3.c58
-rw-r--r--gst/speed/gstspeed.c85
2 files changed, 128 insertions, 15 deletions
diff --git a/gst/speed/demo-mp3.c b/gst/speed/demo-mp3.c
index c61f15ef..d2144cf3 100644
--- a/gst/speed/demo-mp3.c
+++ b/gst/speed/demo-mp3.c
@@ -25,6 +25,8 @@
#include <gtk/gtk.h>
#include <gst/gst.h>
+static GtkWidget *poslabel; /* NULL */
+
void
set_speed (GtkAdjustment * adj, gpointer data)
{
@@ -33,10 +35,34 @@ set_speed (GtkAdjustment * adj, gpointer data)
g_object_set (speed, "speed", adj->value, NULL);
}
+static gboolean
+time_tick_cb (GstElement * audiosink)
+{
+ GstFormat format = GST_FORMAT_TIME;
+ guint64 total, pos;
+
+ if (gst_element_query (audiosink, GST_QUERY_TOTAL, &format, &total)
+ && gst_element_query (audiosink, GST_QUERY_POSITION, &format, &pos)) {
+ guint t_min, t_sec, p_min, p_sec;
+ gchar *s;
+
+ t_min = (guint) (total / (GST_SECOND * 60));
+ t_sec = (guint) ((total % (GST_SECOND * 60)) / GST_SECOND);
+ p_min = (guint) (pos / (GST_SECOND * 60));
+ p_sec = (guint) ((pos % (GST_SECOND * 60)) / GST_SECOND);
+
+ s = g_strdup_printf ("%u:%02u / %u:%02u", p_min, p_sec, t_min, t_sec);
+ gtk_label_set_text (GTK_LABEL (poslabel), s);
+ g_free (s);
+ }
+
+ return TRUE; /* call again */
+}
+
int
main (int argc, char **argv)
{
- GtkWidget *window, *vbox, *hscale, *button;
+ GtkWidget *window, *vbox, *hscale, *button, *hbbox;
GstElement *filesrc, *mad, *audioconvert, *speed, *audiosink, *pipeline;
gst_init (&argc, &argv);
@@ -48,20 +74,23 @@ main (int argc, char **argv)
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 80);
vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (vbox);
- hscale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.01, 4.0,
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+ hscale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.1, 4.0,
0.1, 0.0, 0.0)));
gtk_scale_set_digits (GTK_SCALE (hscale), 2);
gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
- button = gtk_button_new_with_label ("quit");
+ hbbox = gtk_hbutton_box_new ();
+ button = gtk_button_new_from_stock (GTK_STOCK_QUIT);
gtk_container_add (GTK_CONTAINER (window), vbox);
+ gtk_container_add (GTK_CONTAINER (hbbox), button);
+ poslabel = gtk_label_new (NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), poslabel, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 2);
- gtk_widget_show (hscale);
- gtk_signal_connect (GTK_OBJECT (button), "clicked", gtk_main_quit, NULL);
- gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (vbox), hbbox, FALSE, FALSE, 6);
+ g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
filesrc = gst_element_factory_make ("filesrc", "filesrc");
mad = gst_element_factory_make ("mad", "mad");
@@ -69,8 +98,8 @@ main (int argc, char **argv)
speed = gst_element_factory_make ("speed", "speed");
audiosink = gst_element_factory_make (DEFAULT_AUDIOSINK, "audiosink");
- gtk_signal_connect (GTK_OBJECT (gtk_range_get_adjustment (GTK_RANGE
- (hscale))), "value_changed", G_CALLBACK (set_speed), speed);
+ g_signal_connect (gtk_range_get_adjustment (GTK_RANGE (hscale)),
+ "value_changed", G_CALLBACK (set_speed), speed);
pipeline = gst_pipeline_new ("app");
gst_bin_add_many (GST_BIN (pipeline), filesrc, mad, audioconvert, speed,
@@ -80,10 +109,15 @@ main (int argc, char **argv)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
- gtk_widget_show (window);
- gtk_idle_add ((GtkFunction) gst_bin_iterate, pipeline);
+ gtk_widget_show_all (window);
+
+ g_idle_add ((GSourceFunc) gst_bin_iterate, pipeline);
+ g_timeout_add (200, (GSourceFunc) time_tick_cb, audiosink);
gtk_main ();
+ gst_element_set_state (pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (pipeline));
+
return 0;
}
diff --git a/gst/speed/gstspeed.c b/gst/speed/gstspeed.c
index 79b39f85..f784c105 100644
--- a/gst/speed/gstspeed.c
+++ b/gst/speed/gstspeed.c
@@ -169,6 +169,80 @@ gst_speed_get_type (void)
return speed_type;
}
+static const GstQueryType *
+speed_get_query_types (GstPad * pad)
+{
+ static const GstQueryType src_query_types[] = {
+ GST_QUERY_TOTAL,
+ GST_QUERY_POSITION,
+ 0
+ };
+
+ return src_query_types;
+}
+
+static gboolean
+speed_src_query (GstPad * pad, GstQueryType type,
+ GstFormat * format, gint64 * val)
+{
+ gboolean res = TRUE;
+ GstSpeed *filter;
+
+ filter = GST_SPEED (gst_pad_get_parent (pad));
+
+ switch (type) {
+ case GST_QUERY_POSITION:
+ case GST_QUERY_TOTAL:
+ {
+ switch (*format) {
+ case GST_FORMAT_BYTES:
+ case GST_FORMAT_DEFAULT:
+ case GST_FORMAT_TIME:
+ {
+ gint64 peer_value;
+ const GstFormat *peer_formats;
+
+ res = FALSE;
+
+ peer_formats = gst_pad_get_formats (GST_PAD_PEER (filter->sinkpad));
+
+ while (peer_formats && *peer_formats && !res) {
+
+ GstFormat peer_format = *peer_formats;
+
+ /* do the probe */
+ if (gst_pad_query (GST_PAD_PEER (filter->sinkpad), type,
+ &peer_format, &peer_value)) {
+ GstFormat conv_format;
+
+ /* convert to TIME */
+ conv_format = GST_FORMAT_TIME;
+ res = gst_pad_convert (filter->sinkpad,
+ peer_format, peer_value, &conv_format, val);
+
+ /* adjust for speed factor */
+ *val = (gint64) (((gdouble) * val) / filter->speed);
+
+ /* and to final format */
+ res &= gst_pad_convert (pad, GST_FORMAT_TIME, *val, format, val);
+ }
+ peer_formats++;
+ }
+ break;
+ }
+ default:
+ res = FALSE;
+ break;
+ }
+ break;
+ }
+ default:
+ res = FALSE;
+ break;
+ }
+ return res;
+}
+
static void
speed_base_init (gpointer g_class)
{
@@ -214,6 +288,8 @@ speed_init (GstSpeed * filter)
(&gst_speed_src_template), "src");
gst_pad_set_link_function (filter->srcpad, speed_link);
gst_pad_set_getcaps_function (filter->srcpad, gst_pad_proxy_getcaps);
+ gst_pad_set_query_type_function (filter->srcpad, speed_get_query_types);
+ gst_pad_set_query_function (filter->srcpad, speed_src_query);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
filter->offset = 0;
@@ -307,12 +383,15 @@ speed_chain (GstPad * pad, GstData * data)
{
gint64 timestamp, offset;
+ if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_TIME,
+ &timestamp)) {
+ filter->timestamp = timestamp;
+ filter->offset = timestamp * filter->rate / GST_SECOND;
+ }
if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES,
- &timestamp)
- && gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES,
&offset)) {
filter->offset = offset;
- filter->timestamp = timestamp;
+ filter->timestamp = offset * GST_SECOND / filter->rate;
}
break;
}