nlecomposition: Add a 'query-position' signal

In order to get the precise position of the pipeline, the only
way is to ask the 'application' to query the pipeline position and
use it.
This commit is contained in:
Thibault Saunier 2014-11-04 15:38:05 +01:00
parent 3b353be8ea
commit 6367c96d7d
4 changed files with 61 additions and 4 deletions

View file

@ -320,8 +320,9 @@ G_GNUC_INTERNAL void ges_track_element_split_bindings (GESTrackElement *element,
guint64 position); guint64 position);
G_GNUC_INTERNAL GstElement *ges_source_create_topbin (const gchar * bin_name, GstElement * sub_element, ...); 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,
G_GNUC_INTERNAL void ges_track_set_caps (GESTrack *track, const GstCaps *caps); const GstCaps *caps);
G_GNUC_INTERNAL GstElement * ges_track_get_composition (GESTrack *track);
/********************************************* /*********************************************

View file

@ -52,6 +52,8 @@ typedef struct
GstPad *srcpad; /* Timeline source pad */ GstPad *srcpad; /* Timeline source pad */
GstPad *playsinkpad; GstPad *playsinkpad;
GstPad *encodebinpad; GstPad *encodebinpad;
guint query_position_id;
} OutputChain; } 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 static void
_link_track (GESPipeline * self, GESTrack * track) _link_track (GESPipeline * self, GESTrack * track)
{ {
@ -673,6 +687,10 @@ _link_track (GESPipeline * self, GESTrack * track)
if (chain->tee) if (chain->tee)
return; return;
chain->query_position_id =
g_signal_connect (ges_track_get_composition (track), "query-position",
G_CALLBACK (_query_position_cb), self);
chain->srcpad = pad; chain->srcpad = pad;
gst_object_unref (pad); gst_object_unref (pad);
@ -835,6 +853,11 @@ _unlink_track (GESPipeline * self, GESTrack * track)
gst_object_unref (peer); gst_object_unref (peer);
gst_element_set_state (chain->tee, GST_STATE_NULL); gst_element_set_state (chain->tee, GST_STATE_NULL);
gst_bin_remove (GST_BIN (self), chain->tee); 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); self->priv->chains = g_list_remove (self->priv->chains, chain);
g_free (chain); g_free (chain);

View file

@ -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 /* FIXME: Find out how to avoid doing this "hack" using the GDestroyNotify
* function pointer in the trackelements_by_start GSequence * function pointer in the trackelements_by_start GSequence
* *

View file

@ -68,6 +68,7 @@ enum
{ {
COMMIT_SIGNAL, COMMIT_SIGNAL,
COMMITED_SIGNAL, COMMITED_SIGNAL,
QUERY_POSITION_SIGNAL,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -907,6 +908,22 @@ nle_composition_class_init (NleCompositionClass * klass)
0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
G_TYPE_BOOLEAN); 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 (_seek_pipeline_func);
useless = GST_DEBUG_FUNCPTR (_remove_object_func); useless = GST_DEBUG_FUNCPTR (_remove_object_func);
useless = GST_DEBUG_FUNCPTR (_add_object_func); useless = GST_DEBUG_FUNCPTR (_add_object_func);
@ -1340,10 +1357,19 @@ get_current_position (NleComposition * comp)
gboolean res; gboolean res;
gint64 value = GST_CLOCK_TIME_NONE; 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 */ /* Try querying position downstream */
peer = gst_pad_get_peer (NLE_OBJECT (comp)->srcpad);
if (peer) { if (peer) {
res = gst_pad_query_position (peer, GST_FORMAT_TIME, &value); res = gst_pad_query_position (peer, GST_FORMAT_TIME, &value);
gst_object_unref (peer); gst_object_unref (peer);