From: Mathieu Duponchelle Date: Mon, 8 Jul 2013 22:31:30 +0000 (+0200) Subject: formatters: Save and load bindings applied to sources. X-Git-Tag: 1.19.3~493^2~1843 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1a3d65ef6a73e572f3c6256e926e4ae23603bbd;p=platform%2Fupstream%2Fgstreamer.git formatters: Save and load bindings applied to sources. --- diff --git a/ges/ges-base-xml-formatter.c b/ges/ges-base-xml-formatter.c index 12d2ff0..f8f5443 100644 --- a/ges/ges-base-xml-formatter.c +++ b/ges/ges-base-xml-formatter.c @@ -40,6 +40,14 @@ typedef struct PendingEffects } PendingEffects; +typedef struct PendingBinding +{ + gchar *track_id; + GstControlSource *source; + gchar *propname; + gchar *binding_type; +} PendingBinding; + typedef struct PendingClip { gchar *id; @@ -56,6 +64,8 @@ typedef struct PendingClip GList *effects; + GList *pending_bindings; + /* TODO Implement asset effect management * PendingTrackElements *track_elements; */ } PendingClip; @@ -98,6 +108,9 @@ struct _GESBaseXmlFormatterPrivate /* current track element */ GESTrackElement *current_track_element; + + GESClip *current_clip; + PendingClip *current_pending_clip; }; static void @@ -341,6 +354,8 @@ ges_base_xml_formatter_init (GESBaseXmlFormatter * self) priv->layers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) _free_layer_entry); priv->current_track_element = NULL; + priv->current_clip = NULL; + priv->current_pending_clip = NULL; } static void @@ -366,6 +381,16 @@ ges_base_xml_formatter_class_init (GESBaseXmlFormatterClass * self_class) * * ***********************************************/ + +static GESTrackElement * +_get_element_by_track_id (GESBaseXmlFormatterPrivate * priv, + const gchar * track_id, GESClip * clip) +{ + GESTrack *track = g_hash_table_lookup (priv->tracks, track_id); + + return ges_clip_find_track_element (clip, track, GES_TYPE_SOURCE); +} + static void _set_auto_transition (gpointer prio, LayerEntry * entry, gpointer udata) { @@ -460,6 +485,14 @@ _add_track_element (GESFormatter * self, GESClip * clip, } static void +_free_pending_binding (PendingBinding * pend) +{ + g_free (pend->propname); + g_free (pend->binding_type); + g_free (pend->track_id); +} + +static void _free_pending_effect (PendingEffects * pend) { g_free (pend->track_id); @@ -480,6 +513,8 @@ _free_pending_clip (GESBaseXmlFormatterPrivate * priv, PendingClip * pend) if (pend->properties) gst_structure_free (pend->properties); g_list_free_full (pend->effects, (GDestroyNotify) _free_pending_effect); + g_list_free_full (pend->pending_bindings, + (GDestroyNotify) _free_pending_binding); g_hash_table_remove (priv->clipid_pendings, pend->id); g_slice_free (PendingClip, pend); } @@ -497,6 +532,22 @@ _free_pending_asset (GESBaseXmlFormatterPrivate * priv, PendingAsset * passet) } static void +_add_pending_bindings (GESBaseXmlFormatterPrivate * priv, GList * bindings, + GESClip * clip) +{ + GList *tmpbinding; + + for (tmpbinding = bindings; tmpbinding; tmpbinding = tmpbinding->next) { + PendingBinding *pbinding = tmpbinding->data; + GESTrackElement *element = + _get_element_by_track_id (priv, pbinding->track_id, clip); + if (element) + ges_track_element_set_control_source (element, + pbinding->source, pbinding->propname, pbinding->binding_type); + } +} + +static void new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet) { GError *error = NULL; @@ -570,6 +621,8 @@ new_asset_cb (GESAsset * source, GAsyncResult * res, PendingAsset * passet) if (clip == NULL) continue; + _add_pending_bindings (priv, pend->pending_bindings, clip); + GST_DEBUG_OBJECT (self, "Adding %i effect to new object", g_list_length (pend->effects)); for (tmpeffect = pend->effects; tmpeffect; tmpeffect = tmpeffect->next) { @@ -739,6 +792,9 @@ ges_base_xml_formatter_add_clip (GESBaseXmlFormatter * self, g_list_append (pendings, pclip)); g_hash_table_insert (priv->clipid_pendings, g_strdup (id), pclip); + priv->current_clip = NULL; + priv->current_pending_clip = pclip; + return; } @@ -747,6 +803,8 @@ ges_base_xml_formatter_add_clip (GESBaseXmlFormatter * self, if (!nclip) return; + + priv->current_clip = nclip; } void @@ -831,12 +889,35 @@ ges_base_xml_formatter_add_track (GESBaseXmlFormatter * self, void ges_base_xml_formatter_add_control_binding (GESBaseXmlFormatter * self, const gchar * binding_type, const gchar * source_type, - const gchar * property_name, gint mode, GSList * timed_values) + const gchar * property_name, gint mode, const gchar * track_id, + GSList * timed_values) { GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self); - GESTrackElement *element; + GESTrackElement *element = NULL; + + if (track_id[0] != '-' && priv->current_clip) + element = _get_element_by_track_id (priv, track_id, priv->current_clip); + + else if (track_id[0] != '-' && priv->current_pending_clip) { + PendingBinding *pbinding; + + pbinding = g_slice_new0 (PendingBinding); + pbinding->source = gst_interpolation_control_source_new (); + g_object_set (pbinding->source, "mode", mode, NULL); + gst_timed_value_control_source_set_from_list (GST_TIMED_VALUE_CONTROL_SOURCE + (pbinding->source), timed_values); + pbinding->propname = g_strdup (property_name); + pbinding->binding_type = g_strdup (binding_type); + pbinding->track_id = g_strdup (track_id); + priv->current_pending_clip->pending_bindings = + g_list_append (priv->current_pending_clip->pending_bindings, pbinding); + return; + } + + else { + element = priv->current_track_element; + } - element = priv->current_track_element; if (element == NULL) { GST_WARNING ("No current track element to which we can append a binding"); return; diff --git a/ges/ges-internal.h b/ges/ges-internal.h index 0d3a60b..1ea661f 100644 --- a/ges/ges-internal.h +++ b/ges/ges-internal.h @@ -212,7 +212,7 @@ void ges_base_xml_formatter_add_encoding_profile (GESBaseXmlFormat gboolean variableframerate, GstStructure * properties, GError ** error); -G_GNUC_INTERNAL void ges_base_xml_formatter_add_track_element (GESBaseXmlFormatter *self, +G_GNUC_INTERNAL void ges_base_xml_formatter_add_track_element (GESBaseXmlFormatter *self, GType effect_type, const gchar *asset_id, const gchar * track_id, @@ -222,12 +222,13 @@ G_GNUC_INTERNAL void ges_base_xml_formatter_add_track_element (GESBaseXmlForm const gchar *metadatas, GError **error); -G_GNUC_INTERNAL void ges_base_xml_formatter_add_control_binding(GESBaseXmlFormatter * self, - const gchar * binding_type, - const gchar * source_type, - const gchar * property_name, - gint mode, - GSList * timed_values); +G_GNUC_INTERNAL void ges_base_xml_formatter_add_control_bindingi (GESBaseXmlFormatter * self, + const gchar * binding_type, + const gchar * source_type, + const gchar * property_name, + gint mode, + const gchar *track_id, + GSList * timed_values); G_GNUC_INTERNAL void set_property_foreach (GQuark field_id, const GValue * value, diff --git a/ges/ges-xml-formatter.c b/ges/ges-xml-formatter.c index fa595ca..c42457f 100644 --- a/ges/ges-xml-formatter.c +++ b/ges/ges-xml-formatter.c @@ -513,7 +513,7 @@ _parse_binding (GMarkupParseContext * context, const gchar * element_name, GESXmlFormatter * self, GError ** error) { const gchar *type = NULL, *source_type = NULL, *timed_values = - NULL, *property_name = NULL, *mode = NULL; + NULL, *property_name = NULL, *mode = NULL, *track_id = NULL; gchar **pairs, **tmp; gchar *pair; GSList *list = NULL; @@ -524,6 +524,7 @@ _parse_binding (GMarkupParseContext * context, const gchar * element_name, G_MARKUP_COLLECT_STRING, "source_type", &source_type, G_MARKUP_COLLECT_STRING, "property", &property_name, G_MARKUP_COLLECT_STRING, "mode", &mode, + G_MARKUP_COLLECT_STRING, "track_id", &track_id, G_MARKUP_COLLECT_STRING, "values", &timed_values, G_MARKUP_COLLECT_INVALID)) { return; @@ -549,10 +550,11 @@ _parse_binding (GMarkupParseContext * context, const gchar * element_name, } g_strfreev (pairs); + ges_base_xml_formatter_add_control_binding (GES_BASE_XML_FORMATTER (self), type, source_type, - property_name, (gint) g_ascii_strtoll (mode, NULL, 10), list); + property_name, (gint) g_ascii_strtoll (mode, NULL, 10), track_id, list); } static inline void @@ -809,7 +811,7 @@ _save_tracks (GString * str, GESTimeline * timeline) /* TODO : Use this function for every track element with controllable properties */ static inline void -_save_keyframes (GString * str, GESTrackElement * trackelement) +_save_keyframes (GString * str, GESTrackElement * trackelement, gint index) { GHashTable *bindings_hashtable; GHashTableIter iter; @@ -839,6 +841,7 @@ _save_keyframes (GString * str, GESTrackElement * trackelement) (gchar *) key)); g_object_get (source, "mode", &mode, NULL); append_escaped (str, g_markup_printf_escaped (" mode='%d'", mode)); + append_escaped (str, g_markup_printf_escaped (" track_id='%d'", index)); append_escaped (str, g_markup_printf_escaped (" values ='")); timed_values = gst_timed_value_control_source_get_all @@ -917,7 +920,7 @@ _save_effect (GString * str, guint clip_id, GESTrackElement * trackelement, g_markup_printf_escaped (" children-properties='%s'>\n", gst_structure_to_string (structure))); - _save_keyframes (str, trackelement); + _save_keyframes (str, trackelement, -1); append_escaped (str, g_markup_printf_escaped ("\n")); gst_structure_free (structure); @@ -950,6 +953,8 @@ _save_layers (GString * str, GESTimeline * timeline) clips = ges_layer_get_clips (layer); for (tmpclip = clips; tmpclip; tmpclip = tmpclip->next) { GList *effects, *tmpeffect; + GList *tmptrackelement; + GList *tracks; clip = GES_CLIP (tmpclip->data); effects = ges_clip_get_top_effects (clip); @@ -973,6 +978,24 @@ _save_layers (GString * str, GESTimeline * timeline) for (tmpeffect = effects; tmpeffect; tmpeffect = tmpeffect->next) _save_effect (str, nbclips, GES_TRACK_ELEMENT (tmpeffect->data), timeline); + + tracks = ges_timeline_get_tracks (timeline); + + for (tmptrackelement = GES_CONTAINER_CHILDREN (clip); tmptrackelement; + tmptrackelement = tmptrackelement->next) { + gint index; + + if (!GES_IS_SOURCE (tmptrackelement->data)) + continue; + + index = + g_list_index (tracks, + ges_track_element_get_track (tmptrackelement->data)); + _save_keyframes (str, tmptrackelement->data, index); + } + + g_list_free_full (tracks, gst_object_unref); + g_string_append (str, "\n"); nbclips++; }