mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
tests/examples/seek/seek.c: Allow to toggle looping while it plays. Fix callback prototype. Clean up code a bit more....
Original commit message from CVS: * tests/examples/seek/seek.c: (set_scale), (update_scale), (do_seek), (stop_seek), (pause_cb), (stop_cb), (loop_toggle_cb), (rate_spinbutton_changed_cb), (msg_eos), (msg_segment_done), (main): Allow to toggle looping while it plays. Fix callback prototype. Clean up code a bit more. Add copyright header.
This commit is contained in:
parent
bc62bb15e5
commit
268dcb0ab1
2 changed files with 145 additions and 44 deletions
|
@ -1,3 +1,12 @@
|
|||
2007-01-16 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* tests/examples/seek/seek.c: (set_scale), (update_scale),
|
||||
(do_seek), (stop_seek), (pause_cb), (stop_cb), (loop_toggle_cb),
|
||||
(rate_spinbutton_changed_cb), (msg_eos), (msg_segment_done),
|
||||
(main):
|
||||
Allow to toggle looping while it plays. Fix callback prototype. Clean
|
||||
up code a bit more. Add copyright header.
|
||||
|
||||
2007-01-16 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_get_xv_support):
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* seek.c: seeking sample application
|
||||
*
|
||||
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
|
||||
* 2006 Stefan Kost <ensonic@users.sf.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/* FIXME: remove #if 0 code
|
||||
* FIXME: is the flush_seek part after sending the seek still needed?
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
@ -20,15 +46,15 @@ static gboolean play_scrub = FALSE;
|
|||
static gdouble rate = 1.0;
|
||||
|
||||
static GstElement *pipeline;
|
||||
static gint64 position;
|
||||
static gint64 duration;
|
||||
static gint64 position = -1;
|
||||
static gint64 duration = -1;
|
||||
static GtkAdjustment *adjustment;
|
||||
static GtkWidget *hscale;
|
||||
static gboolean stats = FALSE;
|
||||
static gboolean elem_seek = FALSE;
|
||||
static gboolean verbose = FALSE;
|
||||
|
||||
static GstState state;
|
||||
static GstState state = GST_STATE_NULL;
|
||||
static guint update_id = 0;
|
||||
static guint seek_timeout_id = 0;
|
||||
static gulong changed_id;
|
||||
|
@ -958,16 +984,30 @@ query_positions_pads ()
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean start_seek (GtkWidget * widget, GdkEventButton * event,
|
||||
gpointer user_data);
|
||||
static gboolean stop_seek (GtkWidget * widget, GdkEventButton * event,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
set_scale (gdouble value)
|
||||
{
|
||||
g_signal_handlers_block_by_func (hscale, start_seek, pipeline);
|
||||
g_signal_handlers_block_by_func (hscale, stop_seek, pipeline);
|
||||
gtk_adjustment_set_value (adjustment, value);
|
||||
g_signal_handlers_unblock_by_func (hscale, start_seek, pipeline);
|
||||
g_signal_handlers_unblock_by_func (hscale, stop_seek, pipeline);
|
||||
gtk_widget_queue_draw (hscale);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_scale (gpointer data)
|
||||
{
|
||||
GstFormat format;
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
|
||||
position = 0;
|
||||
duration = 0;
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
|
||||
if (elem_seek) {
|
||||
if (seekable_elements) {
|
||||
GstElement *element = GST_ELEMENT (seekable_elements->data);
|
||||
|
@ -996,8 +1036,7 @@ update_scale (gpointer data)
|
|||
duration = position;
|
||||
|
||||
if (duration > 0) {
|
||||
gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
|
||||
gtk_widget_queue_draw (hscale);
|
||||
set_scale (position * 100.0 / duration);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1076,10 +1115,12 @@ do_seek (GtkWidget * widget)
|
|||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, real, GST_SEEK_TYPE_SET, -1);
|
||||
} else {
|
||||
s_event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, real);
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0),
|
||||
GST_SEEK_TYPE_SET, real);
|
||||
}
|
||||
|
||||
GST_DEBUG ("seek to %" GST_TIME_FORMAT, GST_TIME_ARGS (real));
|
||||
GST_DEBUG ("seek with rate %lf to %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT,
|
||||
rate, GST_TIME_ARGS (real), GST_TIME_ARGS (duration));
|
||||
|
||||
res = send_event (s_event);
|
||||
|
||||
|
@ -1153,7 +1194,7 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
stop_seek (GtkWidget * widget, gpointer user_data)
|
||||
stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
|
||||
{
|
||||
if (changed_id) {
|
||||
g_signal_handler_disconnect (GTK_OBJECT (hscale), changed_id);
|
||||
|
@ -1203,9 +1244,9 @@ failed:
|
|||
static void
|
||||
pause_cb (GtkButton * button, gpointer data)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
if (state != GST_STATE_PAUSED) {
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
g_print ("PAUSE pipeline\n");
|
||||
ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
|
@ -1224,15 +1265,15 @@ failed:
|
|||
static void
|
||||
stop_cb (GtkButton * button, gpointer data)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
if (state != GST_STATE_READY) {
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
g_print ("READY pipeline\n");
|
||||
ret = gst_element_set_state (pipeline, GST_STATE_READY);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
goto failed;
|
||||
|
||||
gtk_adjustment_set_value (adjustment, 0.0);
|
||||
set_scale (0.0);
|
||||
|
||||
state = GST_STATE_READY;
|
||||
}
|
||||
|
@ -1260,6 +1301,9 @@ static void
|
|||
loop_toggle_cb (GtkToggleButton * button, GstPipeline * pipeline)
|
||||
{
|
||||
loop_seek = gtk_toggle_button_get_active (button);
|
||||
if (state == GST_STATE_PLAYING) {
|
||||
do_seek (hscale);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1301,10 +1345,12 @@ rate_spinbutton_changed_cb (GtkSpinButton * button, GstPipeline * pipeline)
|
|||
GST_SEEK_TYPE_SET, -1);
|
||||
} else {
|
||||
s_event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
|
||||
position);
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0),
|
||||
GST_SEEK_TYPE_SET, position);
|
||||
}
|
||||
|
||||
GST_DEBUG ("rate changed to %lf", rate);
|
||||
|
||||
res = send_event (s_event);
|
||||
|
||||
if (res) {
|
||||
|
@ -1316,26 +1362,6 @@ rate_spinbutton_changed_cb (GtkSpinButton * button, GstPipeline * pipeline)
|
|||
g_print ("seek failed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
segment_done (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
GstEvent *event;
|
||||
GstSeekFlags flags;
|
||||
gboolean res;
|
||||
|
||||
flags = 0;
|
||||
if (loop_seek)
|
||||
flags |= GST_SEEK_FLAG_SEGMENT;
|
||||
|
||||
event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1);
|
||||
|
||||
res = send_event (event);
|
||||
if (!res) {
|
||||
g_print ("segment seek failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
|
@ -1356,6 +1382,23 @@ message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
msg_eos (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
GST_DEBUG ("position is %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
|
||||
|
||||
g_print ("READY pipeline\n");
|
||||
ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
g_print ("READY failed\n");
|
||||
|
||||
set_scale (0.0);
|
||||
|
||||
state = GST_STATE_READY;
|
||||
}
|
||||
|
||||
static void
|
||||
msg_state_changed (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
|
@ -1378,6 +1421,51 @@ msg_state_changed (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
msg_segment_done (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
GstEvent *s_event;
|
||||
GstSeekFlags flags;
|
||||
gboolean res;
|
||||
GstFormat format;
|
||||
|
||||
GST_DEBUG ("position is %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_message_parse_segment_done (message, &format, &position);
|
||||
GST_DEBUG ("end of segment at %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
|
||||
|
||||
set_update_scale (FALSE);
|
||||
|
||||
flags = GST_SEEK_FLAG_SEGMENT;
|
||||
if (flush_seek)
|
||||
flags |= GST_SEEK_FLAG_FLUSH;
|
||||
|
||||
if (rate >= 0) {
|
||||
s_event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0),
|
||||
GST_SEEK_TYPE_SET, duration);
|
||||
} else {
|
||||
s_event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, duration,
|
||||
GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0));
|
||||
}
|
||||
|
||||
GST_DEBUG ("restart loop with rate %lf to 0 / %" GST_TIME_FORMAT,
|
||||
rate, GST_TIME_ARGS (duration));
|
||||
|
||||
res = send_event (s_event);
|
||||
if (res) {
|
||||
if (flush_seek) {
|
||||
gst_pipeline_set_new_stream_time (GST_PIPELINE (pipeline), 0);
|
||||
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, SEEK_TIMEOUT);
|
||||
}
|
||||
} else
|
||||
g_print ("segment seek failed\n");
|
||||
|
||||
position = 0;
|
||||
set_update_scale (TRUE);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *name;
|
||||
|
@ -1509,7 +1597,6 @@ main (int argc, char **argv)
|
|||
NULL);
|
||||
gtk_tooltips_set_tip (tips, rate_spinbutton, "define the playback rate, "
|
||||
"negative value trigger reverse playback", NULL);
|
||||
/* FIXME: describe these */
|
||||
gtk_tooltips_set_tip (tips, scrub_checkbox, "show images while seeking",
|
||||
NULL);
|
||||
gtk_tooltips_set_tip (tips, play_scrub_checkbox, "play video while seeking",
|
||||
|
@ -1592,7 +1679,12 @@ main (int argc, char **argv)
|
|||
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
||||
gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
|
||||
|
||||
// g_signal_connect (bus, "message::state-changed", (GCallback) message_received, pipeline);
|
||||
g_signal_connect (bus, "message::eos", (GCallback) msg_eos, pipeline);
|
||||
g_signal_connect (bus, "message::state-changed",
|
||||
(GCallback) msg_state_changed, pipeline);
|
||||
g_signal_connect (bus, "message::segment-done",
|
||||
(GCallback) msg_segment_done, pipeline);
|
||||
|
||||
g_signal_connect (bus, "message::new-clock", (GCallback) message_received,
|
||||
pipeline);
|
||||
g_signal_connect (bus, "message::error", (GCallback) message_received,
|
||||
|
@ -1607,10 +1699,10 @@ main (int argc, char **argv)
|
|||
pipeline);
|
||||
g_signal_connect (bus, "message::segment-done",
|
||||
(GCallback) message_received, pipeline);
|
||||
g_signal_connect (bus, "message::state-changed",
|
||||
(GCallback) msg_state_changed, pipeline);
|
||||
g_signal_connect (bus, "message::segment-done", (GCallback) segment_done,
|
||||
pipeline);
|
||||
/*g_signal_connect (bus, "message::state-changed",
|
||||
(GCallback) message_received, pipeline);
|
||||
*/
|
||||
|
||||
}
|
||||
gtk_main ();
|
||||
|
||||
|
|
Loading…
Reference in a new issue