N_PROPERTIES
};
-static GstVaapiDisplayCache *g_display_cache = NULL;
+static GstVaapiDisplayCache *g_display_cache;
+static GMutex g_display_cache_lock;
static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
g_once_init_leave (&g_once, TRUE);
}
-static inline GstVaapiDisplayCache *
+static GstVaapiDisplayCache *
get_display_cache (void)
{
+ GstVaapiDisplayCache *cache = NULL;
+
+ g_mutex_lock (&g_display_cache_lock);
if (!g_display_cache)
g_display_cache = gst_vaapi_display_cache_new ();
- return g_display_cache;
-}
-
-GstVaapiDisplayCache *
-gst_vaapi_display_get_cache (void)
-{
- return get_display_cache ();
+ if (g_display_cache)
+ cache = gst_vaapi_display_cache_ref (g_display_cache);
+ g_mutex_unlock (&g_display_cache_lock);
+ return cache;
}
static void
free_display_cache (void)
{
- if (!g_display_cache)
- return;
- if (gst_vaapi_display_cache_get_size (g_display_cache) > 0)
- return;
- gst_vaapi_display_cache_free (g_display_cache);
- g_display_cache = NULL;
+ g_mutex_lock (&g_display_cache_lock);
+ if (g_display_cache && gst_vaapi_display_cache_is_empty (g_display_cache))
+ gst_vaapi_display_cache_replace (&g_display_cache, NULL);
+ g_mutex_unlock (&g_display_cache_lock);
}
/* GstVaapiDisplayType enumerations */
gst_vaapi_display_replace_internal (&priv->parent, NULL);
- if (g_display_cache) {
- gst_vaapi_display_cache_remove (get_display_cache (), display);
- free_display_cache ();
- }
+ g_mutex_lock (&g_display_cache_lock);
+ if (priv->cache)
+ gst_vaapi_display_cache_remove (priv->cache, display);
+ g_mutex_unlock (&g_display_cache_lock);
+ gst_vaapi_display_cache_replace (&priv->cache, NULL);
+ free_display_cache ();
}
static gboolean
-gst_vaapi_display_create (GstVaapiDisplay * display,
+gst_vaapi_display_create_unlocked (GstVaapiDisplay * display,
GstVaapiDisplayInitType init_type, gpointer init_value)
{
GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
const GstVaapiDisplayClass *const klass =
GST_VAAPI_DISPLAY_GET_CLASS (display);
- GstVaapiDisplayCache *cache;
gint major_version, minor_version;
VAStatus status;
GstVaapiDisplayInfo info;
if (!priv->display)
return FALSE;
- cache = get_display_cache ();
- if (!cache)
- return FALSE;
- cached_info = gst_vaapi_display_cache_lookup_by_va_display (cache,
+ cached_info = gst_vaapi_display_cache_lookup_by_va_display (priv->cache,
info.va_display);
if (cached_info) {
gst_vaapi_display_replace_internal (&priv->parent, cached_info->display);
}
if (!cached_info) {
- if (!gst_vaapi_display_cache_add (cache, &info))
+ if (!gst_vaapi_display_cache_add (priv->cache, &info))
return FALSE;
}
return TRUE;
}
+static gboolean
+gst_vaapi_display_create (GstVaapiDisplay * display,
+ GstVaapiDisplayInitType init_type, gpointer init_value)
+{
+ GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
+ GstVaapiDisplayCache *cache;
+ gboolean success;
+
+ cache = get_display_cache ();
+ if (!cache)
+ return FALSE;
+ gst_vaapi_display_cache_replace (&priv->cache, cache);
+ gst_vaapi_display_cache_unref (cache);
+
+ g_mutex_lock (&g_display_cache_lock);
+ success = gst_vaapi_display_create_unlocked (display, init_type, init_value);
+ g_mutex_unlock (&g_display_cache_lock);
+ return success;
+}
+
static void
gst_vaapi_display_lock_default (GstVaapiDisplay * display)
{
{
GstVaapiDisplayDRMPrivate *const priv =
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *info;
- cache = gst_vaapi_display_get_cache ();
- g_return_val_if_fail (cache != NULL, FALSE);
-
if (!set_device_path (display, name))
return FALSE;
{
GstVaapiDisplayDRMPrivate *const priv =
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *cached_info;
/* Return any cached info even if child has its own VA display */
- cache = gst_vaapi_display_get_cache ();
- if (!cache)
- return FALSE;
- cached_info =
- gst_vaapi_display_cache_lookup_by_native_display (cache,
+ cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache,
GINT_TO_POINTER (priv->drm_device), GST_VAAPI_DISPLAY_TYPES (display));
if (cached_info) {
*info = *cached_info;
#define GST_VAAPI_DISPLAY_HAS_VPP(display) \
gst_vaapi_display_has_video_processing(GST_VAAPI_DISPLAY_CAST(display))
+/**
+ * GST_VAAPI_DISPLAY_CACHE:
+ * @display: a @GstVaapiDisplay
+ *
+ * Returns the #GstVaapiDisplayCache attached to the supplied @display object.
+ */
+#undef GST_VAAPI_DISPLAY_GET_CACHE
+#define GST_VAAPI_DISPLAY_GET_CACHE(display) \
+ (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->cache)
+
struct _GstVaapiDisplayPrivate
{
GstVaapiDisplay *parent;
+ GstVaapiDisplayCache *cache;
GRecMutex mutex;
GstVaapiDisplayType display_type;
VADisplay display;
gst_vaapi_display_new (const GstVaapiDisplayClass * klass,
GstVaapiDisplayInitType init_type, gpointer init_value);
-GstVaapiDisplayCache *
-gst_vaapi_display_get_cache (void);
-
static inline guint
gst_vaapi_display_get_display_types (GstVaapiDisplay * display)
{
{
GstVaapiDisplayWaylandPrivate *const priv =
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *info;
- cache = gst_vaapi_display_get_cache ();
- g_return_val_if_fail (cache != NULL, FALSE);
-
if (!set_display_name (display, name))
return FALSE;
{
GstVaapiDisplayWaylandPrivate *const priv =
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (display);
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *cached_info;
/* Return any cached info even if child has its own VA display */
- cache = gst_vaapi_display_get_cache ();
- if (!cache)
- return FALSE;
cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache,
priv->wl_display, GST_VAAPI_DISPLAY_TYPES (display));
if (cached_info) {
{
GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display);
GstVaapiDisplayX11Private *const priv = &display->priv;
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *info;
- cache = gst_vaapi_display_get_cache ();
- g_return_val_if_fail (cache != NULL, FALSE);
-
if (!set_display_name (display, name))
return FALSE;
{
GstVaapiDisplayX11Private *const priv =
GST_VAAPI_DISPLAY_X11_PRIVATE (display);
- GstVaapiDisplayCache *cache;
+ GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
const GstVaapiDisplayInfo *cached_info;
/* Return any cached info even if child has its own VA display */
- cache = gst_vaapi_display_get_cache ();
- if (!cache)
- return FALSE;
- cached_info =
- gst_vaapi_display_cache_lookup_by_native_display (cache,
+ cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache,
priv->x11_display, GST_VAAPI_DISPLAY_TYPES (display));
if (cached_info) {
*info = *cached_info;
struct _GstVaapiDisplayCache
{
- GMutex mutex;
+ GstVaapiMiniObject parent_instance;
GList *list;
};
{
GList *l;
- g_mutex_lock (&cache->mutex);
for (l = cache->list; l != NULL; l = l->next) {
GstVaapiDisplayInfo *const info = &((CacheEntry *) l->data)->info;
if (!is_compatible_display_type (info->display_type, display_types))
if (func (info, data))
break;
}
- g_mutex_unlock (&cache->mutex);
return l;
}
return strcmp (info->display_name, display_name) == 0;
}
-/**
- * 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)
+static void
+gst_vaapi_display_cache_finalize (GstVaapiDisplayCache * cache)
{
- GstVaapiDisplayCache *cache;
+ GList *l;
- cache = g_slice_new0 (GstVaapiDisplayCache);
- if (!cache)
- return NULL;
+ if (!cache->list)
+ return;
- g_mutex_init (&cache->mutex);
- return cache;
+ for (l = cache->list; l != NULL; l = l->next)
+ cache_entry_free (l->data);
+ g_list_free (cache->list);
+ cache->list = NULL;
+}
+
+static const GstVaapiMiniObjectClass *
+gst_vaapi_display_cache_class (void)
+{
+ static const GstVaapiMiniObjectClass GstVaapiDisplayCacheClass = {
+ .size = sizeof (GstVaapiDisplayCache),
+ .finalize = (GDestroyNotify) gst_vaapi_display_cache_finalize
+ };
+ return &GstVaapiDisplayCacheClass;
}
/**
* gst_vaapi_display_cache_new:
- * @cache: the #GstVaapiDisplayCache to destroy
*
- * Destroys a VA display cache.
+ * Creates a new VA display cache.
+ *
+ * Return value: the newly created #GstVaapiDisplayCache object
*/
-void
-gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache)
+GstVaapiDisplayCache *
+gst_vaapi_display_cache_new (void)
{
- 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_mutex_clear (&cache->mutex);
- g_slice_free (GstVaapiDisplayCache, cache);
+ return (GstVaapiDisplayCache *)
+ gst_vaapi_mini_object_new0 (gst_vaapi_display_cache_class ());
}
/**
- * gst_vaapi_display_cache_get_size:
+ * gst_vaapi_display_cache_is_empty:
* @cache: the #GstVaapiDisplayCache
*
- * Gets the size of the display cache @cache.
+ * Checks whether the display cache @cache is empty.
*
- * Return value: the size of the display cache
+ * Return value: %TRUE if the display @cache is empty, %FALSE otherwise.
*/
-guint
-gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache)
+gboolean
+gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache)
{
- guint size;
-
g_return_val_if_fail (cache != NULL, 0);
- g_mutex_lock (&cache->mutex);
- size = g_list_length (cache->list);
- g_mutex_unlock (&cache->mutex);
- return size;
+ return cache->list == NULL;
}
/**
if (!entry)
return FALSE;
- g_mutex_lock (&cache->mutex);
cache->list = g_list_prepend (cache->list, entry);
- g_mutex_unlock (&cache->mutex);
return TRUE;
}
return;
cache_entry_free (m->data);
- g_mutex_lock (&cache->mutex);
cache->list = g_list_delete_link (cache->list, m);
- g_mutex_unlock (&cache->mutex);
}
/**
#include "libgstvaapi_priv_check.h"
#include <gst/vaapi/gstvaapidisplay.h>
+#include "gstvaapiminiobject.h"
typedef struct _GstVaapiDisplayCache GstVaapiDisplayCache;
GstVaapiDisplayCache *
gst_vaapi_display_cache_new (void);
-G_GNUC_INTERNAL
-void
-gst_vaapi_display_cache_free (GstVaapiDisplayCache * cache);
+#define gst_vaapi_display_cache_ref(cache) \
+ ((GstVaapiDisplayCache *) gst_vaapi_mini_object_ref ( \
+ GST_VAAPI_MINI_OBJECT (cache)))
+#define gst_vaapi_display_cache_unref(cache) \
+ gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (cache))
+#define gst_vaapi_display_cache_replace(old_cache_ptr, new_cache) \
+ gst_vaapi_mini_object_replace ((GstVaapiMiniObject **) (old_cache_ptr), \
+ GST_VAAPI_MINI_OBJECT (new_cache))
G_GNUC_INTERNAL
-guint
-gst_vaapi_display_cache_get_size (GstVaapiDisplayCache * cache);
+gboolean
+gst_vaapi_display_cache_is_empty (GstVaapiDisplayCache * cache);
G_GNUC_INTERNAL
gboolean