gboolean flush_seek;
gboolean scrub;
gboolean play_scrub;
+ gboolean instant_rate_change;
gboolean skip_seek;
gboolean skip_seek_key_only;
gboolean skip_seek_no_audio;
{
gboolean res = FALSE;
GstEvent *s_event;
+ GstClockTime start, stop;
+ GstSeekType start_type = GST_SEEK_TYPE_SET;
+ GstSeekType stop_type = GST_SEEK_TYPE_SET;
GstSeekFlags flags;
flags = 0;
if (app->snap_after)
flags |= GST_SEEK_FLAG_SNAP_AFTER;
+ if (app->instant_rate_change) {
+ flags |= GST_SEEK_FLAG_INSTANT_RATE_CHANGE;
+ start_type = stop_type = GST_SEEK_TYPE_NONE;
+ start = stop = GST_CLOCK_TIME_NONE;
+ if (app->flush_seek) {
+ g_warning ("Instant rate change seek not supported with flushing");
+ return;
+ }
+ } else if (app->rate < 0) {
+ stop = position;
+ start = 0;
+ } else {
+ start = position;
+ stop = GST_CLOCK_TIME_NONE;
+ }
+
if (app->rate >= 0) {
s_event = gst_event_new_seek (app->rate,
- format, flags, GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_SET,
- GST_CLOCK_TIME_NONE);
+ format, flags, start_type, start, stop_type, stop);
GST_DEBUG ("seek with rate %lf to %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT,
- app->rate, GST_TIME_ARGS (position), GST_TIME_ARGS (app->duration));
+ app->rate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
} else {
s_event = gst_event_new_seek (app->rate,
- format, flags, GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0),
- GST_SEEK_TYPE_SET, position);
+ format, flags, start_type, start, stop_type, stop);
GST_DEBUG ("seek with rate %lf to %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT,
- app->rate, GST_TIME_ARGS (0), GST_TIME_ARGS (position));
+ app->rate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
}
res = send_event (app, s_event);
}
static void
+instant_rate_change_toggle_cb (GtkToggleButton * button, PlaybackApp * app)
+{
+ app->instant_rate_change = gtk_toggle_button_get_active (button);
+}
+
+static void
skip_toggle_common (gboolean * v, GtkToggleButton * button, PlaybackApp * app)
{
*v = gtk_toggle_button_get_active (button);
gboolean res = FALSE;
GstEvent *s_event;
GstSeekFlags flags;
+ GstClockTime start, stop;
+ GstSeekType start_type = GST_SEEK_TYPE_SET;
+ GstSeekType stop_type = GST_SEEK_TYPE_SET;
app->rate = gtk_spin_button_get_value (button);
if (app->skip_seek_no_audio)
flags |= GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
+ if (app->instant_rate_change) {
+ flags |= GST_SEEK_FLAG_INSTANT_RATE_CHANGE;
+ start_type = stop_type = GST_SEEK_TYPE_NONE;
+ start = stop = GST_CLOCK_TIME_NONE;
+ if (app->flush_seek) {
+ g_warning ("Instant rate change seek not supported with flushing");
+ return;
+ }
+ } else if (app->rate < 0) {
+ stop = app->position;
+ start = 0;
+ } else {
+ start = app->position;
+ stop = GST_CLOCK_TIME_NONE;
+ }
+
if (app->rate >= 0.0) {
s_event = gst_event_new_seek (app->rate,
- GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, app->position,
- GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE);
+ GST_FORMAT_TIME, flags, start_type, start, stop_type, stop);
} else {
s_event = gst_event_new_seek (app->rate,
- GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, G_GINT64_CONSTANT (0),
- GST_SEEK_TYPE_SET, app->position);
+ GST_FORMAT_TIME, flags, start_type, start, stop_type, stop);
}
res = send_event (app, s_event);
static void
message_received (GstBus * bus, GstMessage * message, PlaybackApp * app)
{
- const GstStructure *s;
-
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_ERROR:
- GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (app->pipeline),
- GST_DEBUG_GRAPH_SHOW_ALL, "seek.error");
- break;
- case GST_MESSAGE_WARNING:
- GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (app->pipeline),
- GST_DEBUG_GRAPH_SHOW_ALL, "seek.warning");
- break;
- default:
- break;
- }
-
- s = gst_message_get_structure (message);
- g_print ("message from \"%s\" (%s): ",
- GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))),
- gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
- if (s) {
- gchar *sstr;
-
- sstr = gst_structure_to_string (s);
- g_print ("%s\n", sstr);
- g_free (sstr);
- } else {
- g_print ("no message details\n");
- }
}
static void
/* seek expander */
{
- GtkWidget *accurate_checkbox, *key_checkbox, *loop_checkbox,
- *flush_checkbox, *snap_before_checkbox, *snap_after_checkbox;
+ GtkWidget *accurate_checkbox, *key_checkbox, *loop_checkbox;
+ GtkWidget *flush_checkbox, *snap_before_checkbox, *snap_after_checkbox;
GtkWidget *scrub_checkbox, *play_scrub_checkbox, *rate_label;
- GtkWidget *skip_checkbox, *skip_key_checkbox, *skip_audio_checkbox,
- *rate_spinbutton;
+ GtkWidget *skip_checkbox, *skip_key_checkbox, *skip_audio_checkbox;
+ GtkWidget *instant_checkbox, *rate_spinbutton;
GtkWidget *flagtable, *advanced_seek, *advanced_seek_grid;
GtkWidget *duration_label, *position_label, *seek_button;
GtkWidget *start_label, *stop_label;
flush_checkbox = gtk_check_button_new_with_label ("Flush");
scrub_checkbox = gtk_check_button_new_with_label ("Scrub");
play_scrub_checkbox = gtk_check_button_new_with_label ("Play Scrub");
+ instant_checkbox = gtk_check_button_new_with_label ("Instant Rate Change");
skip_checkbox = gtk_check_button_new_with_label ("Trickmode Play");
skip_key_checkbox =
gtk_check_button_new_with_label ("Trickmode - Keyframes Only");
gtk_widget_set_tooltip_text (scrub_checkbox, "show images while seeking");
gtk_widget_set_tooltip_text (play_scrub_checkbox,
"play video while seeking");
+ gtk_widget_set_tooltip_text (instant_checkbox, "do instant rate changes");
gtk_widget_set_tooltip_text (skip_checkbox,
"Skip frames while playing at high frame rates");
gtk_widget_set_tooltip_text (skip_key_checkbox,
G_CALLBACK (scrub_toggle_cb), app);
g_signal_connect (G_OBJECT (play_scrub_checkbox), "toggled",
G_CALLBACK (play_scrub_toggle_cb), app);
+ g_signal_connect (G_OBJECT (instant_checkbox), "toggled",
+ G_CALLBACK (instant_rate_change_toggle_cb), app);
g_signal_connect (G_OBJECT (skip_checkbox), "toggled",
G_CALLBACK (skip_toggle_cb), app);
g_signal_connect (G_OBJECT (skip_key_checkbox), "toggled",
gtk_grid_attach (GTK_GRID (flagtable), key_checkbox, 0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (flagtable), scrub_checkbox, 1, 1, 1, 1);
gtk_grid_attach (GTK_GRID (flagtable), play_scrub_checkbox, 2, 1, 1, 1);
+ gtk_grid_attach (GTK_GRID (flagtable), instant_checkbox, 2, 2, 1, 1);
gtk_grid_attach (GTK_GRID (flagtable), skip_checkbox, 3, 0, 1, 1);
gtk_grid_attach (GTK_GRID (flagtable), skip_key_checkbox, 3, 1, 1, 1);
gtk_grid_attach (GTK_GRID (flagtable), skip_audio_checkbox, 3, 2, 1, 1);