From 915cef5e010c83ba28fc5d924ed313f6a2134357 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 7 May 2013 11:39:34 +0200 Subject: [PATCH] libs: use GstVaapiMiniObject for display objects. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 4 +- gst-libs/gst/vaapi/gstvaapidisplay.c | 521 +++++++++++++--------- gst-libs/gst/vaapi/gstvaapidisplay.h | 90 +--- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 260 ++++------- gst-libs/gst/vaapi/gstvaapidisplay_drm.h | 52 +-- gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h | 44 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 48 +- gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 49 +- gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h | 34 +- gst-libs/gst/vaapi/gstvaapidisplay_priv.h | 132 +++++- gst-libs/gst/vaapi/gstvaapidisplay_wayland.c | 272 ++++------- gst-libs/gst/vaapi/gstvaapidisplay_wayland.h | 51 +-- gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h | 38 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 318 +++++-------- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 56 +-- gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h | 54 ++- gst-libs/gst/vaapi/gstvaapiobject.c | 4 +- gst-libs/gst/vaapi/gstvaapivideopool.c | 4 +- 18 files changed, 915 insertions(+), 1116 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 15b09ed..c11b0f6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -465,7 +465,7 @@ gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder) gst_vaapi_object_replace(&decoder->context, NULL); decoder->va_context = VA_INVALID_ID; - g_clear_object(&decoder->display); + gst_vaapi_display_replace(&decoder->display, NULL); decoder->va_display = NULL; } @@ -485,7 +485,7 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display, gst_video_info_init(&codec_state->info); decoder->user_data = NULL; - decoder->display = g_object_ref(display); + decoder->display = gst_vaapi_display_ref(display); decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display); decoder->context = NULL; decoder->va_context = VA_INVALID_ID; diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 602dbb4..a8b4e99 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -39,7 +39,10 @@ GST_DEBUG_CATEGORY(gst_debug_vaapi); -G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT) +/* Ensure those symbols are actually defined in the resulting libraries */ +#undef gst_vaapi_display_ref +#undef gst_vaapi_display_unref +#undef gst_vaapi_display_replace typedef struct _GstVaapiConfig GstVaapiConfig; struct _GstVaapiConfig { @@ -66,10 +69,6 @@ struct _GstVaapiFormatInfo { enum { PROP_0, - PROP_DISPLAY, - PROP_DISPLAY_TYPE, - PROP_WIDTH, - PROP_HEIGHT, PROP_RENDER_MODE, PROP_ROTATION, PROP_HUE, @@ -84,6 +83,9 @@ static GstVaapiDisplayCache *g_display_cache = NULL; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; +static void +gst_vaapi_display_properties_init(void); + static gboolean get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); @@ -109,6 +111,8 @@ libgstvaapi_init_once(void) /* Dump gstreamer-vaapi version for debugging purposes */ GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); + gst_vaapi_display_properties_init(); + g_once_init_leave(&g_once, TRUE); } @@ -417,13 +421,43 @@ find_property_by_type(GArray *properties, VADisplayAttribType type) static inline const GstVaapiProperty * find_property_by_pspec(GstVaapiDisplay *display, GParamSpec *pspec) { - return find_property(display->priv->properties, pspec->name); + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + + return find_property(priv->properties, pspec->name); +} + +static guint +find_property_id(const gchar *name) +{ + typedef struct { + const gchar *name; + guint id; + } property_map; + + static const property_map g_property_map[] = { + { GST_VAAPI_DISPLAY_PROP_RENDER_MODE, PROP_RENDER_MODE }, + { GST_VAAPI_DISPLAY_PROP_ROTATION, PROP_ROTATION }, + { GST_VAAPI_DISPLAY_PROP_HUE, PROP_HUE }, + { GST_VAAPI_DISPLAY_PROP_SATURATION, PROP_SATURATION }, + { GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, PROP_BRIGHTNESS }, + { GST_VAAPI_DISPLAY_PROP_CONTRAST, PROP_CONTRAST }, + { NULL, } + }; + + const property_map *m; + for (m = g_property_map; m->name != NULL; m++) { + if (strcmp(m->name, name) == 0) + return m->id; + } + return 0; } static void gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); gdouble ratio, delta; gint i, j, index, windex; @@ -472,7 +506,8 @@ gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) static void gst_vaapi_display_destroy(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->decoders) { g_array_free(priv->decoders, TRUE); @@ -505,13 +540,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) priv->display = NULL; } - if (priv->create_display) { + if (!priv->use_foreign_display) { GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); if (klass->close_display) klass->close_display(display); } - g_clear_object(&priv->parent); + gst_vaapi_display_replace_internal(&priv->parent, NULL); if (g_display_cache) { gst_vaapi_display_cache_remove(get_display_cache(), display); @@ -520,9 +555,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) } static gboolean -gst_vaapi_display_create(GstVaapiDisplay *display) +gst_vaapi_display_create(GstVaapiDisplay *display, + GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplayPrivate * const priv = display->priv; + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + const GstVaapiDisplayClass * const klass = + GST_VAAPI_DISPLAY_GET_CLASS(display); GstVaapiDisplayCache *cache; gboolean has_errors = TRUE; VADisplayAttribute *display_attrs = NULL; @@ -539,12 +578,21 @@ gst_vaapi_display_create(GstVaapiDisplay *display) info.display = display; info.display_type = priv->display_type; - if (priv->display) - info.va_display = priv->display; - else if (priv->create_display) { - GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); - if (klass->open_display && !klass->open_display(display)) + switch (init_type) { + case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY: + info.va_display = init_value; + priv->display = init_value; + priv->use_foreign_display = TRUE; + break; + case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME: + if (klass->open_display && !klass->open_display(display, init_value)) + return FALSE; + goto create_display; + case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY: + if (klass->bind_display && !klass->bind_display(display, init_value)) return FALSE; + // fall-through + create_display: if (!klass->get_display || !klass->get_display(display, &info)) return FALSE; priv->display = info.va_display; @@ -554,6 +602,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display) if (klass->get_size_mm) klass->get_size_mm(display, &priv->width_mm, &priv->height_mm); gst_vaapi_display_calculate_pixel_aspect_ratio(display); + break; } if (!priv->display) return FALSE; @@ -561,13 +610,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display) cache = get_display_cache(); if (!cache) return FALSE; - cached_info = gst_vaapi_display_cache_lookup_by_va_display( - cache, - info.va_display - ); + cached_info = gst_vaapi_display_cache_lookup_by_va_display(cache, + info.va_display); if (cached_info) { - g_clear_object(&priv->parent); - priv->parent = g_object_ref(cached_info->display); + gst_vaapi_display_replace_internal(&priv->parent, + cached_info->display); priv->display_type = cached_info->display_type; } @@ -766,180 +813,69 @@ end: static void gst_vaapi_display_lock_default(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->parent) - priv = priv->parent->priv; + priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); g_rec_mutex_lock(&priv->mutex); } static void gst_vaapi_display_unlock_default(GstVaapiDisplay *display) { - GstVaapiDisplayPrivate *priv = display->priv; + GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); if (priv->parent) - priv = priv->parent->priv; + priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent); g_rec_mutex_unlock(&priv->mutex); } static void -gst_vaapi_display_finalize(GObject *object) +gst_vaapi_display_init(GstVaapiDisplay *display) { - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + const GstVaapiDisplayClass * const dpy_class = + GST_VAAPI_DISPLAY_GET_CLASS(display); - gst_vaapi_display_destroy(display); + priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; + priv->par_n = 1; + priv->par_d = 1; - g_rec_mutex_clear(&display->priv->mutex); - - G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object); -} - -static void -gst_vaapi_display_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + g_rec_mutex_init(&priv->mutex); - switch (prop_id) { - case PROP_DISPLAY: - display->priv->display = g_value_get_pointer(value); - break; - case PROP_DISPLAY_TYPE: - display->priv->display_type = g_value_get_enum(value); - break; - case PROP_RENDER_MODE: - gst_vaapi_display_set_render_mode(display, g_value_get_enum(value)); - break; - case PROP_ROTATION: - gst_vaapi_display_set_rotation(display, g_value_get_enum(value)); - break; - case PROP_HUE: - case PROP_SATURATION: - case PROP_BRIGHTNESS: - case PROP_CONTRAST: - set_color_balance(display, prop_id, g_value_get_float(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + if (dpy_class->init) + dpy_class->init(display); } static void -gst_vaapi_display_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) +gst_vaapi_display_finalize(GstVaapiDisplay *display) { - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_get_display(display)); - break; - case PROP_DISPLAY_TYPE: - g_value_set_enum(value, gst_vaapi_display_get_display_type(display)); - break; - case PROP_WIDTH: - g_value_set_uint(value, gst_vaapi_display_get_width(display)); - break; - case PROP_HEIGHT: - g_value_set_uint(value, gst_vaapi_display_get_height(display)); - break; - case PROP_RENDER_MODE: { - GstVaapiRenderMode mode; - if (!gst_vaapi_display_get_render_mode(display, &mode)) - mode = DEFAULT_RENDER_MODE; - g_value_set_enum(value, mode); - break; - } - case PROP_ROTATION: - g_value_set_enum(value, gst_vaapi_display_get_rotation(display)); - break; - case PROP_HUE: - case PROP_SATURATION: - case PROP_BRIGHTNESS: - case PROP_CONTRAST: { - gfloat v; - if (!get_color_balance(display, prop_id, &v)) - v = G_PARAM_SPEC_FLOAT(pspec)->default_value; - g_value_set_float(value, v); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_constructed(GObject *object) -{ - GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); - GObjectClass *parent_class; - - display->priv->create_display = display->priv->display == NULL; - if (!gst_vaapi_display_create(display)) - gst_vaapi_display_destroy(display); - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + gst_vaapi_display_destroy(display); + g_rec_mutex_clear(&priv->mutex); } -static void +void gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); libgstvaapi_init_once(); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); - - object_class->finalize = gst_vaapi_display_finalize; - object_class->set_property = gst_vaapi_display_set_property; - object_class->get_property = gst_vaapi_display_get_property; - object_class->constructed = gst_vaapi_display_constructed; - + object_class->size = sizeof(GstVaapiDisplay); + object_class->finalize = (GDestroyNotify)gst_vaapi_display_finalize; dpy_class->lock = gst_vaapi_display_lock_default; dpy_class->unlock = gst_vaapi_display_unlock_default; +} - g_properties[PROP_DISPLAY] = - g_param_spec_pointer("display", - "VA display", - "VA display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_properties[PROP_DISPLAY_TYPE] = - g_param_spec_enum("display-type", - "VA display type", - "VA display type", - GST_VAAPI_TYPE_DISPLAY_TYPE, - GST_VAAPI_DISPLAY_TYPE_ANY, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); - - g_properties[PROP_WIDTH] = - g_param_spec_uint("width", - "Width", - "The display width", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE); - - g_properties[PROP_HEIGHT] = - g_param_spec_uint("height", - "height", - "The display height", - 1, G_MAXUINT32, 1, - G_PARAM_READABLE); - +static void +gst_vaapi_display_properties_init(void) +{ /** * GstVaapiDisplay:render-mode: * @@ -1017,33 +953,40 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE); +} - g_object_class_install_properties(object_class, N_PROPERTIES, g_properties); +static inline const GstVaapiDisplayClass * +gst_vaapi_display_class(void) +{ + static GstVaapiDisplayClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return &g_class; } -static void -gst_vaapi_display_init(GstVaapiDisplay *display) +GstVaapiDisplay * +gst_vaapi_display_new(const GstVaapiDisplayClass *klass, + GstVaapiDisplayInitType init_type, gpointer init_value) { - GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); + GstVaapiDisplay *display; - display->priv = priv; - priv->parent = NULL; - priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; - priv->display = NULL; - priv->width = 0; - priv->height = 0; - priv->width_mm = 0; - priv->height_mm = 0; - priv->par_n = 1; - priv->par_d = 1; - priv->decoders = NULL; - priv->encoders = NULL; - priv->image_formats = NULL; - priv->subpicture_formats = NULL; - priv->properties = NULL; - priv->create_display = TRUE; + display = (GstVaapiDisplay *) + gst_vaapi_mini_object_new0(GST_VAAPI_MINI_OBJECT_CLASS(klass)); + if (!display) + return NULL; - g_rec_mutex_init(&priv->mutex); + gst_vaapi_display_init(display); + if (!gst_vaapi_display_create(display, init_type, init_value)) + goto error; + return display; + +error: + gst_vaapi_display_unref_internal(display); + return NULL; } /** @@ -1066,11 +1009,53 @@ gst_vaapi_display_new_with_display(VADisplay va_display) info = gst_vaapi_display_cache_lookup_by_va_display(cache, va_display); if (info) - return g_object_ref(info->display); + return gst_vaapi_display_ref_internal(info->display); - return g_object_new(GST_VAAPI_TYPE_DISPLAY, - "display", va_display, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_class(), + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display); +} + +/** + * gst_vaapi_display_ref: + * @display: a #GstVaapiDisplay + * + * Atomically increases the reference count of the given @display by one. + * + * Returns: The same @display argument + */ +GstVaapiDisplay * +gst_vaapi_display_ref(GstVaapiDisplay *display) +{ + return gst_vaapi_display_ref_internal(display); +} + +/** + * gst_vaapi_display_unref: + * @display: a #GstVaapiDisplay + * + * Atomically decreases the reference count of the @display by one. If + * the reference count reaches zero, the display will be free'd. + */ +void +gst_vaapi_display_unref(GstVaapiDisplay *display) +{ + gst_vaapi_display_unref_internal(display); +} + +/** + * gst_vaapi_display_replace: + * @old_display_ptr: a pointer to a #GstVaapiDisplay + * @new_display: a #GstVaapiDisplay + * + * Atomically replaces the display display held in @old_display_ptr + * with @new_display. This means that @old_display_ptr shall reference + * a valid display. However, @new_display can be NULL. + */ +void +gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, + GstVaapiDisplay *new_display) +{ + gst_vaapi_display_replace_internal(old_display_ptr, new_display); } /** @@ -1173,7 +1158,7 @@ gst_vaapi_display_get_display_type(GstVaapiDisplay *display) g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), GST_VAAPI_DISPLAY_TYPE_ANY); - return display->priv->display_type; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display_type; } /** @@ -1189,7 +1174,7 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return display->priv->display; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->display; } /** @@ -1205,7 +1190,7 @@ gst_vaapi_display_get_width(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); - return display->priv->width; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; } /** @@ -1221,7 +1206,7 @@ gst_vaapi_display_get_height(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), 0); - return display->priv->height; + return GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; } /** @@ -1238,10 +1223,10 @@ gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheig g_return_if_fail(GST_VAAPI_DISPLAY(display)); if (pwidth) - *pwidth = display->priv->width; + *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width; if (pheight) - *pheight = display->priv->height; + *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->height; } /** @@ -1262,10 +1247,10 @@ gst_vaapi_display_get_pixel_aspect_ratio( g_return_if_fail(GST_VAAPI_IS_DISPLAY(display)); if (par_n) - *par_n = display->priv->par_n; + *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_n; if (par_d) - *par_d = display->priv->par_d; + *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_d; } /** @@ -1281,7 +1266,7 @@ gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_profile_caps(display->priv->decoders); + return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders); } /** @@ -1304,7 +1289,8 @@ gst_vaapi_display_has_decoder( { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_config(display->priv->decoders, profile, entrypoint); + return find_config( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->decoders, profile, entrypoint); } /** @@ -1320,7 +1306,7 @@ gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_profile_caps(display->priv->encoders); + return get_profile_caps(GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders); } /** @@ -1343,7 +1329,8 @@ gst_vaapi_display_has_encoder( { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); - return find_config(display->priv->encoders, profile, entrypoint); + return find_config( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->encoders, profile, entrypoint); } /** @@ -1367,7 +1354,8 @@ gst_vaapi_display_get_image_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_format_caps(display->priv->image_formats); + return get_format_caps( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats); } /** @@ -1388,14 +1376,16 @@ gst_vaapi_display_has_image_format( g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - if (find_format(display->priv->image_formats, format)) + if (find_format( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->image_formats, format)) return TRUE; /* XXX: try subpicture formats since some drivers could report a * set of VA image formats that is not a superset of the set of VA * subpicture formats */ - return find_format(display->priv->subpicture_formats, format); + return find_format( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); } /** @@ -1416,7 +1406,8 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); - return get_format_caps(display->priv->subpicture_formats); + return get_format_caps( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats); } /** @@ -1442,7 +1433,8 @@ gst_vaapi_display_has_subpicture_format( g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(format, FALSE); - fip = find_format_info(display->priv->subpicture_formats, format); + fip = find_format_info( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->subpicture_formats, format); if (!fip) return FALSE; @@ -1469,18 +1461,118 @@ gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name) g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); g_return_val_if_fail(name, FALSE); - return find_property(display->priv->properties, name) != NULL; + return find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name) != NULL; +} + +gboolean +gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, + GValue *out_value) +{ + const GstVaapiProperty *prop; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(out_value != NULL, FALSE); + + prop = find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); + if (!prop) + return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode: { + GstVaapiRenderMode mode; + if (!gst_vaapi_display_get_render_mode(display, &mode)) + return FALSE; + g_value_init(out_value, GST_VAAPI_TYPE_RENDER_MODE); + g_value_set_enum(out_value, mode); + break; + } + case VADisplayAttribRotation: { + GstVaapiRotation rotation; + rotation = gst_vaapi_display_get_rotation(display); + g_value_init(out_value, GST_VAAPI_TYPE_ROTATION); + g_value_set_enum(out_value, rotation); + break; + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast: { + gfloat value; + if (!get_color_balance(display, find_property_id(name), &value)) + return FALSE; + g_value_init(out_value, G_TYPE_FLOAT); + g_value_set_float(out_value, value); + break; + } + default: + GST_WARNING("unsupported property '%s'", name); + return FALSE; + } + return TRUE; +} + +gboolean +gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, + const GValue *value) +{ + const GstVaapiProperty *prop; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE); + g_return_val_if_fail(name != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + prop = find_property( + GST_VAAPI_DISPLAY_GET_PRIVATE(display)->properties, name); + if (!prop) + return FALSE; + + switch (prop->attribute.type) { + case VADisplayAttribRenderMode: { + GstVaapiRenderMode mode; + if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_RENDER_MODE)) + return FALSE; + mode = g_value_get_enum(value); + return gst_vaapi_display_set_render_mode(display, mode); + } + case VADisplayAttribRotation: { + GstVaapiRotation rotation; + if (!G_VALUE_HOLDS(value, GST_VAAPI_TYPE_ROTATION)) + return FALSE; + rotation = g_value_get_enum(value); + return gst_vaapi_display_set_rotation(display, rotation); + } + case VADisplayAttribHue: + case VADisplayAttribSaturation: + case VADisplayAttribBrightness: + case VADisplayAttribContrast: { + gfloat v; + if (!G_VALUE_HOLDS(value, G_TYPE_FLOAT)) + return FALSE; + v = g_value_get_float(value); + return set_color_balance(display, find_property_id(name), v); + } + default: + break; + } + + GST_WARNING("unsupported property '%s'", name); + return FALSE; } static gboolean get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); VADisplayAttribute attr; VAStatus status; attr.type = type; attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; - status = vaGetDisplayAttributes(display->priv->display, &attr, 1); + status = vaGetDisplayAttributes(priv->display, &attr, 1); if (!vaapi_check_status(status, "vaGetDisplayAttributes()")) return FALSE; *value = attr.value; @@ -1490,13 +1582,15 @@ get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) static gboolean set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); VADisplayAttribute attr; VAStatus status; attr.type = type; attr.value = value; attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; - status = vaSetDisplayAttributes(display->priv->display, &attr, 1); + status = vaSetDisplayAttributes(priv->display, &attr, 1); if (!vaapi_check_status(status, "vaSetDisplayAttributes()")) return FALSE; return TRUE; @@ -1553,7 +1647,10 @@ get_render_mode_default( GstVaapiRenderMode *pmode ) { - switch (display->priv->display_type) { + GstVaapiDisplayPrivate * const priv = + GST_VAAPI_DISPLAY_GET_PRIVATE(display); + + switch (priv->display_type) { #if USE_WAYLAND case GST_VAAPI_DISPLAY_TYPE_WAYLAND: /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ @@ -1647,8 +1744,6 @@ gst_vaapi_display_set_render_mode( return FALSE; if (!set_attribute(display, VADisplayAttribRenderMode, modes)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_RENDER_MODE]); return TRUE; } @@ -1700,8 +1795,6 @@ gst_vaapi_display_set_rotation( value = from_GstVaapiRotation(rotation); if (!set_attribute(display, VADisplayAttribRotation, value)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_ROTATION]); return TRUE; } @@ -1769,7 +1862,5 @@ set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v) (attr->value - attr->min_value)); if (!set_attribute(display, attr->type, value)) return FALSE; - - g_object_notify_by_pspec(G_OBJECT(display), g_properties[prop_id]); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index 53809b6..c5f392e 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -31,34 +31,14 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY \ - (gst_vaapi_display_get_type()) - -#define GST_VAAPI_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplay)) - -#define GST_VAAPI_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayClass)) +#define GST_VAAPI_DISPLAY(obj) \ + ((GstVaapiDisplay *)(obj)) #define GST_VAAPI_IS_DISPLAY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY)) - -#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY)) - -#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplay GstVaapiDisplay; -typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; -typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; /** * GstVaapiDisplayType: @@ -111,56 +91,18 @@ struct _GstVaapiDisplayInfo { #define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness" #define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast" -/** - * GstVaapiDisplay: - * - * Base class for VA displays. - */ -struct _GstVaapiDisplay { - /*< private >*/ - GObject parent_instance; - - GstVaapiDisplayPrivate *priv; -}; +GstVaapiDisplay * +gst_vaapi_display_new_with_display(VADisplay va_display); -/** - * GstVaapiDisplayClass: - * @open_display: virtual function to open a display - * @close_display: virtual function to close a display - * @lock: (optional) virtual function to lock a display - * @unlock: (optional) virtual function to unlock a display - * @sync: (optional) virtual function to sync a display - * @flush: (optional) virtual function to flush pending requests of a display - * @get_display: virtual function to retrieve the #GstVaapiDisplayInfo - * @get_size: virtual function to retrieve the display dimensions, in pixels - * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters - * - * Base class for VA displays. - */ -struct _GstVaapiDisplayClass { - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - gboolean (*open_display) (GstVaapiDisplay *display); - void (*close_display) (GstVaapiDisplay *display); - void (*lock) (GstVaapiDisplay *display); - void (*unlock) (GstVaapiDisplay *display); - void (*sync) (GstVaapiDisplay *display); - void (*flush) (GstVaapiDisplay *display); - gboolean (*get_display) (GstVaapiDisplay *display, - GstVaapiDisplayInfo *info); - void (*get_size) (GstVaapiDisplay *display, - guint *pwidth, guint *pheight); - void (*get_size_mm) (GstVaapiDisplay *display, - guint *pwidth, guint *pheight); -}; +GstVaapiDisplay * +gst_vaapi_display_ref(GstVaapiDisplay *display); -GType -gst_vaapi_display_get_type(void) G_GNUC_CONST; +void +gst_vaapi_display_unref(GstVaapiDisplay *display); -GstVaapiDisplay * -gst_vaapi_display_new_with_display(VADisplay va_display); +void +gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr, + GstVaapiDisplay *new_display); void gst_vaapi_display_lock(GstVaapiDisplay *display); @@ -239,6 +181,14 @@ gboolean gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name); gboolean +gst_vaapi_display_get_property(GstVaapiDisplay *display, const gchar *name, + GValue *out_value); + +gboolean +gst_vaapi_display_set_property(GstVaapiDisplay *display, const gchar *name, + const GValue *value); + +gboolean gst_vaapi_display_get_render_mode( GstVaapiDisplay *display, GstVaapiRenderMode *pmode diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index 8178c2c..da6235c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -39,17 +39,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayDRM, - gst_vaapi_display_drm, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_DEVICE_PATH, - PROP_DRM_DEVICE -}; - #define NAME_PREFIX "DRM:" #define NAME_PREFIX_LENGTH 4 @@ -74,18 +63,12 @@ compare_device_path(gconstpointer a, gconstpointer b, gpointer user_data) return strcmp(cached_name, tested_name) == 0; } -static void -gst_vaapi_display_drm_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class)->finalize(object); -} - /* Get default device path. Actually, the first match in the DRM subsystem */ static const gchar * -get_default_device_path(gpointer ptr) +get_default_device_path(GstVaapiDisplay *display) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); const gchar *syspath, *devpath; struct udev *udev = NULL; struct udev_device *device, *parent; @@ -137,10 +120,11 @@ get_default_device_path(gpointer ptr) /* Reconstruct a device path without our prefix */ static const gchar * -get_device_path(gpointer ptr) +get_device_path(GstVaapiDisplay *display) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); - const gchar *device_path = display->priv->device_path; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + const gchar *device_path = priv->device_path; if (!device_path) return NULL; @@ -154,10 +138,11 @@ get_device_path(gpointer ptr) } /* Mangle device path with our prefix */ -static void -set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) +static gboolean +set_device_path(GstVaapiDisplay *display, const gchar *device_path) { - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); g_free(priv->device_path); priv->device_path = NULL; @@ -165,34 +150,37 @@ set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) if (!device_path) { device_path = get_default_device_path(display); if (!device_path) - return; + return FALSE; } priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); + return priv->device_path != NULL; } /* Set device path from file descriptor */ -static void -set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) +static gboolean +set_device_path_from_fd(GstVaapiDisplay *display, gint drm_device) { - GstVaapiDisplayDRMPrivate * const priv = display->priv; + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); const gchar *busid, *path, *str; gsize busid_length, path_length; struct udev *udev = NULL; struct udev_device *device; struct udev_enumerate *e = NULL; struct udev_list_entry *l; + gboolean success = FALSE; g_free(priv->device_path); priv->device_path = NULL; if (drm_device < 0) - return; + goto end; busid = drmGetBusid(drm_device); if (!busid) - return; + goto end; if (strncmp(busid, "pci:", 4) != 0) - return; + goto end; busid += 4; busid_length = strlen(busid); @@ -227,109 +215,57 @@ set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) udev_device_unref(device); break; } + success = TRUE; end: if (e) udev_enumerate_unref(e); if (udev) udev_unref(udev); + return success; } -static void -gst_vaapi_display_drm_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +static gboolean +gst_vaapi_display_drm_bind_display(GstVaapiDisplay *display, + gpointer native_display) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); - - switch (prop_id) { - case PROP_DEVICE_PATH: - set_device_path(display, g_value_get_string(value)); - break; - case PROP_DRM_DEVICE: - display->priv->drm_device = g_value_get_int(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); -static void -gst_vaapi_display_drm_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); + priv->drm_device = GPOINTER_TO_INT(native_display); + priv->use_foreign_display = TRUE; - switch (prop_id) { - case PROP_DEVICE_PATH: - g_value_set_string(value, get_device_path(display)); - break; - case PROP_DRM_DEVICE: - g_value_set_int(value, display->priv->drm_device); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + if (!set_device_path_from_fd(display, priv->drm_device)) + return FALSE; + return TRUE; } -static void -gst_vaapi_display_drm_constructed(GObject *object) +static gboolean +gst_vaapi_display_drm_open_display(GstVaapiDisplay *display, const gchar *name) { - GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object); - GstVaapiDisplayDRMPrivate * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->drm_device < 0; - - /* Don't create DRM display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->device_path, - compare_device_path, NULL - ); - if (info) { - priv->drm_device = GPOINTER_TO_INT(info->native_display); - priv->create_display = FALSE; - } - } - /* Reset device-path if the user provided his own DRM display */ - if (!priv->create_display) - set_device_path_from_fd(display, priv->drm_device); - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_drm_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); -} + cache = gst_vaapi_display_get_cache(); + g_return_val_if_fail(cache != NULL, FALSE); -static gboolean -gst_vaapi_display_drm_open_display(GstVaapiDisplay *display) -{ - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + if (!set_device_path(display, name)) + return FALSE; - if (priv->create_display) { - const gchar *device_path = get_device_path(display); - if (!device_path) - return FALSE; - priv->drm_device = open(device_path, O_RDWR|O_CLOEXEC); + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->device_path, + compare_device_path, NULL); + if (info) { + priv->drm_device = GPOINTER_TO_INT(info->native_display); + priv->use_foreign_display = TRUE; + } + else { + priv->drm_device = open(get_device_path(display), O_RDWR|O_CLOEXEC); if (priv->drm_device < 0) return FALSE; + priv->use_foreign_display = FALSE; } - if (priv->drm_device < 0) - return FALSE; return TRUE; } @@ -337,10 +273,10 @@ static void gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) { GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); if (priv->drm_device >= 0) { - if (priv->create_display) + if (!priv->use_foreign_display) close(priv->drm_device); priv->drm_device = -1; } @@ -357,13 +293,11 @@ gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) } static gboolean -gst_vaapi_display_drm_get_display_info( - GstVaapiDisplay *display, - GstVaapiDisplayInfo *info -) +gst_vaapi_display_drm_get_display_info(GstVaapiDisplay *display, + GstVaapiDisplayInfo *info) { GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM(display)->priv; + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -391,62 +325,42 @@ gst_vaapi_display_drm_get_display_info( } static void +gst_vaapi_display_drm_init(GstVaapiDisplay *display) +{ + GstVaapiDisplayDRMPrivate * const priv = + GST_VAAPI_DISPLAY_DRM_PRIVATE(display); + + priv->drm_device = -1; +} + +static void gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayDRMPrivate)); - - object_class->finalize = gst_vaapi_display_drm_finalize; - object_class->set_property = gst_vaapi_display_drm_set_property; - object_class->get_property = gst_vaapi_display_drm_get_property; - object_class->constructed = gst_vaapi_display_drm_constructed; + gst_vaapi_display_class_init(&klass->parent_class); + object_class->size = sizeof(GstVaapiDisplayDRM); + dpy_class->init = gst_vaapi_display_drm_init; + dpy_class->bind_display = gst_vaapi_display_drm_bind_display; dpy_class->open_display = gst_vaapi_display_drm_open_display; dpy_class->close_display = gst_vaapi_display_drm_close_display; dpy_class->get_display = gst_vaapi_display_drm_get_display_info; - - /** - * GstVaapiDisplayDRM:drm-device: - * - * The DRM device (file descriptor). - */ - g_object_class_install_property - (object_class, - PROP_DRM_DEVICE, - g_param_spec_int("drm-device", - "DRM device", - "DRM device", - -1, G_MAXINT32, -1, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayDRM:device-path: - * - * The DRM device path. - */ - g_object_class_install_property - (object_class, - PROP_DEVICE_PATH, - g_param_spec_string("device-path", - "DRM device path", - "DRM device path", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } -static void -gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_drm_class(void) { - GstVaapiDisplayDRMPrivate * const priv = - GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(display); + static GstVaapiDisplayDRMClass g_class; + static gsize g_class_init = FALSE; - display->priv = priv; - priv->device_path_default = NULL; - priv->device_path = NULL; - priv->drm_device = -1; - priv->create_display = TRUE; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_drm_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -466,9 +380,8 @@ gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) GstVaapiDisplay * gst_vaapi_display_drm_new(const gchar *device_path) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, - "device-path", device_path, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_drm_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)device_path); } /** @@ -487,9 +400,8 @@ gst_vaapi_display_drm_new_with_device(gint device) { g_return_val_if_fail(device >= 0, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, - "drm-device", device, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_drm_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER(device)); } /** @@ -507,7 +419,7 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); - return display->priv->drm_device; + return GST_VAAPI_DISPLAY_DRM_DEVICE(display); } /** @@ -528,5 +440,5 @@ gst_vaapi_display_drm_get_device_path(GstVaapiDisplayDRM *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), NULL); - return display->priv->device_path; + return get_device_path(GST_VAAPI_DISPLAY_CAST(display)); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h index fad0d53..a0b1042 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.h @@ -26,59 +26,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_DRM \ - (gst_vaapi_display_drm_get_type()) - -#define GST_VAAPI_DISPLAY_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRM)) - -#define GST_VAAPI_DISPLAY_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMClass)) +#define GST_VAAPI_DISPLAY_DRM(obj) \ + ((GstVaapiDisplayDRM *)(obj)) #define GST_VAAPI_IS_DISPLAY_DRM(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_DRM)) - -#define GST_VAAPI_IS_DISPLAY_DRM_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_DRM)) - -#define GST_VAAPI_DISPLAY_DRM_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; -typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; -typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; - -/** - * GstVaapiDisplayDRM: - * - * VA/DRM display wrapper. - */ -struct _GstVaapiDisplayDRM { - /*< private >*/ - GstVaapiDisplay parent_instance; - - GstVaapiDisplayDRMPrivate *priv; -}; - - -/** - * GstVaapiDisplayDRMClass: - * - * VA/DRM display wrapper clas. - */ -struct _GstVaapiDisplayDRMClass { - /*< private >*/ - GstVaapiDisplayClass parent_class; -}; - -GType -gst_vaapi_display_drm_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_drm_new(const gchar *device_path); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h index f6211a7..3b8df8c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm_priv.h @@ -26,12 +26,14 @@ G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_DRM, \ - GstVaapiDisplayDRMPrivate)) +#define GST_VAAPI_DISPLAY_DRM_CAST(display) \ + ((GstVaapiDisplayDRM *)(display)) -#define GST_VAAPI_DISPLAY_DRM_CAST(display) ((GstVaapiDisplayDRM *)(display)) +#define GST_VAAPI_DISPLAY_DRM_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_DRM_CAST(display)->priv) + +typedef struct _GstVaapiDisplayDRMPrivate GstVaapiDisplayDRMPrivate; +typedef struct _GstVaapiDisplayDRMClass GstVaapiDisplayDRMClass; /** * GST_VAAPI_DISPLAY_DRM_DEVICE: @@ -41,13 +43,35 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_DRM_DEVICE #define GST_VAAPI_DISPLAY_DRM_DEVICE(display) \ - GST_VAAPI_DISPLAY_DRM_CAST(display)->priv->drm_device + GST_VAAPI_DISPLAY_DRM_PRIVATE(display)->drm_device struct _GstVaapiDisplayDRMPrivate { - gchar *device_path_default; - gchar *device_path; - gint drm_device; - guint create_display : 1; + gchar *device_path_default; + gchar *device_path; + gint drm_device; + guint use_foreign_display : 1; // Foreign native_display? +}; + +/** + * GstVaapiDisplayDRM: + * + * VA/DRM display wrapper. + */ +struct _GstVaapiDisplayDRM { + /*< private >*/ + GstVaapiDisplay parent_instance; + + GstVaapiDisplayDRMPrivate priv; +}; + +/** + * GstVaapiDisplayDRMClass: + * + * VA/DRM display wrapper clas. + */ +struct _GstVaapiDisplayDRMClass { + /*< private >*/ + GstVaapiDisplayClass parent_class; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 10077ee..0810239 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -37,45 +37,47 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayGLX, - gst_vaapi_display_glx, - GST_VAAPI_TYPE_DISPLAY_X11) - -static void -gst_vaapi_display_glx_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_glx_parent_class)->finalize(object); -} - static gboolean gst_vaapi_display_glx_get_display_info( GstVaapiDisplay *display, GstVaapiDisplayInfo *info ) { - GstVaapiDisplayClass * const dpy_class = - GST_VAAPI_DISPLAY_CLASS(gst_vaapi_display_glx_parent_class); + const GstVaapiDisplayGLXClass * const klass = + GST_VAAPI_DISPLAY_GLX_GET_CLASS(display); info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); if (!info->va_display) return FALSE; info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; - return dpy_class->get_display(display, info); + return klass->parent_get_display(display, info); } static void gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - object_class->finalize = gst_vaapi_display_glx_finalize; + gst_vaapi_display_x11_class_init(&klass->parent_class); + + object_class->size = sizeof(GstVaapiDisplayGLX); + klass->parent_get_display = dpy_class->get_display; dpy_class->get_display = gst_vaapi_display_glx_get_display_info; } -static void -gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_glx_class(void) { + static GstVaapiDisplayGLXClass g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_glx_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -91,9 +93,8 @@ gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) GstVaapiDisplay * gst_vaapi_display_glx_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_glx_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -110,7 +111,8 @@ gst_vaapi_display_glx_new(const gchar *display_name) GstVaapiDisplay * gst_vaapi_display_glx_new_with_display(Display *x11_display) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, - "x11-display", x11_display, - NULL); + g_return_val_if_fail(x11_display != NULL, NULL); + + return gst_vaapi_display_new(gst_vaapi_display_glx_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 057baf7..cf318f5 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -29,56 +29,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_GLX \ - (gst_vaapi_display_glx_get_type()) - -#define GST_VAAPI_DISPLAY_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLX)) - -#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLXClass)) +#define GST_VAAPI_DISPLAY_GLX(obj) \ + ((GstVaapiDisplayGLX *)(obj)) #define GST_VAAPI_IS_DISPLAY_GLX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_GLX)) - -#define GST_VAAPI_IS_DISPLAY_GLX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_GLX)) - -#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_GLX, \ - GstVaapiDisplayGLXClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; -typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; - -/** - * GstVaapiDisplayGLX: - * - * VA/GLX display wrapper. - */ -struct _GstVaapiDisplayGLX { - /*< private >*/ - GstVaapiDisplayX11 parent_instance; -}; - - -/** - * GstVaapiDisplayGLXClass: - * - * VA/GLX display wrapper clas. - */ -struct _GstVaapiDisplayGLXClass { - /*< private >*/ - GstVaapiDisplayX11Class parent_class; -}; - -GType -gst_vaapi_display_glx_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_glx_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h index a843b38..72e44d4 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx_priv.h @@ -24,10 +24,42 @@ #include #include +#include "gstvaapidisplay_x11_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_GLX_CAST(display) ((GstVaapiDisplayGLX *)(display)) +#define GST_VAAPI_DISPLAY_GLX_CAST(display) \ + ((GstVaapiDisplayGLX *)(display)) + +#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \ + ((GstVaapiDisplayGLXClass *)(klass)) + +#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \ + GST_VAAPI_DISPLAY_GLX_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass; + +/** + * GstVaapiDisplayGLX: + * + * VA/GLX display wrapper. + */ +struct _GstVaapiDisplayGLX { + /*< private >*/ + GstVaapiDisplayX11 parent_instance; +}; + +/** + * GstVaapiDisplayGLXClass: + * + * VA/GLX display wrapper clas. + */ +struct _GstVaapiDisplayGLXClass { + /*< private >*/ + GstVaapiDisplayX11Class parent_class; + + GstVaapiDisplayGetInfoFunc parent_get_display; +}; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h index cb5302b..24bf751 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_priv.h @@ -25,15 +25,45 @@ #include #include +#include "gstvaapiminiobject.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplayPrivate)) +#define GST_VAAPI_DISPLAY_CAST(display) \ + ((GstVaapiDisplay *)(display)) -#define GST_VAAPI_DISPLAY_CAST(display) ((GstVaapiDisplay *)(display)) +#define GST_VAAPI_DISPLAY_GET_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_CAST(display)->priv) + +#define GST_VAAPI_DISPLAY_CLASS(klass) \ + ((GstVaapiDisplayClass *)(klass)) + +#define GST_VAAPI_IS_DISPLAY_CLASS(klass) \ + ((klass) != NULL) + +#define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ + GST_VAAPI_DISPLAY_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj)) + +typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; +typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; +typedef enum _GstVaapiDisplayInitType GstVaapiDisplayInitType; + +typedef void (*GstVaapiDisplayInitFunc) (GstVaapiDisplay *display); +typedef gboolean (*GstVaapiDisplayBindFunc) (GstVaapiDisplay *display, + gpointer native_dpy); +typedef gboolean (*GstVaapiDisplayOpenFunc) (GstVaapiDisplay *display, + const gchar *name); +typedef void (*GstVaapiDisplayCloseFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayLockFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayUnlockFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplaySyncFunc) (GstVaapiDisplay *display); +typedef void (*GstVaapiDisplayFlushFunc) (GstVaapiDisplay *display); +typedef gboolean (*GstVaapiDisplayGetInfoFunc) (GstVaapiDisplay *display, + GstVaapiDisplayInfo *info); +typedef void (*GstVaapiDisplayGetSizeFunc) (GstVaapiDisplay *display, + guint *pwidth, guint *pheight); +typedef void (*GstVaapiDisplayGetSizeMFunc)(GstVaapiDisplay *display, + guint *pwidth, guint *pheight); /** * GST_VAAPI_DISPLAY_VADISPLAY: @@ -44,7 +74,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_VADISPLAY #define GST_VAAPI_DISPLAY_VADISPLAY(display_) \ - GST_VAAPI_DISPLAY_CAST(display_)->priv->display + GST_VAAPI_DISPLAY_GET_PRIVATE(display_)->display /** * GST_VAAPI_DISPLAY_LOCK: @@ -66,11 +96,6 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_UNLOCK(display) \ gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) -/** - * GstVaapiDisplayPrivate: - * - * Base class for VA displays. - */ struct _GstVaapiDisplayPrivate { GstVaapiDisplay *parent; GRecMutex mutex; @@ -87,12 +112,95 @@ struct _GstVaapiDisplayPrivate { GArray *image_formats; GArray *subpicture_formats; GArray *properties; - guint create_display : 1; + guint use_foreign_display : 1; }; +/** + * GstVaapiDisplay: + * + * Base class for VA displays. + */ +struct _GstVaapiDisplay { + /*< private >*/ + GstVaapiMiniObject parent_instance; + + GstVaapiDisplayPrivate priv; +}; + +/** + * GstVaapiDisplayClass: + * @open_display: virtual function to open a display + * @close_display: virtual function to close a display + * @lock: (optional) virtual function to lock a display + * @unlock: (optional) virtual function to unlock a display + * @sync: (optional) virtual function to sync a display + * @flush: (optional) virtual function to flush pending requests of a display + * @get_display: virtual function to retrieve the #GstVaapiDisplayInfo + * @get_size: virtual function to retrieve the display dimensions, in pixels + * @get_size_mm: virtual function to retrieve the display dimensions, in millimeters + * + * Base class for VA displays. + */ +struct _GstVaapiDisplayClass { + /*< private >*/ + GstVaapiMiniObjectClass parent_class; + + /*< public >*/ + GstVaapiDisplayInitFunc init; + GstVaapiDisplayBindFunc bind_display; + GstVaapiDisplayOpenFunc open_display; + GstVaapiDisplayCloseFunc close_display; + GstVaapiDisplayLockFunc lock; + GstVaapiDisplayUnlockFunc unlock; + GstVaapiDisplaySyncFunc sync; + GstVaapiDisplayFlushFunc flush; + GstVaapiDisplayGetInfoFunc get_display; + GstVaapiDisplayGetSizeFunc get_size; + GstVaapiDisplayGetSizeMFunc get_size_mm; +}; + +/* Initialization types */ +enum _GstVaapiDisplayInitType { + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME = 1, + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, + GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY +}; + +void +gst_vaapi_display_class_init(GstVaapiDisplayClass *klass); + +GstVaapiDisplay * +gst_vaapi_display_new(const GstVaapiDisplayClass *klass, + GstVaapiDisplayInitType init_type, gpointer init_value); + GstVaapiDisplayCache * gst_vaapi_display_get_cache(void); +/* Inline reference counting for core libgstvaapi library */ +#ifdef GST_VAAPI_CORE +#define gst_vaapi_display_ref_internal(display) \ + ((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(display))) + +#define gst_vaapi_display_unref_internal(display) \ + gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(display)) + +#define gst_vaapi_display_replace_internal(old_display_ptr, new_display) \ + gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_display_ptr), \ + GST_VAAPI_MINI_OBJECT(new_display)) + +#undef gst_vaapi_display_ref +#define gst_vaapi_display_ref(display) \ + gst_vaapi_display_ref_internal((display)) + +#undef gst_vaapi_display_unref +#define gst_vaapi_display_unref(display) \ + gst_vaapi_display_unref_internal((display)) + +#undef gst_vaapi_display_replace +#define gst_vaapi_display_replace(old_display_ptr, new_display) \ + gst_vaapi_display_replace_internal((old_display_ptr), (new_display)) +#endif + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c index 3d162b1..08e8cf8 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.c @@ -33,17 +33,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayWayland, - gst_vaapi_display_wayland, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_DISPLAY_NAME, - PROP_WL_DISPLAY -}; - #define NAME_PREFIX "WLD:" #define NAME_PREFIX_LENGTH 4 @@ -98,18 +87,13 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) return TRUE; } -static void -gst_vaapi_display_wayland_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class)->finalize(object); -} - /* Reconstruct a display name without our prefix */ static const gchar * -get_display_name(gpointer ptr) +get_display_name(GstVaapiDisplayWayland *display) { - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(ptr); - const gchar *display_name = display->priv->display_name; + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + const gchar *display_name = priv->display_name; if (!display_name) return NULL; @@ -127,10 +111,11 @@ get_display_name(gpointer ptr) } /* Mangle display name with our prefix */ -static void -set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) +static gboolean +set_display_name(GstVaapiDisplay *display, const gchar *display_name) { - GstVaapiDisplayWaylandPrivate * const priv = display->priv; + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); g_free(priv->display_name); @@ -140,87 +125,7 @@ set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) display_name = ""; } priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); -} - -static void -gst_vaapi_display_wayland_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - - switch (prop_id) { - case PROP_DISPLAY_NAME: - set_display_name(display, g_value_get_string(value)); - break; - case PROP_WL_DISPLAY: - display->priv->wl_display = g_value_get_pointer(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} -static void -gst_vaapi_display_wayland_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - - switch (prop_id) { - case PROP_DISPLAY_NAME: - g_value_set_string(value, get_display_name(display)); - break; - case PROP_WL_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_wayland_get_display(display)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -gst_vaapi_display_wayland_constructed(GObject *object) -{ - GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(object); - GstVaapiDisplayWaylandPrivate * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); - const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->wl_display == NULL; - - /* Don't create Wayland display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->display_name, - compare_display_name, NULL - ); - if (info) { - priv->wl_display = info->native_display; - priv->create_display = FALSE; - } - } - - /* Reset display-name if the user provided his own Wayland display */ - if (!priv->create_display) { - /* XXX: how to get socket/display name? */ - GST_WARNING("wayland: get display name"); - set_display_name(display, NULL); - } - - parent_class = G_OBJECT_CLASS(gst_vaapi_display_wayland_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + return priv->display_name != NULL; } static void @@ -280,16 +185,10 @@ static const struct wl_registry_listener registry_listener = { }; static gboolean -gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) +gst_vaapi_display_wayland_setup(GstVaapiDisplay *display) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; - - if (priv->create_display) { - priv->wl_display = wl_display_connect(get_display_name(display)); - if (!priv->wl_display) - return FALSE; - } + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); wl_display_set_user_data(priv->wl_display, priv); priv->registry = wl_display_get_registry(priv->wl_display); @@ -317,11 +216,58 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) return TRUE; } +static gboolean +gst_vaapi_display_wayland_bind_display(GstVaapiDisplay *display, + gpointer native_display) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + + priv->wl_display = native_display; + priv->use_foreign_display = TRUE; + + /* XXX: how to get socket/display name? */ + GST_WARNING("wayland: get display name"); + set_display_name(display, NULL); + + return gst_vaapi_display_wayland_setup(display); +} + +static gboolean +gst_vaapi_display_wayland_open_display(GstVaapiDisplay *display, + const gchar *name) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + GstVaapiDisplayCache *cache; + 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; + + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, + compare_display_name, NULL); + if (info) { + priv->wl_display = info->native_display; + priv->use_foreign_display = TRUE; + } + else { + priv->wl_display = wl_display_connect(name); + if (!priv->wl_display) + return FALSE; + priv->use_foreign_display = FALSE; + } + return gst_vaapi_display_wayland_setup(display); +} + static void gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (priv->compositor) { wl_compositor_destroy(priv->compositor); @@ -329,7 +275,7 @@ gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) } if (priv->wl_display) { - if (priv->create_display) + if (!priv->use_foreign_display) wl_display_disconnect(priv->wl_display); priv->wl_display = NULL; } @@ -347,7 +293,7 @@ gst_vaapi_display_wayland_get_display_info( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -355,8 +301,8 @@ gst_vaapi_display_wayland_get_display_info( cache = gst_vaapi_display_get_cache(); if (!cache) return FALSE; - cached_info = - gst_vaapi_display_cache_lookup_by_native_display(cache, priv->wl_display); + cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, + priv->wl_display); if (cached_info) { *info = *cached_info; return TRUE; @@ -382,7 +328,7 @@ gst_vaapi_display_wayland_get_size( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (!priv->output) return; @@ -402,7 +348,7 @@ gst_vaapi_display_wayland_get_size_mm( ) { GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND(display)->priv; + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); if (!priv->output) return; @@ -415,72 +361,44 @@ gst_vaapi_display_wayland_get_size_mm( } static void +gst_vaapi_display_wayland_init(GstVaapiDisplay *display) +{ + GstVaapiDisplayWaylandPrivate * const priv = + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + + priv->event_fd = -1; +} + +static void gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayWaylandPrivate)); - - object_class->finalize = gst_vaapi_display_wayland_finalize; - object_class->set_property = gst_vaapi_display_wayland_set_property; - object_class->get_property = gst_vaapi_display_wayland_get_property; - object_class->constructed = gst_vaapi_display_wayland_constructed; + gst_vaapi_display_class_init(&klass->parent_class); + object_class->size = sizeof(GstVaapiDisplayWayland); + dpy_class->init = gst_vaapi_display_wayland_init; + dpy_class->bind_display = gst_vaapi_display_wayland_bind_display; dpy_class->open_display = gst_vaapi_display_wayland_open_display; dpy_class->close_display = gst_vaapi_display_wayland_close_display; dpy_class->get_display = gst_vaapi_display_wayland_get_display_info; dpy_class->get_size = gst_vaapi_display_wayland_get_size; dpy_class->get_size_mm = gst_vaapi_display_wayland_get_size_mm; - - /** - * GstVaapiDisplayWayland:wayland-display: - * - * The Wayland #wl_display that was created by - * gst_vaapi_display_wayland_new() or that was bound from - * gst_vaapi_display_wayland_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_WL_DISPLAY, - g_param_spec_pointer("wl-display", - "Wayland display", - "Wayland display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayWayland:display-name: - * - * The Wayland display name. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", - "Wayland display name", - "Wayland display name", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } -static void -gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_wayland_class(void) { - GstVaapiDisplayWaylandPrivate * const priv = - GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); + static GstVaapiDisplayWaylandClass g_class; + static gsize g_class_init = FALSE; - display->priv = priv; - priv->create_display = TRUE; - priv->display_name = NULL; - priv->wl_display = NULL; - priv->compositor = NULL; - priv->shell = NULL; - priv->output = NULL; - priv->width = 0; - priv->height = 0; - priv->phys_width = 0; - priv->phys_height = 0; - priv->event_fd = -1; + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_wayland_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -496,9 +414,8 @@ gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) GstVaapiDisplay * gst_vaapi_display_wayland_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -517,9 +434,8 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display) { g_return_val_if_fail(wl_display, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, - "wl-display", wl_display, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_wayland_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display); } /** @@ -537,5 +453,5 @@ gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); - return display->priv->wl_display; + return GST_VAAPI_DISPLAY_WL_DISPLAY(display); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h index c5fc0f6..3f17728 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland.h @@ -27,58 +27,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_WAYLAND \ - (gst_vaapi_display_wayland_get_type()) - -#define GST_VAAPI_DISPLAY_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWayland)) - -#define GST_VAAPI_DISPLAY_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandClass)) +#define GST_VAAPI_DISPLAY_WAYLAND(obj) \ + ((GstVaapiDisplayWayland *)(obj)) #define GST_VAAPI_IS_DISPLAY_WAYLAND(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) - -#define GST_VAAPI_IS_DISPLAY_WAYLAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) - -#define GST_VAAPI_DISPLAY_WAYLAND_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandClass)) + ((obj) != NULL) typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; -typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate; -typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; - -/** - * GstVaapiDisplayWayland: - * - * VA/Wayland display wrapper. - */ -struct _GstVaapiDisplayWayland { - /*< private >*/ - GstVaapiDisplay parent_instance; - - GstVaapiDisplayWaylandPrivate *priv; -}; - -/** - * GstVaapiDisplayWaylandClass: - * - * VA/Wayland display wrapper clas. - */ -struct _GstVaapiDisplayWaylandClass { - /*< private >*/ - GstVaapiDisplayClass parent_class; -}; - -GType -gst_vaapi_display_wayland_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_wayland_new(const gchar *display_name); diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h index 1fff458..3c09c5f 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_wayland_priv.h @@ -23,17 +23,19 @@ #define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H #include +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_WAYLAND, \ - GstVaapiDisplayWaylandPrivate)) - #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \ ((GstVaapiDisplayWayland *)(display)) +#define GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_WAYLAND_CAST(display)->priv) + +typedef struct _GstVaapiDisplayWaylandPrivate GstVaapiDisplayWaylandPrivate; +typedef struct _GstVaapiDisplayWaylandClass GstVaapiDisplayWaylandClass; + /** * GST_VAAPI_DISPLAY_WL_DISPLAY: * @display: a #GstVaapiDisplay @@ -43,7 +45,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_WL_DISPLAY #define GST_VAAPI_DISPLAY_WL_DISPLAY(display) \ - GST_VAAPI_DISPLAY_WAYLAND_CAST(display)->priv->wl_display + GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display)->wl_display struct _GstVaapiDisplayWaylandPrivate { gchar *display_name; @@ -57,7 +59,29 @@ struct _GstVaapiDisplayWaylandPrivate { guint phys_width; guint phys_height; gint event_fd; - guint create_display : 1; + guint use_foreign_display : 1; +}; + +/** + * GstVaapiDisplayWayland: + * + * VA/Wayland display wrapper. + */ +struct _GstVaapiDisplayWayland { + /*< private >*/ + GstVaapiDisplay parent_instance; + + GstVaapiDisplayWaylandPrivate priv; +}; + +/** + * GstVaapiDisplayWaylandClass: + * + * VA/Wayland display wrapper clas. + */ +struct _GstVaapiDisplayWaylandClass { + /*< private >*/ + GstVaapiDisplayClass parent_class; }; G_END_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index d632e48..970b255 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -39,19 +39,6 @@ #define DEBUG 1 #include "gstvaapidebug.h" -G_DEFINE_TYPE(GstVaapiDisplayX11, - gst_vaapi_display_x11, - GST_VAAPI_TYPE_DISPLAY) - -enum { - PROP_0, - - PROP_SYNCHRONOUS, - PROP_DISPLAY_NAME, - PROP_X11_DISPLAY, - PROP_X11_SCREEN -}; - #define NAME_PREFIX "X11:" #define NAME_PREFIX_LENGTH 4 @@ -105,18 +92,12 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data) return TRUE; } -static void -gst_vaapi_display_x11_finalize(GObject *object) -{ - G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object); -} - /* Reconstruct a display name without our prefix */ static const gchar * -get_display_name(gpointer ptr) +get_display_name(GstVaapiDisplayX11 *display) { - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(ptr); - const gchar *display_name = display->priv->display_name; + GstVaapiDisplayX11Private * const priv = &display->priv; + const gchar *display_name = priv->display_name; if (!display_name) return NULL; @@ -134,10 +115,10 @@ get_display_name(gpointer ptr) } /* Mangle display name with our prefix */ -static void +static gboolean set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) { - GstVaapiDisplayX11Private * const priv = display->priv; + GstVaapiDisplayX11Private * const priv = &display->priv; g_free(priv->display_name); @@ -147,12 +128,14 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) display_name = ""; } priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); + return priv->display_name != NULL; } +/* Set synchronous behavious on the underlying X11 display */ static void set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) { - GstVaapiDisplayX11Private * const priv = display->priv; + GstVaapiDisplayX11Private * const priv = &display->priv; if (priv->synchronous != synchronous) { priv->synchronous = synchronous; @@ -161,122 +144,70 @@ set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) } } +/* Check whether XRANDR extension is available */ static void -gst_vaapi_display_x11_set_property( - GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec -) +check_xrandr(GstVaapiDisplayX11 *display) { - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); - - switch (prop_id) { - case PROP_SYNCHRONOUS: - set_synchronous(display, g_value_get_boolean(value)); - break; - case PROP_DISPLAY_NAME: - set_display_name(display, g_value_get_string(value)); - break; - case PROP_X11_DISPLAY: - display->priv->x11_display = g_value_get_pointer(value); - break; - case PROP_X11_SCREEN: - display->priv->x11_screen = g_value_get_int(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} +#ifdef HAVE_XRANDR + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11_PRIVATE(display); + int evt_base, err_base; -static void -gst_vaapi_display_x11_get_property( - GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec -) -{ - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); - - switch (prop_id) { - case PROP_SYNCHRONOUS: - g_value_set_boolean(value, display->priv->synchronous); - break; - case PROP_DISPLAY_NAME: - g_value_set_string(value, get_display_name(display)); - break; - case PROP_X11_DISPLAY: - g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); - break; - case PROP_X11_SCREEN: - g_value_set_int(value, gst_vaapi_display_x11_get_screen(display)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } + priv->use_xrandr = XRRQueryExtension(priv->x11_display, + &evt_base, &err_base); +#endif } -static void -gst_vaapi_display_x11_constructed(GObject *object) +static gboolean +gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display, + gpointer native_display) { - GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); - GstVaapiDisplayX11Private * const priv = display->priv; - GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache(); - const GstVaapiDisplayInfo *info; - GObjectClass *parent_class; - - priv->create_display = priv->x11_display == NULL; - - /* Don't create X11 display if there is one in the cache already */ - if (priv->create_display) { - info = gst_vaapi_display_cache_lookup_by_name( - cache, - priv->display_name, - compare_display_name, NULL - ); - if (info) { - priv->x11_display = info->native_display; - priv->create_display = FALSE; - } - } + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11_CAST(base_display); + GstVaapiDisplayX11Private * const priv = &display->priv; + + priv->x11_display = native_display; + priv->x11_screen = DefaultScreen(native_display); + priv->use_foreign_display = TRUE; - /* Reset display-name if the user provided his own X11 display */ - if (!priv->create_display) - set_display_name(display, XDisplayString(priv->x11_display)); + check_xrandr(display); - parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class); - if (parent_class->constructed) - parent_class->constructed(object); + if (!set_display_name(display, XDisplayString(priv->x11_display))) + return FALSE; + return TRUE; } static gboolean -gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) +gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display, + const gchar *name) { - GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GstVaapiDisplayX11 * const display = + GST_VAAPI_DISPLAY_X11_CAST(base_display); + GstVaapiDisplayX11Private * const priv = &display->priv; + GstVaapiDisplayCache *cache; + const GstVaapiDisplayInfo *info; + + cache = gst_vaapi_display_get_cache(); + g_return_val_if_fail(cache != NULL, FALSE); - if (priv->create_display) { + if (!set_display_name(display, name)) + return FALSE; + + info = gst_vaapi_display_cache_lookup_by_name(cache, priv->display_name, + compare_display_name, NULL); + if (info) { + priv->x11_display = info->native_display; + priv->use_foreign_display = TRUE; + } + else { priv->x11_display = XOpenDisplay(get_display_name(display)); if (!priv->x11_display) return FALSE; - priv->x11_screen = DefaultScreen(priv->x11_display); + priv->use_foreign_display = FALSE; } - if (!priv->x11_display) - return FALSE; + priv->x11_screen = DefaultScreen(priv->x11_display); - if (priv->synchronous) - XSynchronize(priv->x11_display, True); - -#ifdef HAVE_XRANDR - { - int evt_base, err_base; - priv->use_xrandr = XRRQueryExtension( - priv->x11_display, &evt_base, &err_base); - } -#endif + check_xrandr(display); return TRUE; } @@ -284,10 +215,10 @@ static void gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { - if (priv->create_display) + if (!priv->use_foreign_display) XCloseDisplay(priv->x11_display); priv->x11_display = NULL; } @@ -302,7 +233,7 @@ static void gst_vaapi_display_x11_sync(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { GST_VAAPI_DISPLAY_LOCK(display); @@ -315,7 +246,7 @@ static void gst_vaapi_display_x11_flush(GstVaapiDisplay *display) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (priv->x11_display) { GST_VAAPI_DISPLAY_LOCK(display); @@ -331,7 +262,7 @@ gst_vaapi_display_x11_get_display_info( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); GstVaapiDisplayCache *cache; const GstVaapiDisplayInfo *cached_info; @@ -366,7 +297,7 @@ gst_vaapi_display_x11_get_size( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); if (!priv->x11_display) return; @@ -386,7 +317,7 @@ gst_vaapi_display_x11_get_size_mm( ) { GstVaapiDisplayX11Private * const priv = - GST_VAAPI_DISPLAY_X11(display)->priv; + GST_VAAPI_DISPLAY_X11_PRIVATE(display); guint width_mm, height_mm; if (!priv->x11_display) @@ -435,19 +366,17 @@ gst_vaapi_display_x11_get_size_mm( *pheight = height_mm; } -static void +void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) { - GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiMiniObjectClass * const object_class = + GST_VAAPI_MINI_OBJECT_CLASS(klass); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); - g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); - - object_class->finalize = gst_vaapi_display_x11_finalize; - object_class->set_property = gst_vaapi_display_x11_set_property; - object_class->get_property = gst_vaapi_display_x11_get_property; - object_class->constructed = gst_vaapi_display_x11_constructed; + gst_vaapi_display_class_init(&klass->parent_class); + object_class->size = sizeof(GstVaapiDisplayX11); + dpy_class->bind_display = gst_vaapi_display_x11_bind_display; dpy_class->open_display = gst_vaapi_display_x11_open_display; dpy_class->close_display = gst_vaapi_display_x11_close_display; dpy_class->sync = gst_vaapi_display_x11_sync; @@ -455,77 +384,19 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) dpy_class->get_display = gst_vaapi_display_x11_get_display_info; dpy_class->get_size = gst_vaapi_display_x11_get_size; dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm; - - /** - * GstVaapiDisplayX11:synchronous: - * - * When enabled, runs the X display in synchronous mode. Note that - * this is used only for debugging. - */ - g_object_class_install_property - (object_class, - PROP_SYNCHRONOUS, - g_param_spec_boolean("synchronous", - "Synchronous mode", - "Toggles X display synchronous mode", - FALSE, - G_PARAM_READWRITE)); - - /** - * GstVaapiDisplayX11:x11-display: - * - * The X11 #Display that was created by gst_vaapi_display_x11_new() - * or that was bound from gst_vaapi_display_x11_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_X11_DISPLAY, - g_param_spec_pointer("x11-display", - "X11 display", - "X11 display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayX11:x11-screen: - * - * The X11 screen that was created by gst_vaapi_display_x11_new() - * or that was bound from gst_vaapi_display_x11_new_with_display(). - */ - g_object_class_install_property - (object_class, - PROP_X11_SCREEN, - g_param_spec_int("x11-screen", - "X11 screen", - "X11 screen", - 0, G_MAXINT32, 0, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVaapiDisplayX11:display-name: - * - * The X11 display name. - */ - g_object_class_install_property - (object_class, - PROP_DISPLAY_NAME, - g_param_spec_string("display-name", - "X11 display name", - "X11 display name", - NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } -static void -gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) +static inline const GstVaapiDisplayClass * +gst_vaapi_display_x11_class(void) { - GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); - - display->priv = priv; - priv->create_display = TRUE; - priv->x11_display = NULL; - priv->x11_screen = 0; - priv->display_name = NULL; - priv->use_xrandr = FALSE; + static GstVaapiDisplayX11Class g_class; + static gsize g_class_init = FALSE; + + if (g_once_init_enter(&g_class_init)) { + gst_vaapi_display_x11_class_init(&g_class); + g_once_init_leave(&g_class_init, TRUE); + } + return GST_VAAPI_DISPLAY_CLASS(&g_class); } /** @@ -541,9 +412,8 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name) { - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "display-name", display_name, - NULL); + return gst_vaapi_display_new(gst_vaapi_display_x11_class(), + GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name); } /** @@ -562,10 +432,8 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display) { g_return_val_if_fail(x11_display, NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "x11-display", x11_display, - "x11-screen", DefaultScreen(x11_display), - NULL); + return gst_vaapi_display_new(gst_vaapi_display_x11_class(), + GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display); } /** @@ -583,7 +451,7 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - return display->priv->x11_display; + return GST_VAAPI_DISPLAY_XDISPLAY(display); } /** @@ -601,5 +469,25 @@ gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display) { g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1); - return display->priv->x11_screen; + return GST_VAAPI_DISPLAY_XSCREEN(display); +} + +/** + * gst_vaapi_display_x11_set_synchronous: + * @display: a #GstVaapiDisplayX11 + * @synchronous: boolean value that indicates whether to enable or + * disable synchronization + * + * If @synchronous is %TRUE, gst_vaapi_display_x11_set_synchronous() + * turns on synchronous behaviour on the underlying X11 + * display. Otherwise, synchronous behaviour is disabled if + * @synchronous is %FALSE. + */ +void +gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, + gboolean synchronous) +{ + g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display)); + + set_synchronous(display, synchronous); } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index 66f8f1b..6892223 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -28,59 +28,13 @@ G_BEGIN_DECLS -#define GST_VAAPI_TYPE_DISPLAY_X11 \ - (gst_vaapi_display_x11_get_type()) - -#define GST_VAAPI_DISPLAY_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11)) - -#define GST_VAAPI_DISPLAY_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Class)) +#define GST_VAAPI_DISPLAY_X11(obj) \ + ((GstVaapiDisplayX11 *)(obj)) #define GST_VAAPI_IS_DISPLAY_X11(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_X11)) - -#define GST_VAAPI_IS_DISPLAY_X11_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_X11)) - -#define GST_VAAPI_DISPLAY_X11_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Class)) + ((obj) != NULL) typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; -typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; -typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; - -/** - * GstVaapiDisplayX11: - * - * VA/X11 display wrapper. - */ -struct _GstVaapiDisplayX11 { - /*< private >*/ - GstVaapiDisplay parent_instance; - - GstVaapiDisplayX11Private *priv; -}; - - -/** - * GstVaapiDisplayX11Class: - * - * VA/X11 display wrapper clas. - */ -struct _GstVaapiDisplayX11Class { - /*< private >*/ - GstVaapiDisplayClass parent_class; -}; - -GType -gst_vaapi_display_x11_get_type(void) G_GNUC_CONST; GstVaapiDisplay * gst_vaapi_display_x11_new(const gchar *display_name); @@ -94,6 +48,10 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); int gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display); +void +gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display, + gboolean synchronous); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h index 17b54be..2d8203c 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11_priv.h @@ -25,15 +25,18 @@ #include #include +#include "gstvaapidisplay_priv.h" G_BEGIN_DECLS -#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ - GST_VAAPI_TYPE_DISPLAY_X11, \ - GstVaapiDisplayX11Private)) +#define GST_VAAPI_DISPLAY_X11_CAST(display) \ + ((GstVaapiDisplayX11 *)(display)) -#define GST_VAAPI_DISPLAY_X11_CAST(display) ((GstVaapiDisplayX11 *)(display)) +#define GST_VAAPI_DISPLAY_X11_PRIVATE(display) \ + (&GST_VAAPI_DISPLAY_X11_CAST(display)->priv) + +typedef struct _GstVaapiDisplayX11Private GstVaapiDisplayX11Private; +typedef struct _GstVaapiDisplayX11Class GstVaapiDisplayX11Class; /** * GST_VAAPI_DISPLAY_XDISPLAY: @@ -43,7 +46,7 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_XDISPLAY #define GST_VAAPI_DISPLAY_XDISPLAY(display) \ - GST_VAAPI_DISPLAY_X11_CAST(display)->priv->x11_display + GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_display /** * GST_VAAPI_DISPLAY_XSCREEN: @@ -53,17 +56,42 @@ G_BEGIN_DECLS */ #undef GST_VAAPI_DISPLAY_XSCREEN #define GST_VAAPI_DISPLAY_XSCREEN(display) \ - GST_VAAPI_DISPLAY_X11_CAST(display)->priv->x11_screen + GST_VAAPI_DISPLAY_X11_PRIVATE(display)->x11_screen struct _GstVaapiDisplayX11Private { - gchar *display_name; - Display *x11_display; - int x11_screen; - guint create_display : 1; - guint synchronous : 1; - guint use_xrandr : 1; + gchar *display_name; + Display *x11_display; + int x11_screen; + guint use_foreign_display : 1; // Foreign native_display? + guint use_xrandr : 1; + guint synchronous : 1; +}; + +/** + * GstVaapiDisplayX11: + * + * VA/X11 display wrapper. + */ +struct _GstVaapiDisplayX11 { + /*< private >*/ + GstVaapiDisplay parent_instance; + + GstVaapiDisplayX11Private priv; }; +/** + * GstVaapiDisplayX11Class: + * + * VA/X11 display wrapper clas. + */ +struct _GstVaapiDisplayX11Class { + /*< private >*/ + GstVaapiDisplayClass parent_class; +}; + +void +gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass); + G_END_DECLS #endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */ diff --git a/gst-libs/gst/vaapi/gstvaapiobject.c b/gst-libs/gst/vaapi/gstvaapiobject.c index 59efb5d..2e38009 100644 --- a/gst-libs/gst/vaapi/gstvaapiobject.c +++ b/gst-libs/gst/vaapi/gstvaapiobject.c @@ -47,7 +47,7 @@ gst_vaapi_object_finalize(GstVaapiObject *object) if (klass->finalize) klass->finalize(object); - g_clear_object(&object->display); + gst_vaapi_display_replace(&object->display, NULL); } void @@ -89,7 +89,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display) if (!object) return NULL; - object->display = g_object_ref(display); + object->display = gst_vaapi_display_ref(display); object->object_id = VA_INVALID_ID; sub_size = object_class->size - sizeof(*object); diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c index adb7b34..1f86ead 100644 --- a/gst-libs/gst/vaapi/gstvaapivideopool.c +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -56,7 +56,7 @@ gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool) void gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display) { - pool->display = g_object_ref(display); + pool->display = gst_vaapi_display_ref(display); pool->used_objects = NULL; pool->used_count = 0; pool->capacity = 0; @@ -69,7 +69,7 @@ gst_vaapi_video_pool_finalize(GstVaapiVideoPool *pool) { g_list_free_full(pool->used_objects, gst_vaapi_object_unref); g_queue_free_full(&pool->free_objects, gst_vaapi_object_unref); - g_clear_object(&pool->display); + gst_vaapi_display_replace(&pool->display, NULL); } /** -- 2.7.4