diff --git a/docs/design/part-toc.txt b/docs/design/part-toc.txt deleted file mode 100644 index 73231dacf2..0000000000 --- a/docs/design/part-toc.txt +++ /dev/null @@ -1,89 +0,0 @@ -Implementing GstToc support in GStreamer elements - -1. General info about GstToc structure - -GstToc introduces a general way to handle chapters within multimedia -formats. GstToc can be represented as tree structure with arbitrary -hierarchy. Tree item can be either of two types: chapter or edition. -Chapter acts like a part of the media data, for example audio track -in CUE sheet, or part of the movie. Edition acts like some kind of -alternative way to process media content, for example DVD angles. -GstToc has one limitation on tree structure: on the same level of -hierarchy there couldn't be items of different type, i.e. you shouldn't -have editions and chapters mixed together. Here is an example of right TOC: - - ------- TOC ------- - / \ - edition1 edition2 - | | - -chapter1 -chapter3 - -chapter2 - -Here are two editions, the first contains two chapters, and the second -has only one chapter. And here is an example of invalid TOC: - - ------- TOC ------- - / \ - edition1 chapter1 - | - -chapter1 - -chapter2 - -Here you have edition1 and chapter1 mixed on the same level of hierarchy, -and such TOC will be considered broken. - -GstToc has 'entries' field of GList type which consists of children items. -Each item is of type GstTocEntry. Also GstToc has list of tags and -GstStructure called 'info'. Please, use GstToc.info and GstTocEntry.info -fields this way: create a GstStructure, put all info related to your element -there and put this structure into the 'info' field under the name of your -element. Some fields in the 'info' structure can be used for internal -purposes, so you should use it in the way described above to not to -overwrite already existent fields. - -Let's look at GstTocEntry a bit closer. One of the most important fields -is 'uid', which must be unique for each item within the TOC. This is used -to identify each item inside TOC, especially when element receives TOC -select event with UID to seek on. Field 'subentries' of type GList contains -children items of type GstTocEntry. Thus you can achieve arbitrary hierarchy -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 -item respectively. Field 'pads' of type GList contains list of GStreamer -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. - -So, a little more about managing GstToc. Use gst_toc_new() and gst_toc_free() -to create/free it. GstTocEntry can be created using gst_toc_entry_new() and -gst_toc_entry_new_with_pad(). The latter method used to create GstTocEntry -linked to particular pad. While building GstToc you can set start and 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 'entries' and 'subentries' fields. - -2. Working with GstQuery - -GstQuery with GstToc can be created using gst_query_new_toc(). Use -gst_query_set_toc() to set TOC into the query and parse it with -gst_query_parse_toc(). The 'extend_uid' parameter (0 for root level) in two -last methods should be used for TOC extending: get GstTocEntry with -gst_toc_find_entry() by given UID and use it to add your own chapters/editions. -The common action on such query is to set TOC for it. - -3. Working with GstMessage - -GstMessage with GstToc can be created using gst_message_new_toc() and parsed -with gst_message_parse_toc(). The 'updated' parameter in these methods indicates -whether the TOC was just discovered (set to false) or TOC was already found and -have been updated (set to true). The common usage for such message is to post it -to pipeline in case you have discovered TOC data within your element. - -4. Working with GstEvent - -GstToc supports select event through GstEvent infrastructure. The idea is the -following: when you receive TOC select event, parse it with -gst_event_parse_toc_select() and seek stream (if it is not streamable) for -specified TOC UID (you can use gst_toc_find_entry() to find entry in TOC by UID). -To create TOC select event use gst_event_new_toc_select(). The common action on -such event is to seek to specified UID within your element. - diff --git a/docs/gst/gstreamer-docs.sgml b/docs/gst/gstreamer-docs.sgml index deda41e720..ca969a141a 100644 --- a/docs/gst/gstreamer-docs.sgml +++ b/docs/gst/gstreamer-docs.sgml @@ -99,8 +99,6 @@ Windows. It is released under the GNU Library General Public License - - diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 0343b26aed..f6e2eb772f 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -850,12 +850,6 @@ gst_event_parse_step gst_event_new_sink_message gst_event_parse_sink_message - -gst_event_new_toc -gst_event_parse_toc - -gst_event_new_toc_select -gst_event_parse_toc_select GstEventClass GST_EVENT @@ -1303,8 +1297,6 @@ gst_message_set_qos_stats gst_message_parse_qos gst_message_parse_qos_values gst_message_parse_qos_stats -gst_message_new_toc -gst_message_parse_toc GstStructureChangeType gst_message_new_structure_change @@ -2091,9 +2083,6 @@ gst_query_new_uri gst_query_parse_uri gst_query_set_uri -gst_query_new_toc -gst_query_parse_toc -gst_query_set_toc GstQueryClass GST_QUERY @@ -2553,51 +2542,6 @@ gst_task_state_get_type -
-gsttoc -GstToc -GstToc -GstTocEntry -GstTocEntryType -gst_toc_entry_new -gst_toc_entry_new_with_pad -gst_toc_entry_free -gst_toc_new -gst_toc_free -gst_toc_entry_copy -gst_toc_copy -gst_toc_find_entry -gst_toc_entry_get_start_stop -gst_toc_entry_set_start_stop - -GST_TYPE_TOC_ENTRY_TYPE - -gst_toc_entry_type_get_type -
- - -
-gsttocsetter -GstTocSetter -GstTocSetter -GstTocSetterIFace -gst_toc_setter_get_toc -gst_toc_setter_get_toc_copy -gst_toc_setter_reset_toc -gst_toc_setter_set_toc -gst_toc_setter_get_toc_entry -gst_toc_setter_get_toc_entry_copy -gst_toc_setter_add_toc_entry - -GST_IS_TOC_SETTER -GST_TOC_SETTER -GST_TOC_SETTER_GET_IFACE -GST_TYPE_TOC_SETTER - -gst_toc_setter_get_type -
- -
gsttrace GstTrace diff --git a/gst/Makefile.am b/gst/Makefile.am index 0da40a0e45..60d4b11a02 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -98,8 +98,6 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gsttagsetter.c \ gsttask.c \ gsttaskpool.c \ - gsttoc.c \ - gsttocsetter.c \ $(GST_TRACE_SRC) \ gsttypefind.c \ gsttypefindfactory.c \ @@ -190,8 +188,6 @@ gst_headers = \ gsttagsetter.h \ gsttask.h \ gsttaskpool.h \ - gsttoc.h \ - gsttocsetter.h \ gsttrace.h \ gsttypefind.h \ gsttypefindfactory.h \ diff --git a/gst/gst.c b/gst/gst.c index c95bb8592e..ea1154aee8 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -756,7 +756,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data, g_type_class_ref (gst_search_mode_get_type ()); g_type_class_ref (gst_progress_type_get_type ()); g_type_class_ref (gst_caps_intersect_mode_get_type ()); - g_type_class_ref (gst_toc_entry_type_get_type ()); gst_structure_get_type (); _gst_value_initialize (); @@ -768,7 +767,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data, gst_buffer_list_iterator_get_type (); _gst_message_initialize (); _gst_tag_initialize (); - priv_gst_toc_initialize (); gst_parse_context_get_type (); _gst_plugin_initialize (); @@ -1126,7 +1124,6 @@ gst_deinit (void) g_type_class_unref (g_type_class_peek (gst_param_spec_fraction_get_type ())); g_type_class_unref (g_type_class_peek (gst_progress_type_get_type ())); g_type_class_unref (g_type_class_peek (gst_caps_intersect_mode_get_type ())); - g_type_class_unref (g_type_class_peek (gst_toc_entry_type_get_type ())); gst_deinitialized = TRUE; GST_INFO ("deinitialized GStreamer"); diff --git a/gst/gst.h b/gst/gst.h index 422cbfb317..35ef29035d 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -68,8 +68,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/gst/gst_private.h b/gst/gst_private.h index 31f258034b..c36a72d99d 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -54,9 +54,6 @@ extern const char g_log_domain_gstreamer[]; /* for GstElement */ #include "gstelement.h" -/* for GstToc */ -#include "gsttoc.h" - G_BEGIN_DECLS /* used by gstparse.c and grammar.y */ @@ -112,17 +109,6 @@ void _gst_query_initialize (void); void _gst_tag_initialize (void); void _gst_value_initialize (void); -void priv_gst_toc_initialize (void); - -/* TOC functions */ -/* These functions are used to parse TOC messages, events and queries */ -GstToc* priv_gst_toc_from_structure (const GstStructure *toc); -GstStructure* priv_gst_toc_to_structure (const GstToc *toc); -gboolean priv_gst_toc_structure_get_updated (const GstStructure * toc); -void priv_gst_toc_structure_set_updated (GstStructure * toc, gboolean updated); -gchar* priv_gst_toc_structure_get_extend_uid (const GstStructure * toc); -void priv_gst_toc_structure_set_extend_uid (GstStructure * toc, const gchar * extend_uid); - /* Private registry functions */ gboolean _priv_gst_registry_remove_cache_plugins (GstRegistry *registry); void _priv_gst_registry_cleanup (void); diff --git a/gst/gstevent.c b/gst/gstevent.c index fbd39a262c..d2e8d10d8e 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -114,7 +114,6 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_EOS, "eos", 0}, {GST_EVENT_NEWSEGMENT, "newsegment", 0}, {GST_EVENT_TAG, "tag", 0}, - {GST_EVENT_TOC, "toc", 0}, {GST_EVENT_BUFFERSIZE, "buffersize", 0}, {GST_EVENT_SINK_MESSAGE, "sink-message", 0}, {GST_EVENT_QOS, "qos", 0}, @@ -122,7 +121,6 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_NAVIGATION, "navigation", 0}, {GST_EVENT_LATENCY, "latency", 0}, {GST_EVENT_STEP, "step", 0}, - {GST_EVENT_TOC_SELECT, "toc-select", 0}, {GST_EVENT_CUSTOM_UPSTREAM, "custom-upstream", 0}, {GST_EVENT_CUSTOM_DOWNSTREAM, "custom-downstream", 0}, {GST_EVENT_CUSTOM_DOWNSTREAM_OOB, "custom-downstream-oob", 0}, @@ -1305,112 +1303,3 @@ gst_event_parse_sink_message (GstEvent * event, GstMessage ** msg) GST_MESSAGE (gst_value_dup_mini_object (gst_structure_id_get_value (event->structure, GST_QUARK (MESSAGE)))); } - -/** - * gst_event_new_toc: - * @toc: #GstToc structure. - * @updated: whether @toc was updated or not. - * - * Generate a TOC event from the given @toc. The purpose of the TOC event is to - * inform elements that some kind of the TOC was found. - * - * Returns: a new #GstEvent. - * - * Since: 0.10.37 - */ -GstEvent * -gst_event_new_toc (GstToc * toc, gboolean updated) -{ - GstStructure *toc_struct; - - g_return_val_if_fail (toc != NULL, NULL); - - GST_CAT_INFO (GST_CAT_EVENT, "creating toc event"); - - toc_struct = priv_gst_toc_to_structure (toc); - - if (G_LIKELY (toc_struct != NULL)) { - priv_gst_toc_structure_set_updated (toc_struct, updated); - return gst_event_new_custom (GST_EVENT_TOC, toc_struct); - } else - return NULL; -} - -/** - * gst_event_parse_toc: - * @event: a TOC event. - * @toc: (out): pointer to #GstToc structure. - * @updated: (out): pointer to store TOC updated flag. - * - * Parse a TOC @event and store the results in the given @toc and @updated locations. - * - * Since: 0.10.37 - */ -void -gst_event_parse_toc (GstEvent * event, GstToc ** toc, gboolean * updated) -{ - const GstStructure *structure; - - g_return_if_fail (event != NULL); - g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TOC); - g_return_if_fail (toc != NULL); - - structure = gst_event_get_structure (event); - *toc = priv_gst_toc_from_structure (structure); - - if (updated != NULL) - *updated = priv_gst_toc_structure_get_updated (structure); -} - -/** - * gst_event_new_toc_select: - * @uid: UID in the TOC to start playback from. - * - * Generate a TOC select event with the given @uid. The purpose of the - * TOC select event is to start playback based on the TOC's entry with the - * given @uid. - * - * Returns: a new #GstEvent. - * - * Since: 0.10.37 - */ -GstEvent * -gst_event_new_toc_select (const gchar * uid) -{ - GstStructure *structure; - - g_return_val_if_fail (uid != NULL, NULL); - - GST_CAT_INFO (GST_CAT_EVENT, "creating toc select event for UID: %s", uid); - - structure = gst_structure_id_new (GST_QUARK (EVENT_TOC_SELECT), - GST_QUARK (UID), G_TYPE_STRING, uid, NULL); - - return gst_event_new_custom (GST_EVENT_TOC_SELECT, structure); -} - -/** - * gst_event_parse_toc_select: - * @event: a TOC select event. - * @uid: (out): storage for the selection UID. - * - * Parse a TOC select @event and store the results in the given @uid location. - * - * Since: 0.10.37 - */ -void -gst_event_parse_toc_select (GstEvent * event, gchar ** uid) -{ - const GstStructure *structure; - const GValue *val; - - g_return_if_fail (event != NULL); - g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TOC_SELECT); - - structure = gst_event_get_structure (event); - val = gst_structure_id_get_value (structure, GST_QUARK (UID)); - - if (uid != NULL) - *uid = g_strdup (g_value_get_string (val)); - -} diff --git a/gst/gstevent.h b/gst/gstevent.h index 8875432985..36ae3c9f06 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -31,7 +31,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -95,8 +94,6 @@ typedef enum { * send messages that should be emitted in sync with * rendering. * Since: 0.10.26 - * @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC) - was found or updated. Since: 0.10.37 * @GST_EVENT_QOS: A quality message. Used to indicate to upstream elements * that the downstream elements should adjust their processing * rate. @@ -109,8 +106,6 @@ typedef enum { * Since: 0.10.12 * @GST_EVENT_STEP: A request for stepping through the media. Sinks will usually * execute the step operation. Since: 0.10.24 - * @GST_EVENT_TOC_SELECT: A request for a new playback position based on TOC - * entry's UID. Since 0.10.37 * @GST_EVENT_CUSTOM_UPSTREAM: Upstream custom event * @GST_EVENT_CUSTOM_DOWNSTREAM: Downstream custom event that travels in the * data flow. @@ -139,14 +134,12 @@ typedef enum { GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), - GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (10, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), /* upstream events */ GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)), GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)), GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (17, FLAG(UPSTREAM)), GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (18, FLAG(UPSTREAM)), GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (19, FLAG(UPSTREAM)), - GST_EVENT_TOC_SELECT = GST_EVENT_MAKE_TYPE (20, FLAG(UPSTREAM)), /* custom events start here */ GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (32, FLAG(UPSTREAM)), @@ -519,11 +512,6 @@ void gst_event_parse_new_segment_full (GstEvent *event, GstEvent* gst_event_new_tag (GstTagList *taglist) G_GNUC_MALLOC; void gst_event_parse_tag (GstEvent *event, GstTagList **taglist); -/* TOC event */ -GstEvent* gst_event_new_toc (GstToc *toc, gboolean updated); -void gst_event_parse_toc (GstEvent *event, GstToc **toc, gboolean *updated); - - /* buffer */ GstEvent * gst_event_new_buffer_size (GstFormat format, gint64 minsize, gint64 maxsize, gboolean async) G_GNUC_MALLOC; @@ -561,10 +549,6 @@ GstEvent* gst_event_new_step (GstFormat format, guint64 amoun void gst_event_parse_step (GstEvent *event, GstFormat *format, guint64 *amount, gdouble *rate, gboolean *flush, gboolean *intermediate); -/* TOC select event */ -GstEvent* gst_event_new_toc_select (const gchar *uid); -void gst_event_parse_toc_select (GstEvent *event, gchar **uid); - G_END_DECLS #endif /* __GST_EVENT_H__ */ diff --git a/gst/gstmessage.c b/gst/gstmessage.c index feabbf070f..423ebc2d88 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -113,7 +113,6 @@ static GstMessageQuarks message_quarks[] = { {GST_MESSAGE_STEP_START, "step-start", 0}, {GST_MESSAGE_QOS, "qos", 0}, {GST_MESSAGE_PROGRESS, "progress", 0}, - {GST_MESSAGE_TOC, "toc", 0}, {0, NULL, 0} }; @@ -2155,61 +2154,3 @@ gst_message_parse_progress (GstMessage * message, GstProgressType * type, GST_QUARK (CODE), G_TYPE_STRING, code, GST_QUARK (TEXT), G_TYPE_STRING, text, NULL); } - -/** - * gst_message_new_toc: - * @src: the object originating the message. - * @toc: #GstToc structure for the message. - * @updated: whether TOC was updated or not. - * - * Create a new TOC message. The message is posted by elements - * that discovered or updated a TOC. - * - * Returns: a new TOC message. - * - * MT safe. - * - * Since: 0.10.37 - */ -GstMessage * -gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated) -{ - GstStructure *toc_struct; - - g_return_val_if_fail (toc != NULL, NULL); - - toc_struct = priv_gst_toc_to_structure (toc); - - if (G_LIKELY (toc_struct != NULL)) { - priv_gst_toc_structure_set_updated (toc_struct, updated); - return gst_message_new_custom (GST_MESSAGE_TOC, src, toc_struct); - } else - return NULL; -} - -/** - * gst_message_parse_toc: - * @message: a valid #GstMessage of type GST_MESSAGE_TOC. - * @toc: (out): return location for the TOC. - * @updated: (out): return location for the updated flag. - * - * Extract the TOC from the #GstMessage. The TOC returned in the - * output argument is a copy; the caller must free it with - * gst_toc_free() when done. - * - * MT safe. - * - * Since: 0.10.37 - */ -void -gst_message_parse_toc (GstMessage * message, GstToc ** toc, gboolean * updated) -{ - g_return_if_fail (GST_IS_MESSAGE (message)); - g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TOC); - g_return_if_fail (toc != NULL); - - *toc = priv_gst_toc_from_structure (message->structure); - - if (updated != NULL) - *updated = priv_gst_toc_structure_get_updated (message->structure); -} diff --git a/gst/gstmessage.h b/gst/gstmessage.h index 0e7ac6bce2..8229f842b9 100644 --- a/gst/gstmessage.h +++ b/gst/gstmessage.h @@ -89,8 +89,6 @@ typedef struct _GstMessageClass GstMessageClass; * @GST_MESSAGE_QOS: A buffer was dropped or an element changed its processing * strategy for Quality of Service reasons. Since: 0.10.29 * @GST_MESSAGE_PROGRESS: A progress message. Since: 0.10.33 - * @GST_MESSAGE_TOC: A new table of contents (TOC) was found or previously found TOC - * was updated. Since: 0.10.37 * @GST_MESSAGE_ANY: mask for all of the above messages. * * The different message types that are available. @@ -127,7 +125,6 @@ typedef enum GST_MESSAGE_STEP_START = (1 << 23), GST_MESSAGE_QOS = (1 << 24), GST_MESSAGE_PROGRESS = (1 << 25), - GST_MESSAGE_TOC = (1 << 26), GST_MESSAGE_ANY = ~0 } GstMessageType; @@ -136,7 +133,6 @@ typedef enum #include #include #include -#include /** * GST_MESSAGE_TRACE_NAME: @@ -526,10 +522,6 @@ GstMessage * gst_message_new_progress (GstObject * src, GstProgress void gst_message_parse_progress (GstMessage * message, GstProgressType * type, gchar ** code, gchar ** text); -/* TOC */ -GstMessage * gst_message_new_toc (GstObject *src, GstToc *toc, gboolean updated); -void gst_message_parse_toc (GstMessage *message, GstToc **toc, gboolean *updated); - /* custom messages */ GstMessage * gst_message_new_custom (GstMessageType type, GstObject * src, diff --git a/gst/gstquark.c b/gst/gstquark.c index f8b54da076..91a201271d 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -50,7 +50,7 @@ static const gchar *_quark_strings[] = { "intermediate", "GstMessageStepStart", "active", "eos", "sink-message", "message", "GstMessageQOS", "running-time", "stream-time", "jitter", "quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress", - "code", "text", "percent", "timeout", "toc-select", "uid" + "code", "text", "percent", "timeout" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquark.h b/gst/gstquark.h index b3cfb459a4..eec5ac1934 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -132,10 +132,7 @@ typedef enum _GstQuarkId GST_QUARK_TEXT = 103, GST_QUARK_PERCENT = 104, GST_QUARK_TIMEOUT = 105, - GST_QUARK_EVENT_TOC_SELECT = 106, - GST_QUARK_UID = 107, - - GST_QUARK_MAX = 108 + GST_QUARK_MAX = 106 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquery.c b/gst/gstquery.c index 84a8809ea9..d9c48f8b91 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -101,7 +101,6 @@ static GstQueryTypeDefinition standard_definitions[] = { {GST_QUERY_BUFFERING, "buffering", "Buffering status", 0}, {GST_QUERY_CUSTOM, "custom", "Custom query", 0}, {GST_QUERY_URI, "uri", "URI of the source or sink", 0}, - {GST_QUERY_TOC, "toc", "Full table of contents", 0}, {GST_QUERY_NONE, NULL, NULL, 0} }; @@ -1496,94 +1495,3 @@ gst_query_parse_uri (GstQuery * query, gchar ** uri) *uri = g_value_dup_string (gst_structure_id_get_value (query->structure, GST_QUARK (URI))); } - -/** - * gst_query_new_toc: - * - * Constructs a new query TOC query object. Use gst_query_unref() - * when done with it. A TOC query is used to query the full TOC with - * the UID marker for TOC extending (to insert some new entries). - * - * Returns: A #GstQuery. - * - * Since: 0.10.37 - */ -GstQuery * -gst_query_new_toc (void) -{ - GstQuery *query; - - query = gst_query_new (GST_QUERY_TOC, NULL); - - return query; -} - -/** - * gst_query_set_toc: - * @query: a #GstQuery with query type GST_QUERY_TOC. - * @toc: the GstToc to set. - * @extend_uid: UID which can be used for TOC extending (may be NULL), - * 0 means root TOC level. - * - * Answer a TOC query by setting appropriate #GstToc structure. - * - * Since: 0.10.37 - */ -void -gst_query_set_toc (GstQuery * query, GstToc * toc, const gchar * extend_uid) -{ - GstStructure *structure; - - g_return_if_fail (query != NULL); - g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_TOC); - g_return_if_fail (toc != NULL); - - structure = priv_gst_toc_to_structure (toc); - - g_return_if_fail (structure != NULL); - - /* that shouldn't be happen in normal usage */ - if (query->structure != NULL) - gst_structure_free (query->structure); - - if (extend_uid != NULL) - priv_gst_toc_structure_set_extend_uid (structure, extend_uid); - - query->structure = structure; - gst_structure_set_parent_refcount (query->structure, - &(query->mini_object.refcount)); -} - -/** - * gst_query_parse_toc: - * @query: a #GstQuery. - * @toc: (out): the storage for the received TOC (may be NULL). - * @extend_uid: (out): the storage for the received extend UID marker (may be NULL), - * 0 means root TOC level. - * - * Parse a TOC query, writing the TOC into @toc as a newly - * allocated #GstToc and extend UID into @extend_uid, if the respective parameters - * are non-NULL. Use @extend_uid value to insert new entries into the TOC (@extend_uid will - * act as root entry for newly inserted entries). - * Free @toc with gst_toc_free() and @extend_uid with g_free() after usage. - * - * Since: 0.10.37 - */ -void -gst_query_parse_toc (GstQuery * query, GstToc ** toc, gchar ** extend_uid) -{ - const GstStructure *structure; - - g_return_if_fail (query != NULL); - g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_TOC); - - structure = gst_query_get_structure (query); - - g_return_if_fail (structure != NULL); - - if (toc != NULL) - *toc = priv_gst_toc_from_structure (structure); - - if (extend_uid != NULL) - *extend_uid = priv_gst_toc_structure_get_extend_uid (structure); -} diff --git a/gst/gstquery.h b/gst/gstquery.h index 9a1a0f91c2..2166537ef2 100644 --- a/gst/gstquery.h +++ b/gst/gstquery.h @@ -51,8 +51,6 @@ G_BEGIN_DECLS * @GST_QUERY_CUSTOM: a custom application or element defined query. Since * 0.10.22. * @GST_QUERY_URI: query the URI of the source or sink. Since 0.10.22. - * @GST_QUERY_TOC: query the full table of contents (TOC) with the marker - * for an entry which can be used to extend received TOC. Since 0.10.37. * * Standard predefined Query types */ @@ -71,8 +69,7 @@ typedef enum { GST_QUERY_FORMATS, GST_QUERY_BUFFERING, GST_QUERY_CUSTOM, - GST_QUERY_URI, - GST_QUERY_TOC + GST_QUERY_URI } GstQueryType; /** @@ -339,11 +336,6 @@ GstQuery * gst_query_new_uri (void) G_GNUC_MALLOC; void gst_query_parse_uri (GstQuery *query, gchar **uri); void gst_query_set_uri (GstQuery *query, const gchar *uri); -/* TOC query */ -GstQuery * gst_query_new_toc (void); -void gst_query_set_toc (GstQuery *query, GstToc *toc, const gchar *extend_uid); -void gst_query_parse_toc (GstQuery *query, GstToc **toc, gchar **extend_uid); - G_END_DECLS #endif /* __GST_QUERY_H__ */ diff --git a/gst/gsttoc.c b/gst/gsttoc.c deleted file mode 100644 index c997c225ea..0000000000 --- a/gst/gsttoc.c +++ /dev/null @@ -1,1038 +0,0 @@ -/* GStreamer - * (c) 2010, 2012 Alexander Saprykin - * - * gsttoc.c: GstToc initialization and parsing/creation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:gsttoc - * @short_description: Generic table of contents support - * @see_also: #GstStructure, #GstEvent, #GstMessage, #GstQuery, #GstPad - * - * #GstToc functions are used to create/free #GstToc and #GstTocEntry structures. - * Also they are used to convert #GstToc into #GstStructure and vice versa. - * - * #GstToc lets you to inform other elements in pipeline or application that playing - * source has some kind of table of contents (TOC). These may be chapters, editions, - * angles or other types. For example: DVD chapters, Matroska chapters or cue sheet - * TOC. Such TOC will be useful for applications to display instead of just a - * playlist. - * - * Using TOC is very easy. Firstly, create #GstToc structure which represents root - * contents of the source. You can also attach TOC-specific tags to it. Then fill - * it with #GstTocEntry entries by appending them to #GstToc.entries #GstTocEntry.subentries - * lists. You should use GST_TOC_ENTRY_TYPE_CHAPTER for generic TOC entry and - * GST_TOC_ENTRY_TYPE_EDITION for the entries which are considered to be alternatives - * (like DVD angles, Matroska editions and so on). - * - * Note that root level of the TOC can contain only either editions or chapters. You - * should not mix them together at the same level. Otherwise you will get serialization - * /deserialization errors. Make sure that no one of the entries has negative start and - * stop values. - * - * Please, use #GstToc.info and #GstTocEntry.info fields in that way: create a #GstStructure, - * put all info related to your element there and put this structure into the info field under - * the name of your element. Some fields in the info structure can be used for internal purposes, - * so you should use it in the way described above to not to overwrite already existent fields. - * - * Use gst_event_new_toc() to create a new TOC #GstEvent, and gst_event_parse_toc() to - * parse received TOC event. Use gst_event_new_toc_select() to create a new TOC select #GstEvent, - * and gst_event_parse_toc_select() to parse received TOC select event. The same rule for - * the #GstMessage: gst_message_new_toc() to create new TOC #GstMessage, and - * gst_message_parse_toc() to parse received TOC message. Also you can create a new TOC query - * with gst_query_new_toc(), set it with gst_query_set_toc() and parse it with - * gst_query_parse_toc(). - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gst_private.h" -#include "gstenumtypes.h" -#include "gsttaglist.h" -#include "gststructure.h" -#include "gstvalue.h" -#include "gsttoc.h" -#include "gstpad.h" - -#define GST_TOC_TOC_NAME "toc" -#define GST_TOC_ENTRY_NAME "entry" - -#define GST_TOC_TOC_UPDATED_FIELD "updated" -#define GST_TOC_TOC_EXTENDUID_FIELD "extenduid" -#define GST_TOC_INFO_FIELD "info" - -#define GST_TOC_ENTRY_UID_FIELD "uid" -#define GST_TOC_ENTRY_TYPE_FIELD "type" -#define GST_TOC_ENTRY_TAGS_FIELD "tags" - -#define GST_TOC_TOC_ENTRIES_FIELD "subentries" - -#define GST_TOC_INFO_NAME "info-structure" -#define GST_TOC_INFO_TIME_FIELD "time" - -#define GST_TOC_TIME_NAME "time-structure" -#define GST_TOC_TIME_START_FIELD "start" -#define GST_TOC_TIME_STOP_FIELD "stop" - - -enum -{ - GST_TOC_TOC = 0, - GST_TOC_ENTRY = 1, - GST_TOC_UPDATED = 2, - GST_TOC_EXTENDUID = 3, - GST_TOC_UID = 4, - GST_TOC_TYPE = 5, - GST_TOC_TAGS = 6, - GST_TOC_SUBENTRIES = 7, - GST_TOC_INFO = 8, - GST_TOC_INFONAME = 9, - GST_TOC_TIME = 10, - GST_TOC_TIMENAME = 11, - GST_TOC_TIME_START = 12, - GST_TOC_TIME_STOP = 13, - GST_TOC_LAST = 14 -}; - -static GQuark gst_toc_fields[GST_TOC_LAST] = { 0 }; - -void -priv_gst_toc_initialize (void) -{ - static gboolean inited = FALSE; - - if (G_LIKELY (!inited)) { - gst_toc_fields[GST_TOC_TOC] = g_quark_from_static_string (GST_TOC_TOC_NAME); - gst_toc_fields[GST_TOC_ENTRY] = - g_quark_from_static_string (GST_TOC_ENTRY_NAME); - - gst_toc_fields[GST_TOC_UPDATED] = - g_quark_from_static_string (GST_TOC_TOC_UPDATED_FIELD); - gst_toc_fields[GST_TOC_EXTENDUID] = - g_quark_from_static_string (GST_TOC_TOC_EXTENDUID_FIELD); - gst_toc_fields[GST_TOC_INFO] = - g_quark_from_static_string (GST_TOC_INFO_FIELD); - - gst_toc_fields[GST_TOC_UID] = - g_quark_from_static_string (GST_TOC_ENTRY_UID_FIELD); - gst_toc_fields[GST_TOC_TYPE] = - g_quark_from_static_string (GST_TOC_ENTRY_TYPE_FIELD); - gst_toc_fields[GST_TOC_TAGS] = - g_quark_from_static_string (GST_TOC_ENTRY_TAGS_FIELD); - - gst_toc_fields[GST_TOC_SUBENTRIES] = - g_quark_from_static_string (GST_TOC_TOC_ENTRIES_FIELD); - - gst_toc_fields[GST_TOC_INFONAME] = - g_quark_from_static_string (GST_TOC_INFO_NAME); - gst_toc_fields[GST_TOC_TIME] = - g_quark_from_static_string (GST_TOC_INFO_TIME_FIELD); - gst_toc_fields[GST_TOC_TIMENAME] = - g_quark_from_static_string (GST_TOC_TIME_NAME); - gst_toc_fields[GST_TOC_TIME_START] = - g_quark_from_static_string (GST_TOC_TIME_START_FIELD); - gst_toc_fields[GST_TOC_TIME_STOP] = - g_quark_from_static_string (GST_TOC_TIME_STOP_FIELD); - - inited = TRUE; - } -} - -/** - * gst_toc_new: - * - * Create new #GstToc structure. - * - * Returns: newly allocated #GstToc structure, free it with gst_toc_free(). - * - * Since: 0.10.37 - */ -GstToc * -gst_toc_new (void) -{ - GstToc *toc; - - toc = g_slice_new0 (GstToc); - toc->tags = gst_tag_list_new (); - toc->info = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_INFONAME]); - - return toc; -} - -/** - * gst_toc_entry_new: - * @type: entry type. - * @uid: unique ID (UID) in the whole TOC. - * - * Create new #GstTocEntry structure. - * - * Returns: newly allocated #GstTocEntry structure, free it with gst_toc_entry_free(). - * - * Since: 0.10.37 - */ -GstTocEntry * -gst_toc_entry_new (GstTocEntryType type, const gchar * uid) -{ - GstTocEntry *entry; - - g_return_val_if_fail (uid != NULL, NULL); - - entry = g_slice_new0 (GstTocEntry); - entry->uid = g_strdup (uid); - entry->type = type; - entry->tags = gst_tag_list_new (); - entry->info = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_INFONAME]); - - return entry; -} - -/** - * 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_free() - * when done. - * - * Since: 0.10.37 - */ -GstTocEntry * -gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar * uid, - gpointer pad) -{ - GstTocEntry *entry; - - g_return_val_if_fail (uid != NULL, NULL); - - entry = g_slice_new0 (GstTocEntry); - entry->uid = g_strdup (uid); - entry->type = type; - entry->tags = gst_tag_list_new (); - entry->info = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_INFONAME]); - - if (pad != NULL && GST_IS_PAD (pad)) - entry->pads = g_list_append (entry->pads, gst_object_ref (pad)); - - return entry; -} - -/** - * gst_toc_free: - * @toc: #GstToc structure to free. - * - * Free unused #GstToc structure. - * - * Since: 0.10.37 - */ -void -gst_toc_free (GstToc * toc) -{ - g_return_if_fail (toc != NULL); - - g_list_foreach (toc->entries, (GFunc) gst_toc_entry_free, NULL); - g_list_free (toc->entries); - - if (toc->tags != NULL) - gst_tag_list_free (toc->tags); - - if (toc->info != NULL) - gst_structure_free (toc->info); - - g_slice_free (GstToc, toc); -} - -/** - * gst_toc_entry_free: - * @entry: #GstTocEntry structure to free. - * - * Free unused #GstTocEntry structure. Note that #GstTocEntry.uid will - * be freed with g_free() and all #GstPad objects in the #GstTocEntry.pads - * list will be unrefed with gst_object_unref(). - * - * Since: 0.10.37 - */ -void -gst_toc_entry_free (GstTocEntry * entry) -{ - GList *cur; - - g_return_if_fail (entry != NULL); - - g_list_foreach (entry->subentries, (GFunc) gst_toc_entry_free, NULL); - g_list_free (entry->subentries); - - g_free (entry->uid); - - if (entry->tags != NULL) - gst_tag_list_free (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); -} - -static GstStructure * -gst_toc_structure_new (GstTagList * tags, GstStructure * info) -{ - GstStructure *ret; - GValue val = { 0 }; - - ret = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_TOC]); - - if (tags != NULL) { - g_value_init (&val, GST_TYPE_STRUCTURE); - gst_value_set_structure (&val, GST_STRUCTURE (tags)); - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_TAGS], &val); - g_value_unset (&val); - } - - if (info != NULL) { - g_value_init (&val, GST_TYPE_STRUCTURE); - gst_value_set_structure (&val, info); - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_INFO], &val); - g_value_unset (&val); - } - - return ret; -} - -static GstStructure * -gst_toc_entry_structure_new (GstTocEntryType type, const gchar * uid, - GstTagList * tags, GstStructure * info) -{ - GValue val = { 0 }; - GstStructure *ret; - - ret = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_ENTRY]); - - gst_structure_id_set (ret, gst_toc_fields[GST_TOC_TYPE], - GST_TYPE_TOC_ENTRY_TYPE, type, NULL); - - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, uid); - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_UID], &val); - g_value_unset (&val); - - if (tags != NULL) { - g_value_init (&val, GST_TYPE_STRUCTURE); - gst_value_set_structure (&val, GST_STRUCTURE (tags)); - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_TAGS], &val); - g_value_unset (&val); - } - - if (info != NULL) { - g_value_init (&val, GST_TYPE_STRUCTURE); - gst_value_set_structure (&val, info); - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_INFO], &val); - g_value_unset (&val); - } - - return ret; -} - -static guint -gst_toc_entry_structure_n_subentries (const GstStructure * entry) -{ - if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY))) - return 0; - else - return gst_value_array_get_size ((gst_structure_id_get_value (entry, - gst_toc_fields[GST_TOC_SUBENTRIES]))); -} - -static const GstStructure * -gst_toc_entry_structure_nth_subentry (const GstStructure * entry, guint nth) -{ - guint count; - const GValue *array; - - count = gst_toc_entry_structure_n_subentries (entry); - - if (count < nth) - return NULL; - - if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY))) - return NULL; - else { - array = - gst_value_array_get_value (gst_structure_id_get_value (entry, - gst_toc_fields[GST_TOC_SUBENTRIES]), nth); - return gst_value_get_structure (array); - } -} - -static GstTocEntry * -gst_toc_entry_from_structure (const GstStructure * entry, guint level) -{ - GstTocEntry *ret, *subentry; - const GValue *val; - const GstStructure *subentry_struct; - GstTagList *list; - GstStructure *st; - gint count, i; - const gchar *uid; - guint chapters_count = 0, editions_count = 0; - - g_return_val_if_fail (entry != NULL, NULL); - g_return_val_if_fail (gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_UID], G_TYPE_STRING), NULL); - g_return_val_if_fail (gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_TYPE], GST_TYPE_TOC_ENTRY_TYPE), NULL); - - val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_UID]); - uid = g_value_get_string (val); - - ret = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid); - - gst_structure_get_enum (entry, GST_TOC_ENTRY_TYPE_FIELD, - GST_TYPE_TOC_ENTRY_TYPE, (gint *) & (ret->type)); - - if (gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)) { - count = gst_toc_entry_structure_n_subentries (entry); - - for (i = 0; i < count; ++i) { - subentry_struct = gst_toc_entry_structure_nth_subentry (entry, i); - subentry = gst_toc_entry_from_structure (subentry_struct, level + 1); - - /* skip empty editions */ - if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION - && subentry->subentries == NULL)) { - g_warning - ("Empty edition found while deserializing TOC from GstStructure, skipping"); - continue; - } - - if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION) - ++editions_count; - else - ++chapters_count; - - /* check for mixed content */ - if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) { - g_critical - ("Mixed editions and chapters in the TOC contents, the TOC is broken"); - gst_toc_entry_free (subentry); - gst_toc_entry_free (ret); - return NULL; - } - - if (G_UNLIKELY (subentry == NULL)) { - gst_toc_entry_free (ret); - return NULL; - } - - ret->subentries = g_list_prepend (ret->subentries, subentry); - } - - ret->subentries = g_list_reverse (ret->subentries); - } - - if (gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_TAGS], GST_TYPE_STRUCTURE)) { - val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_TAGS]); - - if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) { - list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val))); - gst_tag_list_free (ret->tags); - ret->tags = list; - } - } - - if (gst_structure_id_has_field_typed (entry, - gst_toc_fields[GST_TOC_INFO], GST_TYPE_STRUCTURE)) { - val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_INFO]); - - if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) { - st = gst_structure_copy (gst_value_get_structure (val)); - gst_structure_free (ret->info); - ret->info = st; - } - } - - return ret; -} - -GstToc * -priv_gst_toc_from_structure (const GstStructure * toc) -{ - GstToc *ret; - GstTocEntry *subentry; - const GstStructure *subentry_struct; - const GValue *val; - GstTagList *list; - GstStructure *st; - guint count, i; - guint editions_count = 0, chapters_count = 0; - - g_return_val_if_fail (toc != NULL, NULL); - - ret = gst_toc_new (); - - if (gst_structure_id_has_field_typed (toc, - gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)) { - count = gst_toc_entry_structure_n_subentries (toc); - - for (i = 0; i < count; ++i) { - subentry_struct = gst_toc_entry_structure_nth_subentry (toc, i); - subentry = gst_toc_entry_from_structure (subentry_struct, 0); - - /* skip empty editions */ - if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION - && subentry->subentries == NULL)) { - g_warning - ("Empty edition found while deserializing TOC from GstStructure, skipping"); - continue; - } - - /* check for success */ - if (G_UNLIKELY (subentry == NULL)) { - g_critical ("Couldn't serialize deserializing TOC from GstStructure"); - gst_toc_free (ret); - return NULL; - } - - if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION) - ++editions_count; - else - ++chapters_count; - - /* check for mixed content */ - if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) { - g_critical - ("Mixed editions and chapters in the TOC contents, the TOC is broken"); - gst_toc_entry_free (subentry); - gst_toc_free (ret); - return NULL; - } - - ret->entries = g_list_prepend (ret->entries, subentry); - } - - ret->entries = g_list_reverse (ret->entries); - } - - if (gst_structure_id_has_field_typed (toc, - gst_toc_fields[GST_TOC_TAGS], GST_TYPE_STRUCTURE)) { - val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_TAGS]); - - if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) { - list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val))); - gst_tag_list_free (ret->tags); - ret->tags = list; - } - } - - if (gst_structure_id_has_field_typed (toc, - gst_toc_fields[GST_TOC_INFO], GST_TYPE_STRUCTURE)) { - val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_INFO]); - - if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) { - st = gst_structure_copy (gst_value_get_structure (val)); - gst_structure_free (ret->info); - ret->info = st; - } - } - - if (G_UNLIKELY (ret->entries == NULL)) { - gst_toc_free (ret); - return NULL; - } - - return ret; -} - -static GstStructure * -gst_toc_entry_to_structure (const GstTocEntry * entry, guint level) -{ - GstStructure *ret, *subentry_struct; - GstTocEntry *subentry; - GList *cur; - GValue subentries_val = { 0 }; - GValue entry_val = { 0 }; - guint chapters_count = 0, editions_count = 0; - - g_return_val_if_fail (entry != NULL, NULL); - - ret = - gst_toc_entry_structure_new (entry->type, entry->uid, entry->tags, - entry->info); - - g_value_init (&subentries_val, GST_TYPE_ARRAY); - g_value_init (&entry_val, GST_TYPE_STRUCTURE); - - cur = entry->subentries; - while (cur != NULL) { - subentry = cur->data; - - if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION) - ++editions_count; - else - ++chapters_count; - - /* check for mixed content */ - if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) { - g_critical - ("Mixed editions and chapters in the TOC contents, the TOC is broken"); - gst_structure_free (ret); - g_value_unset (&entry_val); - g_value_unset (&subentries_val); - return NULL; - } - - /* skip empty editions */ - if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION - && subentry->subentries == NULL)) { - g_warning - ("Empty edition found while serializing TOC to GstStructure, skipping"); - cur = cur->next; - continue; - } - - subentry_struct = gst_toc_entry_to_structure (subentry, level + 1); - - /* check for success */ - if (G_UNLIKELY (subentry_struct == NULL)) { - gst_structure_free (ret); - g_value_unset (&subentries_val); - g_value_unset (&entry_val); - return NULL; - } - - /* skip empty editions */ - if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION - && subentry->subentries == NULL)) { - g_warning - ("Empty edition found while serializing TOC to GstStructure, skipping"); - cur = cur->next; - continue; - } - - gst_value_set_structure (&entry_val, subentry_struct); - gst_value_array_append_value (&subentries_val, &entry_val); - gst_structure_free (subentry_struct); - - cur = cur->next; - } - - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_SUBENTRIES], - &subentries_val); - - g_value_unset (&subentries_val); - g_value_unset (&entry_val); - return ret; -} - -GstStructure * -priv_gst_toc_to_structure (const GstToc * toc) -{ - GValue val = { 0 }; - GValue subentries_val = { 0 }; - GstStructure *ret, *subentry_struct; - GstTocEntry *subentry; - GList *cur; - guint editions_count = 0, chapters_count = 0; - - g_return_val_if_fail (toc != NULL, NULL); - g_return_val_if_fail (toc->entries != NULL, NULL); - - ret = gst_toc_structure_new (toc->tags, toc->info); - - g_value_init (&val, GST_TYPE_STRUCTURE); - g_value_init (&subentries_val, GST_TYPE_ARRAY); - cur = toc->entries; - - while (cur != NULL) { - subentry = cur->data; - - if (subentry->type == GST_TOC_ENTRY_TYPE_EDITION) - ++editions_count; - else - ++chapters_count; - - /* check for mixed content */ - if (G_UNLIKELY (chapters_count > 0 && editions_count > 0)) { - g_critical - ("Mixed editions and chapters in the TOC contents, the TOC is broken"); - gst_structure_free (ret); - g_value_unset (&val); - g_value_unset (&subentries_val); - return NULL; - } - - /* skip empty editions */ - if (G_UNLIKELY (subentry->type == GST_TOC_ENTRY_TYPE_EDITION - && subentry->subentries == NULL)) { - g_warning - ("Empty edition found while serializing TOC to GstStructure, skipping"); - cur = cur->next; - continue; - } - - subentry_struct = gst_toc_entry_to_structure (subentry, 0); - - /* check for success */ - if (G_UNLIKELY (subentry_struct == NULL)) { - g_critical ("Couldn't serialize TOC to GstStructure"); - gst_structure_free (ret); - g_value_unset (&val); - g_value_unset (&subentries_val); - return NULL; - } - - gst_value_set_structure (&val, subentry_struct); - gst_value_array_append_value (&subentries_val, &val); - gst_structure_free (subentry_struct); - - cur = cur->next; - } - - gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_SUBENTRIES], - &subentries_val); - - g_value_unset (&val); - g_value_unset (&subentries_val); - return ret; -} - -static gboolean -gst_toc_check_entry_for_uid (const GstTocEntry * entry, const gchar * uid) -{ - GList *cur; - - g_return_val_if_fail (entry != NULL, FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - - if (g_strcmp0 (entry->uid, uid) == 0) - return TRUE; - - cur = entry->subentries; - while (cur != NULL) { - if (gst_toc_check_entry_for_uid (cur->data, uid)) - return TRUE; - cur = cur->next; - } - - return FALSE; -} - -/** - * gst_toc_find_entry: - * @toc: #GstToc to search in. - * @uid: UID to find #GstTocEntry with. - * - * Find #GstTocEntry with given @uid in the @toc. - * - * Returns: #GstTocEntry with specified @uid from the @toc, or NULL if not found. - * - * Since: 0.10.37 - */ -GstTocEntry * -gst_toc_find_entry (const GstToc * toc, const gchar * uid) -{ - GList *cur; - - g_return_val_if_fail (toc != NULL, NULL); - g_return_val_if_fail (uid != NULL, NULL); - - cur = toc->entries; - while (cur != NULL) { - if (gst_toc_check_entry_for_uid (cur->data, uid)) - return cur->data; - cur = cur->next; - } - - return NULL; -} - -/** - * gst_toc_entry_copy: - * @entry: #GstTocEntry to copy. - * - * Copy #GstTocEntry with all subentries (deep copy). - * - * Returns: newly allocated #GstTocEntry in case of success, NULL otherwise; - * free it when done with gst_toc_entry_free(). - * - * Since: 0.10.37 - */ -GstTocEntry * -gst_toc_entry_copy (const GstTocEntry * entry) -{ - GstTocEntry *ret, *sub; - GList *cur; - GstTagList *list; - GstStructure *st; - - g_return_val_if_fail (entry != NULL, NULL); - - ret = gst_toc_entry_new (entry->type, entry->uid); - - if (GST_IS_STRUCTURE (entry->info)) { - st = gst_structure_copy (entry->info); - gst_structure_free (ret->info); - ret->info = st; - } - - if (GST_IS_TAG_LIST (entry->tags)) { - list = gst_tag_list_copy (entry->tags); - gst_tag_list_free (ret->tags); - 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; - while (cur != NULL) { - sub = gst_toc_entry_copy (cur->data); - - if (sub != NULL) - ret->subentries = g_list_prepend (ret->subentries, sub); - - cur = cur->next; - } - ret->subentries = g_list_reverse (ret->subentries); - - return ret; -} - -/** - * gst_toc_copy: - * @toc: #GstToc to copy. - * - * Copy #GstToc with all subentries (deep copy). - * - * Returns: newly allocated #GstToc in case of success, NULL otherwise; - * free it when done with gst_toc_free(). - * - * Since: 0.10.37 - */ -GstToc * -gst_toc_copy (const GstToc * toc) -{ - GstToc *ret; - GstTocEntry *entry; - GList *cur; - GstTagList *list; - GstStructure *st; - - g_return_val_if_fail (toc != NULL, NULL); - - 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)) { - list = gst_tag_list_copy (toc->tags); - gst_tag_list_free (ret->tags); - ret->tags = list; - } - - cur = toc->entries; - while (cur != NULL) { - entry = gst_toc_entry_copy (cur->data); - - if (entry != NULL) - ret->entries = g_list_prepend (ret->entries, entry); - - cur = cur->next; - } - ret->entries = g_list_reverse (ret->entries); - - return ret; -} - -/** - * gst_toc_entry_set_start_stop: - * @entry: #GstTocEntry to set values. - * @start: start value to set. - * @stop: stop value to set. - * - * Set @start and @stop values for the @entry. - * - * Since: 0.10.37 - */ -void -gst_toc_entry_set_start_stop (GstTocEntry * entry, gint64 start, gint64 stop) -{ - const GValue *val; - GstStructure *structure = 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_toc_fields[GST_TOC_TIME], GST_TYPE_STRUCTURE)) { - val = - gst_structure_id_get_value (entry->info, gst_toc_fields[GST_TOC_TIME]); - structure = gst_structure_copy (gst_value_get_structure (val)); - } - - if (structure == NULL) - structure = gst_structure_id_empty_new (gst_toc_fields[GST_TOC_TIMENAME]); - - gst_structure_id_set (structure, gst_toc_fields[GST_TOC_TIME_START], - G_TYPE_INT64, start, gst_toc_fields[GST_TOC_TIME_STOP], G_TYPE_INT64, - stop, NULL); - - gst_structure_id_set (entry->info, gst_toc_fields[GST_TOC_TIME], - GST_TYPE_STRUCTURE, structure, NULL); - - gst_structure_free (structure); -} - -/** - * gst_toc_entry_get_start_stop: - * @entry: #GstTocEntry to get values from. - * @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. - * - * Get start and stop values from the @entry and write them into appropriate storages. - * - * Returns: TRUE if all non-NULL storage pointers were filled with appropriate values, - * FALSE otherwise. - * - * Since: 0.10.37 - */ -gboolean -gst_toc_entry_get_start_stop (const GstTocEntry * entry, gint64 * start, - gint64 * stop) -{ - gboolean ret = TRUE; - const GValue *val; - const GstStructure *structure; - - 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, - gst_toc_fields[GST_TOC_TIME], GST_TYPE_STRUCTURE)) - return FALSE; - - val = gst_structure_id_get_value (entry->info, gst_toc_fields[GST_TOC_TIME]); - structure = gst_value_get_structure (val); - - if (start != NULL) { - if (gst_structure_id_has_field_typed (structure, - gst_toc_fields[GST_TOC_TIME_START], G_TYPE_INT64)) - *start = - g_value_get_int64 (gst_structure_id_get_value (structure, - gst_toc_fields[GST_TOC_TIME_START])); - else - ret = FALSE; - } - - if (stop != NULL) { - if (gst_structure_id_has_field_typed (structure, - gst_toc_fields[GST_TOC_TIME_STOP], G_TYPE_INT64)) - *stop = - g_value_get_int64 (gst_structure_id_get_value (structure, - gst_toc_fields[GST_TOC_TIME_STOP])); - else - ret = FALSE; - } - - return ret; -} - -gboolean -priv_gst_toc_structure_get_updated (const GstStructure * toc) -{ - const GValue *val; - - g_return_val_if_fail (GST_IS_STRUCTURE (toc), FALSE); - - if (G_LIKELY (gst_structure_id_has_field_typed (toc, - gst_toc_fields[GST_TOC_UPDATED], G_TYPE_BOOLEAN))) { - val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_UPDATED]); - return g_value_get_boolean (val); - } - - return FALSE; -} - -void -priv_gst_toc_structure_set_updated (GstStructure * toc, gboolean updated) -{ - GValue val = { 0 }; - - g_return_if_fail (toc != NULL); - - g_value_init (&val, G_TYPE_BOOLEAN); - g_value_set_boolean (&val, updated); - gst_structure_id_set_value (toc, gst_toc_fields[GST_TOC_UPDATED], &val); - g_value_unset (&val); -} - -gchar * -priv_gst_toc_structure_get_extend_uid (const GstStructure * toc) -{ - const GValue *val; - - g_return_val_if_fail (GST_IS_STRUCTURE (toc), NULL); - - if (G_LIKELY (gst_structure_id_has_field_typed (toc, - gst_toc_fields[GST_TOC_EXTENDUID], G_TYPE_STRING))) { - val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_EXTENDUID]); - return g_strdup (g_value_get_string (val)); - } - - return NULL; -} - -void -priv_gst_toc_structure_set_extend_uid (GstStructure * toc, - const gchar * extend_uid) -{ - GValue val = { 0 }; - - g_return_if_fail (toc != NULL); - g_return_if_fail (extend_uid != NULL); - - g_value_init (&val, G_TYPE_STRING); - g_value_set_string (&val, extend_uid); - gst_structure_id_set_value (toc, gst_toc_fields[GST_TOC_EXTENDUID], &val); - g_value_unset (&val); -} diff --git a/gst/gsttoc.h b/gst/gsttoc.h deleted file mode 100644 index a817efecfe..0000000000 --- a/gst/gsttoc.h +++ /dev/null @@ -1,111 +0,0 @@ -/* GStreamer - * (c) 2010, 2012 Alexander Saprykin - * - * gsttoc.h: generic TOC API declaration - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_TOC_H__ -#define __GST_TOC_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _GstTocEntry GstTocEntry; -typedef struct _GstToc GstToc; - -/** - * GstTocEntryType: - * @GST_TOC_ENTRY_TYPE_CHAPTER: a chapter type entry. - * @GST_TOC_ENTRY_TYPE_EDITION: an edition entry (angle or alternative in other terms). - * - * The different types of TOC entry. - */ -typedef enum { - GST_TOC_ENTRY_TYPE_CHAPTER = 0, - GST_TOC_ENTRY_TYPE_EDITION = 1 -} GstTocEntryType; - -/** - * 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: list of #GstTocEntry children. - * @pads: 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 { - 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: 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 { - GList *entries; - GstTagList *tags; - GstStructure *info; - - /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; -}; - -/* functions to create new structures */ -GstToc * gst_toc_new (void); -GstTocEntry * gst_toc_entry_new (GstTocEntryType type, const gchar *uid); -GstTocEntry * gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar *uid, gpointer pad); - -/* functions to free structures */ -void gst_toc_entry_free (GstTocEntry *entry); -void gst_toc_free (GstToc *toc); - -GstTocEntry * gst_toc_find_entry (const GstToc *toc, const gchar *uid); -GstTocEntry * gst_toc_entry_copy (const GstTocEntry *entry); -GstToc * gst_toc_copy (const GstToc *toc); - -void gst_toc_entry_set_start_stop (GstTocEntry *entry, gint64 start, gint64 stop); -gboolean gst_toc_entry_get_start_stop (const GstTocEntry *entry, gint64 *start, gint64 *stop); - -G_END_DECLS - -#endif /* __GST_TOC_H__ */ - diff --git a/gst/gsttocsetter.c b/gst/gsttocsetter.c deleted file mode 100644 index bee9b34ff1..0000000000 --- a/gst/gsttocsetter.c +++ /dev/null @@ -1,362 +0,0 @@ -/* GStreamer - * Copyright (C) 2010, 2012 Alexander Saprykin - * - * gsttocsetter.c: interface for TOC setting on elements - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:gsttocsetter - * @short_description: Element interface that allows setting and retrieval - * of the TOC - * - * Element interface that allows setting of the TOC. - * - * Elements that support some kind of chapters or editions (or tracks like in - * the FLAC cue sheet) will implement this interface. - * - * If you just want to retrieve the TOC in your application then all you - * need to do is watch for TOC messages on your pipeline's bus (or you can - * perform TOC query). This interface is only for setting TOC data, not for - * extracting it. To set TOC from the application, find proper tocsetter element - * and set TOC using gst_toc_setter_set_toc(). - * - * Elements implementing the #GstTocSetter interface can extend existing TOC - * by getting extend UID for that (you can use gst_toc_find_entry() to retrieve it) - * with any TOC entries received from downstream. - */ - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gst_private.h" -#include "gsttocsetter.h" -#include -#include - -GST_DEBUG_CATEGORY_STATIC (gst_toc_interface_debug); -#define GST_CAT_DEFAULT tag_toc_interface_debug - -static GQuark gst_toc_key; - -typedef struct -{ - GstToc *toc; - GStaticMutex lock; -} GstTocData; - -GType -gst_toc_setter_get_type (void) -{ - static volatile gsize toc_setter_type = 0; - - if (g_once_init_enter (&toc_setter_type)) { - GType _type; - static const GTypeInfo toc_setter_info = { - sizeof (GstTocSetterIFace), /* class_size */ - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, - NULL - }; - - GST_DEBUG_CATEGORY_INIT (gst_toc_interface_debug, "GstTocInterface", 0, - "interfaces for the TOC"); - - _type = g_type_register_static (G_TYPE_INTERFACE, "GstTocSetter", - &toc_setter_info, 0); - - g_type_interface_add_prerequisite (_type, GST_TYPE_ELEMENT); - - gst_toc_key = g_quark_from_static_string ("GST_TOC_SETTER"); - g_once_init_leave (&toc_setter_type, _type); - } - - return toc_setter_type; -} - -static void -gst_toc_data_free (gpointer p) -{ - GstTocData *data = (GstTocData *) p; - - if (data->toc) - gst_toc_free (data->toc); - - g_static_mutex_free (&data->lock); - - g_slice_free (GstTocData, data); -} - -static GstTocData * -gst_toc_setter_get_data (GstTocSetter * setter) -{ - GstTocData *data; - - data = g_object_get_qdata (G_OBJECT (setter), gst_toc_key); - if (!data) { - static GStaticMutex create_mutex = G_STATIC_MUTEX_INIT; - - /* make sure no other thread is creating a GstTocData at the same time */ - g_static_mutex_lock (&create_mutex); - data = g_object_get_qdata (G_OBJECT (setter), gst_toc_key); - if (!data) { - data = g_slice_new (GstTocData); - g_static_mutex_init (&data->lock); - data->toc = NULL; - g_object_set_qdata_full (G_OBJECT (setter), gst_toc_key, data, - gst_toc_data_free); - } - g_static_mutex_unlock (&create_mutex); - } - - return data; -} - -/** - * gst_toc_setter_reset_toc: - * @setter: a #GstTocSetter. - * - * Reset the internal TOC. Elements should call this from within the - * state-change handler. - * - * Since: 0.10.37 - */ -void -gst_toc_setter_reset_toc (GstTocSetter * setter) -{ - GstTocData *data; - - g_return_if_fail (GST_IS_TOC_SETTER (setter)); - - data = gst_toc_setter_get_data (setter); - - g_static_mutex_lock (&data->lock); - if (data->toc) { - gst_toc_free (data->toc); - data->toc = NULL; - } - g_static_mutex_unlock (&data->lock); -} - -/** - * gst_toc_setter_get_toc: - * @setter: a #GstTocSetter. - * - * Return current TOC the setter uses. The TOC should not be - * modified or freed. - * - * This function is not thread-safe. Use gst_toc_setter_get_toc_copy() instead. - * - * Returns: a current snapshot of the TOC used in the setter - * or NULL if none is used. - * - * Since: 0.10.37 - */ -const GstToc * -gst_toc_setter_get_toc (GstTocSetter * setter) -{ - g_return_val_if_fail (GST_IS_TOC_SETTER (setter), NULL); - - return gst_toc_setter_get_data (setter)->toc; -} - -/** - * gst_toc_setter_get_toc_copy: - * @setter: a #GstTocSetter. - * - * Return current TOC the setter uses. The difference between this - * function and gst_toc_setter_get_toc() is that this function returns deep - * copy of the TOC, so you can modify it in any way. This function is thread-safe. - * Free it when done with gst_toc_free(). - * - * Returns: a copy of the current snapshot of the TOC used in the setter - * or NULL if none is used. - * - * Since: 0.10.37 - */ -GstToc * -gst_toc_setter_get_toc_copy (GstTocSetter * setter) -{ - GstTocData *data; - GstToc *ret = NULL; - - g_return_val_if_fail (GST_IS_TOC_SETTER (setter), NULL); - - data = gst_toc_setter_get_data (setter); - g_static_mutex_lock (&data->lock); - - if (data->toc != NULL) - ret = gst_toc_copy (data->toc); - - g_static_mutex_unlock (&data->lock); - - return ret; -} - -/** - * gst_toc_setter_set_toc: - * @setter: a #GstTocSetter. - * @toc: a #GstToc to set. - * - * Set the given TOC on the setter. Previously setted TOC will be - * freed before setting a new one. - * - * Since: 0.10.37 - */ -void -gst_toc_setter_set_toc (GstTocSetter * setter, const GstToc * toc) -{ - GstTocData *data; - - g_return_if_fail (GST_IS_TOC_SETTER (setter)); - - data = gst_toc_setter_get_data (setter); - - g_static_mutex_lock (&data->lock); - if (data->toc) - gst_toc_free (data->toc); - - data->toc = gst_toc_copy (toc); - - g_static_mutex_unlock (&data->lock); -} - -/** - * gst_toc_setter_get_toc_entry: - * @setter: a #GstTocSetter. - * @uid: UID to find entry with. - * - * Return #GstTocEntry (if any) with given @uid. Returned entry should - * not be modified or freed. - * - * This function is not thread-safe. Use gst_toc_setter_get_toc_entry_copy() instead. - * - * Returns: a TOC entry with given @uid from the TOC in the setter - * or NULL if none entry with such @uid was found. - * - * Since: 0.10.37 - */ -const GstTocEntry * -gst_toc_setter_get_toc_entry (GstTocSetter * setter, const gchar * uid) -{ - GstTocData *data; - const GstTocEntry *ret; - - g_return_val_if_fail (GST_IS_TOC_SETTER (setter), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - data = gst_toc_setter_get_data (setter); - - g_static_mutex_lock (&data->lock); - - ret = gst_toc_find_entry (data->toc, uid); - - g_static_mutex_unlock (&data->lock); - - return ret; -} - -/** - * gst_toc_setter_get_toc_entry_copy: - * @setter: a #GstTocSetter. - * @uid: UID to find entry with. - * - * Return #GstTocEntry (if any) with given @uid. It perform a deep copying, - * so you can modify returned value. Free it when done with gst_toc_entry_free(). - * This function is thread-safe. - * - * Returns: a TOC entry with given @uid from the TOC in the setter - * or NULL if none entry with such @uid was found. - * - * Since: 0.10.37 - */ -GstTocEntry * -gst_toc_setter_get_toc_entry_copy (GstTocSetter * setter, const gchar * uid) -{ - GstTocData *data; - GstTocEntry *ret = NULL; - const GstTocEntry *search; - - g_return_val_if_fail (GST_IS_TOC_SETTER (setter), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - data = gst_toc_setter_get_data (setter); - - g_static_mutex_lock (&data->lock); - - search = gst_toc_find_entry (data->toc, uid); - if (search != NULL) - ret = gst_toc_entry_copy (search); - - g_static_mutex_unlock (&data->lock); - - return ret; -} - -/** - * gst_toc_setter_add_toc_entry: - * @setter: a #GstTocSetter. - * @parent_uid: UID of the parent entry to append given @entry. Use 0 for the TOC root level. - * @entry: #GstTocEntry to append. - * - * Try to find entry with given @parent_uid and append an @entry to that #GstTocEntry. - * - * Returns: TRUE if entry with @parent_uid was found, FALSE otherwise. - * - * Since: 0.10.37 - */ -gboolean -gst_toc_setter_add_toc_entry (GstTocSetter * setter, const gchar * parent_uid, - const GstTocEntry * entry) -{ - GstTocData *data; - GstTocEntry *parent; - GstTocEntry *copy_entry; - gboolean ret = FALSE; - - g_return_val_if_fail (GST_IS_TOC_SETTER (setter), FALSE); - g_return_val_if_fail (parent_uid != NULL, FALSE); - g_return_val_if_fail (entry != NULL, FALSE); - - data = gst_toc_setter_get_data (setter); - - g_static_mutex_lock (&data->lock); - - copy_entry = gst_toc_entry_copy (entry); - - if (g_strcmp0 (parent_uid, "0") == 0) - data->toc->entries = g_list_append (data->toc->entries, copy_entry); - else { - parent = gst_toc_find_entry (data->toc, parent_uid); - - if (parent != NULL) { - parent->subentries = g_list_append (parent->subentries, copy_entry); - ret = TRUE; - } - } - - g_static_mutex_unlock (&data->lock); - - return ret; -} diff --git a/gst/gsttocsetter.h b/gst/gsttocsetter.h deleted file mode 100644 index 2174e0d00f..0000000000 --- a/gst/gsttocsetter.h +++ /dev/null @@ -1,67 +0,0 @@ -/* GStreamer - * Copyright (C) 2010, 2012 Alexander Saprykin - * - * gsttocsetter.h: Interfaces for TOC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_TOC_SETTER_H__ -#define __GST_TOC_SETTER_H__ - -#include - -G_BEGIN_DECLS -#define GST_TYPE_TOC_SETTER (gst_toc_setter_get_type ()) -#define GST_TOC_SETTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TOC_SETTER, GstTocSetter)) -#define GST_IS_TOC_SETTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TOC_SETTER)) -#define GST_TOC_SETTER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_TOC_SETTER, GstTocSetterIFace)) -/** - * GstTocSetter: - * - * Opaque #GstTocSetter data structure. - */ -typedef struct _GstTocSetter GstTocSetter; -typedef struct _GstTocSetterIFace GstTocSetterIFace; - -/** - * GstTocSetterIFace: - * @g_iface: parent interface type. - * - * #GstTocSetterIFace interface. - */ - -struct _GstTocSetterIFace -{ - GTypeInterface g_iface; - - /* signals */ - - /* virtual table */ -}; - -GType gst_toc_setter_get_type (void); -void gst_toc_setter_reset_toc (GstTocSetter *setter); -const GstToc * gst_toc_setter_get_toc (GstTocSetter *setter); -GstToc * gst_toc_setter_get_toc_copy (GstTocSetter *setter); -void gst_toc_setter_set_toc (GstTocSetter *setter, const GstToc *toc); -const GstTocEntry * gst_toc_setter_get_toc_entry (GstTocSetter *setter, const gchar *uid); -GstTocEntry * gst_toc_setter_get_toc_entry_copy (GstTocSetter *setter, const gchar *uid); -gboolean gst_toc_setter_add_toc_entry (GstTocSetter *setter, const gchar *parent_uid, const GstTocEntry *entry); - -G_END_DECLS -#endif /* __GST_TOC_SETTER_H__ */ - diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index c91bece8c8..68dec66565 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -118,8 +118,6 @@ check_PROGRAMS = \ gst/gsttag \ gst/gsttagsetter \ gst/gsttask \ - gst/gsttoc \ - gst/gsttocsetter \ gst/gstvalue \ generic/states \ $(PARSE_CHECKS) \ diff --git a/tests/check/gst/.gitignore b/tests/check/gst/.gitignore index 1fd25553cd..cfe258863a 100644 --- a/tests/check/gst/.gitignore +++ b/tests/check/gst/.gitignore @@ -39,8 +39,6 @@ gstutils gstvalue gstquery gsttask -gsttoc -gsttocsetter *.check.xml gstinfo gstxml diff --git a/tests/check/gst/gsttoc.c b/tests/check/gst/gsttoc.c deleted file mode 100644 index 3788b16570..0000000000 --- a/tests/check/gst/gsttoc.c +++ /dev/null @@ -1,369 +0,0 @@ -/* GStreamer - * - * unit test for GstToc - * - * Copyright (C) 2010, 2012 Alexander Saprykin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* ------- TOC ------- - * / \ - * edition1 edition2 - * | | - * -chapter1 -chapter3 - * -chapter2 | - * -subchapter1 - */ - -#include - -#define ENTRY_ED1 "/edition1" -#define ENTRY_ED2 "/edition2" -#define ENTRY_ED3 "test-edition" - -#define ENTRY_CH1 "/edition1/chapter1" -#define ENTRY_CH2 "/edition1/chapter2" -#define ENTRY_CH3 "/edition2/chapter3" -#define ENTRY_CH4 "/test-chapter" - -#define ENTRY_SUB1 "/edition2/chapter3/subchapter1" - -#define ENTRY_TAG "EntryTag" -#define TOC_TAG "TocTag" - -#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) \ -{ \ - gchar *tag_c; \ - const GValue *val; \ - GstStructure *struct_c; \ - \ - fail_unless_equals_string (entry_c->uid, uid_c); \ - fail_unless (entry_c->type == type_c); \ - fail_unless (entry_c->tags != NULL); \ - fail_unless (entry_c->pads == NULL); \ - \ - fail_unless (entry_c->info != NULL); \ - gst_structure_get (entry_c->info, INFO_NAME, GST_TYPE_STRUCTURE, \ - &struct_c, NULL); \ - 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)); \ - fail_unless_equals_string (tag_c, ENTRY_TAG); \ - g_free (tag_c); \ - gst_structure_free (struct_c); \ -} - -#define CHECK_TOC(toc_t) \ -{ \ - GstTocEntry *entry_t, *subentry_t; \ - gchar *tag_t; \ - const GValue *val; \ - GstStructure *struct_toc; \ - \ - /* check TOC */ \ - fail_unless (g_list_length (toc_t->entries) == 2); \ - fail_unless (toc_t->tags != NULL); \ - fail_unless (gst_tag_list_get_string (toc_t->tags, \ - GST_TAG_TITLE, &tag_t)); \ - fail_unless_equals_string (tag_t, TOC_TAG); \ - g_free (tag_t); \ - \ - fail_unless (toc_t->info != NULL); \ - gst_structure_get (toc_t->info, INFO_NAME, GST_TYPE_STRUCTURE, \ - &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 */ \ - entry_t = g_list_nth_data (toc_t->entries, 0); \ - fail_if (entry_t == NULL); \ - fail_unless (g_list_length (entry_t->subentries) == 2); \ - CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \ - /* check chapter1 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \ - /* check chapter2 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 1); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \ - /* check edition2 */ \ - entry_t = g_list_nth_data (toc_t->entries, 1); \ - fail_if (entry_t == NULL); \ - fail_unless (g_list_length (entry_t->subentries) == 1); \ - CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \ - /* check chapter3 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 1); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \ - /* check subchapter1 */ \ - subentry_t = g_list_nth_data (subentry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \ -} - -GST_START_TEST (test_serializing) -{ - GstStructure *structure; - GstToc *toc, *test_toc = NULL; - GstTocEntry *ed, *ch, *subch; - GstEvent *event; - GstMessage *message; - GstQuery *query; - gboolean updated; - gchar *uid; - gint64 start = -1, stop = -1; - - toc = gst_toc_new (); - fail_if (toc == NULL); - gst_tag_list_add (toc->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - TOC_TAG, NULL); - structure = - 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 */ - ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); - fail_if (ed == NULL); - gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - /* append chapter1 to edition1 */ - ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); - fail_if (ch == NULL); - gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - ed->subentries = g_list_append (ed->subentries, ch); - fail_unless (g_list_length (ed->subentries) == 1); - - /* append chapter2 to edition1 */ - ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); - fail_if (ch == NULL); - gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - ed->subentries = g_list_append (ed->subentries, ch); - fail_unless (g_list_length (ed->subentries) == 2); - - /* append edition1 to the TOC */ - toc->entries = g_list_append (toc->entries, ed); - fail_unless (g_list_length (toc->entries) == 1); - - /* test gst_toc_entry_find() */ - ed = NULL; - ed = gst_toc_find_entry (toc, ENTRY_ED1); - - fail_if (ed == NULL); - - CHECK_TOC_ENTRY (ed, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); - - /* test info GstStructure */ - gst_toc_entry_set_start_stop (ch, 100, 1000); - fail_if (!gst_toc_entry_get_start_stop (ch, &start, &stop)); - fail_unless (start == 100); - fail_unless (stop == 1000); - - /* create edition2 */ - ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); - fail_if (ed == NULL); - gst_tag_list_add (ed->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - /* create chapter3 */ - ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); - fail_if (ch == NULL); - gst_tag_list_add (ch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - /* create subchapter1 */ - subch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); - fail_if (subch == NULL); - gst_tag_list_add (subch->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - ENTRY_TAG, NULL); - structure = - 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); - - /* append subchapter1 to chapter3 */ - ch->subentries = g_list_append (ch->subentries, subch); - fail_unless (g_list_length (ch->subentries) == 1); - - /* append chapter3 to edition2 */ - ed->subentries = g_list_append (ed->subentries, ch); - fail_unless (g_list_length (ed->subentries) == 1); - - /* finally append edition2 to the TOC */ - toc->entries = g_list_append (toc->entries, ed); - fail_unless (g_list_length (toc->entries) == 2); - - /* test gst_toc_copy() */ - test_toc = gst_toc_copy (toc); - fail_if (test_toc == NULL); - CHECK_TOC (test_toc); - gst_toc_free (test_toc); - test_toc = NULL; - - /* check TOC event handling */ - event = gst_event_new_toc (toc, TRUE); - fail_if (event == NULL); - fail_if (event->structure == NULL); - fail_unless (event->type == GST_EVENT_TOC); - ASSERT_MINI_OBJECT_REFCOUNT (GST_MINI_OBJECT (event), "GstEvent", 1); - - gst_event_parse_toc (event, &test_toc, &updated); - fail_unless (updated == TRUE); - fail_if (test_toc == NULL); - CHECK_TOC (test_toc); - gst_toc_free (test_toc); - gst_event_unref (event); - updated = FALSE; - test_toc = NULL; - - /* check TOC message handling */ - message = gst_message_new_toc (NULL, toc, TRUE); - fail_if (message == NULL); - fail_if (event->structure == NULL); - fail_unless (message->type == GST_MESSAGE_TOC); - ASSERT_MINI_OBJECT_REFCOUNT (GST_MINI_OBJECT (message), "GstMessage", 1); - - gst_message_parse_toc (message, &test_toc, &updated); - fail_unless (updated == TRUE); - fail_if (test_toc == NULL); - CHECK_TOC (test_toc); - gst_toc_free (test_toc); - gst_message_unref (message); - test_toc = NULL; - - /* check TOC select event handling */ - event = gst_event_new_toc_select (TEST_UID); - fail_if (event == NULL); - fail_if (event->structure == NULL); - fail_unless (event->type == GST_EVENT_TOC_SELECT); - ASSERT_MINI_OBJECT_REFCOUNT (GST_MINI_OBJECT (event), "GstEvent", 1); - - gst_event_parse_toc_select (event, &uid); - fail_unless_equals_string (uid, TEST_UID); - gst_event_unref (event); - g_free (uid); - - /* check TOC query handling */ - query = gst_query_new_toc (); - fail_if (query == NULL); - gst_query_set_toc (query, toc, TEST_UID); - fail_if (query->structure == NULL); - fail_unless (query->type == GST_QUERY_TOC); - ASSERT_MINI_OBJECT_REFCOUNT (GST_MINI_OBJECT (query), "GstQuery", 1); - - gst_query_parse_toc (query, &test_toc, &uid); - fail_unless_equals_string (uid, TEST_UID); - fail_if (test_toc == NULL); - CHECK_TOC (test_toc); - gst_toc_free (test_toc); - gst_query_unref (query); - g_free (uid); - - /* that's wrong code, we should fail */ - ch = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH4); - toc->entries = g_list_prepend (toc->entries, ch); - ASSERT_CRITICAL (message = gst_message_new_toc (NULL, toc, TRUE)); - - /* and yet another one */ - toc->entries = g_list_remove (toc->entries, ch); - gst_toc_entry_free (ch); - ed = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED3); - ch = (GstTocEntry *) (toc->entries->data); - ch->subentries = g_list_prepend (ch->subentries, ed); - ASSERT_WARNING (message = gst_message_new_toc (NULL, toc, TRUE)); - - gst_toc_free (toc); -} - -GST_END_TEST; - -static Suite * -gst_toc_suite (void) -{ - Suite *s = suite_create ("GstToc"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_serializing); - - return s; -} - -GST_CHECK_MAIN (gst_toc); diff --git a/tests/check/gst/gsttocsetter.c b/tests/check/gst/gsttocsetter.c deleted file mode 100644 index eabf41eb87..0000000000 --- a/tests/check/gst/gsttocsetter.c +++ /dev/null @@ -1,431 +0,0 @@ -/* GStreamer GstTocSetter interface unit tests - * Copyright (C) 2010, 2012 Alexander Saprykin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#define ENTRY_ED1 "/edition1" -#define ENTRY_ED2 "/edition2" -#define ENTRY_ED3 "test-edition" - -#define ENTRY_CH1 "/edition1/chapter1" -#define ENTRY_CH2 "/edition1/chapter2" -#define ENTRY_CH3 "/edition2/chapter3" -#define ENTRY_CH4 "/test-chapter" - -#define ENTRY_SUB1 "/edition2/chapter3/subchapter1" - -#define ENTRY_TAG "EntryTag" -#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) \ -{ \ - gchar *tag_c; \ - const GValue *val; \ - GstStructure *struct_c; \ - \ - fail_unless_equals_string (entry_c->uid, uid_c); \ - fail_unless (entry_c->type == type_c); \ - fail_unless (entry_c->tags != NULL); \ - fail_unless (entry_c->pads == NULL); \ - \ - fail_unless (entry_c->info != NULL); \ - gst_structure_get (entry_c->info, INFO_NAME, GST_TYPE_STRUCTURE, \ - &struct_c, NULL); \ - 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)); \ - fail_unless_equals_string (tag_c, ENTRY_TAG); \ - g_free (tag_c); \ - gst_structure_free (struct_c); \ -} - -#define CHECK_TOC(toc_t) \ -{ \ - GstTocEntry *entry_t, *subentry_t; \ - gchar *tag_t; \ - const GValue *val; \ - GstStructure *struct_toc; \ - \ - /* check TOC */ \ - fail_unless (g_list_length (toc_t->entries) == 2); \ - fail_unless (toc_t->tags != NULL); \ - fail_unless (gst_tag_list_get_string (toc_t->tags, \ - GST_TAG_TITLE, &tag_t)); \ - fail_unless_equals_string (tag_t, TOC_TAG); \ - g_free (tag_t); \ - \ - fail_unless (toc_t->info != NULL); \ - gst_structure_get (toc_t->info, INFO_NAME, GST_TYPE_STRUCTURE, \ - &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 */ \ - entry_t = g_list_nth_data (toc_t->entries, 0); \ - fail_if (entry_t == NULL); \ - fail_unless (g_list_length (entry_t->subentries) == 2); \ - CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED1); \ - /* check chapter1 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH1); \ - /* check chapter2 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 1); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH2); \ - /* check edition2 */ \ - entry_t = g_list_nth_data (toc_t->entries, 1); \ - fail_if (entry_t == NULL); \ - fail_unless (g_list_length (entry_t->subentries) == 1); \ - CHECK_TOC_ENTRY (entry_t, GST_TOC_ENTRY_TYPE_EDITION, ENTRY_ED2); \ - /* check chapter3 */ \ - subentry_t = g_list_nth_data (entry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 1); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_CH3); \ - /* check subchapter1 */ \ - subentry_t = g_list_nth_data (subentry_t->subentries, 0); \ - fail_if (subentry_t == NULL); \ - fail_unless (g_list_length (subentry_t->subentries) == 0); \ - CHECK_TOC_ENTRY (subentry_t, GST_TOC_ENTRY_TYPE_CHAPTER, ENTRY_SUB1); \ -} - -/* some minimal GstTocSetter object */ -#define GST_TYPE_DUMMY_ENC gst_dummy_enc_get_type() - -typedef GstElement GstDummyEnc; -typedef GstElementClass GstDummyEncClass; - -static void gst_dummy_enc_add_interfaces (GType enc_type); - -GType gst_dummy_enc_get_type (void); -GST_BOILERPLATE_FULL (GstDummyEnc, gst_dummy_enc, GstElement, - GST_TYPE_ELEMENT, gst_dummy_enc_add_interfaces); - -static void -gst_dummy_enc_add_interfaces (GType enc_type) -{ - static const GInterfaceInfo toc_setter_info = { NULL, NULL, NULL }; - - g_type_add_interface_static (enc_type, GST_TYPE_TOC_SETTER, &toc_setter_info); -} - -static void -gst_dummy_enc_base_init (gpointer g_class) -{ -} - -static void -gst_dummy_enc_class_init (GstDummyEncClass * klass) -{ -} - -static void -gst_dummy_enc_init (GstDummyEnc * enc, GstDummyEncClass * klass) -{ -} - -static GstToc * -create_toc (void) -{ - GstStructure *structure; - GstToc *toc; - GstTocEntry *ed, *ch, *subch; - - toc = gst_toc_new (); - gst_tag_list_add (toc->tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, - TOC_TAG, NULL); - structure = - 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 */ - 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, - ENTRY_TAG, NULL); - structure = - 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 */ - 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, - ENTRY_TAG, NULL); - structure = - 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); - - /* append chapter2 to edition1 */ - 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, - ENTRY_TAG, NULL); - structure = - 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); - - /* append edition1 to the TOC */ - toc->entries = g_list_append (toc->entries, ed); - - /* create edition2 */ - 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, - ENTRY_TAG, NULL); - structure = - 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 */ - 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, - ENTRY_TAG, NULL); - structure = - 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 */ - 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, - ENTRY_TAG, NULL); - structure = - 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 */ - ch->subentries = g_list_append (ch->subentries, subch); - - /* append chapter3 to edition2 */ - ed->subentries = g_list_append (ed->subentries, ch); - - /* finally append edition2 to the TOC */ - toc->entries = g_list_append (toc->entries, ed); - - return toc; -} - -GST_START_TEST (test_set) -{ - GstToc *toc; - GstTocEntry *entry, *ed; - GstTocSetter *setter; - GstElement *enc; - - enc = g_object_new (GST_TYPE_DUMMY_ENC, NULL); - fail_unless (enc != NULL); - - setter = GST_TOC_SETTER (enc); - - toc = create_toc (); - fail_unless (toc != NULL); - - gst_toc_setter_set_toc (setter, toc); - - gst_toc_free (toc); - toc = gst_toc_setter_get_toc_copy (setter); - - CHECK_TOC (toc); - - /* test entry adding into the root TOC */ - entry = g_list_last (toc->entries)->data; - toc->entries = g_list_remove (toc->entries, entry); - - gst_toc_setter_set_toc (setter, toc); - gst_toc_setter_add_toc_entry (setter, "0", entry); - - gst_toc_free (toc); - gst_toc_entry_free (entry); - toc = gst_toc_setter_get_toc_copy (setter); - - CHECK_TOC (toc); - - /* test entry adding into the arbitrary entry */ - entry = gst_toc_find_entry (toc, ENTRY_CH2); - fail_if (entry == NULL); - - ed = toc->entries->data; - ed->subentries = g_list_remove (ed->subentries, entry); - - gst_toc_setter_add_toc_entry (setter, ed->uid, entry); - - CHECK_TOC (toc); - - gst_toc_free (toc); - gst_toc_setter_reset_toc (setter); - toc = gst_toc_setter_get_toc_copy (setter); - - fail_unless (toc == NULL); - - g_object_unref (enc); -} - -GST_END_TEST static int spin_and_wait = 1; -static int threads_running = 0; - -#define THREADS_TEST_SECONDS 1.5 - -static gpointer -test_threads_thread_func1 (gpointer data) -{ - GstToc *toc; - GstTocSetter *setter = GST_TOC_SETTER (data); - GTimer *timer; - - toc = create_toc (); - timer = g_timer_new (); - - g_atomic_int_inc (&threads_running); - while (g_atomic_int_get (&spin_and_wait)) - g_usleep (0); - - GST_INFO ("Go!"); - g_timer_start (timer); - - while (g_timer_elapsed (timer, NULL) < THREADS_TEST_SECONDS) - gst_toc_setter_set_toc (setter, toc); - - gst_toc_free (toc); - g_timer_destroy (timer); - GST_INFO ("Done"); - - return NULL; -} - -static gpointer -test_threads_thread_func2 (gpointer data) -{ - GstToc *toc; - GstTocSetter *setter = GST_TOC_SETTER (data); - GTimer *timer; - - toc = create_toc (); - timer = g_timer_new (); - - g_atomic_int_inc (&threads_running); - while (g_atomic_int_get (&spin_and_wait)) - g_usleep (0); - - GST_INFO ("Go!"); - g_timer_start (timer); - - while (g_timer_elapsed (timer, NULL) < THREADS_TEST_SECONDS) - gst_toc_setter_set_toc (setter, toc); - - gst_toc_free (toc); - g_timer_destroy (timer); - GST_INFO ("Done"); - - return NULL; -} - -static gpointer -test_threads_thread_func3 (gpointer data) -{ - GstTocSetter *setter = GST_TOC_SETTER (data); - GTimer *timer; - - timer = g_timer_new (); - - g_atomic_int_inc (&threads_running); - while (g_atomic_int_get (&spin_and_wait)) - g_usleep (0); - - GST_INFO ("Go!"); - g_timer_start (timer); - - while (g_timer_elapsed (timer, NULL) < THREADS_TEST_SECONDS) { - gst_toc_setter_reset_toc (setter); - } - - g_timer_destroy (timer); - GST_INFO ("Done"); - - return NULL; -} - -GST_START_TEST (test_threads) -{ - GstTocSetter *setter; - GThread *threads[3]; - - setter = GST_TOC_SETTER (g_object_new (GST_TYPE_DUMMY_ENC, NULL)); - - spin_and_wait = TRUE; - threads[0] = g_thread_create (test_threads_thread_func1, setter, TRUE, NULL); - threads[1] = g_thread_create (test_threads_thread_func2, setter, TRUE, NULL); - threads[2] = g_thread_create (test_threads_thread_func3, setter, TRUE, NULL); - - while (g_atomic_int_get (&threads_running) < 3) - g_usleep (10); - - g_atomic_int_set (&spin_and_wait, FALSE); - - g_thread_join (threads[0]); - g_thread_join (threads[1]); - g_thread_join (threads[2]); - - g_object_unref (G_OBJECT (setter)); -} - -GST_END_TEST static Suite * -gst_toc_setter_suite (void) -{ - Suite *s = suite_create ("GstTocSetter"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_set); - tcase_add_test (tc_chain, test_threads); - - return s; -} - -GST_CHECK_MAIN (gst_toc_setter); diff --git a/tools/gst-launch.c b/tools/gst-launch.c index d8072b1f57..34e023b714 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -69,7 +69,6 @@ static GstElement *pipeline; static EventLoopResult caught_error = ELR_NO_ERROR; static gboolean quiet = FALSE; static gboolean tags = FALSE; -static gboolean toc = FALSE; static gboolean messages = FALSE; static gboolean is_live = FALSE; static gboolean waiting_eos = FALSE; @@ -508,36 +507,6 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused) } } -#define MAX_INDENT 40 - -static void -print_toc_entry (gpointer data, gpointer user_data) -{ - GstTocEntry *entry = (GstTocEntry *) data; - const gchar spc[MAX_INDENT + 1] = " "; - const gchar *entry_types[] = { "chapter", "edition" }; - guint indent = MIN (GPOINTER_TO_UINT (user_data), MAX_INDENT); - gint64 start, stop; - - gst_toc_entry_get_start_stop (entry, &start, &stop); - - PRINT ("%s%s:", &spc[MAX_INDENT - indent], entry_types[entry->type]); - if (GST_CLOCK_TIME_IS_VALID (start)) { - PRINT (" start: %" GST_TIME_FORMAT, GST_TIME_ARGS (start)); - } - if (GST_CLOCK_TIME_IS_VALID (stop)) { - PRINT (" stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (stop)); - } - PRINT ("\n"); - indent += 2; - - /* TODO: print tags */ - - /* loop over sub-toc entries */ - g_list_foreach (entry->subentries, print_toc_entry, - GUINT_TO_POINTER (indent)); -} - #ifndef DISABLE_FAULT_HANDLER /* we only use sighandler here because the registers are not important */ static void @@ -740,28 +709,6 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state) gst_tag_list_free (tag_list); } break; - case GST_MESSAGE_TOC: - if (toc) { - GstToc *toc_msg; - gboolean updated; - - if (GST_IS_ELEMENT (GST_MESSAGE_SRC (message))) { - PRINT (_("FOUND TOC : found by element \"%s\".\n"), - GST_MESSAGE_SRC_NAME (message)); - } else if (GST_IS_OBJECT (GST_MESSAGE_SRC (message))) { - PRINT (_("FOUND TOC : found by object \"%s\".\n"), - GST_MESSAGE_SRC_NAME (message)); - } else { - PRINT (_("FOUND TOC\n")); - } - - gst_message_parse_toc (message, &toc_msg, &updated); - /* recursively loop over toc entries */ - g_list_foreach (toc_msg->entries, print_toc_entry, - GUINT_TO_POINTER (0)); - gst_toc_free (toc_msg); - } - break; case GST_MESSAGE_INFO:{ GError *gerror; gchar *debug; @@ -982,8 +929,6 @@ main (int argc, char *argv[]) GOptionEntry options[] = { {"tags", 't', 0, G_OPTION_ARG_NONE, &tags, N_("Output tags (also known as metadata)"), NULL}, - {"toc", 'c', 0, G_OPTION_ARG_NONE, &toc, - N_("Ouput TOC (chapters and editions)"), NULL}, {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, N_("Output status information and property notifications"), NULL}, {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 627268c225..03f4a046bf 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -416,8 +416,6 @@ EXPORTS gst_event_new_sink_message gst_event_new_step gst_event_new_tag - gst_event_new_toc - gst_event_new_toc_select gst_event_parse_buffer_size gst_event_parse_latency gst_event_parse_new_segment @@ -428,8 +426,6 @@ EXPORTS gst_event_parse_sink_message gst_event_parse_step gst_event_parse_tag - gst_event_parse_toc - gst_event_parse_toc_select gst_event_set_seqnum gst_event_type_flags_get_type gst_event_type_get_flags @@ -575,7 +571,6 @@ EXPORTS gst_message_new_structure_change gst_message_new_tag gst_message_new_tag_full - gst_message_new_toc gst_message_new_warning gst_message_parse_async_start gst_message_parse_buffering @@ -600,7 +595,6 @@ EXPORTS gst_message_parse_structure_change gst_message_parse_tag gst_message_parse_tag_full - gst_message_parse_toc gst_message_parse_warning gst_message_set_buffering_stats gst_message_set_qos_stats @@ -884,7 +878,6 @@ EXPORTS gst_query_new_position gst_query_new_seeking gst_query_new_segment - gst_query_new_toc gst_query_new_uri gst_query_parse_buffering_percent gst_query_parse_buffering_range @@ -898,7 +891,6 @@ EXPORTS gst_query_parse_position gst_query_parse_seeking gst_query_parse_segment - gst_query_parse_toc gst_query_parse_uri gst_query_set_buffering_percent gst_query_set_buffering_range @@ -911,7 +903,6 @@ EXPORTS gst_query_set_position gst_query_set_seeking gst_query_set_segment - gst_query_set_toc gst_query_set_uri gst_query_type_get_by_nick gst_query_type_get_details @@ -1143,25 +1134,6 @@ EXPORTS gst_task_start gst_task_state_get_type gst_task_stop - gst_toc_copy - gst_toc_entry_copy - gst_toc_entry_free - gst_toc_entry_get_start_stop - gst_toc_entry_new - gst_toc_entry_new_with_pad - gst_toc_entry_set_start_stop - gst_toc_entry_type_get_type - gst_toc_find_entry - gst_toc_free - gst_toc_new - gst_toc_setter_add_toc_entry - gst_toc_setter_get_toc - gst_toc_setter_get_toc_copy - gst_toc_setter_get_toc_entry - gst_toc_setter_get_toc_entry_copy - gst_toc_setter_get_type - gst_toc_setter_reset_toc - gst_toc_setter_set_toc gst_trace_destroy gst_trace_flush gst_trace_new