} PendingEffects;
+typedef struct PendingBinding
+{
+ gchar *track_id;
+ GstControlSource *source;
+ gchar *propname;
+ gchar *binding_type;
+} PendingBinding;
+
typedef struct PendingClip
{
gchar *id;
GList *effects;
+ GList *pending_bindings;
+
/* TODO Implement asset effect management
* PendingTrackElements *track_elements; */
} PendingClip;
/* current track element */
GESTrackElement *current_track_element;
+
+ GESClip *current_clip;
+ PendingClip *current_pending_clip;
};
static void
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
* *
***********************************************/
+
+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)
{
}
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);
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);
}
}
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;
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) {
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;
}
if (!nclip)
return;
+
+ priv->current_clip = nclip;
}
void
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;
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,
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,
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;
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;
}
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
/* 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;
(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
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 ("</effect>\n"));
gst_structure_free (structure);
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);
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, "</clip>\n");
nbclips++;
}