summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clutter-gst/clutter-gst-video-texture.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/clutter-gst/clutter-gst-video-texture.c b/clutter-gst/clutter-gst-video-texture.c
index 85b2160..a396683 100644
--- a/clutter-gst/clutter-gst-video-texture.c
+++ b/clutter-gst/clutter-gst-video-texture.c
@@ -56,6 +56,9 @@ struct _ClutterGstVideoTexturePrivate
gchar *uri;
guint can_seek : 1;
+ guint in_seek : 1;
+ gdouble stacked_progress;
+ GstState stacked_state;
guint tick_timeout_id;
@@ -296,6 +299,8 @@ set_playing (ClutterGstVideoTexture *video_texture,
if (playing)
state = GST_STATE_PLAYING;
+ priv->in_seek = FALSE;
+
gst_element_set_state (priv->pipeline, state);
}
else
@@ -335,7 +340,7 @@ set_progress (ClutterGstVideoTexture *video_texture,
gdouble progress)
{
ClutterGstVideoTexturePrivate *priv = video_texture->priv;
- GstState state, pending;
+ GstState pending;
GstQuery *duration_q;
gint64 position;
@@ -344,10 +349,17 @@ set_progress (ClutterGstVideoTexture *video_texture,
CLUTTER_GST_NOTE (MEDIA, "set progress: %.02f", progress);
- gst_element_get_state (priv->pipeline, &state, &pending, 0);
+ if (priv->in_seek)
+ {
+ CLUTTER_GST_NOTE (MEDIA, "already seeking. stacking progress point.");
+ priv->stacked_progress = progress;
+ return;
+ }
+
+ gst_element_get_state (priv->pipeline, &priv->stacked_state, &pending, 0);
if (pending)
- state = pending;
+ priv->stacked_state = pending;
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
@@ -369,14 +381,13 @@ set_progress (ClutterGstVideoTexture *video_texture,
gst_element_seek (priv->pipeline,
1.0,
GST_FORMAT_TIME,
- GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
GST_SEEK_TYPE_SET,
position,
- 0, 0);
-
- gst_element_set_state (priv->pipeline, state);
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
- g_object_notify (G_OBJECT (video_texture), "progress");
+ priv->in_seek = TRUE;
+ priv->stacked_progress = 0.0;
}
static gdouble
@@ -778,6 +789,27 @@ bus_message_state_change_cb (GstBus *bus,
}
}
+static void
+bus_message_async_done_cb (GstBus *bus,
+ GstMessage *message,
+ ClutterGstVideoTexture *video_texture)
+{
+ ClutterGstVideoTexturePrivate *priv = video_texture->priv;
+
+ if (priv->in_seek)
+ {
+ g_object_notify (G_OBJECT (video_texture), "progress");
+
+ priv->in_seek = FALSE;
+ gst_element_set_state (priv->pipeline, priv->stacked_state);
+
+ if (priv->stacked_progress)
+ {
+ set_progress (video_texture, priv->stacked_progress);
+ }
+ }
+}
+
static gboolean
lay_pipeline (ClutterGstVideoTexture *video_texture)
{
@@ -840,6 +872,8 @@ clutter_gst_video_texture_init (ClutterGstVideoTexture *video_texture)
return;
}
+ priv->in_seek = FALSE;
+
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
gst_bus_add_signal_watch (bus);
@@ -859,6 +893,9 @@ clutter_gst_video_texture_init (ClutterGstVideoTexture *video_texture)
g_signal_connect_object (bus, "message::state-changed",
G_CALLBACK (bus_message_state_change_cb),
video_texture, 0);
+ g_signal_connect_object (bus, "message::async-done",
+ G_CALLBACK (bus_message_async_done_cb),
+ video_texture, 0);
gst_object_unref (GST_OBJECT (bus));
}