[PATCH 1/8] core: Add filtering by media type



From: "Juan A. Suarez Romero" <jasuarez igalia com>

Signed-off-by: Juan A. Suarez Romero <jasuarez igalia com>
---
 src/Makefile.am                  |   10 +++--
 src/grl-caps.c                   |   31 +++++++++++++
 src/grl-caps.h                   |   22 +++++++++
 src/grl-operation-options-priv.h |    1 +
 src/grl-operation-options.c      |   92 +++++++++++++++++++++++++++++++++++++-
 src/grl-operation-options.h      |    5 ++
 6 files changed, 156 insertions(+), 5 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 53f3eda..085fc32 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,13 +15,15 @@ grl-marshal.c: grl-marshal.h grl-marshal.list
 	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix grl_marshal	\
 	--body grl-marshal.list >> $@
 
-grl-type-builtins.h: grl-media-source.h grl-type-builtins.h.template
+enum_headers = grl-media-source.h grl-caps.h
+
+grl-type-builtins.h: $(enum_headers) grl-type-builtins.h.template
 	$(AM_V_GEN) $(GLIB_MKENUMS) --template grl-type-builtins.h.template	\
-	grl-media-source.h > $@
+	$(enum_headers) > $@
 
-grl-type-builtins.c: grl-type-builtins.h grl-media-source.h grl-type-builtins.c.template
+grl-type-builtins.c: grl-type-builtins.h $(enum_headers) grl-type-builtins.c.template
 	$(AM_V_GEN) $(GLIB_MKENUMS) --template grl-type-builtins.c.template	\
-	grl-media-source.h > $@
+	$(enum_headers) > $@
 
 lib_LTLIBRARIES = lib@GRL_NAME@.la
 
diff --git a/src/grl-caps.c b/src/grl-caps.c
index c80a3e3..afbc9e3 100644
--- a/src/grl-caps.c
+++ b/src/grl-caps.c
@@ -48,6 +48,7 @@
 #include <grl-value-helper.h>
 
 #include "grl-operation-options-priv.h"
+#include "grl-type-builtins.h"
 
 #define GRL_CAPS_KEY_PAGINATION "pagination"
 #define GRL_CAPS_KEY_FLAGS "flags"
@@ -59,6 +60,7 @@ G_DEFINE_TYPE (GrlCaps, grl_caps, G_TYPE_OBJECT);
 
 struct _GrlCapsPrivate {
   GHashTable *data;
+  GrlTypeFilter type_filter;
 };
 
 
@@ -82,6 +84,10 @@ grl_caps_init (GrlCaps *self)
   self->priv = GRL_CAPS_GET_PRIVATE (self);
 
   self->priv->data = grl_g_value_hashtable_new ();
+
+  /* by default, type filtering is not considered to be supported. The source
+   * has to explicitly modify its caps. */
+  self->priv->type_filter = GRL_TYPE_FILTER_NONE;
 }
 
 static void
@@ -129,6 +135,31 @@ grl_caps_test_option (GrlCaps *caps, const gchar *key, const GValue *value)
     /* these options must always be handled by plugins */
     return TRUE;
 
+  if (0 == g_strcmp0 (key, GRL_OPERATION_OPTION_TYPE_FILTER)) {
+    GrlTypeFilter filter, supported_filter;
+
+    supported_filter = grl_caps_get_type_filter (caps);
+    filter = g_value_get_flags (value);
+
+    return filter == (filter & supported_filter);
+  }
+
   return FALSE;
 }
 
+GrlTypeFilter
+grl_caps_get_type_filter (GrlCaps *caps)
+{
+  g_return_val_if_fail (caps != NULL, GRL_TYPE_FILTER_NONE);
+
+  return caps->priv->type_filter;
+}
+
+void
+grl_caps_set_type_filter (GrlCaps *caps, GrlTypeFilter filter)
+{
+  g_return_if_fail (caps != NULL);
+
+  caps->priv->type_filter = filter;
+}
+
diff --git a/src/grl-caps.h b/src/grl-caps.h
index 656c350..de1ecef 100644
--- a/src/grl-caps.h
+++ b/src/grl-caps.h
@@ -57,6 +57,24 @@ typedef struct {
 #define IS_GRL_CAPS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GRL_CAPS_TYPE))
 #define GRL_CAPS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GRL_CAPS_TYPE, GrlCapsClass))
 
+/**
+ * GrlTypeFilter:
+ * @GRL_TYPE_FILTER_NONE: no type filtering
+ * @GRL_TYPE_FILTER_AUDIO: allow audio content
+ * @GRL_TYPE_FILTER_VIDEO: allow video content
+ * @GRL_TYPE_FILTER_IMAGE: allow image content
+ *
+ * Type of media to allow.
+ **/
+typedef enum {
+  GRL_TYPE_FILTER_NONE = 0,
+  GRL_TYPE_FILTER_AUDIO = (1 << 0),
+  GRL_TYPE_FILTER_VIDEO = (1 << 1),
+  GRL_TYPE_FILTER_IMAGE = (1 << 2),
+  GRL_TYPE_FILTER_ALL = (GRL_TYPE_FILTER_AUDIO | GRL_TYPE_FILTER_VIDEO | GRL_TYPE_FILTER_IMAGE),
+} GrlTypeFilter;
+
+
 GType grl_caps_get_type (void);
 
 GrlCaps *grl_caps_new (void);
@@ -65,6 +83,10 @@ gboolean grl_caps_test_option (GrlCaps *caps,
                                const gchar *key,
                                const GValue *value);
 
+GrlTypeFilter grl_caps_get_type_filter (GrlCaps *caps);
+
+void grl_caps_set_type_filter (GrlCaps *caps, GrlTypeFilter filter);
+
 G_END_DECLS
 
 #endif /* _GRL_CAPS_H_ */
diff --git a/src/grl-operation-options-priv.h b/src/grl-operation-options-priv.h
index d07084e..b420bc5 100644
--- a/src/grl-operation-options-priv.h
+++ b/src/grl-operation-options-priv.h
@@ -34,6 +34,7 @@
 #define GRL_OPERATION_OPTION_SKIP "skip"
 #define GRL_OPERATION_OPTION_COUNT "count"
 #define GRL_OPERATION_OPTION_FLAGS "flags"
+#define GRL_OPERATION_OPTION_TYPE_FILTER "type-filter"
 
 gboolean grl_operation_options_key_is_set (GrlOperationOptions *options,
                                            const gchar *key);
diff --git a/src/grl-operation-options.c b/src/grl-operation-options.c
index 056fb58..f5632ff 100644
--- a/src/grl-operation-options.c
+++ b/src/grl-operation-options.c
@@ -32,6 +32,7 @@
 #include <grl-value-helper.h>
 
 #include "grl-operation-options-priv.h"
+#include "grl-type-builtins.h"
 
 G_DEFINE_TYPE (GrlOperationOptions, grl_operation_options, G_TYPE_OBJECT);
 
@@ -47,6 +48,7 @@ struct _GrlOperationOptionsPrivate {
 #define SKIP_DEFAULT 0;
 #define COUNT_DEFAULT GRL_COUNT_INFINITY;
 #define FLAGS_DEFAULT GRL_RESOLVE_NORMAL;
+#define TYPE_FILTER_DEFAULT GRL_TYPE_FILTER_ALL;
 
 static void
 grl_operation_options_dispose (GrlOperationOptions *self)
@@ -103,6 +105,32 @@ copy_option (GrlOperationOptions *source,
     set_value (destination, key, value);
 }
 
+static gboolean
+check_and_copy_option (GrlOperationOptions *options,
+                       GrlCaps *caps,
+                       const gchar *key,
+                       GrlOperationOptions **supported_options,
+                       GrlOperationOptions **unsupported_options)
+{
+  if (grl_operation_options_key_is_set (options, key)) {
+    GValue *value;
+    gboolean filter_is_supported;
+
+    value = g_hash_table_lookup (options->priv->data, key);
+    filter_is_supported = grl_caps_test_option (caps, key, value);
+
+    if (filter_is_supported && supported_options)
+      set_value (*supported_options, key, value);
+    else if (!filter_is_supported && unsupported_options)
+      set_value (*unsupported_options, key, value);
+
+    return filter_is_supported;
+  }
+
+  return TRUE;
+}
+
+
 /* ========== API ========== */
 
 /**
@@ -149,6 +177,8 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
                                  GrlOperationOptions **supported_options,
                                  GrlOperationOptions **unsupported_options)
 {
+  gboolean ret = TRUE;
+
   if (supported_options) {
     *supported_options = grl_operation_options_new (caps);
 
@@ -161,7 +191,13 @@ grl_operation_options_obey_caps (GrlOperationOptions *options,
   if (unsupported_options)
     *unsupported_options = grl_operation_options_new (NULL);
 
-  return TRUE;
+  ret &= check_and_copy_option (options,
+                                caps,
+                                GRL_OPERATION_OPTION_TYPE_FILTER,
+                                supported_options,
+                                unsupported_options);
+
+  return ret;
 }
 
 /**
@@ -179,6 +215,7 @@ grl_operation_options_copy (GrlOperationOptions *options)
   copy_option (options, copy, GRL_OPERATION_OPTION_SKIP);
   copy_option (options, copy, GRL_OPERATION_OPTION_COUNT);
   copy_option (options, copy, GRL_OPERATION_OPTION_FLAGS);
+  copy_option (options, copy, GRL_OPERATION_OPTION_TYPE_FILTER);
 
   return copy;
 }
@@ -341,3 +378,56 @@ grl_operation_options_get_flags (GrlOperationOptions *options)
 
   return FLAGS_DEFAULT;
 }
+
+/**
+ * grl_operation_options_set_type_filter:
+ * @options: a #GrlOperationOptions instance
+ * @filter: the type of media to get
+ *
+ * Set the type of media filter for an operation. Only those media elements that
+ * match the @filter will be returned. Will only succeed if @filter obey to the
+ * inherent capabilities of @options.
+ *
+ * Returns: %TRUE if @flags could be set, %FALSE otherwise
+ **/
+gboolean
+grl_operation_options_set_type_filter (GrlOperationOptions *options,
+                                       GrlTypeFilter filter)
+{
+  GValue value = { 0 };
+  gboolean ret;
+
+  g_value_init (&value, GRL_TYPE_TYPE_FILTER);
+  g_value_set_flags (&value, filter);
+
+  ret = (options->priv->caps == NULL) ||
+      grl_caps_test_option (options->priv->caps,
+                            GRL_OPERATION_OPTION_TYPE_FILTER, &value);
+
+  if (ret)
+    set_value (options, GRL_OPERATION_OPTION_TYPE_FILTER, &value);
+
+  g_value_unset (&value);
+
+  return ret;
+}
+
+/**
+ * grl_operation_options_get_type_filter:
+ * @options: a #GrlOperationOptions instance
+ *
+ *
+ * Returns: resolution flags of @options
+ **/
+GrlTypeFilter
+grl_operation_options_get_type_filter (GrlOperationOptions *options)
+{
+  const GValue *value = g_hash_table_lookup (options->priv->data,
+                                             GRL_OPERATION_OPTION_TYPE_FILTER);
+
+  if (value) {
+    return g_value_get_flags (value);
+  }
+
+  return TYPE_FILTER_DEFAULT;
+}
diff --git a/src/grl-operation-options.h b/src/grl-operation-options.h
index e433eff..0cf992f 100644
--- a/src/grl-operation-options.h
+++ b/src/grl-operation-options.h
@@ -96,6 +96,11 @@ gboolean grl_operation_options_set_flags (GrlOperationOptions *options,
 GrlMetadataResolutionFlags
     grl_operation_options_get_flags (GrlOperationOptions *options);
 
+gboolean grl_operation_options_set_type_filter (GrlOperationOptions *options,
+                                                GrlTypeFilter filter);
+
+GrlTypeFilter grl_operation_options_get_type_filter (GrlOperationOptions *options);
+
 G_END_DECLS
 
 #endif /* _GRL_OPERATION_OPTIONS_H_ */
-- 
1.7.5.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]