diff --git a/ges/ges-internal.h b/ges/ges-internal.h index e9ab737dbb..119a58dac0 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -320,8 +320,9 @@ G_GNUC_INTERNAL void ges_track_element_split_bindings (GESTrackElement *element, guint64 position); G_GNUC_INTERNAL GstElement *ges_source_create_topbin (const gchar * bin_name, GstElement * sub_element, ...); - -G_GNUC_INTERNAL void ges_track_set_caps (GESTrack *track, const GstCaps *caps); +G_GNUC_INTERNAL void ges_track_set_caps (GESTrack *track, + const GstCaps *caps); +G_GNUC_INTERNAL GstElement * ges_track_get_composition (GESTrack *track); /********************************************* diff --git a/ges/ges-pipeline.c b/ges/ges-pipeline.c index 2b1985b0f4..d6d7c7d53d 100644 --- a/ges/ges-pipeline.c +++ b/ges/ges-pipeline.c @@ -52,6 +52,8 @@ typedef struct GstPad *srcpad; /* Timeline source pad */ GstPad *playsinkpad; GstPad *encodebinpad; + + guint query_position_id; } OutputChain; @@ -629,6 +631,18 @@ no_track: } } +static GstClockTime +_query_position_cb (GstElement * composition, GESPipeline * self) +{ + gint64 position; + + if (gst_element_query_position (GST_ELEMENT (self), GST_FORMAT_TIME, + &position)) + return position; + + return GST_CLOCK_TIME_NONE; +} + static void _link_track (GESPipeline * self, GESTrack * track) { @@ -673,6 +687,10 @@ _link_track (GESPipeline * self, GESTrack * track) if (chain->tee) return; + chain->query_position_id = + g_signal_connect (ges_track_get_composition (track), "query-position", + G_CALLBACK (_query_position_cb), self); + chain->srcpad = pad; gst_object_unref (pad); @@ -835,6 +853,11 @@ _unlink_track (GESPipeline * self, GESTrack * track) gst_object_unref (peer); gst_element_set_state (chain->tee, GST_STATE_NULL); gst_bin_remove (GST_BIN (self), chain->tee); + if (chain->query_position_id) { + g_signal_handler_disconnect (ges_track_get_composition (track), + chain->query_position_id); + chain->query_position_id = 0; + } self->priv->chains = g_list_remove (self->priv->chains, chain); g_free (chain); diff --git a/ges/ges-track.c b/ges/ges-track.c index 35cc208928..e097b38c10 100644 --- a/ges/ges-track.c +++ b/ges/ges-track.c @@ -309,6 +309,13 @@ composition_duration_cb (GstElement * composition, } } +/* Internal */ +GstElement * +ges_track_get_composition (GESTrack * track) +{ + return track->priv->composition; +} + /* FIXME: Find out how to avoid doing this "hack" using the GDestroyNotify * function pointer in the trackelements_by_start GSequence * diff --git a/ges/nle/nlecomposition.c b/ges/nle/nlecomposition.c index 31aee3ec06..7af3212689 100644 --- a/ges/nle/nlecomposition.c +++ b/ges/nle/nlecomposition.c @@ -68,6 +68,7 @@ enum { COMMIT_SIGNAL, COMMITED_SIGNAL, + QUERY_POSITION_SIGNAL, LAST_SIGNAL }; @@ -907,6 +908,22 @@ nle_composition_class_init (NleCompositionClass * klass) 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + /** + * NleComposition::query-position + * @comp: a #NleComposition + * + * A signal that *has* to be connected and which should return the current + * position of the pipeline. + * + * This signal is used in order to know the current position of the whole + * pipeline so it is user's responsability to give that answer as there + * is no other way to precisely know the position in the whole pipeline. + */ + _signals[QUERY_POSITION_SIGNAL] = + g_signal_new ("query-position", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_UINT64, 0, NULL); + useless = GST_DEBUG_FUNCPTR (_seek_pipeline_func); useless = GST_DEBUG_FUNCPTR (_remove_object_func); useless = GST_DEBUG_FUNCPTR (_add_object_func); @@ -1340,10 +1357,19 @@ get_current_position (NleComposition * comp) gboolean res; gint64 value = GST_CLOCK_TIME_NONE; - GstPad *peer = gst_pad_get_peer (NLE_OBJECT (comp)->srcpad); + GstPad *peer; + + g_signal_emit (comp, _signals[QUERY_POSITION_SIGNAL], 0, &value); + + if (value >= 0) { + GST_DEBUG_OBJECT (comp, "Got position %" GST_TIME_FORMAT, + GST_TIME_ARGS (value)); + + return value; + } /* Try querying position downstream */ - + peer = gst_pad_get_peer (NLE_OBJECT (comp)->srcpad); if (peer) { res = gst_pad_query_position (peer, GST_FORMAT_TIME, &value); gst_object_unref (peer);