/**
* gst_query_set_toc:
* @query: a #GstQuery with query type GST_QUERY_TOC.
- * @toc: the GstToc to set.
+ * @toc: (transfer none): the GstToc to set.
* @extend_uid: UID which can be used for TOC extending (may be NULL),
* 0 means root TOC level.
*
void
gst_query_set_toc (GstQuery * query, GstToc * toc, const gchar * extend_uid)
{
- GstStructure *structure;
- GstStructure *old_structure;
-
g_return_if_fail (query != NULL);
g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_TOC);
+ g_return_if_fail (gst_query_is_writable (query));
g_return_if_fail (toc != NULL);
- structure = __gst_toc_to_structure (toc);
-
- g_return_if_fail (structure != NULL);
-
- /* that shouldn't be happen in normal usage */
- old_structure = GST_QUERY_STRUCTURE (query);
- if (old_structure) {
- gst_structure_set_parent_refcount (old_structure, NULL);
- gst_structure_free (old_structure);
- }
-
- if (extend_uid != NULL)
- __gst_toc_structure_set_extend_uid (structure, extend_uid);
-
- gst_structure_set_parent_refcount (structure, &(query->mini_object.refcount));
- GST_QUERY_STRUCTURE (query) = structure;
+ gst_structure_id_set (GST_QUERY_STRUCTURE (query),
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (EXTEND_UID), G_TYPE_STRING, extend_uid, NULL);
}
/**
* gst_query_parse_toc:
* @query: a #GstQuery.
- * @toc: (out): the storage for the received TOC (may be NULL).
- * @extend_uid: (out): the storage for the received extend UID marker (may be NULL),
- * 0 means root TOC level.
+ * @toc: (out) (allow-none) (transfer full): the storage for the received
+ * TOC (may be NULL).
+ * @extend_uid: (out) (allow-none) (transfer full): the storage for the
+ received extend UID marker (may be NULL), 0 means root TOC level.
*
* Parse a TOC query, writing the TOC into @toc as a newly
* allocated #GstToc and extend UID into @extend_uid, if the respective parameters
- * are non-NULL. Use @extend_uid value to insert new entries into the TOC (@extend_uid will
- * act as root entry for newly inserted entries).
- * Free @toc with gst_toc_free() and @extend_uid with g_free() after usage.
+ * are non-NULL. Use @extend_uid value to insert new entries into the TOC
+ * (@extend_uid will act as root entry for newly inserted entries).
+ * Free @toc with gst_toc_unref() and @extend_uid with g_free() after usage.
*/
void
gst_query_parse_toc (GstQuery * query, GstToc ** toc, gchar ** extend_uid)
structure = gst_query_get_structure (query);
- g_return_if_fail (structure != NULL);
-
- if (toc != NULL)
- *toc = __gst_toc_from_structure (structure);
-
- if (extend_uid != NULL)
- *extend_uid = __gst_toc_structure_get_extend_uid (structure);
+ gst_structure_id_get (structure,
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (EXTEND_UID), G_TYPE_STRING, extend_uid, NULL);
}
g_slice_free (GstTocEntry, entry);
}
-static GstStructure *
-gst_toc_structure_new (GstTagList * tags, GstStructure * info)
-{
- GstStructure *ret;
-
- ret = gst_structure_new_id_empty (GST_QUARK (TOC));
-
- if (tags != NULL) {
- gst_structure_id_set (ret, GST_QUARK (TAGS), GST_TYPE_TAG_LIST, tags, NULL);
- }
-
- if (info != NULL) {
- gst_structure_id_set (ret, GST_QUARK (INFO), GST_TYPE_STRUCTURE, info,
- NULL);
- }
-
- return ret;
-}
-
-static GstStructure *
-gst_toc_entry_structure_new (GstTocEntryType type, const gchar * uid,
- GstTagList * tags, GstStructure * info)
-{
- GstStructure *ret;
-
- ret = gst_structure_new_id_empty (GST_QUARK (TOC_ENTRY));
-
- gst_structure_id_set (ret, GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE, type,
- NULL);
- gst_structure_id_set (ret, GST_QUARK (UID), G_TYPE_STRING, uid, NULL);
-
- if (tags != NULL) {
- gst_structure_id_set (ret, GST_QUARK (TAGS), GST_TYPE_TAG_LIST, tags, NULL);
- }
-
- if (info != NULL) {
- gst_structure_id_set (ret, GST_QUARK (INFO), GST_TYPE_STRUCTURE, info,
- NULL);
- }
-
- return ret;
-}
-
-static guint
-gst_toc_entry_structure_n_subentries (const GstStructure * entry)
-{
- if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
- GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
- return 0;
- else
- return gst_value_array_get_size ((gst_structure_id_get_value (entry,
- GST_QUARK (SUB_ENTRIES))));
-}
-
-static const GstStructure *
-gst_toc_entry_structure_nth_subentry (const GstStructure * entry, guint nth)
-{
- guint count;
- const GValue *array;
-
- count = gst_toc_entry_structure_n_subentries (entry);
-
- if (count < nth)
- return NULL;
-
- if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
- GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
- return NULL;
- else {
- array =
- gst_value_array_get_value (gst_structure_id_get_value (entry,
- GST_QUARK (SUB_ENTRIES)), nth);
- return gst_value_get_structure (array);
- }
-}
-
-static GstTocEntry *
-gst_toc_entry_from_structure (const GstStructure * entry, guint level)
-{
- GstTocEntry *ret, *subentry;
- const GValue *val;
- const GstStructure *subentry_struct;
- GstTagList *list;
- GstStructure *st;
- gint count, i;
- const gchar *uid;
- guint chapters_count = 0, editions_count = 0;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
- GST_QUARK (UID), G_TYPE_STRING), NULL);
- g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
- GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE), NULL);
-
- val = gst_structure_id_get_value (entry, GST_QUARK (UID));
- uid = g_value_get_string (val);
-
- ret = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid);
-
- gst_structure_get_enum (entry, g_quark_to_string (GST_QUARK (TYPE)),
- GST_TYPE_TOC_ENTRY_TYPE, (gint *) & (ret->type));
-
- if (gst_structure_id_has_field_typed (entry,
- GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
- count = gst_toc_entry_structure_n_subentries (entry);
-
- for (i = 0; i < count; ++i) {
- subentry_struct = gst_toc_entry_structure_nth_subentry (entry, i);
- subentry = gst_toc_entry_from_structure (subentry_struct, level + 1);
-
- /* skip empty editions */
- if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
- && subentry->subentries == NULL)) {
- g_warning
- ("Empty edition found while deserializing TOC from GstStructure, skipping");
- continue;
- }
-
- if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
- ++editions_count;
- else
- ++chapters_count;
-
- /* check for mixed content */
- if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
- g_critical
- ("Mixed editions and chapters in the TOC contents, the TOC is broken");
- gst_toc_entry_unref (subentry);
- gst_toc_entry_unref (ret);
- return NULL;
- }
-
- if (G_UNLIKELY (subentry == NULL)) {
- gst_toc_entry_unref (ret);
- return NULL;
- }
-
- ret->subentries = g_list_prepend (ret->subentries, subentry);
- }
-
- ret->subentries = g_list_reverse (ret->subentries);
- }
-
- if (gst_structure_id_has_field_typed (entry, GST_QUARK (TAGS),
- GST_TYPE_TAG_LIST)) {
- val = gst_structure_id_get_value (entry, GST_QUARK (TAGS));
-
- if (G_LIKELY (GST_IS_TAG_LIST (g_value_get_boxed (val)))) {
- list = gst_tag_list_copy (GST_TAG_LIST (g_value_get_boxed (val)));
- gst_tag_list_unref (ret->tags);
- ret->tags = list;
- }
- }
-
- if (gst_structure_id_has_field_typed (entry,
- GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (entry, GST_QUARK (INFO));
-
- if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
- st = gst_structure_copy (gst_value_get_structure (val));
- gst_structure_free (ret->info);
- ret->info = st;
- }
- }
-
- return ret;
-}
-
-GstToc *
-__gst_toc_from_structure (const GstStructure * toc)
-{
- GstToc *ret;
- GstTocEntry *subentry;
- const GstStructure *subentry_struct;
- const GValue *val;
- GstTagList *list;
- GstStructure *st;
- guint count, i;
- guint editions_count = 0, chapters_count = 0;
-
- g_return_val_if_fail (toc != NULL, NULL);
-
- ret = gst_toc_new ();
-
- if (gst_structure_id_has_field_typed (toc,
- GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
- count = gst_toc_entry_structure_n_subentries (toc);
-
- for (i = 0; i < count; ++i) {
- subentry_struct = gst_toc_entry_structure_nth_subentry (toc, i);
- subentry = gst_toc_entry_from_structure (subentry_struct, 0);
-
- /* skip empty editions */
- if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
- && subentry->subentries == NULL)) {
- g_warning
- ("Empty edition found while deserializing TOC from GstStructure, skipping");
- continue;
- }
-
- /* check for success */
- if (G_UNLIKELY (subentry == NULL)) {
- g_critical ("Couldn't serialize deserializing TOC from GstStructure");
- gst_toc_free (ret);
- return NULL;
- }
-
- if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
- ++editions_count;
- else
- ++chapters_count;
-
- /* check for mixed content */
- if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
- g_critical
- ("Mixed editions and chapters in the TOC contents, the TOC is broken");
- gst_toc_entry_unref (subentry);
- gst_toc_free (ret);
- return NULL;
- }
-
- ret->entries = g_list_prepend (ret->entries, subentry);
- }
-
- ret->entries = g_list_reverse (ret->entries);
- }
-
- if (gst_structure_id_has_field_typed (toc, GST_QUARK (TAGS),
- GST_TYPE_TAG_LIST)) {
- val = gst_structure_id_get_value (toc, GST_QUARK (TAGS));
-
- if (G_LIKELY (GST_IS_TAG_LIST (g_value_get_boxed (val)))) {
- list = gst_tag_list_copy (GST_TAG_LIST (g_value_get_boxed (val)));
- gst_tag_list_unref (ret->tags);
- ret->tags = list;
- }
- }
-
- if (gst_structure_id_has_field_typed (toc,
- GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (toc, GST_QUARK (INFO));
-
- if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
- st = gst_structure_copy (gst_value_get_structure (val));
- gst_structure_free (ret->info);
- ret->info = st;
- }
- }
-
- if (G_UNLIKELY (ret->entries == NULL)) {
- gst_toc_free (ret);
- return NULL;
- }
-
- return ret;
-}
-
-static GstStructure *
-gst_toc_entry_to_structure (const GstTocEntry * entry, guint level)
-{
- GstStructure *ret, *subentry_struct;
- GstTocEntry *subentry;
- GList *cur;
- GValue subentries_val = { 0 };
- GValue entry_val = { 0 };
- guint chapters_count = 0, editions_count = 0;
-
- g_return_val_if_fail (entry != NULL, NULL);
-
- ret =
- gst_toc_entry_structure_new (entry->type, entry->uid, entry->tags,
- entry->info);
-
- g_value_init (&subentries_val, GST_TYPE_ARRAY);
- g_value_init (&entry_val, GST_TYPE_STRUCTURE);
-
- cur = entry->subentries;
- while (cur != NULL) {
- subentry = cur->data;
-
- if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
- ++editions_count;
- else
- ++chapters_count;
-
- /* check for mixed content */
- if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
- g_critical
- ("Mixed editions and chapters in the TOC contents, the TOC is broken");
- gst_structure_free (ret);
- g_value_unset (&entry_val);
- g_value_unset (&subentries_val);
- return NULL;
- }
-
- /* skip empty editions */
- if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
- && subentry->subentries == NULL)) {
- g_warning
- ("Empty edition found while serializing TOC to GstStructure, skipping");
- cur = cur->next;
- continue;
- }
-
- subentry_struct = gst_toc_entry_to_structure (subentry, level + 1);
-
- /* check for success */
- if (G_UNLIKELY (subentry_struct == NULL)) {
- gst_structure_free (ret);
- g_value_unset (&subentries_val);
- g_value_unset (&entry_val);
- return NULL;
- }
-
- /* skip empty editions */
- if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
- && subentry->subentries == NULL)) {
- g_warning
- ("Empty edition found while serializing TOC to GstStructure, skipping");
- cur = cur->next;
- continue;
- }
-
- gst_value_set_structure (&entry_val, subentry_struct);
- gst_value_array_append_value (&subentries_val, &entry_val);
- gst_structure_free (subentry_struct);
-
- cur = cur->next;
- }
-
- gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
-
- g_value_unset (&subentries_val);
- g_value_unset (&entry_val);
- return ret;
-}
-
-GstStructure *
-__gst_toc_to_structure (const GstToc * toc)
-{
- GValue val = { 0 };
- GValue subentries_val = { 0 };
- GstStructure *ret, *subentry_struct;
- GstTocEntry *subentry;
- GList *cur;
- guint editions_count = 0, chapters_count = 0;
-
- g_return_val_if_fail (toc != NULL, NULL);
- g_return_val_if_fail (toc->entries != NULL, NULL);
-
- ret = gst_toc_structure_new (toc->tags, toc->info);
-
- g_value_init (&val, GST_TYPE_STRUCTURE);
- g_value_init (&subentries_val, GST_TYPE_ARRAY);
- cur = toc->entries;
-
- while (cur != NULL) {
- subentry = cur->data;
-
- if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION)
- ++editions_count;
- else
- ++chapters_count;
-
- /* check for mixed content */
- if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) {
- g_critical
- ("Mixed editions and chapters in the TOC contents, the TOC is broken");
- gst_structure_free (ret);
- g_value_unset (&val);
- g_value_unset (&subentries_val);
- return NULL;
- }
-
- /* skip empty editions */
- if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION
- && subentry->subentries == NULL)) {
- g_warning
- ("Empty edition found while serializing TOC to GstStructure, skipping");
- cur = cur->next;
- continue;
- }
-
- subentry_struct = gst_toc_entry_to_structure (subentry, 0);
-
- /* check for success */
- if (G_UNLIKELY (subentry_struct == NULL)) {
- g_critical ("Couldn't serialize TOC to GstStructure");
- gst_structure_free (ret);
- g_value_unset (&val);
- g_value_unset (&subentries_val);
- return NULL;
- }
-
- gst_value_set_structure (&val, subentry_struct);
- gst_value_array_append_value (&subentries_val, &val);
- gst_structure_free (subentry_struct);
-
- cur = cur->next;
- }
-
- gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
-
- g_value_unset (&val);
- g_value_unset (&subentries_val);
- return ret;
-}
-
static gboolean
gst_toc_check_entry_for_uid (const GstTocEntry * entry, const gchar * uid)
{
return GST_TOC_ENTRY_TYPE_IS_SEQUENCE (entry->type);
}
-
-
-gboolean
-__gst_toc_structure_get_updated (const GstStructure * toc)
-{
- const GValue *val;
-
- g_return_val_if_fail (GST_IS_STRUCTURE (toc), FALSE);
-
- if (G_LIKELY (gst_structure_id_has_field_typed (toc,
- GST_QUARK (UPDATED), G_TYPE_BOOLEAN))) {
- val = gst_structure_id_get_value (toc, GST_QUARK (UPDATED));
- return g_value_get_boolean (val);
- }
-
- return FALSE;
-}
-
-void
-__gst_toc_structure_set_updated (GstStructure * toc, gboolean updated)
-{
- g_return_if_fail (toc != NULL);
-
- gst_structure_id_set (toc, GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated,
- NULL);
-}
-
-gchar *
-__gst_toc_structure_get_extend_uid (const GstStructure * toc)
-{
- const GValue *val;
-
- g_return_val_if_fail (GST_IS_STRUCTURE (toc), NULL);
-
- if (G_LIKELY (gst_structure_id_has_field_typed (toc,
- GST_QUARK (EXTEND_UID), G_TYPE_STRING))) {
- val = gst_structure_id_get_value (toc, GST_QUARK (EXTEND_UID));
- return g_strdup (g_value_get_string (val));
- }
-
- return NULL;
-}
-
-void
-__gst_toc_structure_set_extend_uid (GstStructure * toc,
- const gchar * extend_uid)
-{
- g_return_if_fail (toc != NULL);
- g_return_if_fail (extend_uid != NULL);
-
- gst_structure_id_set (toc, GST_QUARK (EXTEND_UID), G_TYPE_STRING, extend_uid,
- NULL);
-}