toc: Make structures opaque and clean up function names and fields a bit

This commit is contained in:
Sebastian Dröge 2012-07-03 18:45:05 +02:00
parent 070f7c4e1c
commit dfd9b60221
10 changed files with 469 additions and 432 deletions

View file

@ -48,15 +48,12 @@ select event with UID to seek on. Field 'subentries' of type GList contains
children items of type GstTocEntry. Thus you can achieve arbitrary hierarchy children items of type GstTocEntry. Thus you can achieve arbitrary hierarchy
level. Field 'type' can be either GST_TOC_ENTRY_TYPE_CHAPTER or level. Field 'type' can be either GST_TOC_ENTRY_TYPE_CHAPTER or
GST_TOC_ENTRY_TYPE_EDITION which corresponds to chapter or edition type of GST_TOC_ENTRY_TYPE_EDITION which corresponds to chapter or edition type of
item respectively. Field 'pads' of type GList contains list of GStreamer item respectively. Field 'tags' is a list of tags related to the item. And field
pads related to the item. It can be used for example to link a TOC with
specific pad. Field 'tags' is a list of tags related to the item. And field
'info' is similar to GstToc.info described above. 'info' is similar to GstToc.info described above.
So, a little more about managing GstToc. Use gst_toc_new() and gst_toc_unref() So, a little more about managing GstToc. Use gst_toc_new() and gst_toc_unref()
to create/free it. GstTocEntry can be created using gst_toc_entry_new() and to create/free it. GstTocEntry can be created using gst_toc_entry_new().
gst_toc_entry_new_with_pad(). The latter method used to create GstTocEntry While building GstToc you can set start and stop
linked to particular pad. While building GstToc you can set start and stop
timestamps for each item using gst_toc_entry_set_start_stop(). timestamps for each item using gst_toc_entry_set_start_stop().
The best way to process already created GstToc is to recursively go through The best way to process already created GstToc is to recursively go through
the 'entries' and 'subentries' fields. the 'entries' and 'subentries' fields.

View file

@ -2720,14 +2720,25 @@ gst_toc_new
gst_toc_ref gst_toc_ref
gst_toc_unref gst_toc_unref
gst_toc_copy gst_toc_copy
gst_toc_get_entries
gst_toc_append_entry
gst_toc_get_tags
gst_toc_merge_tags
gst_toc_set_tags
gst_toc_entry_new gst_toc_entry_new
gst_toc_entry_new_with_pad gst_toc_entry_new_with_pad
gst_toc_entry_ref gst_toc_entry_ref
gst_toc_entry_unref gst_toc_entry_unref
gst_toc_entry_copy gst_toc_entry_copy
gst_toc_find_entry gst_toc_find_entry
gst_toc_entry_get_start_stop gst_toc_entry_get_uid
gst_toc_entry_set_start_stop gst_toc_entry_get_sub_entries
gst_toc_entry_append_sub_entry
gst_toc_entry_get_start_stop_times
gst_toc_entry_set_start_stop_times
gst_toc_entry_get_tags
gst_toc_entry_merge_tags
gst_toc_entry_set_tags
gst_toc_entry_type_get_nick gst_toc_entry_type_get_nick
gst_toc_entry_get_entry_type gst_toc_entry_get_entry_type
gst_toc_entry_is_alternative gst_toc_entry_is_alternative

View file

@ -22,7 +22,7 @@
/** /**
* SECTION:gsttoc * SECTION:gsttoc
* @short_description: Generic table of contents support * @short_description: Generic table of contents support
* @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery, #GstPad * @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery
* *
* #GstToc functions are used to create/free #GstToc and #GstTocEntry structures. * #GstToc functions are used to create/free #GstToc and #GstTocEntry structures.
* Also they are used to convert #GstToc into #GstStructure and vice versa. * Also they are used to convert #GstToc into #GstStructure and vice versa.
@ -72,6 +72,31 @@
#include "gstpad.h" #include "gstpad.h"
#include "gstquark.h" #include "gstquark.h"
struct _GstTocEntry
{
GstMiniObject mini_object;
gchar *uid;
GstTocEntryType type;
GstClockTime start, stop;
GList *subentries;
GstTagList *tags;
/*< private > */
gpointer _gst_reserved[GST_PADDING];
};
struct _GstToc
{
GstMiniObject mini_object;
GList *entries;
GstTagList *tags;
/*< private > */
gpointer _gst_reserved[GST_PADDING];
};
#undef gst_toc_copy #undef gst_toc_copy
static GstToc *gst_toc_copy (const GstToc * toc); static GstToc *gst_toc_copy (const GstToc * toc);
static void gst_toc_free (GstToc * toc); static void gst_toc_free (GstToc * toc);
@ -104,14 +129,111 @@ gst_toc_new (void)
(GstMiniObjectFreeFunction) gst_toc_free); (GstMiniObjectFreeFunction) gst_toc_free);
toc->tags = gst_tag_list_new_empty (); toc->tags = gst_tag_list_new_empty ();
toc->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
return toc; return toc;
} }
/**
* gst_toc_set_tags:
* @toc: A #GstToc instance
* @tags: (allow-none) (transfer full): A #GstTagList or %NULL
*
* Set a #GstTagList with tags for the complete @toc.
*
* Since: 0.10.37
*/
void
gst_toc_set_tags (GstToc * toc, GstTagList * tags)
{
g_return_if_fail (toc != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));
if (toc->tags)
gst_tag_list_unref (toc->tags);
toc->tags = tags;
}
/**
* gst_toc_merge_tags:
* @toc: A #GstToc instance
* @tags: (allow-none): A #GstTagList or %NULL
* @mode: A #GstTagMergeMode
*
* Merge @tags into the existing tags of @toc using @mode.
*
* Since: 0.10.37
*/
void
gst_toc_merge_tags (GstToc * toc, GstTagList * tags, GstTagMergeMode mode)
{
g_return_if_fail (toc != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));
if (!toc->tags) {
toc->tags = gst_tag_list_ref (tags);
} else {
GstTagList *tmp = gst_tag_list_merge (toc->tags, tags, mode);
gst_tag_list_unref (toc->tags);
toc->tags = tmp;
}
}
/**
* gst_toc_get_tags:
* @toc: A #GstToc instance
*
* Gets the tags for @toc.
*
* Returns: (transfer none): A #GstTagList for @entry
*
* Since: 0.10.37
*/
GstTagList *
gst_toc_get_tags (const GstToc * toc)
{
g_return_val_if_fail (toc != NULL, NULL);
return toc->tags;
}
/**
* gst_toc_append_entry:
* @toc: A #GstToc instance
* @entry: (transfer full): A #GstTocEntry
*
* Appends the #GstTocEntry @entry to @toc.
*
* Since: 0.10.37
*/
void
gst_toc_append_entry (GstToc * toc, GstTocEntry * entry)
{
g_return_if_fail (toc != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc)));
toc->entries = g_list_append (toc->entries, entry);
}
/**
* gst_toc_get_entries:
* @toc: A #GstToc instance
*
* Gets the list of #GstTocEntry of @toc.
*
* Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry for @entry
*
* Since: 0.10.37
*/
GList *
gst_toc_get_entries (const GstToc * toc)
{
g_return_val_if_fail (toc != NULL, NULL);
return toc->entries;
}
static GstTocEntry * static GstTocEntry *
gst_toc_entry_new_internal (GstTocEntryType type, const gchar * uid, gst_toc_entry_new_internal (GstTocEntryType type, const gchar * uid)
GstPad * pad)
{ {
GstTocEntry *entry; GstTocEntry *entry;
@ -123,11 +245,8 @@ gst_toc_entry_new_internal (GstTocEntryType type, const gchar * uid,
entry->uid = g_strdup (uid); entry->uid = g_strdup (uid);
entry->type = type; entry->type = type;
entry->tags = gst_tag_list_new_empty (); entry->tags = NULL;
entry->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE)); entry->start = entry->stop = GST_CLOCK_TIME_NONE;
if (pad != NULL && GST_IS_PAD (pad))
entry->pads = g_list_append (entry->pads, gst_object_ref (pad));
return entry; return entry;
} }
@ -148,29 +267,7 @@ gst_toc_entry_new (GstTocEntryType type, const gchar * uid)
{ {
g_return_val_if_fail (uid != NULL, NULL); g_return_val_if_fail (uid != NULL, NULL);
return gst_toc_entry_new_internal (type, uid, NULL); return gst_toc_entry_new_internal (type, uid);
}
/**
* gst_toc_entry_new_with_pad:
* @type: entry type.
* @uid: unique ID (UID) in the whole TOC.
* @pad: #GstPad related to this entry.
*
* Create new #GstTocEntry structure with #GstPad related.
*
* Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_unref()
* when done.
*
* Since: 0.10.37
*/
GstTocEntry *
gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar * uid,
GstPad * pad)
{
g_return_val_if_fail (uid != NULL, NULL);
return gst_toc_entry_new_internal (type, uid, pad);
} }
static void static void
@ -182,17 +279,12 @@ gst_toc_free (GstToc * toc)
if (toc->tags != NULL) if (toc->tags != NULL)
gst_tag_list_unref (toc->tags); gst_tag_list_unref (toc->tags);
if (toc->info != NULL)
gst_structure_free (toc->info);
g_slice_free (GstToc, toc); g_slice_free (GstToc, toc);
} }
static void static void
gst_toc_entry_free (GstTocEntry * entry) gst_toc_entry_free (GstTocEntry * entry)
{ {
GList *cur;
g_return_if_fail (entry != NULL); g_return_if_fail (entry != NULL);
g_list_foreach (entry->subentries, (GFunc) gst_mini_object_unref, NULL); g_list_foreach (entry->subentries, (GFunc) gst_mini_object_unref, NULL);
@ -203,18 +295,6 @@ gst_toc_entry_free (GstTocEntry * entry)
if (entry->tags != NULL) if (entry->tags != NULL)
gst_tag_list_unref (entry->tags); gst_tag_list_unref (entry->tags);
if (entry->info != NULL)
gst_structure_free (entry->info);
cur = entry->pads;
while (cur != NULL) {
if (GST_IS_PAD (cur->data))
gst_object_unref (cur->data);
cur = cur->next;
}
g_list_free (entry->pads);
g_slice_free (GstTocEntry, entry); g_slice_free (GstTocEntry, entry);
} }
@ -283,34 +363,23 @@ static GstTocEntry *
gst_toc_entry_copy (const GstTocEntry * entry) gst_toc_entry_copy (const GstTocEntry * entry)
{ {
GstTocEntry *ret, *sub; GstTocEntry *ret, *sub;
GList *cur;
GstTagList *list; GstTagList *list;
GstStructure *st; GList *cur;
g_return_val_if_fail (entry != NULL, NULL); g_return_val_if_fail (entry != NULL, NULL);
ret = gst_toc_entry_new (entry->type, entry->uid); ret = gst_toc_entry_new (entry->type, entry->uid);
if (GST_IS_STRUCTURE (entry->info)) { ret->start = entry->start;
st = gst_structure_copy (entry->info); ret->stop = entry->stop;
gst_structure_free (ret->info);
ret->info = st;
}
if (GST_IS_TAG_LIST (entry->tags)) { if (GST_IS_TAG_LIST (entry->tags)) {
list = gst_tag_list_copy (entry->tags); list = gst_tag_list_copy (entry->tags);
gst_tag_list_unref (ret->tags); if (ret->tags)
gst_tag_list_unref (ret->tags);
ret->tags = list; ret->tags = list;
} }
cur = entry->pads;
while (cur != NULL) {
if (GST_IS_PAD (cur->data))
ret->pads = g_list_prepend (ret->pads, gst_object_ref (cur->data));
cur = cur->next;
}
ret->pads = g_list_reverse (ret->pads);
cur = entry->subentries; cur = entry->subentries;
while (cur != NULL) { while (cur != NULL) {
sub = gst_toc_entry_copy (cur->data); sub = gst_toc_entry_copy (cur->data);
@ -343,18 +412,11 @@ gst_toc_copy (const GstToc * toc)
GstTocEntry *entry; GstTocEntry *entry;
GList *cur; GList *cur;
GstTagList *list; GstTagList *list;
GstStructure *st;
g_return_val_if_fail (toc != NULL, NULL); g_return_val_if_fail (toc != NULL, NULL);
ret = gst_toc_new (); ret = gst_toc_new ();
if (GST_IS_STRUCTURE (toc->info)) {
st = gst_structure_copy (toc->info);
gst_structure_free (ret->info);
ret->info = st;
}
if (GST_IS_TAG_LIST (toc->tags)) { if (GST_IS_TAG_LIST (toc->tags)) {
list = gst_tag_list_copy (toc->tags); list = gst_tag_list_copy (toc->tags);
gst_tag_list_unref (ret->tags); gst_tag_list_unref (ret->tags);
@ -376,7 +438,7 @@ gst_toc_copy (const GstToc * toc)
} }
/** /**
* gst_toc_entry_set_start_stop: * gst_toc_entry_set_start_stop_times:
* @entry: #GstTocEntry to set values. * @entry: #GstTocEntry to set values.
* @start: start value to set. * @start: start value to set.
* @stop: stop value to set. * @stop: stop value to set.
@ -386,34 +448,17 @@ gst_toc_copy (const GstToc * toc)
* Since: 0.10.37 * Since: 0.10.37
*/ */
void void
gst_toc_entry_set_start_stop (GstTocEntry * entry, gint64 start, gint64 stop) gst_toc_entry_set_start_stop_times (GstTocEntry * entry, gint64 start,
gint64 stop)
{ {
const GValue *val;
GstStructure *structure = NULL;
g_return_if_fail (entry != NULL); g_return_if_fail (entry != NULL);
g_return_if_fail (GST_IS_STRUCTURE (entry->info));
if (gst_structure_id_has_field_typed (entry->info, GST_QUARK (TIME), entry->start = start;
GST_TYPE_STRUCTURE)) { entry->stop = stop;
val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
structure = gst_structure_copy (gst_value_get_structure (val));
}
if (structure == NULL)
structure = gst_structure_new_id_empty (GST_QUARK (TIME_STRUCTURE));
gst_structure_id_set (structure, GST_QUARK (START),
G_TYPE_INT64, start, GST_QUARK (STOP), G_TYPE_INT64, stop, NULL);
gst_structure_id_set (entry->info, GST_QUARK (TIME),
GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
} }
/** /**
* gst_toc_entry_get_start_stop: * gst_toc_entry_get_start_stop_times:
* @entry: #GstTocEntry to get values from. * @entry: #GstTocEntry to get values from.
* @start: (out): the storage for the start value, leave #NULL if not need. * @start: (out): the storage for the start value, leave #NULL if not need.
* @stop: (out): the storage for the stop value, leave #NULL if not need. * @stop: (out): the storage for the stop value, leave #NULL if not need.
@ -426,42 +471,17 @@ gst_toc_entry_set_start_stop (GstTocEntry * entry, gint64 start, gint64 stop)
* Since: 0.10.37 * Since: 0.10.37
*/ */
gboolean gboolean
gst_toc_entry_get_start_stop (const GstTocEntry * entry, gint64 * start, gst_toc_entry_get_start_stop_times (const GstTocEntry * entry, gint64 * start,
gint64 * stop) gint64 * stop)
{ {
gboolean ret = TRUE; gboolean ret = TRUE;
const GValue *val;
const GstStructure *structure;
g_return_val_if_fail (entry != NULL, FALSE); g_return_val_if_fail (entry != NULL, FALSE);
g_return_val_if_fail (GST_IS_STRUCTURE (entry->info), FALSE);
if (!gst_structure_id_has_field_typed (entry->info, if (start != NULL)
GST_QUARK (TIME), GST_TYPE_STRUCTURE)) *start = entry->start;
return FALSE; if (stop != NULL)
*stop = entry->stop;
val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
structure = gst_value_get_structure (val);
if (start != NULL) {
if (gst_structure_id_has_field_typed (structure,
GST_QUARK (START), G_TYPE_INT64))
*start =
g_value_get_int64 (gst_structure_id_get_value (structure,
GST_QUARK (START)));
else
ret = FALSE;
}
if (stop != NULL) {
if (gst_structure_id_has_field_typed (structure,
GST_QUARK (STOP), G_TYPE_INT64))
*stop =
g_value_get_int64 (gst_structure_id_get_value (structure,
GST_QUARK (STOP)));
else
ret = FALSE;
}
return ret; return ret;
} }
@ -505,7 +525,7 @@ gst_toc_entry_type_get_nick (GstTocEntryType type)
* Returns: @entry's entry type * Returns: @entry's entry type
*/ */
GstTocEntryType GstTocEntryType
gst_toc_entry_get_entry_type (GstTocEntry * entry) gst_toc_entry_get_entry_type (const GstTocEntry * entry)
{ {
g_return_val_if_fail (entry != NULL, GST_TOC_ENTRY_TYPE_INVALID); g_return_val_if_fail (entry != NULL, GST_TOC_ENTRY_TYPE_INVALID);
@ -519,7 +539,7 @@ gst_toc_entry_get_entry_type (GstTocEntry * entry)
* Returns: %TRUE if @entry's type is an alternative type, otherwise %FALSE * Returns: %TRUE if @entry's type is an alternative type, otherwise %FALSE
*/ */
gboolean gboolean
gst_toc_entry_is_alternative (GstTocEntry * entry) gst_toc_entry_is_alternative (const GstTocEntry * entry)
{ {
g_return_val_if_fail (entry != NULL, FALSE); g_return_val_if_fail (entry != NULL, FALSE);
@ -533,9 +553,128 @@ gst_toc_entry_is_alternative (GstTocEntry * entry)
* Returns: %TRUE if @entry's type is a sequence type, otherwise %FALSE * Returns: %TRUE if @entry's type is a sequence type, otherwise %FALSE
*/ */
gboolean gboolean
gst_toc_entry_is_sequence (GstTocEntry * entry) gst_toc_entry_is_sequence (const GstTocEntry * entry)
{ {
g_return_val_if_fail (entry != NULL, FALSE); g_return_val_if_fail (entry != NULL, FALSE);
return GST_TOC_ENTRY_TYPE_IS_SEQUENCE (entry->type); return GST_TOC_ENTRY_TYPE_IS_SEQUENCE (entry->type);
} }
/**
* gst_toc_entry_get_uid:
* @entry: A #GstTocEntry instance
*
* Gets the UID of @entry.
*
* Returns: (transfer none): The UID of @entry
*
* Since: 0.10.37
*/
const gchar *
gst_toc_entry_get_uid (const GstTocEntry * entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->uid;
}
/**
* gst_toc_entry_append_sub_entry:
* @entry: A #GstTocEntry instance
* @subentry: (transfer full): A #GstTocEntry
*
* Appends the #GstTocEntry @subentry to @entry.
*
* Since: 0.10.37
*/
void
gst_toc_entry_append_sub_entry (GstTocEntry * entry, GstTocEntry * subentry)
{
g_return_if_fail (entry != NULL);
g_return_if_fail (subentry != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));
entry->subentries = g_list_append (entry->subentries, subentry);
}
/**
* gst_toc_entry_get_uid:
* @entry: A #GstTocEntry instance
*
* Gets the sub-entries of @entry.
*
* Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry of @entry
*
* Since: 0.10.37
*/
GList *
gst_toc_entry_get_sub_entries (const GstTocEntry * entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->subentries;
}
/**
* gst_toc_entry_set_tags:
* @entry: A #GstTocEntry instance
* @tags: (allow-none) (transfer full): A #GstTagList or %NULL
*
* Set a #GstTagList with tags for the complete @entry.
*
* Since: 0.10.37
*/
void
gst_toc_entry_set_tags (GstTocEntry * entry, GstTagList * tags)
{
g_return_if_fail (entry != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));
if (entry->tags)
gst_tag_list_unref (entry->tags);
entry->tags = tags;
}
/**
* gst_toc_entry_merge_tags:
* @entry: A #GstTocEntry instance
* @tags: (allow-none): A #GstTagList or %NULL
* @mode: A #GstTagMergeMode
*
* Merge @tags into the existing tags of @entry using @mode.
*
* Since: 0.10.37
*/
void
gst_toc_entry_merge_tags (GstTocEntry * entry, GstTagList * tags,
GstTagMergeMode mode)
{
g_return_if_fail (entry != NULL);
g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry)));
if (!entry->tags) {
entry->tags = gst_tag_list_ref (tags);
} else {
GstTagList *tmp = gst_tag_list_merge (entry->tags, tags, mode);
gst_tag_list_unref (entry->tags);
entry->tags = tmp;
}
}
/**
* gst_toc_entry_get_tags:
* @entry: A #GstTocEntry instance
*
* Gets the tags for @entry.
*
* Returns: (transfer none): A #GstTagList for @entry
*
* Since: 0.10.37
*/
GstTagList *
gst_toc_entry_get_tags (const GstTocEntry * entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return entry->tags;
}

View file

@ -63,65 +63,19 @@ typedef enum {
#define GST_TOC_ENTRY_TYPE_IS_ALTERNATIVE(entry_type) (entry_type < 0) #define GST_TOC_ENTRY_TYPE_IS_ALTERNATIVE(entry_type) (entry_type < 0)
#define GST_TOC_ENTRY_TYPE_IS_SEQUENCE(entry_type) (entry_type > 0) #define GST_TOC_ENTRY_TYPE_IS_SEQUENCE(entry_type) (entry_type > 0)
/**
* GstTocEntry:
* @uid: unique (for a whole TOC) id of the entry. This value should be persistent and
* should not be changed while updating TOC. @uid should be handled as "opaque" value
* without meaning (e.g. applications should not assume the /editionX/chapterY/chapter/Z structure,
* other demuxers could do something else), it should help to track updates of certain entries.
* @type: #GstTocEntryType of this entry.
* @subentries: (element-type GstTocEntry): list of #GstTocEntry
* children.
* @pads: (element-type GstPad): list of #GstPad objects, related to
* this #GstTocEntry.
* @tags: tags related to this entry.
* @info: extra information related to this entry.
*
* Definition of TOC entry structure.
*/
struct _GstTocEntry {
GstMiniObject mini_object;
gchar *uid;
GstTocEntryType type;
GList *subentries;
GList *pads;
GstTagList *tags;
GstStructure *info;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
/* FIXME: pad member should be GstPad type, but that's
* impossible due to recursive includes */
/**
* GstToc:
* @entries: (element-type GstTocEntry): list of #GstTocEntry entries
* of the TOC.
* @tags: tags related to the whole TOC.
* @info: extra information related to the TOC.
*
* Definition of TOC structure.
*/
struct _GstToc {
GstMiniObject mini_object;
GList *entries;
GstTagList *tags;
GstStructure *info;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
/* functions to return type structures */ /* functions to return type structures */
GType gst_toc_get_type (void); GType gst_toc_get_type (void);
GType gst_toc_entry_get_type (void); GType gst_toc_entry_get_type (void);
/* functions to create, ref and unref/free TOCs */ /* functions to create, ref and unref/free TOCs */
GstToc * gst_toc_new (void); GstToc * gst_toc_new (void);
void gst_toc_set_tags (GstToc *toc, GstTagList * tags);
void gst_toc_merge_tags (GstToc *toc, GstTagList *tags, GstTagMergeMode mode);
GstTagList * gst_toc_get_tags (const GstToc *toc);
void gst_toc_append_entry (GstToc *toc, GstTocEntry *entry);
GList * gst_toc_get_entries (const GstToc *toc);
#define gst_toc_ref(toc) (GstToc*)gst_mini_object_ref(GST_MINI_OBJECT_CAST(toc)) #define gst_toc_ref(toc) (GstToc*)gst_mini_object_ref(GST_MINI_OBJECT_CAST(toc))
#define gst_toc_unref(toc) gst_mini_object_unref(GST_MINI_OBJECT_CAST(toc)) #define gst_toc_unref(toc) gst_mini_object_unref(GST_MINI_OBJECT_CAST(toc))
@ -130,23 +84,32 @@ GstToc * gst_toc_new (void);
/* functions to create, ref and unref/free TOC entries */ /* functions to create, ref and unref/free TOC entries */
GstTocEntry * gst_toc_entry_new (GstTocEntryType type, const gchar *uid); GstTocEntry * gst_toc_entry_new (GstTocEntryType type, const gchar *uid);
GstTocEntry * gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar *uid, GstPad * pad);
#define gst_toc_entry_ref(entry) (GstTocEntry*)gst_mini_object_ref(GST_MINI_OBJECT_CAST(entry)) #define gst_toc_entry_ref(entry) (GstTocEntry*)gst_mini_object_ref(GST_MINI_OBJECT_CAST(entry))
#define gst_toc_entry_unref(entry) gst_mini_object_unref(GST_MINI_OBJECT_CAST(entry)) #define gst_toc_entry_unref(entry) gst_mini_object_unref(GST_MINI_OBJECT_CAST(entry))
#define gst_toc_entry_copy(entry) (GstTocEntry*)gst_mini_object_copy(GST_MINI_OBJECT_CAST(entry)) #define gst_toc_entry_copy(entry) (GstTocEntry*)gst_mini_object_copy(GST_MINI_OBJECT_CAST(entry))
#define gst_toc_entry_make_writable(entry) (GstTocEntry*)gst_mini_object_make_writable(GST_MINI_OBJECT_CAST(entry)) #define gst_toc_entry_make_writable(entry) (GstTocEntry*)gst_mini_object_make_writable(GST_MINI_OBJECT_CAST(entry))
GstTocEntry * gst_toc_find_entry (const GstToc *toc, const gchar *uid); GstTocEntry * gst_toc_find_entry (const GstToc *toc, const gchar *uid);
GstTocEntryType gst_toc_entry_get_entry_type (GstTocEntry * entry); GstTocEntryType gst_toc_entry_get_entry_type (const GstTocEntry *entry);
const gchar * gst_toc_entry_get_uid (const GstTocEntry *entry);
gboolean gst_toc_entry_is_alternative (GstTocEntry * entry); void gst_toc_entry_append_sub_entry (GstTocEntry *entry, GstTocEntry *subentry);
gboolean gst_toc_entry_is_sequence (GstTocEntry * entry); GList * gst_toc_entry_get_sub_entries (const GstTocEntry *entry);
void gst_toc_entry_set_start_stop (GstTocEntry *entry, gint64 start, gint64 stop); void gst_toc_entry_set_tags (GstTocEntry *entry, GstTagList *tags);
gboolean gst_toc_entry_get_start_stop (const GstTocEntry *entry, gint64 *start, gint64 *stop); void gst_toc_entry_merge_tags (GstTocEntry *entry, GstTagList *tags, GstTagMergeMode mode);
const gchar * gst_toc_entry_type_get_nick (GstTocEntryType type); GstTagList * gst_toc_entry_get_tags (const GstTocEntry *entry);
gboolean gst_toc_entry_is_alternative (const GstTocEntry *entry);
gboolean gst_toc_entry_is_sequence (const GstTocEntry *entry);
void gst_toc_entry_set_start_stop_times (GstTocEntry *entry, gint64 start, gint64 stop);
gboolean gst_toc_entry_get_start_stop_times (const GstTocEntry *entry, gint64 *start, gint64 *stop);
const gchar * gst_toc_entry_type_get_nick (GstTocEntryType type);
G_END_DECLS G_END_DECLS

View file

@ -46,90 +46,75 @@
#define TOC_TAG "TocTag" #define TOC_TAG "TocTag"
#define TEST_UID "129537542" #define TEST_UID "129537542"
#define INFO_NAME "gst-toc-check"
#define INFO_FIELD "info-test"
#define INFO_TEXT_EN "info-text-entry"
#define INFO_TEXT_TOC "info-text-toc"
#define CHECK_TOC_ENTRY(entry_c,type_c,uid_c) \ #define CHECK_TOC_ENTRY(entry_c,type_c,uid_c) \
{ \ { \
GstTagList *tags; \
gchar *tag_c; \ gchar *tag_c; \
const GValue *val; \
GstStructure *struct_c; \
\ \
fail_unless_equals_string (entry_c->uid, uid_c); \ fail_unless_equals_string (gst_toc_entry_get_uid (entry_c), uid_c); \
fail_unless (entry_c->type == type_c); \ fail_unless (gst_toc_entry_get_entry_type (entry_c) == type_c); \
fail_unless (entry_c->tags != NULL); \
fail_unless (entry_c->pads == NULL); \
\ \
fail_unless (entry_c->info != NULL); \ tags = gst_toc_entry_get_tags (entry_c); \
gst_structure_get (entry_c->info, INFO_NAME, GST_TYPE_STRUCTURE, \ fail_unless (tags != NULL); \
&struct_c, NULL); \ fail_unless (gst_tag_list_get_string (tags, \
fail_unless (struct_c != NULL); \ GST_TAG_TITLE, &tag_c)); \
val = gst_structure_get_value (struct_c, INFO_FIELD); \
fail_unless (val != NULL); \
fail_unless_equals_string (g_value_get_string (val), INFO_TEXT_EN); \
\
fail_unless (gst_tag_list_get_string (entry_c->tags, \
GST_TAG_TITLE, &tag_c)); \
fail_unless_equals_string (tag_c, ENTRY_TAG); \ fail_unless_equals_string (tag_c, ENTRY_TAG); \
g_free (tag_c); \ g_free (tag_c); \
gst_structure_free (struct_c); \
} }
#define CHECK_TOC(toc_t) \ #define CHECK_TOC(toc_t) \
{ \ { \
GstTocEntry *entry_t, *subentry_t; \ GstTocEntry *entry_t, *subentry_t; \
GstTagList *tags; \
GList *entries, *subentries, *subsubentries; \
gchar *tag_t; \ gchar *tag_t; \
const GValue *val; \
GstStructure *struct_toc; \
\ \
/* check TOC */ \ /* check TOC */ \
fail_unless (g_list_length (toc_t->entries) == 2); \ tags = gst_toc_get_tags (toc_t); \
fail_unless (toc_t->tags != NULL); \ fail_unless (tags != NULL); \
fail_unless (gst_tag_list_get_string (toc_t->tags, \ fail_unless (gst_tag_list_get_string (tags, \
GST_TAG_TITLE, &tag_t)); \ GST_TAG_TITLE, &tag_t)); \
fail_unless_equals_string (tag_t, TOC_TAG); \ fail_unless_equals_string (tag_t, TOC_TAG); \
g_free (tag_t); \ g_free (tag_t); \
\ \
fail_unless (toc_t->info != NULL); \ entries = gst_toc_get_entries (toc_t); \
gst_structure_get (toc_t->info, INFO_NAME, GST_TYPE_STRUCTURE, \ fail_unless_equals_int (g_list_length (entries), 2); \
&struct_toc, NULL); \
fail_unless (struct_toc != NULL); \
val = gst_structure_get_value (struct_toc, INFO_FIELD); \
fail_unless (val != NULL); \
fail_unless_equals_string (g_value_get_string (val), INFO_TEXT_TOC); \
gst_structure_free (struct_toc); \
\
/* check edition1 */ \ /* check edition1 */ \
entry_t = g_list_nth_data (toc_t->entries, 0); \ entry_t = g_list_nth_data (entries, 0); \
fail_if (entry_t == NULL); \ fail_if (entry_t == NULL); \
fail_unless (g_list_length (entry_t->subentries) == 2); \ subentries = gst_toc_entry_get_sub_entries (entry_t); \
fail_unless_equals_int (g_list_length (subentries), 2); \
CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \ CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \
/* check chapter1 */ \ /* check chapter1 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \
/* check chapter2 */ \ /* check chapter2 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 1); \ subentry_t = g_list_nth_data (subentries, 1); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \
/* check edition2 */ \ /* check edition2 */ \
entry_t = g_list_nth_data (toc_t->entries, 1); \ entry_t = g_list_nth_data (entries, 1); \
fail_if (entry_t == NULL); \ fail_if (entry_t == NULL); \
fail_unless (g_list_length (entry_t->subentries) == 1); \ subentries = gst_toc_entry_get_sub_entries (entry_t); \
fail_unless_equals_int (g_list_length (subentries), 1); \
CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \ CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \
/* check chapter3 */ \ /* check chapter3 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 1); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 1); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \
/* check subchapter1 */ \ /* check subchapter1 */ \
subentry_t = g_list_nth_data (subentry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \
} }
@ -137,9 +122,9 @@
* the original TOC into the message/query/event */ * the original TOC into the message/query/event */
GST_START_TEST (test_serializing) GST_START_TEST (test_serializing)
{ {
GstStructure *structure;
GstToc *toc, *test_toc = NULL; GstToc *toc, *test_toc = NULL;
GstTocEntry *ed, *ch, *subch; GstTocEntry *ed, *ch, *subch;
GstTagList *tags;
GstEvent *event; GstEvent *event;
GstMessage *message; GstMessage *message;
GstQuery *query; GstQuery *query;
@ -149,62 +134,48 @@ GST_START_TEST (test_serializing)
toc = gst_toc_new (); toc = gst_toc_new ();
fail_if (toc == NULL); fail_if (toc == NULL);
gst_tag_list_add (toc->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
TOC_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, TOC_TAG, NULL);
structure = gst_toc_set_tags (toc, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_TOC,
NULL);
gst_structure_set (toc->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
/* create edition1 */ /* create edition1 */
ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1);
fail_if (ed == NULL); fail_if (ed == NULL);
gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ed, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ed->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1);
/* append chapter1 to edition1 */ /* append chapter1 to edition1 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1);
fail_if (ch == NULL); fail_if (ch == NULL);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1);
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
fail_unless (g_list_length (ed->subentries) == 1); fail_unless_equals_int (g_list_length (gst_toc_entry_get_sub_entries (ed)),
1);
/* append chapter2 to edition1 */ /* append chapter2 to edition1 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2);
fail_if (ch == NULL); fail_if (ch == NULL);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2);
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
fail_unless (g_list_length (ed->subentries) == 2); fail_unless_equals_int (g_list_length (gst_toc_entry_get_sub_entries (ed)),
2);
/* append edition1 to the TOC */ /* append edition1 to the TOC */
toc->entries = g_list_append (toc->entries, ed); gst_toc_append_entry (toc, ed);
fail_unless (g_list_length (toc->entries) == 1); fail_unless_equals_int (g_list_length (gst_toc_get_entries (toc)), 1);
/* test gst_toc_entry_find() */ /* test gst_toc_entry_find() */
ed = NULL; ed = NULL;
@ -215,62 +186,51 @@ GST_START_TEST (test_serializing)
CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1);
/* test info GstStructure */ /* test info GstStructure */
gst_toc_entry_set_start_stop (ch, 100, 1000); gst_toc_entry_set_start_stop_times (ch, 100, 1000);
fail_if (!gst_toc_entry_get_start_stop (ch, &start, &stop)); fail_if (!gst_toc_entry_get_start_stop_times (ch, &start, &stop));
fail_unless (start == 100); fail_unless (start == 100);
fail_unless (stop == 1000); fail_unless (stop == 1000);
/* create edition2 */ /* create edition2 */
ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2);
fail_if (ed == NULL); fail_if (ed == NULL);
gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ed, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ed->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2);
/* create chapter3 */ /* create chapter3 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3);
fail_if (ch == NULL); fail_if (ch == NULL);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); CHECK_TOC_ENTRY (ch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3);
/* create subchapter1 */ /* create subchapter1 */
subch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); subch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1);
fail_if (subch == NULL); fail_if (subch == NULL);
gst_tag_list_add (subch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (subch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (subch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure,
NULL);
gst_structure_free (structure);
CHECK_TOC_ENTRY (subch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); CHECK_TOC_ENTRY (subch, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1);
/* append subchapter1 to chapter3 */ /* append subchapter1 to chapter3 */
ch->subentries = g_list_append (ch->subentries, subch); gst_toc_entry_append_sub_entry (ch, subch);
fail_unless (g_list_length (ch->subentries) == 1); fail_unless_equals_int (g_list_length (gst_toc_entry_get_sub_entries (ch)),
1);
/* append chapter3 to edition2 */ /* append chapter3 to edition2 */
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
fail_unless (g_list_length (ed->subentries) == 1); fail_unless_equals_int (g_list_length (gst_toc_entry_get_sub_entries (ed)),
1);
/* finally append edition2 to the TOC */ /* finally append edition2 to the TOC */
toc->entries = g_list_append (toc->entries, ed); gst_toc_append_entry (toc, ed);
fail_unless (g_list_length (toc->entries) == 2); fail_unless_equals_int (g_list_length (gst_toc_get_entries (toc)), 2);
/* test gst_toc_copy() */ /* test gst_toc_copy() */
test_toc = gst_toc_copy (toc); test_toc = gst_toc_copy (toc);

View file

@ -34,90 +34,75 @@
#define ENTRY_TAG "EntryTag" #define ENTRY_TAG "EntryTag"
#define TOC_TAG "TocTag" #define TOC_TAG "TocTag"
#define INFO_NAME "gst-toc-setter-check"
#define INFO_FIELD "info-test"
#define INFO_TEXT_EN "info-text-entry"
#define INFO_TEXT_TOC "info-text-toc"
#define CHECK_TOC_ENTRY(entry_c,type_c,uid_c) \ #define CHECK_TOC_ENTRY(entry_c,type_c,uid_c) \
{ \ { \
GstTagList *tags; \
gchar *tag_c; \ gchar *tag_c; \
const GValue *val; \
GstStructure *struct_c; \
\ \
fail_unless_equals_string (entry_c->uid, uid_c); \ fail_unless_equals_string (gst_toc_entry_get_uid (entry_c), uid_c); \
fail_unless (entry_c->type == type_c); \ fail_unless (gst_toc_entry_get_entry_type (entry_c) == type_c); \
fail_unless (entry_c->tags != NULL); \
fail_unless (entry_c->pads == NULL); \
\ \
fail_unless (entry_c->info != NULL); \ tags = gst_toc_entry_get_tags (entry_c); \
gst_structure_get (entry_c->info, INFO_NAME, GST_TYPE_STRUCTURE, \ fail_unless (tags != NULL); \
&struct_c, NULL); \ fail_unless (gst_tag_list_get_string (tags, \
fail_unless (struct_c != NULL); \
val = gst_structure_get_value (struct_c, INFO_FIELD); \
fail_unless (val != NULL); \
fail_unless_equals_string (g_value_get_string (val), INFO_TEXT_EN); \
\
fail_unless (gst_tag_list_get_string (entry_c->tags, \
GST_TAG_TITLE, &tag_c)); \ GST_TAG_TITLE, &tag_c)); \
fail_unless_equals_string (tag_c, ENTRY_TAG); \ fail_unless_equals_string (tag_c, ENTRY_TAG); \
g_free (tag_c); \ g_free (tag_c); \
gst_structure_free (struct_c); \
} }
#define CHECK_TOC(toc_t) \ #define CHECK_TOC(toc_t) \
{ \ { \
GstTocEntry *entry_t, *subentry_t; \ GstTocEntry *entry_t, *subentry_t; \
GstTagList *tags; \
GList *entries, *subentries, *subsubentries; \
gchar *tag_t; \ gchar *tag_t; \
const GValue *val; \
GstStructure *struct_toc; \
\ \
/* check TOC */ \ /* check TOC */ \
fail_unless (g_list_length (toc_t->entries) == 2); \ tags = gst_toc_get_tags (toc_t); \
fail_unless (toc_t->tags != NULL); \ fail_unless (tags != NULL); \
fail_unless (gst_tag_list_get_string (toc_t->tags, \ fail_unless (gst_tag_list_get_string (tags, \
GST_TAG_TITLE, &tag_t)); \ GST_TAG_TITLE, &tag_t)); \
fail_unless_equals_string (tag_t, TOC_TAG); \ fail_unless_equals_string (tag_t, TOC_TAG); \
g_free (tag_t); \ g_free (tag_t); \
\ \
fail_unless (toc_t->info != NULL); \ entries = gst_toc_get_entries (toc_t); \
gst_structure_get (toc_t->info, INFO_NAME, GST_TYPE_STRUCTURE, \ fail_unless_equals_int (g_list_length (entries), 2); \
&struct_toc, NULL); \
fail_unless (struct_toc != NULL); \
val = gst_structure_get_value (struct_toc, INFO_FIELD); \
fail_unless (val != NULL); \
fail_unless_equals_string (g_value_get_string (val), INFO_TEXT_TOC); \
gst_structure_free (struct_toc); \
\
/* check edition1 */ \ /* check edition1 */ \
entry_t = g_list_nth_data (toc_t->entries, 0); \ entry_t = g_list_nth_data (entries, 0); \
fail_if (entry_t == NULL); \ fail_if (entry_t == NULL); \
fail_unless (g_list_length (entry_t->subentries) == 2); \ subentries = gst_toc_entry_get_sub_entries (entry_t); \
fail_unless_equals_int (g_list_length (subentries), 2); \
CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \ CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \
/* check chapter1 */ \ /* check chapter1 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \
/* check chapter2 */ \ /* check chapter2 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 1); \ subentry_t = g_list_nth_data (subentries, 1); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \
/* check edition2 */ \ /* check edition2 */ \
entry_t = g_list_nth_data (toc_t->entries, 1); \ entry_t = g_list_nth_data (entries, 1); \
fail_if (entry_t == NULL); \ fail_if (entry_t == NULL); \
fail_unless (g_list_length (entry_t->subentries) == 1); \ subentries = gst_toc_entry_get_sub_entries (entry_t); \
fail_unless_equals_int (g_list_length (subentries), 1); \
CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \ CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \
/* check chapter3 */ \ /* check chapter3 */ \
subentry_t = g_list_nth_data (entry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 1); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 1); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \
/* check subchapter1 */ \ /* check subchapter1 */ \
subentry_t = g_list_nth_data (subentry_t->subentries, 0); \ subentry_t = g_list_nth_data (subentries, 0); \
fail_if (subentry_t == NULL); \ fail_if (subentry_t == NULL); \
fail_unless (g_list_length (subentry_t->subentries) == 0); \ subsubentries = gst_toc_entry_get_sub_entries (subentry_t); \
fail_unless_equals_int (g_list_length (subsubentries), 0); \
CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \ CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \
} }
@ -144,95 +129,66 @@ gst_dummy_enc_init (GstDummyEnc * enc)
static GstToc * static GstToc *
create_toc (void) create_toc (void)
{ {
GstStructure *structure;
GstToc *toc; GstToc *toc;
GstTocEntry *ed, *ch, *subch; GstTocEntry *ed, *ch, *subch;
GstTagList *tags;
toc = gst_toc_new (); toc = gst_toc_new ();
gst_tag_list_add (toc->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
TOC_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, TOC_TAG, NULL);
structure = gst_toc_set_tags (toc, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_TOC,
NULL);
gst_structure_set (toc->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
/* create edition1 */ /* create edition1 */
ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1);
gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ed, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ed->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
/* append chapter1 to edition1 */ /* append chapter1 to edition1 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
/* append chapter2 to edition1 */ /* append chapter2 to edition1 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
/* append edition1 to the TOC */ /* append edition1 to the TOC */
toc->entries = g_list_append (toc->entries, ed); gst_toc_append_entry (toc, ed);
/* create edition2 */ /* create edition2 */
ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2);
gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ed, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ed->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
/* create chapter3 */ /* create chapter3 */
ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3);
gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (ch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (ch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
/* create subchapter1 */ /* create subchapter1 */
subch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); subch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1);
gst_tag_list_add (subch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tags = gst_tag_list_new_empty ();
ENTRY_TAG, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, ENTRY_TAG, NULL);
structure = gst_toc_entry_set_tags (subch, tags);
gst_structure_new (INFO_NAME, INFO_FIELD, G_TYPE_STRING, INFO_TEXT_EN,
NULL);
gst_structure_set (subch->info, INFO_NAME, GST_TYPE_STRUCTURE, structure,
NULL);
gst_structure_free (structure);
/* append subchapter1 to chapter3 */ /* append subchapter1 to chapter3 */
ch->subentries = g_list_append (ch->subentries, subch); gst_toc_entry_append_sub_entry (ch, subch);
/* append chapter3 to edition2 */ /* append chapter3 to edition2 */
ed->subentries = g_list_append (ed->subentries, ch); gst_toc_entry_append_sub_entry (ed, ch);
/* finally append edition2 to the TOC */ /* finally append edition2 to the TOC */
toc->entries = g_list_append (toc->entries, ed); gst_toc_append_entry (toc, ed);
return toc; return toc;
} }

View file

@ -468,12 +468,14 @@ print_toc_entry (gpointer data, gpointer user_data)
GstTocEntry *entry = (GstTocEntry *) data; GstTocEntry *entry = (GstTocEntry *) data;
const gchar spc[MAX_INDENT + 1] = " "; const gchar spc[MAX_INDENT + 1] = " ";
guint indent = MIN (GPOINTER_TO_UINT (user_data), MAX_INDENT); guint indent = MIN (GPOINTER_TO_UINT (user_data), MAX_INDENT);
const GstTagList *tags;
GList *subentries;
gint64 start, stop; gint64 start, stop;
gst_toc_entry_get_start_stop (entry, &start, &stop); gst_toc_entry_get_start_stop_times (entry, &start, &stop);
PRINT ("%s%s:", &spc[MAX_INDENT - indent], PRINT ("%s%s:", &spc[MAX_INDENT - indent],
gst_toc_entry_type_get_nick (entry->type)); gst_toc_entry_type_get_nick (gst_toc_entry_get_entry_type (entry)));
if (GST_CLOCK_TIME_IS_VALID (start)) { if (GST_CLOCK_TIME_IS_VALID (start)) {
PRINT (" start: %" GST_TIME_FORMAT, GST_TIME_ARGS (start)); PRINT (" start: %" GST_TIME_FORMAT, GST_TIME_ARGS (start));
} }
@ -484,12 +486,13 @@ print_toc_entry (gpointer data, gpointer user_data)
indent += 2; indent += 2;
/* print tags */ /* print tags */
gst_tag_list_foreach (entry->tags, print_tag_foreach, tags = gst_toc_entry_get_tags (entry);
GUINT_TO_POINTER (indent)); if (tags)
gst_tag_list_foreach (tags, print_tag_foreach, GUINT_TO_POINTER (indent));
/* loop over sub-toc entries */ /* loop over sub-toc entries */
g_list_foreach (entry->subentries, print_toc_entry, subentries = gst_toc_entry_get_sub_entries (entry);
GUINT_TO_POINTER (indent)); g_list_foreach (subentries, print_toc_entry, GUINT_TO_POINTER (indent));
} }
#ifndef DISABLE_FAULT_HANDLER #ifndef DISABLE_FAULT_HANDLER
@ -669,7 +672,8 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
break; break;
case GST_MESSAGE_TOC: case GST_MESSAGE_TOC:
if (toc) { if (toc) {
GstToc *toc_msg; GstToc *toc;
GList *entries;
gboolean updated; gboolean updated;
if (GST_IS_ELEMENT (GST_MESSAGE_SRC (message))) { if (GST_IS_ELEMENT (GST_MESSAGE_SRC (message))) {
@ -682,11 +686,11 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
PRINT (_("FOUND TOC\n")); PRINT (_("FOUND TOC\n"));
} }
gst_message_parse_toc (message, &toc_msg, &updated); gst_message_parse_toc (message, &toc, &updated);
/* recursively loop over toc entries */ /* recursively loop over toc entries */
g_list_foreach (toc_msg->entries, print_toc_entry, entries = gst_toc_get_entries (toc);
GUINT_TO_POINTER (0)); g_list_foreach (entries, print_toc_entry, GUINT_TO_POINTER (0));
gst_toc_unref (toc_msg); gst_toc_unref (toc);
} }
break; break;
case GST_MESSAGE_INFO:{ case GST_MESSAGE_INFO:{

View file

@ -56,8 +56,8 @@ EXPORTS
gst_base_sink_set_sync gst_base_sink_set_sync
gst_base_sink_set_throttle_time gst_base_sink_set_throttle_time
gst_base_sink_set_ts_offset gst_base_sink_set_ts_offset
gst_base_sink_wait
gst_base_sink_wait_clock gst_base_sink_wait_clock
gst_base_sink_wait_eos
gst_base_sink_wait_preroll gst_base_sink_wait_preroll
gst_base_src_get_blocksize gst_base_src_get_blocksize
gst_base_src_get_do_timestamp gst_base_src_get_do_timestamp

View file

@ -4,9 +4,6 @@ EXPORTS
gst_net_address_meta_get_info gst_net_address_meta_get_info
gst_net_client_clock_get_type gst_net_client_clock_get_type
gst_net_client_clock_new gst_net_client_clock_new
gst_net_time_packet_copy
gst_net_time_packet_free
gst_net_time_packet_get_type
gst_net_time_packet_new gst_net_time_packet_new
gst_net_time_packet_receive gst_net_time_packet_receive
gst_net_time_packet_send gst_net_time_packet_send

View file

@ -1133,19 +1133,29 @@ EXPORTS
gst_task_start gst_task_start
gst_task_state_get_type gst_task_state_get_type
gst_task_stop gst_task_stop
gst_toc_append_entry
gst_toc_entry_append_sub_entry
gst_toc_entry_get_entry_type gst_toc_entry_get_entry_type
gst_toc_entry_get_start_stop gst_toc_entry_get_start_stop_times
gst_toc_entry_get_sub_entries
gst_toc_entry_get_tags
gst_toc_entry_get_type gst_toc_entry_get_type
gst_toc_entry_get_uid
gst_toc_entry_is_alternative gst_toc_entry_is_alternative
gst_toc_entry_is_sequence gst_toc_entry_is_sequence
gst_toc_entry_merge_tags
gst_toc_entry_new gst_toc_entry_new
gst_toc_entry_new_with_pad gst_toc_entry_set_start_stop_times
gst_toc_entry_set_start_stop gst_toc_entry_set_tags
gst_toc_entry_type_get_nick gst_toc_entry_type_get_nick
gst_toc_entry_type_get_type gst_toc_entry_type_get_type
gst_toc_find_entry gst_toc_find_entry
gst_toc_get_entries
gst_toc_get_tags
gst_toc_get_type gst_toc_get_type
gst_toc_merge_tags
gst_toc_new gst_toc_new
gst_toc_set_tags
gst_toc_setter_get_toc gst_toc_setter_get_toc
gst_toc_setter_get_type gst_toc_setter_get_type
gst_toc_setter_reset gst_toc_setter_reset