uri: Add new uri API to get media fragments URI as table
authorSeungha Yang <sh.yang@lge.com>
Tue, 22 Nov 2016 07:52:46 +0000 (16:52 +0900)
committerTim-Philipp Müller <tim@centricular.com>
Tue, 6 Dec 2016 20:28:55 +0000 (20:28 +0000)
As an usecase of URI fragment, it can indicate temporal or spatial
dimension of a media stream. To easily parse key-value pair,
newly added gst_uri_get_media_fragment_table () API will provide
the table of key-value pair likewise URI query.
See also https://www.w3.org/TR/media-frags/

https://bugzilla.gnome.org/show_bug.cgi?id=774830

docs/gst/gstreamer-sections.txt
gst/gsturi.c
gst/gsturi.h
tests/check/gst/gsturi.c
win32/common/libgstreamer.def

index 30150fe..bccaac5 100644 (file)
@@ -3452,6 +3452,7 @@ gst_uri_query_has_key
 gst_uri_get_query_keys
 gst_uri_get_fragment
 gst_uri_set_fragment
+gst_uri_get_media_fragment_table
 <SUBSECTION Standard>
 GST_IS_URI
 GST_TYPE_URI
index d87d4db..cb0d01b 100644 (file)
@@ -2803,3 +2803,34 @@ gst_uri_set_fragment (GstUri * uri, const gchar * fragment)
   uri->fragment = g_strdup (fragment);
   return TRUE;
 }
+
+/**
+ * gst_uri_get_media_fragment_table:
+ * @uri: (nullable): The #GstUri to get the fragment table from.
+ *
+ * Get the media fragment table from the URI, as defined by "Media Fragments URI 1.0".
+ * Hash table returned by this API is a list of "key-value" pairs, and the each
+ * pair is generated by splitting "URI fragment" per "&" sub-delims, then "key"
+ * and "value" are splitted by "=" sub-delims. The "key" returned by this API may
+ * be undefined keyword by standard.
+ * A value may be %NULL to indicate that the key should appear in the fragment
+ * string in the URI, but does not have a value. Free the returned #GHashTable
+ * with #g_hash_table_unref() when it is no longer required.
+ * Modifying this hash table does not affect the fragment in the URI.
+ *
+ * See more about Media Fragments URI 1.0 (W3C) at https://www.w3.org/TR/media-frags/
+ *
+ * Returns: (transfer full)(element-type gchar* gchar*): The fragment hash table
+ *          from the URI.
+ *
+ * Since: 1.12
+ */
+GHashTable *
+gst_uri_get_media_fragment_table (const GstUri * uri)
+{
+  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
+
+  if (!uri->fragment)
+    return NULL;
+  return _gst_uri_string_to_table (uri->fragment, "&", "=", TRUE, TRUE);
+}
index 7e0f0b3..9a78fa3 100644 (file)
@@ -250,6 +250,7 @@ const gchar * gst_uri_get_query_value  (const GstUri * uri,
 GList * gst_uri_get_query_keys         (const GstUri * uri);
 const gchar * gst_uri_get_fragment     (const GstUri * uri);
 gboolean gst_uri_set_fragment          (GstUri * uri, const gchar * fragment);
+GHashTable * gst_uri_get_media_fragment_table  (const GstUri * uri);
 
 /**
  * gst_uri_copy:
index e7ce6df..dbd1509 100644 (file)
@@ -980,6 +980,80 @@ GST_START_TEST (test_url_get_set)
 
 GST_END_TEST;
 
+GST_START_TEST (test_url_get_media_fragment_table)
+{
+  GstUri *url;
+  gchar *val;
+  GHashTable *table;
+
+  /* Examples at https://www.w3.org/TR/media-frags/#processing-media-fragment-uri */
+
+  /* TEST "t=1" */
+  url = gst_uri_from_string ("http://foo/var/file#t=1");
+  table = gst_uri_get_media_fragment_table (url);
+  fail_unless (table);
+  fail_unless (g_hash_table_size (table) == 1);
+  fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
+          (gpointer) & val));
+  fail_unless_equals_string ("1", val);
+  g_hash_table_unref (table);
+  gst_uri_unref (url);
+
+  /* NOTE: Media Fragments URI 1.0 (W3C) is saying that
+   * "Multiple occurrences of the same dimension: only the last valid occurrence
+   *  of a dimension (e.g. t=10 in #t=2&t=10) is interpreted and all previous
+   *  occurrences (valid or invalid) SHOULD be ignored by the user agent"
+   */
+  /* TEST "t=1&t=2" */
+  url = gst_uri_from_string ("http://foo/var/file#t=1&t=2");
+  table = gst_uri_get_media_fragment_table (url);
+  fail_unless (table);
+  fail_unless (g_hash_table_size (table) == 1);
+  fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
+          (gpointer) & val));
+  fail_unless_equals_string ("2", val);
+  g_hash_table_unref (table);
+  gst_uri_unref (url);
+
+  /* TEST "a=b=c" */
+  url = gst_uri_from_string ("http://foo/var/file#a=b=c");
+  table = gst_uri_get_media_fragment_table (url);
+  fail_unless (table);
+  fail_unless (g_hash_table_size (table) == 1);
+  fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
+          (gpointer) & val));
+  fail_unless_equals_string ("b=c", val);
+  g_hash_table_unref (table);
+  gst_uri_unref (url);
+
+  /* TEST "a&b=c" */
+  url = gst_uri_from_string ("http://foo/var/file#a&b=c");
+  table = gst_uri_get_media_fragment_table (url);
+  fail_unless (table);
+  fail_unless (g_hash_table_size (table) == 2);
+  fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
+          (gpointer) & val));
+  fail_unless (val == NULL);
+  fail_unless (g_hash_table_lookup_extended (table, "b", NULL,
+          (gpointer) & val));
+  fail_unless_equals_string ("c", val);
+  g_hash_table_unref (table);
+  gst_uri_unref (url);
+
+  /* TEST "%74=%6ept%3A%310" */
+  url = gst_uri_from_string ("http://foo/var/file#%74=%6ept%3A%310");
+  table = gst_uri_get_media_fragment_table (url);
+  fail_unless (table);
+  fail_unless (g_hash_table_size (table) == 1);
+  fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
+          (gpointer) & val));
+  fail_unless_equals_string ("npt:10", val);
+  g_hash_table_unref (table);
+  gst_uri_unref (url);
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_uri_suite (void)
 {
@@ -1003,6 +1077,7 @@ gst_uri_suite (void)
   tcase_add_test (tc_chain, test_url_equality);
   tcase_add_test (tc_chain, test_url_constructors);
   tcase_add_test (tc_chain, test_url_get_set);
+  tcase_add_test (tc_chain, test_url_get_media_fragment_table);
 
   return s;
 }
index f63ffee..9ecf089 100644 (file)
@@ -1493,6 +1493,7 @@ EXPORTS
        gst_uri_get_fragment
        gst_uri_get_host
        gst_uri_get_location
+       gst_uri_get_media_fragment_table
        gst_uri_get_path
        gst_uri_get_path_segments
        gst_uri_get_path_string