mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-10 11:29:55 +00:00
378 lines
9.5 KiB
C
378 lines
9.5 KiB
C
/*
|
|
* 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;
|
|
}
|