Rename GESTimelineObject to GESClip
[platform/upstream/gst-editing-services.git] / ges / ges-meta-container.c
1 #include <glib-object.h>
2 #include <gst/gst.h>
3
4 #include "ges-meta-container.h"
5
6 /**
7 * SECTION: ges-meta-container
8 * @short_description: An interface for storing meta
9 *
10 * Interface that allows reading and writing meta
11 */
12
13 static GQuark ges_meta_key;
14
15 G_DEFINE_INTERFACE_WITH_CODE (GESMetaContainer, ges_meta_container,
16     G_TYPE_OBJECT, ges_meta_key =
17     g_quark_from_static_string ("ges-meta-container-data"););
18
19 enum
20 {
21   NOTIFY_SIGNAL,
22   LAST_SIGNAL
23 };
24
25 static guint _signals[LAST_SIGNAL] = { 0 };
26
27 typedef struct RegisteredMeta
28 {
29   GType item_type;
30   GESMetaFlag flags;
31 } RegisteredMeta;
32
33 typedef struct ContainerData
34 {
35   GstStructure *structure;
36   GHashTable *static_items;
37 } ContainerData;
38
39 static void
40 ges_meta_container_default_init (GESMetaContainerInterface * iface)
41 {
42
43   /**
44    * GESMetaContainer::notify:
45    * @container: a #GESMetaContainer
46    * @prop: the key of the value that changed
47    * @value: the #GValue containing the new value
48    *
49    * The notify signal is used to be notify of changes of values
50    * of some metadatas
51    */
52   _signals[NOTIFY_SIGNAL] =
53       g_signal_new ("notify-meta", G_TYPE_FROM_INTERFACE (iface),
54       G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
55       G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_generic,
56       G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE);
57 }
58
59 static void
60 _free_meta_container_data (ContainerData * data)
61 {
62   gst_structure_free (data->structure);
63   g_hash_table_unref (data->static_items);
64
65   g_slice_free (ContainerData, data);
66 }
67
68 static void
69 _free_static_item (RegisteredMeta * item)
70 {
71   g_slice_free (RegisteredMeta, item);
72 }
73
74 static ContainerData *
75 _create_container_data (GESMetaContainer * container)
76 {
77   ContainerData *data = g_slice_new (ContainerData);
78   data->structure = gst_structure_new_empty ("metadatas");
79   data->static_items = g_hash_table_new_full (g_str_hash, g_str_equal,
80       g_free, (GDestroyNotify) (GDestroyNotify) _free_static_item);
81   g_object_set_qdata_full (G_OBJECT (container), ges_meta_key, data,
82       (GDestroyNotify) _free_meta_container_data);
83
84   return data;
85 }
86
87 static GstStructure *
88 _meta_container_get_structure (GESMetaContainer * container)
89 {
90   ContainerData *data;
91
92   data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
93   if (!data)
94     data = _create_container_data (container);
95
96   return data->structure;
97 }
98
99 typedef struct
100 {
101   GESMetaForeachFunc func;
102   const GESMetaContainer *container;
103   gpointer data;
104 } MetadataForeachData;
105
106 static void
107 structure_foreach_wrapper (GQuark field_id, const GValue * value,
108     gpointer user_data)
109 {
110   MetadataForeachData *data = (MetadataForeachData *) user_data;
111
112   data->func (data->container, g_quark_to_string (field_id), value, data->data);
113 }
114
115 static gboolean
116 _append_foreach (GQuark field_id, const GValue * value, GESMetaContainer * self)
117 {
118   ges_meta_container_set_meta (self, g_quark_to_string (field_id), value);
119
120   return TRUE;
121 }
122
123 /**
124  * ges_meta_container_foreach:
125  * @container: container to iterate over
126  * @func: (scope call): function to be called for each metadata
127  * @user_data: (closure): user specified data
128  *
129  * Calls the given function for each metadata inside the meta container. Note
130  * that if there is no metadata, the function won't be called at all.
131  */
132 void
133 ges_meta_container_foreach (GESMetaContainer * container,
134     GESMetaForeachFunc func, gpointer user_data)
135 {
136   GstStructure *structure;
137   MetadataForeachData foreach_data;
138
139   g_return_if_fail (GES_IS_META_CONTAINER (container));
140   g_return_if_fail (func != NULL);
141
142   structure = _meta_container_get_structure (container);
143
144   foreach_data.func = func;
145   foreach_data.container = container;
146   foreach_data.data = user_data;
147
148   gst_structure_foreach (structure,
149       (GstStructureForeachFunc) structure_foreach_wrapper, &foreach_data);
150 }
151
152 /* _can_write_value should have been checked before calling */
153 static gboolean
154 _register_meta (GESMetaContainer * container, GESMetaFlag flags,
155     const gchar * meta_item, GType type)
156 {
157   ContainerData *data;
158   RegisteredMeta *static_item;
159
160   data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
161   if (!data)
162     data = _create_container_data (container);
163   else if (g_hash_table_lookup (data->static_items, meta_item)) {
164     GST_WARNING_OBJECT (container, "Static meta %s already registered",
165         meta_item);
166
167     return FALSE;
168   }
169
170   static_item = g_slice_new0 (RegisteredMeta);
171   static_item->item_type = type;
172   static_item->flags = flags;
173   g_hash_table_insert (data->static_items, g_strdup (meta_item), static_item);
174
175   return TRUE;
176 }
177
178 static gboolean
179 _set_value (GESMetaContainer * container, const gchar * meta_item,
180     const GValue * value)
181 {
182   GstStructure *structure;
183   gchar *val = gst_value_serialize (value);
184
185   if (val == NULL) {
186     GST_WARNING_OBJECT (container, "Could not set value on item: %s",
187         meta_item);
188
189     g_free (val);
190     return FALSE;
191   }
192
193   structure = _meta_container_get_structure (container);
194
195   GST_DEBUG_OBJECT (container, "Setting meta_item %s value: %s::%s",
196       meta_item, G_VALUE_TYPE_NAME (value), val);
197
198   gst_structure_set_value (structure, meta_item, value);
199   g_signal_emit (container, _signals[NOTIFY_SIGNAL], 0, meta_item, value);
200
201   g_free (val);
202   return TRUE;
203 }
204
205 static gboolean
206 _can_write_value (GESMetaContainer * container, const gchar * item_name,
207     GType type)
208 {
209   ContainerData *data;
210   RegisteredMeta *static_item = NULL;
211
212   data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
213   if (!data) {
214     data = _create_container_data (container);
215     return TRUE;
216   }
217
218   static_item = g_hash_table_lookup (data->static_items, item_name);
219
220   if (static_item == NULL)
221     return TRUE;
222
223   if ((static_item->flags & GES_META_WRITABLE) == FALSE) {
224     GST_WARNING_OBJECT (container, "Can not write %s", item_name);
225     return FALSE;
226   }
227
228   if (static_item->item_type != type) {
229     GST_WARNING_OBJECT (container, "Can not set value of type %s on %s "
230         "its type is: %s", g_type_name (static_item->item_type), item_name,
231         g_type_name (type));
232     return FALSE;
233   }
234
235   return TRUE;
236 }
237
238 #define CREATE_SETTER(name, value_ctype, value_gtype,  setter_name)     \
239 gboolean                                                                \
240 ges_meta_container_set_ ## name (GESMetaContainer *container,      \
241                            const gchar *meta_item, value_ctype value)   \
242 {                                                                       \
243   GValue gval = { 0 };                                                  \
244                                                                         \
245   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);      \
246   g_return_val_if_fail (meta_item != NULL, FALSE);                      \
247                                                                         \
248   if (_can_write_value (container, meta_item, value_gtype) == FALSE)    \
249     return FALSE;                                                       \
250                                                                         \
251   g_value_init (&gval, value_gtype);                                    \
252   g_value_set_ ##setter_name (&gval, value);                            \
253                                                                         \
254   return _set_value (container, meta_item, &gval);                      \
255 }
256
257 /**
258  * ges_meta_container_set_boolean:
259  * @container: Target container
260  * @meta_item: Name of the meta item to set
261  * @value: (allow-none): Value to set
262  *
263  * Sets the value of a given meta item
264  *
265  * Return: %TRUE if the meta could be added, %FALSE otherwize
266  */
267 CREATE_SETTER (boolean, gboolean, G_TYPE_BOOLEAN, boolean)
268
269 /**
270  * ges_meta_container_set_int:
271  * @container: Target container
272  * @meta_item: Name of the meta item to set
273  * @value: Value to set
274  *
275  * Sets the value of a given meta item
276  *
277  * Return: %TRUE if the meta could be added, %FALSE otherwize
278  */
279     CREATE_SETTER (int, gint, G_TYPE_INT, int)
280
281 /**
282  * ges_meta_container_set_uint:
283  * @container: Target container
284  * @meta_item: Name of the meta item to set
285  * @value: Value to set
286  *
287  * Sets the value of a given meta item
288  *
289  * Return: %TRUE if the meta could be added, %FALSE otherwize
290  */
291     CREATE_SETTER (uint, guint, G_TYPE_UINT, uint)
292
293 /**
294  * ges_meta_container_set_int64:
295  * @container: Target container
296  * @meta_item: Name of the meta item to set
297  * @value: Value to set
298  *
299  * Sets the value of a given meta item
300  *
301  * Return: %TRUE if the meta could be added, %FALSE otherwize
302  */
303     CREATE_SETTER (int64, gint64, G_TYPE_INT64, int64)
304
305 /**
306  * ges_meta_container_set_uint64:
307  * @container: Target container
308  * @meta_item: Name of the meta item to set
309  * @value: Value to set
310  *
311  * Sets the value of a given meta item
312  *
313  * Return: %TRUE if the meta could be added, %FALSE otherwize
314  */
315     CREATE_SETTER (uint64, guint64, G_TYPE_UINT64, uint64)
316
317 /**
318  * ges_meta_container_set_float:
319  * @container: Target container
320  * @meta_item: Name of the meta item to set
321  * @value: Value to set
322  *
323  * Sets the value of a given meta item
324  *
325  * Return: %TRUE if the meta could be added, %FALSE otherwize
326  */
327     CREATE_SETTER (float, float, G_TYPE_FLOAT, float)
328
329 /**
330  * ges_meta_container_set_double:
331  * @container: Target container
332  * @meta_item: Name of the meta item to set
333  * @value: Value to set
334  *
335  * Sets the value of a given meta item
336  *
337  * Return: %TRUE if the meta could be added, %FALSE otherwize
338  */
339 CREATE_SETTER (double, double, G_TYPE_DOUBLE, double)
340
341 /**
342  * ges_meta_container_set_date:
343  * @container: Target container
344  * @meta_item: Name of the meta item to set
345  * @value: Value to set
346  *
347  * Sets the value of a given meta item
348  *
349  * Return: %TRUE if the meta could be added, %FALSE otherwize
350  */
351 CREATE_SETTER (date, const GDate *, G_TYPE_DATE, boxed)
352
353 /**
354  * ges_meta_container_set_date_time:
355  * @container: Target container
356  * @meta_item: Name of the meta item to set
357  * @value: Value to set
358  *
359  * Sets the value of a given meta item
360  *
361  * Return: %TRUE if the meta could be added, %FALSE otherwize
362  */
363 CREATE_SETTER (date_time, const GstDateTime *, GST_TYPE_DATE_TIME, boxed)
364
365 /**
366 * ges_meta_container_set_string:
367 * @container: Target container
368 * @meta_item: Name of the meta item to set
369 * @value: Value to set
370 *
371 * Sets the value of a given meta item
372 *
373 * Return: %TRUE if the meta could be added, %FALSE otherwize
374 */
375 CREATE_SETTER (string, const gchar *, G_TYPE_STRING, string)
376
377 /**
378  * ges_meta_container_set_meta:
379  * @container: Target container
380  * @meta_item: Name of the meta item to set
381  * @value: Value to set
382  * Sets the value of a given meta item
383  *
384  * Return: %TRUE if the meta could be added, %FALSE otherwize
385  */
386   gboolean
387 ges_meta_container_set_meta (GESMetaContainer * container,
388     const gchar * meta_item, const GValue * value)
389 {
390   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
391   g_return_val_if_fail (meta_item != NULL, FALSE);
392
393   if (_can_write_value (container, meta_item, G_VALUE_TYPE (value)) == FALSE)
394     return FALSE;
395
396   return _set_value (container, meta_item, value);
397 }
398
399 /**
400  * ges_meta_container_metas_to_string:
401  * @container: a #GESMetaContainer
402  *
403  * Serializes a meta container to a string.
404  *
405  * Returns: a newly-allocated string, or NULL in case of an error. The
406  *    string must be freed with g_free() when no longer needed.
407  */
408 gchar *
409 ges_meta_container_metas_to_string (GESMetaContainer * container)
410 {
411   GstStructure *structure;
412
413   g_return_val_if_fail (GES_IS_META_CONTAINER (container), NULL);
414
415   structure = _meta_container_get_structure (container);
416
417   return gst_structure_to_string (structure);
418 }
419
420 /**
421  * ges_meta_container_add_metas_from_string:
422  * @str: a string created with ges_meta_container_metas_to_string()
423  * @container: Target container
424  *
425  * Deserializes a meta container.
426  *
427  * Returns: (transfer full): a new #GESMetaContainer, or NULL in case of an
428  * error.
429  */
430 gboolean
431 ges_meta_container_add_metas_from_string (GESMetaContainer * container,
432     const gchar * str)
433 {
434   GstStructure *n_structure;
435
436   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
437
438   n_structure = gst_structure_from_string (str, NULL);
439   if (n_structure == NULL) {
440     GST_WARNING_OBJECT (container, "Could not add metas: %s", str);
441     return FALSE;
442   }
443
444   gst_structure_foreach (n_structure, (GstStructureForeachFunc) _append_foreach,
445       container);
446
447   gst_structure_free (n_structure);
448   return TRUE;
449 }
450
451 #define CREATE_REGISTER_STATIC(name, value_ctype, value_gtype, setter_name) \
452 gboolean                                                                      \
453 ges_meta_container_register_meta_ ## name (GESMetaContainer *container,\
454     GESMetaFlag flags, const gchar *meta_item, value_ctype value)             \
455 {                                                                             \
456   gboolean ret;                                                               \
457   GValue gval = { 0 };                                                        \
458                                                                               \
459   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);            \
460   g_return_val_if_fail (meta_item != NULL, FALSE);                            \
461                                                                               \
462   if (!_register_meta (container, flags, meta_item, value_gtype))             \
463     return FALSE;                                                             \
464                                                                               \
465   g_value_init (&gval, value_gtype);                                          \
466   g_value_set_ ##setter_name (&gval, value);                                  \
467                                                                               \
468   ret = _set_value  (container, meta_item, &gval);                            \
469                                                                               \
470   g_value_unset (&gval);                                                      \
471   return ret;                                                                 \
472 }
473
474 /**
475  * register_meta_:
476  * @container: Target container
477  * @flags: The #GESMetaFlag to be used
478  * @meta_item: Name of the meta item to set
479  * @value: (allow-none): Value to set
480  *
481  * Sets a static meta on @container. This method lets you define static
482  * metadatas, which means that the type of the registered will be the only
483  * type accepted for this meta on that particular @container.
484  *
485  * Return: %TRUE if the meta could be register, %FALSE otherwize
486  */
487 CREATE_REGISTER_STATIC (boolean, gboolean, G_TYPE_BOOLEAN, boolean)
488
489 /**
490  * ges_meta_container_register_meta_int:
491  * @container: Target container
492  * @flags: The #GESMetaFlag to be used
493  * @meta_item: Name of the meta item to set
494  * @value: (allow-none): Value to set
495  *
496  * Sets a static meta on @container. This method lets you define static
497  * metadatas, which means that the type of the registered will be the only
498  * type accepted for this meta on that particular @container.
499  *
500  * Return: %TRUE if the meta could be register, %FALSE otherwize
501  */
502     CREATE_REGISTER_STATIC (int, gint, G_TYPE_INT, int)
503
504 /**
505  * ges_meta_container_register_meta_uint:
506  * @container: Target container
507  * @flags: The #GESMetaFlag to be used
508  * @meta_item: Name of the meta item to set
509  * @value: (allow-none): Value to set
510  *
511  * Sets a static meta on @container. This method lets you define static
512  * metadatas, which means that the type of the registered will be the only
513  * type accepted for this meta on that particular @container.
514  *
515  * Return: %TRUE if the meta could be register, %FALSE otherwize
516  */
517     CREATE_REGISTER_STATIC (uint, guint, G_TYPE_UINT, uint)
518
519 /**
520  * ges_meta_container_register_meta_int64:
521  * @container: Target container
522  * @flags: The #GESMetaFlag to be used
523  * @meta_item: Name of the meta item to set
524  * @value: (allow-none): Value to set
525  *
526  * Sets a static meta on @container. This method lets you define static
527  * metadatas, which means that the type of the registered will be the only
528  * type accepted for this meta on that particular @container.
529  *
530  * Return: %TRUE if the meta could be register, %FALSE otherwize
531  */
532     CREATE_REGISTER_STATIC (int64, gint64, G_TYPE_INT64, int64)
533
534 /**
535  * ges_meta_container_register_meta_uint64:
536  * @container: Target container
537  * @flags: The #GESMetaFlag to be used
538  * @meta_item: Name of the meta item to set
539  * @value: (allow-none): Value to set
540  *
541  * Sets a static meta on @container. This method lets you define static
542  * metadatas, which means that the type of the registered will be the only
543  * type accepted for this meta on that particular @container.
544  *
545  * Return: %TRUE if the meta could be register, %FALSE otherwize
546  */
547     CREATE_REGISTER_STATIC (uint64, guint64, G_TYPE_UINT64, uint64)
548
549 /**
550  * ges_meta_container_register_meta_float:
551  * @container: Target container
552  * @flags: The #GESMetaFlag to be used
553  * @meta_item: Name of the meta item to set
554  * @value: (allow-none): Value to set
555  *
556  * Sets a static meta on @container. This method lets you define static
557  * metadatas, which means that the type of the registered will be the only
558  * type accepted for this meta on that particular @container.
559  *
560  * Return: %TRUE if the meta could be register, %FALSE otherwize
561 */
562     CREATE_REGISTER_STATIC (float, float, G_TYPE_FLOAT, float)
563
564 /**
565  * ges_meta_container_register_meta_double:
566  * @container: Target container
567  * @flags: The #GESMetaFlag to be used
568  * @meta_item: Name of the meta item to set
569  * @value: (allow-none): Value to set
570  *
571  * Sets a static meta on @container. This method lets you define static
572  * metadatas, which means that the type of the registered will be the only
573  * type accepted for this meta on that particular @container.
574  *
575  * Return: %TRUE if the meta could be register, %FALSE otherwize
576  */
577 CREATE_REGISTER_STATIC (double, double, G_TYPE_DOUBLE, double)
578
579 /**
580  * ges_meta_container_register_meta_date:
581  * @container: Target container
582  * @flags: The #GESMetaFlag to be used
583  * @meta_item: Name of the meta item to set
584  * @value: (allow-none): Value to set
585  *
586  * Sets a static meta on @container. This method lets you define static
587  * metadatas, which means that the type of the registered will be the only
588  * type accepted for this meta on that particular @container.
589  *
590  * Return: %TRUE if the meta could be register, %FALSE otherwize
591  */
592 CREATE_REGISTER_STATIC (date, const GDate *, G_TYPE_DATE, boxed)
593
594 /**
595  * ges_meta_container_register_meta_date_time:
596  * @container: Target container
597  * @flags: The #GESMetaFlag to be used
598  * @meta_item: Name of the meta item to set
599  * @value: (allow-none): Value to set
600  *
601  * Sets a static meta on @container. This method lets you define static
602  * metadatas, which means that the type of the registered will be the only
603  * type accepted for this meta on that particular @container.
604  *
605  * Return: %TRUE if the meta could be register, %FALSE otherwize
606  */
607 CREATE_REGISTER_STATIC (date_time, const GstDateTime *, GST_TYPE_DATE_TIME,
608     boxed)
609
610 /**
611  * ges_meta_container_register_meta_string:
612  * @container: Target container
613  * @flags: The #GESMetaFlag to be used
614  * @meta_item: Name of the meta item to set
615  * @value: (allow-none): Value to set
616  *
617  * Sets a static meta on @container. This method lets you define static
618  * metadatas, which means that the type of the registered will be the only
619  * type accepted for this meta on that particular @container.
620  *
621  * Return: %TRUE if the meta could be register, %FALSE otherwize
622  */
623 CREATE_REGISTER_STATIC (string, const gchar *, G_TYPE_STRING, string)
624
625 /**
626  * ges_meta_container_register_meta:
627  * @container: Target container
628  * @flags: The #GESMetaFlag to be used
629  * @meta_item: Name of the meta item to set
630  * @value: Value to set
631  *
632  * Sets a static meta on @container. This method lets you define static
633  * metadatas, which means that the type of the registered will be the only
634  * type accepted for this meta on that particular @container.
635  *
636  * Return: %TRUE if the static meta could be added, %FALSE otherwize
637  */
638   gboolean
639 ges_meta_container_register_meta (GESMetaContainer * container,
640     GESMetaFlag flags, const gchar * meta_item, const GValue * value)
641 {
642   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
643   g_return_val_if_fail (meta_item != NULL, FALSE);
644
645   if (!_register_meta (container, flags, meta_item, G_VALUE_TYPE (value)))
646     return FALSE;
647
648   return _set_value (container, meta_item, value);
649 }
650
651 gboolean
652 ges_meta_container_check_meta_registered (GESMetaContainer * container,
653     const gchar * meta_item, GESMetaFlag * flags, GType * type)
654 {
655   ContainerData *data;
656   RegisteredMeta *static_item;
657
658   data = g_object_get_qdata (G_OBJECT (container), ges_meta_key);
659   if (!data)
660     return FALSE;
661
662   static_item = g_hash_table_lookup (data->static_items, meta_item);
663   if (static_item == NULL) {
664     GST_WARNING_OBJECT (container, "Static meta %s already registered",
665         meta_item);
666
667     return FALSE;
668   }
669
670   if (type)
671     *type = static_item->item_type;
672
673   if (flags)
674     *flags = static_item->flags;
675
676   return TRUE;
677 }
678
679 /* Copied from gsttaglist.c */
680 /***** evil macros to get all the *_get_* functions right *****/
681
682 #define CREATE_GETTER(name,type)                                         \
683 gboolean                                                                 \
684 ges_meta_container_get_ ## name (GESMetaContainer *container,    \
685                            const gchar *meta_item, type value)       \
686 {                                                                        \
687   GstStructure *structure;                                                     \
688                                                                          \
689   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);   \
690   g_return_val_if_fail (meta_item != NULL, FALSE);                   \
691   g_return_val_if_fail (value != NULL, FALSE);                           \
692                                                                          \
693   structure = _meta_container_get_structure (container);                    \
694                                                                          \
695   return gst_structure_get_ ## name (structure, meta_item, value);   \
696 }
697
698 /**
699  * ges_meta_container_get_boolean:
700  * @container: Target container
701  * @meta_item: Name of the meta item to get
702  * @dest: (out): Destination to which value of meta item will be copied
703  * Gets the value of a given meta item, returns NULL if @meta_item
704  * can not be found.
705  */
706 CREATE_GETTER (boolean, gboolean *);
707 /**
708  * ges_meta_container_get_int:
709  * @container: Target container
710  * @meta_item: Name of the meta item to get
711  * @dest: (out): Destination to which value of meta item will be copied
712  * Gets the value of a given meta item, returns NULL if @meta_item
713  * can not be found.
714  */
715 CREATE_GETTER (int, gint *);
716 /**
717  * ges_meta_container_get_uint:
718  * @container: Target container
719  * @meta_item: Name of the meta item to get
720  * @dest: (out): Destination to which value of meta item will be copied
721  * Gets the value of a given meta item, returns NULL if @meta_item
722  * can not be found.
723  */
724 CREATE_GETTER (uint, guint *);
725 /**
726  * ges_meta_container_get_double:
727  * @container: Target container
728  * @meta_item: Name of the meta item to get
729  * @dest: (out): Destination to which value of meta item will be copied
730  * Gets the value of a given meta item, returns NULL if @meta_item
731  * can not be found.
732  */
733 CREATE_GETTER (double, gdouble *);
734
735 /**
736  * ges_meta_container_get_int64:
737  * @container: Target container
738  * @meta_item: Name of the meta item to get
739  * @dest: (out): Destination to which value of meta item will be copied
740  * Gets the value of a given meta item, returns %FALSE if @meta_item
741  * can not be found.
742  */
743 gboolean
744 ges_meta_container_get_int64 (GESMetaContainer * container,
745     const gchar * meta_item, gint64 * dest)
746 {
747   GstStructure *structure;
748   const GValue *value;
749
750   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
751   g_return_val_if_fail (meta_item != NULL, FALSE);
752   g_return_val_if_fail (dest != NULL, FALSE);
753
754   structure = _meta_container_get_structure (container);
755
756   value = gst_structure_get_value (structure, meta_item);
757   if (!value || G_VALUE_TYPE (value) != G_TYPE_INT64)
758     return FALSE;
759
760   *dest = g_value_get_int64 (value);
761
762   return TRUE;
763 }
764
765 /**
766  * ges_meta_container_get_uint64:
767  * @container: Target container
768  * @meta_item: Name of the meta item to get
769  * @dest: (out): Destination to which value of meta item will be copied
770  * Gets the value of a given meta item, returns NULL if @meta_item
771  * can not be found.
772  */
773 gboolean
774 ges_meta_container_get_uint64 (GESMetaContainer * container,
775     const gchar * meta_item, guint64 * dest)
776 {
777   GstStructure *structure;
778   const GValue *value;
779
780   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
781   g_return_val_if_fail (meta_item != NULL, FALSE);
782   g_return_val_if_fail (dest != NULL, FALSE);
783
784   structure = _meta_container_get_structure (container);
785
786   value = gst_structure_get_value (structure, meta_item);
787   if (!value || G_VALUE_TYPE (value) != G_TYPE_UINT64)
788     return FALSE;
789
790   *dest = g_value_get_uint64 (value);
791
792   return TRUE;
793 }
794
795 /**
796  * ges_meta_container_get_float:
797  * @container: Target container
798  * @meta_item: Name of the meta item to get
799  * @dest: (out): Destination to which value of meta item will be copied
800  * Gets the value of a given meta item, returns FALSE if @meta_item
801  * can not be found.
802  */
803 gboolean
804 ges_meta_container_get_float (GESMetaContainer * container,
805     const gchar * meta_item, gfloat * dest)
806 {
807   GstStructure *structure;
808   const GValue *value;
809
810   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
811   g_return_val_if_fail (meta_item != NULL, FALSE);
812   g_return_val_if_fail (dest != NULL, FALSE);
813
814   structure = _meta_container_get_structure (container);
815
816   value = gst_structure_get_value (structure, meta_item);
817   if (!value || G_VALUE_TYPE (value) != G_TYPE_FLOAT)
818     return FALSE;
819
820   *dest = g_value_get_float (value);
821
822   return TRUE;
823 }
824
825 static inline gchar *
826 _gst_strdup0 (const gchar * s)
827 {
828   if (s == NULL || *s == '\0')
829     return NULL;
830
831   return g_strdup (s);
832 }
833
834 /**
835  * ges_meta_container_get_string:
836  * @container: Target container
837  * @meta_item: Name of the meta item to get
838  * Gets the value of a given meta item, returns NULL if @meta_item
839  * can not be found.
840  */
841 const gchar *
842 ges_meta_container_get_string (GESMetaContainer * container,
843     const gchar * meta_item)
844 {
845   GstStructure *structure;
846
847   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
848   g_return_val_if_fail (meta_item != NULL, FALSE);
849
850   structure = _meta_container_get_structure (container);
851
852   return gst_structure_get_string (structure, meta_item);
853 }
854
855 /**
856  * ges_meta_container_get_meta:
857  * @container: Target container
858  * @key: Get the key name of the meta to retrieve
859  *
860  * Gets the value of a given meta item, returns NULL if @meta_item
861  * can not be found.
862  *
863  * Returns: %TRUE if the vale could be optained %FALSE otherwize
864  */
865 const GValue *
866 ges_meta_container_get_meta (GESMetaContainer * container, const gchar * key)
867 {
868   GstStructure *structure;
869
870   g_return_val_if_fail (GES_IS_META_CONTAINER (container), FALSE);
871   g_return_val_if_fail (key != NULL, FALSE);
872
873   structure = _meta_container_get_structure (container);
874
875   return gst_structure_get_value (structure, key);
876 }
877
878 /**
879  * ges_meta_container_get_date:
880  * @container: Target container
881  * @meta_item: Name of the meta item to get
882  * @dest: (out): Destination to which value of meta item will be copied
883  * Gets the value of a given meta item, returns NULL if @meta_item
884  * can not be found.
885  */
886 CREATE_GETTER (date, GDate **);
887
888 /**
889  * ges_meta_container_get_date_time:
890  * @container: Target container
891  * @meta_item: Name of the meta item to get
892  * @dest: (out): Destination to which value of meta item will be copied
893  * Gets the value of a given meta item, returns NULL if @meta_item
894  * can not be found.
895  */
896 CREATE_GETTER (date_time, GstDateTime **);