mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-03 09:12:19 +00:00
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
This commit is contained in:
parent
3d40ce2900
commit
8bc146d759
3 changed files with 140 additions and 15 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2005-02-15 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst/speed/demo-mp3.c: (time_tick_cb), (main):
|
||||
Display current position and track length; misc. clean-ups.
|
||||
|
||||
* gst/speed/gstspeed.c: (speed_get_query_types), (speed_src_query),
|
||||
(speed_init), (speed_chain):
|
||||
Add query function, 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).
|
||||
|
||||
2005-02-13 Benjamin Otte <otte@gnome.org>
|
||||
|
||||
* gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_link),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
×tamp)) {
|
||||
filter->timestamp = timestamp;
|
||||
filter->offset = timestamp * filter->rate / GST_SECOND;
|
||||
}
|
||||
if (gst_event_discont_get_value (GST_EVENT (data), GST_FORMAT_BYTES,
|
||||
×tamp)
|
||||
&& 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue