2 * (c) 2010, 2012 Alexander Saprykin <xelfium@gmail.com>
4 * gsttoc.c: GstToc initialization and parsing/creation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
24 * @short_description: Generic table of contents support
25 * @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery, #GstPad
27 * #GstToc functions are used to create/free #GstToc and #GstTocEntry structures.
28 * Also they are used to convert #GstToc into #GstStructure and vice versa.
30 * #GstToc lets you to inform other elements in pipeline or application that playing
31 * source has some kind of table of contents (TOC). These may be chapters, editions,
32 * angles or other types. For example: DVD chapters, Matroska chapters or cue sheet
33 * TOC. Such TOC will be useful for applications to display instead of just a
36 * Using TOC is very easy. Firstly, create #GstToc structure which represents root
37 * contents of the source. You can also attach TOC-specific tags to it. Then fill
38 * it with #GstTocEntry entries by appending them to #GstToc.entries #GstTocEntry.subentries
39 * lists. You should use GST_TOC_ENTRY_TYPE_CHAPTER for generic TOC entry and
40 * GST_TOC_ENTRY_TYPE_EDITION for the entries which are considered to be alternatives
41 * (like DVD angles, Matroska editions and so on).
43 * Note that root level of the TOC can contain only either editions or chapters. You
44 * should not mix them together at the same level. Otherwise you will get serialization
45 * /deserialization errors. Make sure that no one of the entries has negative start and
48 * Please, use #GstToc.info and #GstTocEntry.info fields in that way: create a #GstStructure,
49 * put all info related to your element there and put this structure into the info field under
50 * the name of your element. Some fields in the info structure can be used for internal purposes,
51 * so you should use it in the way described above to not to overwrite already existent fields.
53 * Use gst_event_new_toc() to create a new TOC #GstEvent, and gst_event_parse_toc() to
54 * parse received TOC event. Use gst_event_new_toc_select() to create a new TOC select #GstEvent,
55 * and gst_event_parse_toc_select() to parse received TOC select event. The same rule for
56 * the #GstMessage: gst_message_new_toc() to create new TOC #GstMessage, and
57 * gst_message_parse_toc() to parse received TOC message. Also you can create a new TOC query
58 * with gst_query_new_toc(), set it with gst_query_set_toc() and parse it with
59 * gst_query_parse_toc().
66 #include "gst_private.h"
67 #include "gstenumtypes.h"
68 #include "gsttaglist.h"
69 #include "gststructure.h"
78 * Create new #GstToc structure.
80 * Returns: newly allocated #GstToc structure, free it with gst_toc_free().
89 toc = g_slice_new0 (GstToc);
90 toc->tags = gst_tag_list_new_empty ();
91 toc->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
99 * @uid: unique ID (UID) in the whole TOC.
101 * Create new #GstTocEntry structure.
103 * Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_free().
108 gst_toc_entry_new (GstTocEntryType type, const gchar * uid)
112 g_return_val_if_fail (uid != NULL, NULL);
114 entry = g_slice_new0 (GstTocEntry);
115 entry->uid = g_strdup (uid);
117 entry->tags = gst_tag_list_new_empty ();
118 entry->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
124 * gst_toc_entry_new_with_pad:
126 * @uid: unique ID (UID) in the whole TOC.
127 * @pad: #GstPad related to this entry.
129 * Create new #GstTocEntry structure with #GstPad related.
131 * Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_free()
137 gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar * uid,
142 g_return_val_if_fail (uid != NULL, NULL);
144 entry = g_slice_new0 (GstTocEntry);
145 entry->uid = g_strdup (uid);
147 entry->tags = gst_tag_list_new_empty ();
148 entry->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
150 if (pad != NULL && GST_IS_PAD (pad))
151 entry->pads = g_list_append (entry->pads, gst_object_ref (pad));
158 * @toc: #GstToc structure to free.
160 * Free unused #GstToc structure.
165 gst_toc_free (GstToc * toc)
167 g_return_if_fail (toc != NULL);
169 g_list_foreach (toc->entries, (GFunc) gst_toc_entry_free, NULL);
170 g_list_free (toc->entries);
172 if (toc->tags != NULL)
173 gst_tag_list_free (toc->tags);
175 if (toc->info != NULL)
176 gst_structure_free (toc->info);
178 g_slice_free (GstToc, toc);
182 * gst_toc_entry_free:
183 * @entry: #GstTocEntry structure to free.
185 * Free unused #GstTocEntry structure. Note that #GstTocEntry.uid will
186 * be freed with g_free() and all #GstPad objects in the #GstTocEntry.pads
187 * list will be unrefed with gst_object_unref().
192 gst_toc_entry_free (GstTocEntry * entry)
196 g_return_if_fail (entry != NULL);
198 g_list_foreach (entry->subentries, (GFunc) gst_toc_entry_free, NULL);
199 g_list_free (entry->subentries);
203 if (entry->tags != NULL)
204 gst_tag_list_free (entry->tags);
206 if (entry->info != NULL)
207 gst_structure_free (entry->info);
210 while (cur != NULL) {
211 if (GST_IS_PAD (cur->data))
212 gst_object_unref (cur->data);
216 g_list_free (entry->pads);
218 g_slice_free (GstTocEntry, entry);
221 static GstStructure *
222 gst_toc_structure_new (GstTagList * tags, GstStructure * info)
227 ret = gst_structure_new_id_empty (GST_QUARK (TOC));
230 g_value_init (&val, GST_TYPE_STRUCTURE);
231 gst_value_set_structure (&val, GST_STRUCTURE (tags));
232 gst_structure_id_set_value (ret, GST_QUARK (TAGS), &val);
233 g_value_unset (&val);
237 g_value_init (&val, GST_TYPE_STRUCTURE);
238 gst_value_set_structure (&val, info);
239 gst_structure_id_set_value (ret, GST_QUARK (INFO), &val);
240 g_value_unset (&val);
246 static GstStructure *
247 gst_toc_entry_structure_new (GstTocEntryType type, const gchar * uid,
248 GstTagList * tags, GstStructure * info)
253 ret = gst_structure_new_id_empty (GST_QUARK (TOC_ENTRY));
255 gst_structure_id_set (ret, GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE, type,
258 g_value_init (&val, G_TYPE_STRING);
259 g_value_set_string (&val, uid);
260 gst_structure_id_set_value (ret, GST_QUARK (UID), &val);
261 g_value_unset (&val);
264 g_value_init (&val, GST_TYPE_STRUCTURE);
265 gst_value_set_structure (&val, GST_STRUCTURE (tags));
266 gst_structure_id_set_value (ret, GST_QUARK (TAGS), &val);
267 g_value_unset (&val);
271 g_value_init (&val, GST_TYPE_STRUCTURE);
272 gst_value_set_structure (&val, info);
273 gst_structure_id_set_value (ret, GST_QUARK (INFO), &val);
274 g_value_unset (&val);
281 gst_toc_entry_structure_n_subentries (const GstStructure * entry)
283 if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
284 GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
287 return gst_value_array_get_size ((gst_structure_id_get_value (entry,
288 GST_QUARK (SUB_ENTRIES))));
291 static const GstStructure *
292 gst_toc_entry_structure_nth_subentry (const GstStructure * entry, guint nth)
297 count = gst_toc_entry_structure_n_subentries (entry);
302 if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
303 GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
307 gst_value_array_get_value (gst_structure_id_get_value (entry,
308 GST_QUARK (SUB_ENTRIES)), nth);
309 return gst_value_get_structure (array);
314 gst_toc_entry_from_structure (const GstStructure * entry, guint level)
316 GstTocEntry *ret, *subentry;
318 const GstStructure *subentry_struct;
323 guint chapters_count = 0, editions_count = 0;
325 g_return_val_if_fail (entry != NULL, NULL);
326 g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
327 GST_QUARK (UID), G_TYPE_STRING), NULL);
328 g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
329 GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE), NULL);
331 val = gst_structure_id_get_value (entry, GST_QUARK (UID));
332 uid = g_value_get_string (val);
334 ret = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid);
336 gst_structure_get_enum (entry, g_quark_to_string (GST_QUARK (TYPE)),
337 GST_TYPE_TOC_ENTRY_TYPE, (gint *) & (ret->type));
339 if (gst_structure_id_has_field_typed (entry,
340 GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
341 count = gst_toc_entry_structure_n_subentries (entry);
343 for (i = 0; i < count; ++i) {
344 subentry_struct = gst_toc_entry_structure_nth_subentry (entry, i);
345 subentry = gst_toc_entry_from_structure (subentry_struct, level + 1);
347 /* skip empty editions */
348 if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
349 && subentry->subentries == NULL)) {
351 ("Empty edition found while deserializing TOC from GstStructure, skipping");
355 if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
360 /* check for mixed content */
361 if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
363 ("Mixed editions and chapters in the TOC contents, the TOC is broken");
364 gst_toc_entry_free (subentry);
365 gst_toc_entry_free (ret);
369 if (G_UNLIKELY (subentry == NULL)) {
370 gst_toc_entry_free (ret);
374 ret->subentries = g_list_prepend (ret->subentries, subentry);
377 ret->subentries = g_list_reverse (ret->subentries);
380 if (gst_structure_id_has_field_typed (entry,
381 GST_QUARK (TAGS), GST_TYPE_STRUCTURE)) {
382 val = gst_structure_id_get_value (entry, GST_QUARK (TAGS));
384 if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) {
385 list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val)));
386 gst_tag_list_free (ret->tags);
391 if (gst_structure_id_has_field_typed (entry,
392 GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
393 val = gst_structure_id_get_value (entry, GST_QUARK (INFO));
395 if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
396 st = gst_structure_copy (gst_value_get_structure (val));
397 gst_structure_free (ret->info);
406 __gst_toc_from_structure (const GstStructure * toc)
409 GstTocEntry *subentry;
410 const GstStructure *subentry_struct;
415 guint editions_count = 0, chapters_count = 0;
417 g_return_val_if_fail (toc != NULL, NULL);
419 ret = gst_toc_new ();
421 if (gst_structure_id_has_field_typed (toc,
422 GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
423 count = gst_toc_entry_structure_n_subentries (toc);
425 for (i = 0; i < count; ++i) {
426 subentry_struct = gst_toc_entry_structure_nth_subentry (toc, i);
427 subentry = gst_toc_entry_from_structure (subentry_struct, 0);
429 /* skip empty editions */
430 if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
431 && subentry->subentries == NULL)) {
433 ("Empty edition found while deserializing TOC from GstStructure, skipping");
437 /* check for success */
438 if (G_UNLIKELY (subentry == NULL)) {
439 g_critical ("Couldn't serialize deserializing TOC from GstStructure");
444 if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
449 /* check for mixed content */
450 if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
452 ("Mixed editions and chapters in the TOC contents, the TOC is broken");
453 gst_toc_entry_free (subentry);
458 ret->entries = g_list_prepend (ret->entries, subentry);
461 ret->entries = g_list_reverse (ret->entries);
464 if (gst_structure_id_has_field_typed (toc,
465 GST_QUARK (TAGS), GST_TYPE_STRUCTURE)) {
466 val = gst_structure_id_get_value (toc, GST_QUARK (TAGS));
468 if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) {
469 list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val)));
470 gst_tag_list_free (ret->tags);
475 if (gst_structure_id_has_field_typed (toc,
476 GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
477 val = gst_structure_id_get_value (toc, GST_QUARK (INFO));
479 if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
480 st = gst_structure_copy (gst_value_get_structure (val));
481 gst_structure_free (ret->info);
486 if (G_UNLIKELY (ret->entries == NULL)) {
494 static GstStructure *
495 gst_toc_entry_to_structure (const GstTocEntry * entry, guint level)
497 GstStructure *ret, *subentry_struct;
498 GstTocEntry *subentry;
500 GValue subentries_val = { 0 };
501 GValue entry_val = { 0 };
502 guint chapters_count = 0, editions_count = 0;
504 g_return_val_if_fail (entry != NULL, NULL);
507 gst_toc_entry_structure_new (entry->type, entry->uid, entry->tags,
510 g_value_init (&subentries_val, GST_TYPE_ARRAY);
511 g_value_init (&entry_val, GST_TYPE_STRUCTURE);
513 cur = entry->subentries;
514 while (cur != NULL) {
515 subentry = cur->data;
517 if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
522 /* check for mixed content */
523 if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
525 ("Mixed editions and chapters in the TOC contents, the TOC is broken");
526 gst_structure_free (ret);
527 g_value_unset (&entry_val);
528 g_value_unset (&subentries_val);
532 /* skip empty editions */
533 if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
534 && subentry->subentries == NULL)) {
536 ("Empty edition found while serializing TOC to GstStructure, skipping");
541 subentry_struct = gst_toc_entry_to_structure (subentry, level + 1);
543 /* check for success */
544 if (G_UNLIKELY (subentry_struct == NULL)) {
545 gst_structure_free (ret);
546 g_value_unset (&subentries_val);
547 g_value_unset (&entry_val);
551 /* skip empty editions */
552 if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
553 && subentry->subentries == NULL)) {
555 ("Empty edition found while serializing TOC to GstStructure, skipping");
560 gst_value_set_structure (&entry_val, subentry_struct);
561 gst_value_array_append_value (&subentries_val, &entry_val);
562 gst_structure_free (subentry_struct);
567 gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
569 g_value_unset (&subentries_val);
570 g_value_unset (&entry_val);
575 __gst_toc_to_structure (const GstToc * toc)
578 GValue subentries_val = { 0 };
579 GstStructure *ret, *subentry_struct;
580 GstTocEntry *subentry;
582 guint editions_count = 0, chapters_count = 0;
584 g_return_val_if_fail (toc != NULL, NULL);
585 g_return_val_if_fail (toc->entries != NULL, NULL);
587 ret = gst_toc_structure_new (toc->tags, toc->info);
589 g_value_init (&val, GST_TYPE_STRUCTURE);
590 g_value_init (&subentries_val, GST_TYPE_ARRAY);
593 while (cur != NULL) {
594 subentry = cur->data;
596 if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
601 /* check for mixed content */
602 if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
604 ("Mixed editions and chapters in the TOC contents, the TOC is broken");
605 gst_structure_free (ret);
606 g_value_unset (&val);
607 g_value_unset (&subentries_val);
611 /* skip empty editions */
612 if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
613 && subentry->subentries == NULL)) {
615 ("Empty edition found while serializing TOC to GstStructure, skipping");
620 subentry_struct = gst_toc_entry_to_structure (subentry, 0);
622 /* check for success */
623 if (G_UNLIKELY (subentry_struct == NULL)) {
624 g_critical ("Couldn't serialize TOC to GstStructure");
625 gst_structure_free (ret);
626 g_value_unset (&val);
627 g_value_unset (&subentries_val);
631 gst_value_set_structure (&val, subentry_struct);
632 gst_value_array_append_value (&subentries_val, &val);
633 gst_structure_free (subentry_struct);
638 gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
640 g_value_unset (&val);
641 g_value_unset (&subentries_val);
646 gst_toc_check_entry_for_uid (const GstTocEntry * entry, const gchar * uid)
650 g_return_val_if_fail (entry != NULL, FALSE);
651 g_return_val_if_fail (uid != NULL, FALSE);
653 if (g_strcmp0 (entry->uid, uid) == 0)
656 cur = entry->subentries;
657 while (cur != NULL) {
658 if (gst_toc_check_entry_for_uid (cur->data, uid))
667 * gst_toc_find_entry:
668 * @toc: #GstToc to search in.
669 * @uid: UID to find #GstTocEntry with.
671 * Find #GstTocEntry with given @uid in the @toc.
673 * Returns: #GstTocEntry with specified @uid from the @toc, or NULL if not found.
678 gst_toc_find_entry (const GstToc * toc, const gchar * uid)
682 g_return_val_if_fail (toc != NULL, NULL);
683 g_return_val_if_fail (uid != NULL, NULL);
686 while (cur != NULL) {
687 if (gst_toc_check_entry_for_uid (cur->data, uid))
696 * gst_toc_entry_copy:
697 * @entry: #GstTocEntry to copy.
699 * Copy #GstTocEntry with all subentries (deep copy).
701 * Returns: newly allocated #GstTocEntry in case of success, NULL otherwise;
702 * free it when done with gst_toc_entry_free().
707 gst_toc_entry_copy (const GstTocEntry * entry)
709 GstTocEntry *ret, *sub;
714 g_return_val_if_fail (entry != NULL, NULL);
716 ret = gst_toc_entry_new (entry->type, entry->uid);
718 if (GST_IS_STRUCTURE (entry->info)) {
719 st = gst_structure_copy (entry->info);
720 gst_structure_free (ret->info);
724 if (GST_IS_TAG_LIST (entry->tags)) {
725 list = gst_tag_list_copy (entry->tags);
726 gst_tag_list_free (ret->tags);
731 while (cur != NULL) {
732 if (GST_IS_PAD (cur->data))
733 ret->pads = g_list_prepend (ret->pads, gst_object_ref (cur->data));
736 ret->pads = g_list_reverse (ret->pads);
738 cur = entry->subentries;
739 while (cur != NULL) {
740 sub = gst_toc_entry_copy (cur->data);
743 ret->subentries = g_list_prepend (ret->subentries, sub);
747 ret->subentries = g_list_reverse (ret->subentries);
754 * @toc: #GstToc to copy.
756 * Copy #GstToc with all subentries (deep copy).
758 * Returns: newly allocated #GstToc in case of success, NULL otherwise;
759 * free it when done with gst_toc_free().
764 gst_toc_copy (const GstToc * toc)
772 g_return_val_if_fail (toc != NULL, NULL);
774 ret = gst_toc_new ();
776 if (GST_IS_STRUCTURE (toc->info)) {
777 st = gst_structure_copy (toc->info);
778 gst_structure_free (ret->info);
782 if (GST_IS_TAG_LIST (toc->tags)) {
783 list = gst_tag_list_copy (toc->tags);
784 gst_tag_list_free (ret->tags);
789 while (cur != NULL) {
790 entry = gst_toc_entry_copy (cur->data);
793 ret->entries = g_list_prepend (ret->entries, entry);
797 ret->entries = g_list_reverse (ret->entries);
803 * gst_toc_entry_set_start_stop:
804 * @entry: #GstTocEntry to set values.
805 * @start: start value to set.
806 * @stop: stop value to set.
808 * Set @start and @stop values for the @entry.
813 gst_toc_entry_set_start_stop (GstTocEntry * entry, gint64 start, gint64 stop)
816 GstStructure *structure = NULL;
818 g_return_if_fail (entry != NULL);
819 g_return_if_fail (GST_IS_STRUCTURE (entry->info));
821 if (gst_structure_id_has_field_typed (entry->info, GST_QUARK (TIME),
822 GST_TYPE_STRUCTURE)) {
823 val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
824 structure = gst_structure_copy (gst_value_get_structure (val));
827 if (structure == NULL)
828 structure = gst_structure_new_id_empty (GST_QUARK (TIME_STRUCTURE));
830 gst_structure_id_set (structure, GST_QUARK (START),
831 G_TYPE_INT64, start, GST_QUARK (STOP), G_TYPE_INT64, stop, NULL);
833 gst_structure_id_set (entry->info, GST_QUARK (TIME),
834 GST_TYPE_STRUCTURE, structure, NULL);
836 gst_structure_free (structure);
840 * gst_toc_entry_get_start_stop:
841 * @entry: #GstTocEntry to get values from.
842 * @start: (out): the storage for the start value, leave #NULL if not need.
843 * @stop: (out): the storage for the stop value, leave #NULL if not need.
845 * Get start and stop values from the @entry and write them into appropriate storages.
847 * Returns: TRUE if all non-NULL storage pointers were filled with appropriate values,
853 gst_toc_entry_get_start_stop (const GstTocEntry * entry, gint64 * start,
858 const GstStructure *structure;
860 g_return_val_if_fail (entry != NULL, FALSE);
861 g_return_val_if_fail (GST_IS_STRUCTURE (entry->info), FALSE);
863 if (!gst_structure_id_has_field_typed (entry->info,
864 GST_QUARK (TIME), GST_TYPE_STRUCTURE))
867 val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
868 structure = gst_value_get_structure (val);
871 if (gst_structure_id_has_field_typed (structure,
872 GST_QUARK (START), G_TYPE_INT64))
874 g_value_get_int64 (gst_structure_id_get_value (structure,
881 if (gst_structure_id_has_field_typed (structure,
882 GST_QUARK (STOP), G_TYPE_INT64))
884 g_value_get_int64 (gst_structure_id_get_value (structure,
894 * gst_toc_entry_type_get_nick:
895 * @type: a #GstTocEntryType.
897 * Converts @type to a string representation.
899 * Returns: Returns the human-readable @type. Can be NULL if an error occurred.
903 gst_toc_entry_type_get_nick (GstTocEntryType type)
905 const gchar *entry_types[] = { "chapter", "edition" };
907 g_return_val_if_fail ((gint) type >= 0
908 && (gint) type < G_N_ELEMENTS (entry_types), NULL);
909 return entry_types[type];
913 __gst_toc_structure_get_updated (const GstStructure * toc)
917 g_return_val_if_fail (GST_IS_STRUCTURE (toc), FALSE);
919 if (G_LIKELY (gst_structure_id_has_field_typed (toc,
920 GST_QUARK (UPDATED), G_TYPE_BOOLEAN))) {
921 val = gst_structure_id_get_value (toc, GST_QUARK (UPDATED));
922 return g_value_get_boolean (val);
929 __gst_toc_structure_set_updated (GstStructure * toc, gboolean updated)
933 g_return_if_fail (toc != NULL);
935 g_value_init (&val, G_TYPE_BOOLEAN);
936 g_value_set_boolean (&val, updated);
937 gst_structure_id_set_value (toc, GST_QUARK (UPDATED), &val);
938 g_value_unset (&val);
942 __gst_toc_structure_get_extend_uid (const GstStructure * toc)
946 g_return_val_if_fail (GST_IS_STRUCTURE (toc), NULL);
948 if (G_LIKELY (gst_structure_id_has_field_typed (toc,
949 GST_QUARK (EXTEND_UID), G_TYPE_STRING))) {
950 val = gst_structure_id_get_value (toc, GST_QUARK (EXTEND_UID));
951 return g_strdup (g_value_get_string (val));
958 __gst_toc_structure_set_extend_uid (GstStructure * toc,
959 const gchar * extend_uid)
963 g_return_if_fail (toc != NULL);
964 g_return_if_fail (extend_uid != NULL);
966 g_value_init (&val, G_TYPE_STRING);
967 g_value_set_string (&val, extend_uid);
968 gst_structure_id_set_value (toc, GST_QUARK (EXTEND_UID), &val);
969 g_value_unset (&val);