Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 1 | /* GStreamer |
| 2 | * (c) 2010, 2012 Alexander Saprykin <xelfium@gmail.com> |
| 3 | * |
| 4 | * gsttoc.c: GstToc initialization and parsing/creation |
| 5 | * |
| 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. |
| 10 | * |
| 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. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Library General Public |
| 17 | * License along with this library; if not, write to the |
Tim-Philipp Müller | 666c8c1 | 2012-11-03 20:44:48 +0000 | [diff] [blame] | 18 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| 19 | * Boston, MA 02110-1301, USA. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 20 | */ |
| 21 | |
| 22 | /** |
| 23 | * SECTION:gsttoc |
Thibault Saunier | a87b455 | 2017-01-16 11:26:16 -0300 | [diff] [blame] | 24 | * @title: GstToc |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 25 | * @short_description: Generic table of contents support |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 26 | * @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 27 | * |
| 28 | * #GstToc functions are used to create/free #GstToc and #GstTocEntry structures. |
| 29 | * Also they are used to convert #GstToc into #GstStructure and vice versa. |
| 30 | * |
| 31 | * #GstToc lets you to inform other elements in pipeline or application that playing |
| 32 | * source has some kind of table of contents (TOC). These may be chapters, editions, |
| 33 | * angles or other types. For example: DVD chapters, Matroska chapters or cue sheet |
| 34 | * TOC. Such TOC will be useful for applications to display instead of just a |
| 35 | * playlist. |
| 36 | * |
| 37 | * Using TOC is very easy. Firstly, create #GstToc structure which represents root |
| 38 | * contents of the source. You can also attach TOC-specific tags to it. Then fill |
Tim-Philipp Müller | dddcc31 | 2012-08-11 22:19:32 +0100 | [diff] [blame] | 39 | * it with #GstTocEntry entries by appending them to the #GstToc using |
| 40 | * gst_toc_append_entry(), and appending subentries to a #GstTocEntry using |
| 41 | * gst_toc_entry_append_sub_entry(). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 42 | * |
| 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 |
| 46 | * stop values. |
| 47 | * |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 48 | * Use gst_event_new_toc() to create a new TOC #GstEvent, and gst_event_parse_toc() to |
| 49 | * parse received TOC event. Use gst_event_new_toc_select() to create a new TOC select #GstEvent, |
| 50 | * and gst_event_parse_toc_select() to parse received TOC select event. The same rule for |
| 51 | * the #GstMessage: gst_message_new_toc() to create new TOC #GstMessage, and |
Tim-Philipp Müller | dddcc31 | 2012-08-11 22:19:32 +0100 | [diff] [blame] | 52 | * gst_message_parse_toc() to parse received TOC message. |
| 53 | * |
| 54 | * TOCs can have global scope or current scope. Global scope TOCs contain |
| 55 | * all entries that can possibly be selected using a toc select event, and |
| 56 | * are what an application is usually interested in. TOCs with current scope |
| 57 | * only contain the parts of the TOC relevant to the currently selected/playing |
| 58 | * stream; the current scope TOC is used by downstream elements such as muxers |
| 59 | * to write correct TOC entries when transcoding files, for example. When |
| 60 | * playing a DVD, the global TOC would contain a hierarchy of all titles, |
| 61 | * chapters and angles, for example, while the current TOC would only contain |
| 62 | * the chapters for the currently playing title if playback of a specific |
| 63 | * title was requested. |
Tim-Philipp Müller | a76885f | 2013-03-24 17:53:35 +0000 | [diff] [blame] | 64 | * |
| 65 | * Applications and plugins should not rely on TOCs having a certain kind of |
| 66 | * structure, but should allow for different alternatives. For example, a |
| 67 | * simple CUE sheet embedded in a file may be presented as a flat list of |
| 68 | * track entries, or could have a top-level edition node (or some other |
| 69 | * alternative type entry) with track entries underneath that node; or even |
| 70 | * multiple top-level edition nodes (or some other alternative type entries) |
| 71 | * each with track entries underneath, in case the source file has extracted |
| 72 | * a track listing from different sources). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 73 | */ |
| 74 | |
| 75 | #ifdef HAVE_CONFIG_H |
| 76 | # include "config.h" |
| 77 | #endif |
| 78 | |
| 79 | #include "gst_private.h" |
| 80 | #include "gstenumtypes.h" |
| 81 | #include "gsttaglist.h" |
| 82 | #include "gststructure.h" |
| 83 | #include "gstvalue.h" |
| 84 | #include "gsttoc.h" |
| 85 | #include "gstpad.h" |
Tim-Philipp Müller | 68da2ae | 2012-05-20 17:48:55 +0100 | [diff] [blame] | 86 | #include "gstquark.h" |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 87 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 88 | struct _GstTocEntry |
| 89 | { |
| 90 | GstMiniObject mini_object; |
| 91 | |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 92 | GstToc *toc; |
| 93 | GstTocEntry *parent; |
| 94 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 95 | gchar *uid; |
| 96 | GstTocEntryType type; |
| 97 | GstClockTime start, stop; |
| 98 | GList *subentries; |
| 99 | GstTagList *tags; |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 100 | GstTocLoopType loop_type; |
| 101 | gint repeat_count; |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 102 | }; |
| 103 | |
| 104 | struct _GstToc |
| 105 | { |
| 106 | GstMiniObject mini_object; |
| 107 | |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 108 | GstTocScope scope; |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 109 | GList *entries; |
| 110 | GstTagList *tags; |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 111 | }; |
| 112 | |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 113 | #undef gst_toc_copy |
| 114 | static GstToc *gst_toc_copy (const GstToc * toc); |
| 115 | static void gst_toc_free (GstToc * toc); |
| 116 | #undef gst_toc_entry_copy |
| 117 | static GstTocEntry *gst_toc_entry_copy (const GstTocEntry * toc); |
| 118 | static void gst_toc_entry_free (GstTocEntry * toc); |
| 119 | |
Sebastian Dröge | db1e442 | 2014-06-19 08:05:03 +0200 | [diff] [blame] | 120 | GType _gst_toc_type = 0; |
| 121 | GType _gst_toc_entry_type = 0; |
| 122 | |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 123 | GST_DEFINE_MINI_OBJECT_TYPE (GstToc, gst_toc); |
| 124 | GST_DEFINE_MINI_OBJECT_TYPE (GstTocEntry, gst_toc_entry); |
Anton Belka | 6f54f36 | 2012-05-21 01:48:29 +0300 | [diff] [blame] | 125 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 126 | /** |
| 127 | * gst_toc_new: |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 128 | * @scope: scope of this TOC |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 129 | * |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 130 | * Create a new #GstToc structure. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 131 | * |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 132 | * Returns: (transfer full): newly allocated #GstToc structure, free it |
| 133 | * with gst_toc_unref(). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 134 | */ |
| 135 | GstToc * |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 136 | gst_toc_new (GstTocScope scope) |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 137 | { |
| 138 | GstToc *toc; |
| 139 | |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 140 | g_return_val_if_fail (scope == GST_TOC_SCOPE_GLOBAL || |
| 141 | scope == GST_TOC_SCOPE_CURRENT, NULL); |
| 142 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 143 | toc = g_slice_new0 (GstToc); |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 144 | |
Wim Taymans | 3b16efa | 2012-07-04 16:38:15 +0200 | [diff] [blame] | 145 | gst_mini_object_init (GST_MINI_OBJECT_CAST (toc), 0, GST_TYPE_TOC, |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 146 | (GstMiniObjectCopyFunction) gst_toc_copy, NULL, |
| 147 | (GstMiniObjectFreeFunction) gst_toc_free); |
| 148 | |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 149 | toc->scope = scope; |
Stefan Sauer | 3b0af8d | 2012-04-02 22:09:07 +0200 | [diff] [blame] | 150 | toc->tags = gst_tag_list_new_empty (); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 151 | |
| 152 | return toc; |
| 153 | } |
| 154 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 155 | /** |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 156 | * gst_toc_get_scope: |
| 157 | * @toc: a #GstToc instance |
| 158 | * |
| 159 | * Returns: scope of @toc |
| 160 | */ |
| 161 | GstTocScope |
| 162 | gst_toc_get_scope (const GstToc * toc) |
| 163 | { |
| 164 | g_return_val_if_fail (toc != NULL, GST_TOC_SCOPE_GLOBAL); |
| 165 | |
| 166 | return toc->scope; |
| 167 | } |
| 168 | |
| 169 | /** |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 170 | * gst_toc_set_tags: |
| 171 | * @toc: A #GstToc instance |
| 172 | * @tags: (allow-none) (transfer full): A #GstTagList or %NULL |
| 173 | * |
| 174 | * Set a #GstTagList with tags for the complete @toc. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 175 | */ |
| 176 | void |
| 177 | gst_toc_set_tags (GstToc * toc, GstTagList * tags) |
| 178 | { |
| 179 | g_return_if_fail (toc != NULL); |
| 180 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc))); |
| 181 | |
| 182 | if (toc->tags) |
| 183 | gst_tag_list_unref (toc->tags); |
| 184 | toc->tags = tags; |
| 185 | } |
| 186 | |
| 187 | /** |
| 188 | * gst_toc_merge_tags: |
| 189 | * @toc: A #GstToc instance |
| 190 | * @tags: (allow-none): A #GstTagList or %NULL |
| 191 | * @mode: A #GstTagMergeMode |
| 192 | * |
| 193 | * Merge @tags into the existing tags of @toc using @mode. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 194 | */ |
| 195 | void |
| 196 | gst_toc_merge_tags (GstToc * toc, GstTagList * tags, GstTagMergeMode mode) |
| 197 | { |
| 198 | g_return_if_fail (toc != NULL); |
| 199 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc))); |
| 200 | |
| 201 | if (!toc->tags) { |
| 202 | toc->tags = gst_tag_list_ref (tags); |
| 203 | } else { |
| 204 | GstTagList *tmp = gst_tag_list_merge (toc->tags, tags, mode); |
| 205 | gst_tag_list_unref (toc->tags); |
| 206 | toc->tags = tmp; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | /** |
| 211 | * gst_toc_get_tags: |
| 212 | * @toc: A #GstToc instance |
| 213 | * |
| 214 | * Gets the tags for @toc. |
| 215 | * |
| 216 | * Returns: (transfer none): A #GstTagList for @entry |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 217 | */ |
| 218 | GstTagList * |
| 219 | gst_toc_get_tags (const GstToc * toc) |
| 220 | { |
| 221 | g_return_val_if_fail (toc != NULL, NULL); |
| 222 | |
| 223 | return toc->tags; |
| 224 | } |
| 225 | |
| 226 | /** |
| 227 | * gst_toc_append_entry: |
| 228 | * @toc: A #GstToc instance |
| 229 | * @entry: (transfer full): A #GstTocEntry |
| 230 | * |
| 231 | * Appends the #GstTocEntry @entry to @toc. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 232 | */ |
| 233 | void |
| 234 | gst_toc_append_entry (GstToc * toc, GstTocEntry * entry) |
| 235 | { |
| 236 | g_return_if_fail (toc != NULL); |
| 237 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (toc))); |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 238 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry))); |
| 239 | g_return_if_fail (entry->toc == NULL); |
| 240 | g_return_if_fail (entry->parent == NULL); |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 241 | |
| 242 | toc->entries = g_list_append (toc->entries, entry); |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 243 | entry->toc = toc; |
Tim-Philipp Müller | 1ba0d6f | 2012-07-09 13:12:27 +0100 | [diff] [blame] | 244 | |
| 245 | GST_LOG ("appended %s entry with uid %s to toc %p", |
| 246 | gst_toc_entry_type_get_nick (entry->type), entry->uid, toc); |
| 247 | |
| 248 | gst_toc_dump (toc); |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 249 | } |
| 250 | |
| 251 | /** |
| 252 | * gst_toc_get_entries: |
| 253 | * @toc: A #GstToc instance |
| 254 | * |
| 255 | * Gets the list of #GstTocEntry of @toc. |
| 256 | * |
| 257 | * Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry for @entry |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 258 | */ |
| 259 | GList * |
| 260 | gst_toc_get_entries (const GstToc * toc) |
| 261 | { |
| 262 | g_return_val_if_fail (toc != NULL, NULL); |
| 263 | |
| 264 | return toc->entries; |
| 265 | } |
| 266 | |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 267 | static GstTocEntry * |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 268 | gst_toc_entry_new_internal (GstTocEntryType type, const gchar * uid) |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 269 | { |
| 270 | GstTocEntry *entry; |
| 271 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 272 | entry = g_slice_new0 (GstTocEntry); |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 273 | |
Wim Taymans | 3b16efa | 2012-07-04 16:38:15 +0200 | [diff] [blame] | 274 | gst_mini_object_init (GST_MINI_OBJECT_CAST (entry), 0, GST_TYPE_TOC_ENTRY, |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 275 | (GstMiniObjectCopyFunction) gst_toc_entry_copy, NULL, |
| 276 | (GstMiniObjectFreeFunction) gst_toc_entry_free); |
| 277 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 278 | entry->uid = g_strdup (uid); |
| 279 | entry->type = type; |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 280 | entry->tags = NULL; |
| 281 | entry->start = entry->stop = GST_CLOCK_TIME_NONE; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 282 | |
| 283 | return entry; |
| 284 | } |
| 285 | |
| 286 | /** |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 287 | * gst_toc_entry_new: |
| 288 | * @type: entry type. |
| 289 | * @uid: unique ID (UID) in the whole TOC. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 290 | * |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 291 | * Create new #GstTocEntry structure. |
| 292 | * |
| 293 | * Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_unref(). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 294 | */ |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 295 | GstTocEntry * |
| 296 | gst_toc_entry_new (GstTocEntryType type, const gchar * uid) |
| 297 | { |
| 298 | g_return_val_if_fail (uid != NULL, NULL); |
| 299 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 300 | return gst_toc_entry_new_internal (type, uid); |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | static void |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 304 | gst_toc_free (GstToc * toc) |
| 305 | { |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 306 | g_list_foreach (toc->entries, (GFunc) gst_mini_object_unref, NULL); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 307 | g_list_free (toc->entries); |
| 308 | |
| 309 | if (toc->tags != NULL) |
Tim-Philipp Müller | cd38758 | 2012-05-28 00:08:18 +0100 | [diff] [blame] | 310 | gst_tag_list_unref (toc->tags); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 311 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 312 | g_slice_free (GstToc, toc); |
| 313 | } |
| 314 | |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 315 | static void |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 316 | gst_toc_entry_free (GstTocEntry * entry) |
| 317 | { |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 318 | g_return_if_fail (entry != NULL); |
| 319 | |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 320 | g_list_foreach (entry->subentries, (GFunc) gst_mini_object_unref, NULL); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 321 | g_list_free (entry->subentries); |
| 322 | |
| 323 | g_free (entry->uid); |
| 324 | |
| 325 | if (entry->tags != NULL) |
Tim-Philipp Müller | cd38758 | 2012-05-28 00:08:18 +0100 | [diff] [blame] | 326 | gst_tag_list_unref (entry->tags); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 327 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 328 | g_slice_free (GstTocEntry, entry); |
| 329 | } |
| 330 | |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 331 | static GstTocEntry * |
| 332 | gst_toc_entry_find_sub_entry (const GstTocEntry * entry, const gchar * uid) |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 333 | { |
| 334 | GList *cur; |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 335 | GstTocEntry *subentry, *subsubentry; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 336 | |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 337 | g_return_val_if_fail (entry != NULL, NULL); |
| 338 | g_return_val_if_fail (uid != NULL, NULL); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 339 | |
| 340 | cur = entry->subentries; |
| 341 | while (cur != NULL) { |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 342 | subentry = cur->data; |
| 343 | |
| 344 | if (g_strcmp0 (subentry->uid, uid) == 0) |
| 345 | return subentry; |
| 346 | |
| 347 | subsubentry = gst_toc_entry_find_sub_entry (subentry, uid); |
| 348 | if (subsubentry != NULL) |
| 349 | return subsubentry; |
| 350 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 351 | cur = cur->next; |
| 352 | } |
| 353 | |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 354 | return NULL; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 355 | } |
| 356 | |
| 357 | /** |
| 358 | * gst_toc_find_entry: |
| 359 | * @toc: #GstToc to search in. |
| 360 | * @uid: UID to find #GstTocEntry with. |
| 361 | * |
| 362 | * Find #GstTocEntry with given @uid in the @toc. |
| 363 | * |
Evan Nemerson | 2759882 | 2014-06-11 15:21:34 -0700 | [diff] [blame] | 364 | * Returns: (transfer none) (nullable): #GstTocEntry with specified |
| 365 | * @uid from the @toc, or %NULL if not found. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 366 | */ |
| 367 | GstTocEntry * |
| 368 | gst_toc_find_entry (const GstToc * toc, const gchar * uid) |
| 369 | { |
| 370 | GList *cur; |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 371 | GstTocEntry *entry, *subentry; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 372 | |
| 373 | g_return_val_if_fail (toc != NULL, NULL); |
| 374 | g_return_val_if_fail (uid != NULL, NULL); |
| 375 | |
| 376 | cur = toc->entries; |
| 377 | while (cur != NULL) { |
Anton Belka | be38fbb | 2012-07-10 18:15:20 +0300 | [diff] [blame] | 378 | entry = cur->data; |
| 379 | |
| 380 | if (g_strcmp0 (entry->uid, uid) == 0) |
| 381 | return entry; |
| 382 | |
| 383 | subentry = gst_toc_entry_find_sub_entry (entry, uid); |
| 384 | if (subentry != NULL) |
| 385 | return subentry; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 386 | cur = cur->next; |
| 387 | } |
| 388 | |
| 389 | return NULL; |
| 390 | } |
| 391 | |
Tim-Philipp Müller | b77446b | 2014-11-02 20:16:53 +0000 | [diff] [blame] | 392 | static GList * |
| 393 | gst_toc_deep_copy_toc_entries (GList * entry_list) |
| 394 | { |
| 395 | GQueue new_entries = G_QUEUE_INIT; |
| 396 | GList *l; |
| 397 | |
| 398 | for (l = entry_list; l != NULL; l = l->next) |
| 399 | g_queue_push_tail (&new_entries, gst_toc_entry_copy (l->data)); |
| 400 | |
| 401 | return new_entries.head; |
| 402 | } |
| 403 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 404 | /** |
| 405 | * gst_toc_entry_copy: |
| 406 | * @entry: #GstTocEntry to copy. |
| 407 | * |
| 408 | * Copy #GstTocEntry with all subentries (deep copy). |
| 409 | * |
Evan Nemerson | 2759882 | 2014-06-11 15:21:34 -0700 | [diff] [blame] | 410 | * Returns: (nullable): newly allocated #GstTocEntry in case of |
| 411 | * success, %NULL otherwise; free it when done with |
| 412 | * gst_toc_entry_unref(). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 413 | */ |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 414 | static GstTocEntry * |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 415 | gst_toc_entry_copy (const GstTocEntry * entry) |
| 416 | { |
Tim-Philipp Müller | b77446b | 2014-11-02 20:16:53 +0000 | [diff] [blame] | 417 | GstTocEntry *ret; |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 418 | GstTagList *list; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 419 | |
| 420 | g_return_val_if_fail (entry != NULL, NULL); |
| 421 | |
| 422 | ret = gst_toc_entry_new (entry->type, entry->uid); |
| 423 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 424 | ret->start = entry->start; |
| 425 | ret->stop = entry->stop; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 426 | |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 427 | if (GST_IS_TAG_LIST (entry->tags)) { |
| 428 | list = gst_tag_list_copy (entry->tags); |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 429 | if (ret->tags) |
| 430 | gst_tag_list_unref (ret->tags); |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 431 | ret->tags = list; |
| 432 | } |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 433 | |
Tim-Philipp Müller | b77446b | 2014-11-02 20:16:53 +0000 | [diff] [blame] | 434 | ret->subentries = gst_toc_deep_copy_toc_entries (entry->subentries); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 435 | |
| 436 | return ret; |
| 437 | } |
| 438 | |
| 439 | /** |
| 440 | * gst_toc_copy: |
| 441 | * @toc: #GstToc to copy. |
| 442 | * |
| 443 | * Copy #GstToc with all subentries (deep copy). |
| 444 | * |
Evan Nemerson | 2759882 | 2014-06-11 15:21:34 -0700 | [diff] [blame] | 445 | * Returns: (nullable): newly allocated #GstToc in case of success, |
| 446 | * %NULL otherwise; free it when done with gst_toc_unref(). |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 447 | */ |
Tim-Philipp Müller | f20efe2 | 2012-06-24 20:08:33 +0100 | [diff] [blame] | 448 | static GstToc * |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 449 | gst_toc_copy (const GstToc * toc) |
| 450 | { |
| 451 | GstToc *ret; |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 452 | GstTagList *list; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 453 | |
| 454 | g_return_val_if_fail (toc != NULL, NULL); |
| 455 | |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 456 | ret = gst_toc_new (toc->scope); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 457 | |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 458 | if (GST_IS_TAG_LIST (toc->tags)) { |
| 459 | list = gst_tag_list_copy (toc->tags); |
Tim-Philipp Müller | cd38758 | 2012-05-28 00:08:18 +0100 | [diff] [blame] | 460 | gst_tag_list_unref (ret->tags); |
Alexander Saprykin | feb19b6 | 2012-04-10 14:11:26 +0400 | [diff] [blame] | 461 | ret->tags = list; |
| 462 | } |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 463 | |
Tim-Philipp Müller | b77446b | 2014-11-02 20:16:53 +0000 | [diff] [blame] | 464 | ret->entries = gst_toc_deep_copy_toc_entries (toc->entries); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 465 | |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 466 | return ret; |
| 467 | } |
| 468 | |
| 469 | /** |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 470 | * gst_toc_entry_set_start_stop_times: |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 471 | * @entry: #GstTocEntry to set values. |
| 472 | * @start: start value to set. |
| 473 | * @stop: stop value to set. |
| 474 | * |
| 475 | * Set @start and @stop values for the @entry. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 476 | */ |
| 477 | void |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 478 | gst_toc_entry_set_start_stop_times (GstTocEntry * entry, gint64 start, |
| 479 | gint64 stop) |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 480 | { |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 481 | g_return_if_fail (entry != NULL); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 482 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 483 | entry->start = start; |
| 484 | entry->stop = stop; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 485 | } |
| 486 | |
| 487 | /** |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 488 | * gst_toc_entry_get_start_stop_times: |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 489 | * @entry: #GstTocEntry to get values from. |
Evan Nemerson | 5d80cf1 | 2014-06-11 16:06:19 -0700 | [diff] [blame] | 490 | * @start: (out) (allow-none): the storage for the start value, leave |
| 491 | * %NULL if not need. |
| 492 | * @stop: (out) (allow-none): the storage for the stop value, leave |
| 493 | * %NULL if not need. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 494 | * |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 495 | * Get @start and @stop values from the @entry and write them into appropriate |
| 496 | * storages. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 497 | * |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 498 | * Returns: %TRUE if all non-%NULL storage pointers were filled with appropriate |
| 499 | * values, %FALSE otherwise. |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 500 | */ |
| 501 | gboolean |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 502 | gst_toc_entry_get_start_stop_times (const GstTocEntry * entry, gint64 * start, |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 503 | gint64 * stop) |
| 504 | { |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 505 | g_return_val_if_fail (entry != NULL, FALSE); |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 506 | |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 507 | if (start != NULL) |
| 508 | *start = entry->start; |
| 509 | if (stop != NULL) |
| 510 | *stop = entry->stop; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 511 | |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 512 | return TRUE; |
Alexander Saprykin | 63256d2 | 2012-03-14 20:01:51 +0400 | [diff] [blame] | 513 | } |
| 514 | |
Anton Belka | 71d1af2 | 2012-05-15 14:48:35 +0300 | [diff] [blame] | 515 | /** |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 516 | * gst_toc_entry_set_loop: |
| 517 | * @entry: #GstTocEntry to set values. |
| 518 | * @loop_type: loop_type value to set. |
| 519 | * @repeat_count: repeat_count value to set. |
| 520 | * |
| 521 | * Set @loop_type and @repeat_count values for the @entry. |
| 522 | * |
| 523 | * Since: 1.4 |
| 524 | */ |
| 525 | void |
| 526 | gst_toc_entry_set_loop (GstTocEntry * entry, GstTocLoopType loop_type, |
| 527 | gint repeat_count) |
| 528 | { |
| 529 | g_return_if_fail (entry != NULL); |
| 530 | |
| 531 | entry->loop_type = loop_type; |
| 532 | entry->repeat_count = repeat_count; |
| 533 | } |
| 534 | |
| 535 | /** |
| 536 | * gst_toc_entry_get_loop: |
| 537 | * @entry: #GstTocEntry to get values from. |
Evan Nemerson | 5d80cf1 | 2014-06-11 16:06:19 -0700 | [diff] [blame] | 538 | * @loop_type: (out) (allow-none): the storage for the loop_type |
| 539 | * value, leave %NULL if not need. |
| 540 | * @repeat_count: (out) (allow-none): the storage for the repeat_count |
| 541 | * value, leave %NULL if not need. |
Stefan Sauer | 0fb6a15 | 2014-01-02 22:30:11 +0100 | [diff] [blame] | 542 | * |
| 543 | * Get @loop_type and @repeat_count values from the @entry and write them into |
| 544 | * appropriate storages. Loops are e.g. used by sampled instruments. GStreamer |
| 545 | * is not automatically applying the loop. The application can process this |
| 546 | * meta data and use it e.g. to send a seek-event to loop a section. |
| 547 | * |
| 548 | * Returns: %TRUE if all non-%NULL storage pointers were filled with appropriate |
| 549 | * values, %FALSE otherwise. |
| 550 | * |
| 551 | * Since: 1.4 |
| 552 | */ |
| 553 | gboolean |
| 554 | gst_toc_entry_get_loop (const GstTocEntry * entry, GstTocLoopType * loop_type, |
| 555 | gint * repeat_count) |
| 556 | { |
| 557 | g_return_val_if_fail (entry != NULL, FALSE); |
| 558 | |
| 559 | if (loop_type != NULL) |
| 560 | *loop_type = entry->loop_type; |
| 561 | if (repeat_count != NULL) |
| 562 | *repeat_count = entry->repeat_count; |
| 563 | |
| 564 | return TRUE; |
| 565 | } |
| 566 | |
| 567 | |
| 568 | /** |
Sebastian Dröge | cacdea6 | 2012-05-15 16:38:30 +0200 | [diff] [blame] | 569 | * gst_toc_entry_type_get_nick: |
Anton Belka | 71d1af2 | 2012-05-15 14:48:35 +0300 | [diff] [blame] | 570 | * @type: a #GstTocEntryType. |
| 571 | * |
| 572 | * Converts @type to a string representation. |
| 573 | * |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 574 | * Returns: Returns a human-readable string for @type. This string is |
| 575 | * only for debugging purpose and should not be displayed in a user |
| 576 | * interface. |
Anton Belka | 71d1af2 | 2012-05-15 14:48:35 +0300 | [diff] [blame] | 577 | */ |
| 578 | const gchar * |
Sebastian Dröge | cacdea6 | 2012-05-15 16:38:30 +0200 | [diff] [blame] | 579 | gst_toc_entry_type_get_nick (GstTocEntryType type) |
Anton Belka | 71d1af2 | 2012-05-15 14:48:35 +0300 | [diff] [blame] | 580 | { |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 581 | switch (type) { |
| 582 | case GST_TOC_ENTRY_TYPE_ANGLE: |
| 583 | return "angle"; |
| 584 | case GST_TOC_ENTRY_TYPE_VERSION: |
| 585 | return "version"; |
| 586 | case GST_TOC_ENTRY_TYPE_EDITION: |
| 587 | return "edition"; |
| 588 | case GST_TOC_ENTRY_TYPE_TITLE: |
| 589 | return "title"; |
| 590 | case GST_TOC_ENTRY_TYPE_TRACK: |
| 591 | return "track"; |
| 592 | case GST_TOC_ENTRY_TYPE_CHAPTER: |
| 593 | return "chapter"; |
| 594 | default: |
| 595 | break; |
| 596 | } |
| 597 | return "invalid"; |
Anton Belka | 71d1af2 | 2012-05-15 14:48:35 +0300 | [diff] [blame] | 598 | } |
| 599 | |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 600 | /** |
| 601 | * gst_toc_entry_get_entry_type: |
| 602 | * @entry: a #GstTocEntry |
| 603 | * |
| 604 | * Returns: @entry's entry type |
| 605 | */ |
| 606 | GstTocEntryType |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 607 | gst_toc_entry_get_entry_type (const GstTocEntry * entry) |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 608 | { |
| 609 | g_return_val_if_fail (entry != NULL, GST_TOC_ENTRY_TYPE_INVALID); |
| 610 | |
| 611 | return entry->type; |
| 612 | } |
| 613 | |
| 614 | /** |
| 615 | * gst_toc_entry_is_alternative: |
| 616 | * @entry: a #GstTocEntry |
| 617 | * |
| 618 | * Returns: %TRUE if @entry's type is an alternative type, otherwise %FALSE |
| 619 | */ |
| 620 | gboolean |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 621 | gst_toc_entry_is_alternative (const GstTocEntry * entry) |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 622 | { |
| 623 | g_return_val_if_fail (entry != NULL, FALSE); |
| 624 | |
| 625 | return GST_TOC_ENTRY_TYPE_IS_ALTERNATIVE (entry->type); |
| 626 | } |
| 627 | |
| 628 | /** |
| 629 | * gst_toc_entry_is_sequence: |
| 630 | * @entry: a #GstTocEntry |
| 631 | * |
| 632 | * Returns: %TRUE if @entry's type is a sequence type, otherwise %FALSE |
| 633 | */ |
| 634 | gboolean |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 635 | gst_toc_entry_is_sequence (const GstTocEntry * entry) |
Tim-Philipp Müller | e11f38b | 2012-06-25 23:17:32 +0100 | [diff] [blame] | 636 | { |
| 637 | g_return_val_if_fail (entry != NULL, FALSE); |
| 638 | |
| 639 | return GST_TOC_ENTRY_TYPE_IS_SEQUENCE (entry->type); |
| 640 | } |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 641 | |
| 642 | /** |
| 643 | * gst_toc_entry_get_uid: |
| 644 | * @entry: A #GstTocEntry instance |
| 645 | * |
| 646 | * Gets the UID of @entry. |
| 647 | * |
| 648 | * Returns: (transfer none): The UID of @entry |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 649 | */ |
| 650 | const gchar * |
| 651 | gst_toc_entry_get_uid (const GstTocEntry * entry) |
| 652 | { |
| 653 | g_return_val_if_fail (entry != NULL, NULL); |
| 654 | |
| 655 | return entry->uid; |
| 656 | } |
| 657 | |
| 658 | /** |
| 659 | * gst_toc_entry_append_sub_entry: |
| 660 | * @entry: A #GstTocEntry instance |
| 661 | * @subentry: (transfer full): A #GstTocEntry |
| 662 | * |
| 663 | * Appends the #GstTocEntry @subentry to @entry. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 664 | */ |
| 665 | void |
| 666 | gst_toc_entry_append_sub_entry (GstTocEntry * entry, GstTocEntry * subentry) |
| 667 | { |
| 668 | g_return_if_fail (entry != NULL); |
| 669 | g_return_if_fail (subentry != NULL); |
| 670 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry))); |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 671 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST |
| 672 | (subentry))); |
| 673 | g_return_if_fail (subentry->toc == NULL); |
| 674 | g_return_if_fail (subentry->parent == NULL); |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 675 | |
| 676 | entry->subentries = g_list_append (entry->subentries, subentry); |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 677 | subentry->toc = entry->toc; |
| 678 | subentry->parent = entry; |
Tim-Philipp Müller | 1ba0d6f | 2012-07-09 13:12:27 +0100 | [diff] [blame] | 679 | |
| 680 | GST_LOG ("appended %s subentry with uid %s to entry %s", |
| 681 | gst_toc_entry_type_get_nick (subentry->type), subentry->uid, entry->uid); |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 682 | } |
| 683 | |
| 684 | /** |
Evan Nemerson | 823d27e | 2012-07-24 13:26:00 -0700 | [diff] [blame] | 685 | * gst_toc_entry_get_sub_entries: |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 686 | * @entry: A #GstTocEntry instance |
| 687 | * |
| 688 | * Gets the sub-entries of @entry. |
| 689 | * |
| 690 | * Returns: (transfer none) (element-type Gst.TocEntry): A #GList of #GstTocEntry of @entry |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 691 | */ |
| 692 | GList * |
| 693 | gst_toc_entry_get_sub_entries (const GstTocEntry * entry) |
| 694 | { |
| 695 | g_return_val_if_fail (entry != NULL, NULL); |
| 696 | |
| 697 | return entry->subentries; |
| 698 | } |
| 699 | |
| 700 | /** |
| 701 | * gst_toc_entry_set_tags: |
| 702 | * @entry: A #GstTocEntry instance |
| 703 | * @tags: (allow-none) (transfer full): A #GstTagList or %NULL |
| 704 | * |
| 705 | * Set a #GstTagList with tags for the complete @entry. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 706 | */ |
| 707 | void |
| 708 | gst_toc_entry_set_tags (GstTocEntry * entry, GstTagList * tags) |
| 709 | { |
| 710 | g_return_if_fail (entry != NULL); |
| 711 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry))); |
| 712 | |
| 713 | if (entry->tags) |
| 714 | gst_tag_list_unref (entry->tags); |
| 715 | entry->tags = tags; |
| 716 | } |
| 717 | |
| 718 | /** |
| 719 | * gst_toc_entry_merge_tags: |
| 720 | * @entry: A #GstTocEntry instance |
| 721 | * @tags: (allow-none): A #GstTagList or %NULL |
| 722 | * @mode: A #GstTagMergeMode |
| 723 | * |
| 724 | * Merge @tags into the existing tags of @entry using @mode. |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 725 | */ |
| 726 | void |
| 727 | gst_toc_entry_merge_tags (GstTocEntry * entry, GstTagList * tags, |
| 728 | GstTagMergeMode mode) |
| 729 | { |
| 730 | g_return_if_fail (entry != NULL); |
| 731 | g_return_if_fail (gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (entry))); |
| 732 | |
| 733 | if (!entry->tags) { |
| 734 | entry->tags = gst_tag_list_ref (tags); |
| 735 | } else { |
| 736 | GstTagList *tmp = gst_tag_list_merge (entry->tags, tags, mode); |
| 737 | gst_tag_list_unref (entry->tags); |
| 738 | entry->tags = tmp; |
| 739 | } |
| 740 | } |
| 741 | |
| 742 | /** |
| 743 | * gst_toc_entry_get_tags: |
| 744 | * @entry: A #GstTocEntry instance |
| 745 | * |
| 746 | * Gets the tags for @entry. |
| 747 | * |
| 748 | * Returns: (transfer none): A #GstTagList for @entry |
Sebastian Dröge | dfd9b60 | 2012-07-03 18:45:05 +0200 | [diff] [blame] | 749 | */ |
| 750 | GstTagList * |
| 751 | gst_toc_entry_get_tags (const GstTocEntry * entry) |
| 752 | { |
| 753 | g_return_val_if_fail (entry != NULL, NULL); |
| 754 | |
| 755 | return entry->tags; |
| 756 | } |
Tim-Philipp Müller | 1ba0d6f | 2012-07-09 13:12:27 +0100 | [diff] [blame] | 757 | |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 758 | /** |
| 759 | * gst_toc_entry_get_toc: |
| 760 | * @entry: A #GstTocEntry instance |
| 761 | * |
| 762 | * Gets the parent #GstToc of @entry. |
| 763 | * |
| 764 | * Returns: (transfer none): The parent #GstToc of @entry |
| 765 | */ |
| 766 | GstToc * |
| 767 | gst_toc_entry_get_toc (GstTocEntry * entry) |
| 768 | { |
| 769 | g_return_val_if_fail (entry != NULL, NULL); |
| 770 | |
| 771 | return entry->toc; |
| 772 | } |
| 773 | |
| 774 | /** |
| 775 | * gst_toc_entry_get_parent: |
| 776 | * @entry: A #GstTocEntry instance |
| 777 | * |
| 778 | * Gets the parent #GstTocEntry of @entry. |
| 779 | * |
Arun Raghavan | b502838 | 2017-10-22 18:05:30 +0530 | [diff] [blame] | 780 | * Returns: (transfer none) (nullable): The parent #GstTocEntry of @entry |
Sebastian Dröge | 0c5b3cc | 2012-07-11 12:45:51 +0200 | [diff] [blame] | 781 | */ |
| 782 | GstTocEntry * |
| 783 | gst_toc_entry_get_parent (GstTocEntry * entry) |
| 784 | { |
| 785 | g_return_val_if_fail (entry != NULL, NULL); |
| 786 | |
| 787 | return entry->parent; |
| 788 | } |
| 789 | |
Tim-Philipp Müller | 1ba0d6f | 2012-07-09 13:12:27 +0100 | [diff] [blame] | 790 | #ifndef GST_DISABLE_GST_DEBUG |
| 791 | static void |
| 792 | gst_toc_dump_entries (GList * entries, guint depth) |
| 793 | { |
| 794 | GList *e; |
| 795 | gchar *indent; |
| 796 | |
| 797 | indent = g_malloc0 (depth + 1); |
| 798 | memset (indent, ' ', depth); |
| 799 | for (e = entries; e != NULL; e = e->next) { |
| 800 | GstTocEntry *entry = e->data; |
| 801 | |
| 802 | GST_TRACE ("%s+ %s (%s), %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT ", " |
| 803 | "tags: %" GST_PTR_FORMAT, indent, entry->uid, |
| 804 | gst_toc_entry_type_get_nick (entry->type), |
| 805 | GST_TIME_ARGS (entry->start), GST_TIME_ARGS (entry->stop), entry->tags); |
| 806 | |
| 807 | if (entry->subentries != NULL) |
| 808 | gst_toc_dump_entries (entry->subentries, depth + 2); |
| 809 | } |
| 810 | g_free (indent); |
| 811 | } |
| 812 | #endif |
| 813 | |
| 814 | void |
| 815 | gst_toc_dump (GstToc * toc) |
| 816 | { |
| 817 | #ifndef GST_DISABLE_GST_DEBUG |
Tim-Philipp Müller | e8ab100 | 2012-07-27 23:56:54 +0100 | [diff] [blame] | 818 | GST_TRACE (" Toc %p, scope: %s, tags: %" GST_PTR_FORMAT, toc, |
| 819 | (toc->scope == GST_TOC_SCOPE_GLOBAL) ? "global" : "current", toc->tags); |
Tim-Philipp Müller | 1ba0d6f | 2012-07-09 13:12:27 +0100 | [diff] [blame] | 820 | gst_toc_dump_entries (toc->entries, 2); |
| 821 | #endif |
| 822 | } |
Sebastian Dröge | db1e442 | 2014-06-19 08:05:03 +0200 | [diff] [blame] | 823 | |
| 824 | void |
| 825 | _priv_gst_toc_initialize (void) |
| 826 | { |
| 827 | _gst_toc_type = gst_toc_get_type (); |
| 828 | _gst_toc_entry_type = gst_toc_entry_get_type (); |
| 829 | } |