display: implement a VA display cache.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 12 Jan 2012 11:46:34 +0000 (12:46 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 12 Jan 2012 15:09:08 +0000 (16:09 +0100)
gst-libs/gst/vaapi/Makefile.am
gst-libs/gst/vaapi/gstvaapidisplay.h
gst-libs/gst/vaapi/gstvaapidisplaycache.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapidisplaycache.h [new file with mode: 0644]

index 6361cc14a46ca5fca938caadc4b3034acde1206b..5485b5f3e5bcbaed3b2cba2ed4e1f96765c594ce 100644 (file)
@@ -25,6 +25,7 @@ libgstvaapi_source_c =                                \
        gstvaapicontext.c                       \
        gstvaapidecoder.c                       \
        gstvaapidisplay.c                       \
+       gstvaapidisplaycache.c                  \
        gstvaapiimage.c                         \
        gstvaapiimageformat.c                   \
        gstvaapiimagepool.c                     \
@@ -49,6 +50,7 @@ libgstvaapi_source_h =                                \
        gstvaapicontext.h                       \
        gstvaapidecoder.h                       \
        gstvaapidisplay.h                       \
+       gstvaapidisplaycache.h                  \
        gstvaapiimage.h                         \
        gstvaapiimageformat.h                   \
        gstvaapiimagepool.h                     \
index 075c1f617f8d73a0fc1d4c0cc447743bef749369..0517e4262627b877e3bc5146ee9863761d84d436 100644 (file)
@@ -58,10 +58,23 @@ G_BEGIN_DECLS
                                GST_VAAPI_TYPE_DISPLAY,  \
                                GstVaapiDisplayClass))
 
+typedef struct _GstVaapiDisplayInfo             GstVaapiDisplayInfo;
 typedef struct _GstVaapiDisplay                 GstVaapiDisplay;
 typedef struct _GstVaapiDisplayPrivate          GstVaapiDisplayPrivate;
 typedef struct _GstVaapiDisplayClass            GstVaapiDisplayClass;
 
+/**
+ * GstVaapiDisplayInfo:
+ *
+ * Generic class to retrieve VA display info
+ */
+struct _GstVaapiDisplayInfo {
+    GstVaapiDisplay    *display;
+    gchar              *display_name;
+    VADisplay           va_display;
+    gpointer            native_display;
+};
+
 /**
  * GstVaapiDisplay:
  *
diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.c b/gst-libs/gst/vaapi/gstvaapidisplaycache.c
new file mode 100644 (file)
index 0000000..a6bb39d
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ *  gstvaapidisplaycache.c - VA display cache
+ *
+ *  Copyright (C) 2012 Intel Corporation
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1
+ *  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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <string.h>
+#include "gstvaapidisplaycache.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+typedef struct _CacheEntry CacheEntry;
+struct _CacheEntry {
+    GstVaapiDisplayInfo info;
+};
+
+struct _GstVaapiDisplayCache {
+    GStaticMutex        mutex;
+    GList              *list;
+};
+
+static void
+cache_entry_free(CacheEntry *entry)
+{
+    GstVaapiDisplayInfo *info;
+
+    if (!entry)
+        return;
+
+    info = &entry->info;
+
+    if (info->display_name) {
+        g_free(info->display_name);
+        info->display_name = NULL;
+    }
+    g_slice_free(CacheEntry, entry);
+}
+
+static CacheEntry *
+cache_entry_new(const GstVaapiDisplayInfo *di)
+{
+    GstVaapiDisplayInfo *info;
+    CacheEntry *entry;
+
+    entry = g_slice_new(CacheEntry);
+    if (!entry)
+        return NULL;
+
+    info                 = &entry->info;
+    info->display        = di->display;
+    info->va_display     = di->va_display;
+    info->native_display = di->native_display;
+    info->display_name   = NULL;
+
+    if (di->display_name) {
+        info->display_name = g_strdup(di->display_name);
+        if (!info->display_name)
+            goto error;
+    }
+    return entry;
+
+error:
+    cache_entry_free(entry);
+    return NULL;
+}
+
+#define CACHE_LOOKUP(cache, res, prop, comp_func, comp_data, user_data) do { \
+        GList *l;                                                       \
+                                                                        \
+        g_static_mutex_lock(&(cache)->mutex);                           \
+        for (l = (cache)->list; l != NULL; l = l->next) {               \
+            GstVaapiDisplayInfo * const info =                          \
+                &((CacheEntry *)l->data)->info;                         \
+            if (comp_func(info->prop, comp_data, user_data))            \
+                break;                                                  \
+        }                                                               \
+        g_static_mutex_unlock(&(cache)->mutex);                         \
+        res = l;                                                        \
+    } while (0)
+
+#define compare_equal(a, b, user_data) \
+    ((a) == (b))
+
+#define compare_string(a, b, user_data) \
+    ((a) == (b) || ((a) && (b) && strcmp(a, b) == 0))
+
+static GList *
+cache_lookup_display(GstVaapiDisplayCache *cache, GstVaapiDisplay *display)
+{
+    GList *m;
+
+    CACHE_LOOKUP(cache, m, display, compare_equal, display, NULL);
+    return m;
+}
+
+static GList *
+cache_lookup_va_display(GstVaapiDisplayCache *cache, VADisplay va_display)
+{
+    GList *m;
+
+    CACHE_LOOKUP(cache, m, va_display, compare_equal, va_display, NULL);
+    return m;
+}
+
+static GList *
+cache_lookup_native_display(GstVaapiDisplayCache *cache, gpointer native_display)
+{
+    GList *m;
+
+    CACHE_LOOKUP(cache, m, native_display, compare_equal, native_display, NULL);
+    return m;
+}
+
+/**
+ * gst_vaapi_display_cache_new:
+ *
+ * Creates a new VA display cache.
+ *
+ * Return value: the newly created #GstVaapiDisplayCache object
+ */
+GstVaapiDisplayCache *
+gst_vaapi_display_cache_new(void)
+{
+    GstVaapiDisplayCache *cache;
+
+    cache = g_slice_new0(GstVaapiDisplayCache);
+    if (!cache)
+        return NULL;
+
+    g_static_mutex_init(&cache->mutex);
+    return cache;
+}
+
+/**
+ * gst_vaapi_display_cache_new:
+ * @cache: the #GstVaapiDisplayCache to destroy
+ *
+ * Destroys a VA display cache.
+ */
+void
+gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache)
+{
+    GList *l;
+
+    if (!cache)
+        return;
+
+    if (cache->list) {
+        for (l = cache->list; l != NULL; l = l->next)
+            cache_entry_free(l->data);
+        g_list_free(cache->list);
+        cache->list = NULL;
+    }
+    g_slice_free(GstVaapiDisplayCache, cache);
+}
+
+/**
+ * gst_vaapi_display_cache_get_size:
+ * @cache: the #GstVaapiDisplayCache
+ *
+ * Gets the size of the display cache @cache.
+ *
+ * Return value: the size of the display cache
+ */
+guint
+gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache)
+{
+    guint size;
+
+    g_return_val_if_fail(cache != NULL, 0);
+
+    g_static_mutex_lock(&cache->mutex);
+    size = g_list_length(cache->list);
+    g_static_mutex_unlock(&cache->mutex);
+    return size;
+}
+
+/**
+ * gst_vaapi_display_cache_add:
+ * @cache: the #GstVaapiDisplayCache
+ * @info: the display cache info to add
+ *
+ * Adds a new entry with data from @info. The display @info data is
+ * copied into the newly created cache entry.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_display_cache_add(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplayInfo        *info
+)
+{
+    CacheEntry *entry;
+
+    g_return_val_if_fail(cache != NULL, FALSE);
+    g_return_val_if_fail(info != NULL, FALSE);
+
+    entry = cache_entry_new(info);
+    if (!entry)
+        return FALSE;
+
+    g_static_mutex_lock(&cache->mutex);
+    cache->list = g_list_prepend(cache->list, entry);
+    g_static_mutex_unlock(&cache->mutex);
+    return TRUE;
+}
+
+/**
+ * gst_vaapi_display_cache_remove:
+ * @cache: the #GstVaapiDisplayCache
+ * @display: the display to remove from cache
+ *
+ * Removes any cache entry that matches the specified #GstVaapiDisplay.
+ */
+void
+gst_vaapi_display_cache_remove(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplay            *display
+)
+{
+    GList *m;
+
+    m = cache_lookup_display(cache, display);
+    if (!m)
+        return;
+
+    cache_entry_free(m->data);
+    g_static_mutex_lock(&cache->mutex);
+    cache->list = g_list_delete_link(cache->list, m);
+    g_static_mutex_unlock(&cache->mutex);
+}
+
+/**
+ * gst_vaapi_display_cache_lookup:
+ * @cache: the #GstVaapiDisplayCache
+ * @display: the display to find
+ *
+ * Looks up the display cache for the specified #GstVaapiDisplay.
+ *
+ * Return value: a #GstVaapiDisplayInfo matching @display, or %NULL if
+ *   none was found
+ */
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplay            *display
+)
+{
+    CacheEntry *entry;
+    GList *m;
+
+    g_return_val_if_fail(cache != NULL, NULL);
+    g_return_val_if_fail(display != NULL, NULL);
+
+    m = cache_lookup_display(cache, display);
+    if (!m)
+        return NULL;
+
+    entry = m->data;
+    return &entry->info;
+}
+
+/**
+ * gst_vaapi_display_cache_lookup_by_va_display:
+ * @cache: the #GstVaapiDisplayCache
+ * @va_display: the VA display to find
+ *
+ * Looks up the display cache for the specified VA display.
+ *
+ * Return value: a #GstVaapiDisplayInfo matching @va_display, or %NULL
+ *   if none was found
+ */
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_va_display(
+    GstVaapiDisplayCache       *cache,
+    VADisplay                   va_display
+)
+{
+    CacheEntry *entry;
+    GList *m;
+
+    g_return_val_if_fail(cache != NULL, NULL);
+    g_return_val_if_fail(va_display != NULL, NULL);
+
+    m = cache_lookup_va_display(cache, va_display);
+    if (!m)
+        return NULL;
+
+    entry = m->data;
+    return &entry->info;
+}
+
+/**
+ * gst_vaapi_display_cache_lookup_by_native_display:
+ * @cache: the #GstVaapiDisplayCache
+ * @native_display: the native display to find
+ *
+ * Looks up the display cache for the specified native display.
+ *
+ * Return value: a #GstVaapiDisplayInfo matching @native_display, or
+ *   %NULL if none was found
+ */
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_native_display(
+    GstVaapiDisplayCache       *cache,
+    gpointer                    native_display
+)
+{
+    CacheEntry *entry;
+    GList *m;
+
+    g_return_val_if_fail(cache != NULL, NULL);
+    g_return_val_if_fail(native_display != NULL, NULL);
+
+    m = cache_lookup_native_display(cache, native_display);
+    if (!m)
+        return NULL;
+
+    entry = m->data;
+    return &entry->info;
+}
+
+/**
+ * gst_vaapi_display_cache_lookup_by_name:
+ * @cache: the #GstVaapiDisplayCache
+ * @display_name: the display name to match
+ * @compare_func: an optional string comparison function
+ * @user_data: any relevant data pointer to the comparison function
+ *
+ * Looks up the display cache for the specified display name. A
+ * specific comparison function can be provided to avoid a plain
+ * strcmp().
+ *
+ * Return value: a #GstVaapiDisplayInfo matching @display_name, or
+ *   %NULL if none was found
+ */
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_name(
+    GstVaapiDisplayCache       *cache,
+    const gchar                *display_name,
+    GCompareDataFunc            compare_func,
+    gpointer                    user_data
+)
+{
+    CacheEntry *entry;
+    GList *m;
+
+    g_return_val_if_fail(cache != NULL, NULL);
+
+    if (compare_func)
+        CACHE_LOOKUP(cache, m, display_name, compare_func, display_name, user_data);
+    else
+        CACHE_LOOKUP(cache, m, display_name, compare_string, display_name, NULL);
+    if (!m)
+        return NULL;
+
+    entry = m->data;
+    return &entry->info;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapidisplaycache.h b/gst-libs/gst/vaapi/gstvaapidisplaycache.h
new file mode 100644 (file)
index 0000000..12c2953
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *  gstvaapidisplaycache.h - VA display cache
+ *
+ *  Copyright (C) 2012 Intel Corporation
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1
+ *  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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301 USA
+ */
+
+#ifndef GSTVAAPIDISPLAYCACHE_H
+#define GSTVAAPIDISPLAYCACHE_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+
+typedef struct _GstVaapiDisplayCache    GstVaapiDisplayCache;
+
+GstVaapiDisplayCache *
+gst_vaapi_display_cache_new(void);
+
+void
+gst_vaapi_display_cache_free(GstVaapiDisplayCache *cache);
+
+guint
+gst_vaapi_display_cache_get_size(GstVaapiDisplayCache *cache);
+
+gboolean
+gst_vaapi_display_cache_add(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplayInfo        *info
+);
+
+void
+gst_vaapi_display_cache_remove(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplay            *display
+);
+
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup(
+    GstVaapiDisplayCache       *cache,
+    GstVaapiDisplay            *display
+);
+
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_va_display(
+    GstVaapiDisplayCache       *cache,
+    VADisplay                   va_display
+);
+
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_native_display(
+    GstVaapiDisplayCache       *cache,
+    gpointer                    native_display
+);
+
+const GstVaapiDisplayInfo *
+gst_vaapi_display_cache_lookup_by_name(
+    GstVaapiDisplayCache       *cache,
+    const gchar                *display_name,
+    GCompareDataFunc            compare_func,
+    gpointer                    user_data
+);
+
+#endif /* GSTVAAPIDISPLAYCACHE_H */