libs: use GstVaapiMiniObject for display objects.

This commit is contained in:
Gwenole Beauchesne 2013-05-07 11:39:34 +02:00
parent 3cc7b26961
commit 915cef5e01
18 changed files with 938 additions and 1139 deletions

View file

@ -465,7 +465,7 @@ gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder)
gst_vaapi_object_replace(&decoder->context, NULL); gst_vaapi_object_replace(&decoder->context, NULL);
decoder->va_context = VA_INVALID_ID; decoder->va_context = VA_INVALID_ID;
g_clear_object(&decoder->display); gst_vaapi_display_replace(&decoder->display, NULL);
decoder->va_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); gst_video_info_init(&codec_state->info);
decoder->user_data = NULL; 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->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display);
decoder->context = NULL; decoder->context = NULL;
decoder->va_context = VA_INVALID_ID; decoder->va_context = VA_INVALID_ID;

View file

@ -39,7 +39,10 @@
GST_DEBUG_CATEGORY(gst_debug_vaapi); 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; typedef struct _GstVaapiConfig GstVaapiConfig;
struct _GstVaapiConfig { struct _GstVaapiConfig {
@ -66,10 +69,6 @@ struct _GstVaapiFormatInfo {
enum { enum {
PROP_0, PROP_0,
PROP_DISPLAY,
PROP_DISPLAY_TYPE,
PROP_WIDTH,
PROP_HEIGHT,
PROP_RENDER_MODE, PROP_RENDER_MODE,
PROP_ROTATION, PROP_ROTATION,
PROP_HUE, PROP_HUE,
@ -84,6 +83,9 @@ static GstVaapiDisplayCache *g_display_cache = NULL;
static GParamSpec *g_properties[N_PROPERTIES] = { NULL, }; static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
static void
gst_vaapi_display_properties_init(void);
static gboolean static gboolean
get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value); get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value);
@ -109,6 +111,8 @@ libgstvaapi_init_once(void)
/* Dump gstreamer-vaapi version for debugging purposes */ /* Dump gstreamer-vaapi version for debugging purposes */
GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID); GST_INFO("gstreamer-vaapi version %s", GST_VAAPI_VERSION_ID);
gst_vaapi_display_properties_init();
g_once_init_leave(&g_once, TRUE); g_once_init_leave(&g_once, TRUE);
} }
@ -417,13 +421,43 @@ find_property_by_type(GArray *properties, VADisplayAttribType type)
static inline const GstVaapiProperty * static inline const GstVaapiProperty *
find_property_by_pspec(GstVaapiDisplay *display, GParamSpec *pspec) 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 static void
gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display) 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; gdouble ratio, delta;
gint i, j, index, windex; gint i, j, index, windex;
@ -472,7 +506,8 @@ gst_vaapi_display_calculate_pixel_aspect_ratio(GstVaapiDisplay *display)
static void static void
gst_vaapi_display_destroy(GstVaapiDisplay *display) gst_vaapi_display_destroy(GstVaapiDisplay *display)
{ {
GstVaapiDisplayPrivate * const priv = display->priv; GstVaapiDisplayPrivate * const priv =
GST_VAAPI_DISPLAY_GET_PRIVATE(display);
if (priv->decoders) { if (priv->decoders) {
g_array_free(priv->decoders, TRUE); g_array_free(priv->decoders, TRUE);
@ -505,13 +540,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display)
priv->display = NULL; priv->display = NULL;
} }
if (priv->create_display) { if (!priv->use_foreign_display) {
GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display);
if (klass->close_display) if (klass->close_display)
klass->close_display(display); klass->close_display(display);
} }
g_clear_object(&priv->parent); gst_vaapi_display_replace_internal(&priv->parent, NULL);
if (g_display_cache) { if (g_display_cache) {
gst_vaapi_display_cache_remove(get_display_cache(), display); gst_vaapi_display_cache_remove(get_display_cache(), display);
@ -520,9 +555,13 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display)
} }
static gboolean 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; GstVaapiDisplayCache *cache;
gboolean has_errors = TRUE; gboolean has_errors = TRUE;
VADisplayAttribute *display_attrs = NULL; VADisplayAttribute *display_attrs = NULL;
@ -539,12 +578,21 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
info.display = display; info.display = display;
info.display_type = priv->display_type; info.display_type = priv->display_type;
if (priv->display) switch (init_type) {
info.va_display = priv->display; case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY:
else if (priv->create_display) { info.va_display = init_value;
GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); priv->display = init_value;
if (klass->open_display && !klass->open_display(display)) 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; 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)) if (!klass->get_display || !klass->get_display(display, &info))
return FALSE; return FALSE;
priv->display = info.va_display; priv->display = info.va_display;
@ -554,6 +602,7 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
if (klass->get_size_mm) if (klass->get_size_mm)
klass->get_size_mm(display, &priv->width_mm, &priv->height_mm); klass->get_size_mm(display, &priv->width_mm, &priv->height_mm);
gst_vaapi_display_calculate_pixel_aspect_ratio(display); gst_vaapi_display_calculate_pixel_aspect_ratio(display);
break;
} }
if (!priv->display) if (!priv->display)
return FALSE; return FALSE;
@ -561,13 +610,11 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
cache = get_display_cache(); cache = get_display_cache();
if (!cache) if (!cache)
return FALSE; return FALSE;
cached_info = gst_vaapi_display_cache_lookup_by_va_display( cached_info = gst_vaapi_display_cache_lookup_by_va_display(cache,
cache, info.va_display);
info.va_display
);
if (cached_info) { if (cached_info) {
g_clear_object(&priv->parent); gst_vaapi_display_replace_internal(&priv->parent,
priv->parent = g_object_ref(cached_info->display); cached_info->display);
priv->display_type = cached_info->display_type; priv->display_type = cached_info->display_type;
} }
@ -766,180 +813,69 @@ end:
static void static void
gst_vaapi_display_lock_default(GstVaapiDisplay *display) gst_vaapi_display_lock_default(GstVaapiDisplay *display)
{ {
GstVaapiDisplayPrivate *priv = display->priv; GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display);
if (priv->parent) if (priv->parent)
priv = priv->parent->priv; priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent);
g_rec_mutex_lock(&priv->mutex); g_rec_mutex_lock(&priv->mutex);
} }
static void static void
gst_vaapi_display_unlock_default(GstVaapiDisplay *display) gst_vaapi_display_unlock_default(GstVaapiDisplay *display)
{ {
GstVaapiDisplayPrivate *priv = display->priv; GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display);
if (priv->parent) if (priv->parent)
priv = priv->parent->priv; priv = GST_VAAPI_DISPLAY_GET_PRIVATE(priv->parent);
g_rec_mutex_unlock(&priv->mutex); g_rec_mutex_unlock(&priv->mutex);
} }
static void 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);
priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
priv->par_n = 1;
priv->par_d = 1;
g_rec_mutex_init(&priv->mutex);
if (dpy_class->init)
dpy_class->init(display);
}
static void
gst_vaapi_display_finalize(GstVaapiDisplay *display)
{
GstVaapiDisplayPrivate * const priv =
GST_VAAPI_DISPLAY_GET_PRIVATE(display);
gst_vaapi_display_destroy(display); gst_vaapi_display_destroy(display);
g_rec_mutex_clear(&priv->mutex);
g_rec_mutex_clear(&display->priv->mutex);
G_OBJECT_CLASS(gst_vaapi_display_parent_class)->finalize(object);
} }
static void void
gst_vaapi_display_set_property(
GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec
)
{
GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object);
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;
}
}
static void
gst_vaapi_display_get_property(
GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec
)
{
GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object);
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);
}
static void
gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) 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); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
libgstvaapi_init_once(); libgstvaapi_init_once();
g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate)); object_class->size = sizeof(GstVaapiDisplay);
object_class->finalize = (GDestroyNotify)gst_vaapi_display_finalize;
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;
dpy_class->lock = gst_vaapi_display_lock_default; dpy_class->lock = gst_vaapi_display_lock_default;
dpy_class->unlock = gst_vaapi_display_unlock_default; dpy_class->unlock = gst_vaapi_display_unlock_default;
}
g_properties[PROP_DISPLAY] = static void
g_param_spec_pointer("display", gst_vaapi_display_properties_init(void)
"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);
/** /**
* GstVaapiDisplay:render-mode: * GstVaapiDisplay:render-mode:
* *
@ -1017,33 +953,40 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass)
"The display contrast value", "The display contrast value",
0.0, 2.0, 1.0, 0.0, 2.0, 1.0,
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_properties(object_class, N_PROPERTIES, g_properties);
} }
static void static inline const GstVaapiDisplayClass *
gst_vaapi_display_init(GstVaapiDisplay *display) gst_vaapi_display_class(void)
{ {
GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display); static GstVaapiDisplayClass g_class;
static gsize g_class_init = FALSE;
display->priv = priv; if (g_once_init_enter(&g_class_init)) {
priv->parent = NULL; gst_vaapi_display_class_init(&g_class);
priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY; g_once_init_leave(&g_class_init, TRUE);
priv->display = NULL; }
priv->width = 0; return &g_class;
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;
g_rec_mutex_init(&priv->mutex); GstVaapiDisplay *
gst_vaapi_display_new(const GstVaapiDisplayClass *klass,
GstVaapiDisplayInitType init_type, gpointer init_value)
{
GstVaapiDisplay *display;
display = (GstVaapiDisplay *)
gst_vaapi_mini_object_new0(GST_VAAPI_MINI_OBJECT_CLASS(klass));
if (!display)
return NULL;
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); info = gst_vaapi_display_cache_lookup_by_va_display(cache, va_display);
if (info) if (info)
return g_object_ref(info->display); return gst_vaapi_display_ref_internal(info->display);
return g_object_new(GST_VAAPI_TYPE_DISPLAY, return gst_vaapi_display_new(gst_vaapi_display_class(),
"display", va_display, GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display);
NULL); }
/**
* 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), g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display),
GST_VAAPI_DISPLAY_TYPE_ANY); 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); 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); 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); 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)); g_return_if_fail(GST_VAAPI_DISPLAY(display));
if (pwidth) if (pwidth)
*pwidth = display->priv->width; *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->width;
if (pheight) 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)); g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
if (par_n) if (par_n)
*par_n = display->priv->par_n; *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE(display)->par_n;
if (par_d) 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); 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); 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); 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); 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); 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(GST_VAAPI_IS_DISPLAY(display), FALSE);
g_return_val_if_fail(format, 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; return TRUE;
/* XXX: try subpicture formats since some drivers could report a /* 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 * set of VA image formats that is not a superset of the set of VA
* subpicture formats * 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); 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(GST_VAAPI_IS_DISPLAY(display), FALSE);
g_return_val_if_fail(format, 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) if (!fip)
return FALSE; 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(GST_VAAPI_IS_DISPLAY(display), FALSE);
g_return_val_if_fail(name, 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 static gboolean
get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value) get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value)
{ {
GstVaapiDisplayPrivate * const priv =
GST_VAAPI_DISPLAY_GET_PRIVATE(display);
VADisplayAttribute attr; VADisplayAttribute attr;
VAStatus status; VAStatus status;
attr.type = type; attr.type = type;
attr.flags = VA_DISPLAY_ATTRIB_GETTABLE; 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()")) if (!vaapi_check_status(status, "vaGetDisplayAttributes()"))
return FALSE; return FALSE;
*value = attr.value; *value = attr.value;
@ -1490,13 +1582,15 @@ get_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint *value)
static gboolean static gboolean
set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value) set_attribute(GstVaapiDisplay *display, VADisplayAttribType type, gint value)
{ {
GstVaapiDisplayPrivate * const priv =
GST_VAAPI_DISPLAY_GET_PRIVATE(display);
VADisplayAttribute attr; VADisplayAttribute attr;
VAStatus status; VAStatus status;
attr.type = type; attr.type = type;
attr.value = value; attr.value = value;
attr.flags = VA_DISPLAY_ATTRIB_SETTABLE; 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()")) if (!vaapi_check_status(status, "vaSetDisplayAttributes()"))
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -1553,7 +1647,10 @@ get_render_mode_default(
GstVaapiRenderMode *pmode GstVaapiRenderMode *pmode
) )
{ {
switch (display->priv->display_type) { GstVaapiDisplayPrivate * const priv =
GST_VAAPI_DISPLAY_GET_PRIVATE(display);
switch (priv->display_type) {
#if USE_WAYLAND #if USE_WAYLAND
case GST_VAAPI_DISPLAY_TYPE_WAYLAND: case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
/* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */ /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */
@ -1647,8 +1744,6 @@ gst_vaapi_display_set_render_mode(
return FALSE; return FALSE;
if (!set_attribute(display, VADisplayAttribRenderMode, modes)) if (!set_attribute(display, VADisplayAttribRenderMode, modes))
return FALSE; return FALSE;
g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_RENDER_MODE]);
return TRUE; return TRUE;
} }
@ -1700,8 +1795,6 @@ gst_vaapi_display_set_rotation(
value = from_GstVaapiRotation(rotation); value = from_GstVaapiRotation(rotation);
if (!set_attribute(display, VADisplayAttribRotation, value)) if (!set_attribute(display, VADisplayAttribRotation, value))
return FALSE; return FALSE;
g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_ROTATION]);
return TRUE; return TRUE;
} }
@ -1769,7 +1862,5 @@ set_color_balance(GstVaapiDisplay *display, guint prop_id, gfloat v)
(attr->value - attr->min_value)); (attr->value - attr->min_value));
if (!set_attribute(display, attr->type, value)) if (!set_attribute(display, attr->type, value))
return FALSE; return FALSE;
g_object_notify_by_pspec(G_OBJECT(display), g_properties[prop_id]);
return TRUE; return TRUE;
} }

View file

@ -31,34 +31,14 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DISPLAY \ #define GST_VAAPI_DISPLAY(obj) \
(gst_vaapi_display_get_type()) ((GstVaapiDisplay *)(obj))
#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_IS_DISPLAY(obj) \ #define GST_VAAPI_IS_DISPLAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY)) ((obj) != NULL)
#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))
typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo; typedef struct _GstVaapiDisplayInfo GstVaapiDisplayInfo;
typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplay GstVaapiDisplay;
typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate;
typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass;
/** /**
* GstVaapiDisplayType: * GstVaapiDisplayType:
@ -111,57 +91,19 @@ struct _GstVaapiDisplayInfo {
#define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness" #define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness"
#define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast" #define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast"
/**
* GstVaapiDisplay:
*
* Base class for VA displays.
*/
struct _GstVaapiDisplay {
/*< private >*/
GObject 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 >*/
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);
};
GType
gst_vaapi_display_get_type(void) G_GNUC_CONST;
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_display_new_with_display(VADisplay va_display); gst_vaapi_display_new_with_display(VADisplay va_display);
GstVaapiDisplay *
gst_vaapi_display_ref(GstVaapiDisplay *display);
void
gst_vaapi_display_unref(GstVaapiDisplay *display);
void
gst_vaapi_display_replace(GstVaapiDisplay **old_display_ptr,
GstVaapiDisplay *new_display);
void void
gst_vaapi_display_lock(GstVaapiDisplay *display); gst_vaapi_display_lock(GstVaapiDisplay *display);
@ -238,6 +180,14 @@ gst_vaapi_display_has_subpicture_format(
gboolean gboolean
gst_vaapi_display_has_property(GstVaapiDisplay *display, const gchar *name); 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 gboolean
gst_vaapi_display_get_render_mode( gst_vaapi_display_get_render_mode(
GstVaapiDisplay *display, GstVaapiDisplay *display,

View file

@ -39,17 +39,6 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #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 "DRM:"
#define NAME_PREFIX_LENGTH 4 #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; 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 */ /* Get default device path. Actually, the first match in the DRM subsystem */
static const gchar * 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 =
GstVaapiDisplayDRMPrivate * const priv = display->priv; GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
const gchar *syspath, *devpath; const gchar *syspath, *devpath;
struct udev *udev = NULL; struct udev *udev = NULL;
struct udev_device *device, *parent; struct udev_device *device, *parent;
@ -137,10 +120,11 @@ get_default_device_path(gpointer ptr)
/* Reconstruct a device path without our prefix */ /* Reconstruct a device path without our prefix */
static const gchar * static const gchar *
get_device_path(gpointer ptr) get_device_path(GstVaapiDisplay *display)
{ {
GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(ptr); GstVaapiDisplayDRMPrivate * const priv =
const gchar *device_path = display->priv->device_path; GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
const gchar *device_path = priv->device_path;
if (!device_path) if (!device_path)
return NULL; return NULL;
@ -154,10 +138,11 @@ get_device_path(gpointer ptr)
} }
/* Mangle device path with our prefix */ /* Mangle device path with our prefix */
static void static gboolean
set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path) 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); g_free(priv->device_path);
priv->device_path = NULL; priv->device_path = NULL;
@ -165,34 +150,37 @@ set_device_path(GstVaapiDisplayDRM *display, const gchar *device_path)
if (!device_path) { if (!device_path) {
device_path = get_default_device_path(display); device_path = get_default_device_path(display);
if (!device_path) if (!device_path)
return; return FALSE;
} }
priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path); priv->device_path = g_strdup_printf("%s%s", NAME_PREFIX, device_path);
return priv->device_path != NULL;
} }
/* Set device path from file descriptor */ /* Set device path from file descriptor */
static void static gboolean
set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device) 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; const gchar *busid, *path, *str;
gsize busid_length, path_length; gsize busid_length, path_length;
struct udev *udev = NULL; struct udev *udev = NULL;
struct udev_device *device; struct udev_device *device;
struct udev_enumerate *e = NULL; struct udev_enumerate *e = NULL;
struct udev_list_entry *l; struct udev_list_entry *l;
gboolean success = FALSE;
g_free(priv->device_path); g_free(priv->device_path);
priv->device_path = NULL; priv->device_path = NULL;
if (drm_device < 0) if (drm_device < 0)
return; goto end;
busid = drmGetBusid(drm_device); busid = drmGetBusid(drm_device);
if (!busid) if (!busid)
return; goto end;
if (strncmp(busid, "pci:", 4) != 0) if (strncmp(busid, "pci:", 4) != 0)
return; goto end;
busid += 4; busid += 4;
busid_length = strlen(busid); busid_length = strlen(busid);
@ -227,109 +215,57 @@ set_device_path_from_fd(GstVaapiDisplayDRM *display, gint drm_device)
udev_device_unref(device); udev_device_unref(device);
break; break;
} }
success = TRUE;
end: end:
if (e) if (e)
udev_enumerate_unref(e); udev_enumerate_unref(e);
if (udev) if (udev)
udev_unref(udev); udev_unref(udev);
} return success;
static void
gst_vaapi_display_drm_set_property(
GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec
)
{
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;
}
}
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);
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;
}
}
static void
gst_vaapi_display_drm_constructed(GObject *object)
{
GstVaapiDisplayDRM * const display = GST_VAAPI_DISPLAY_DRM(object);
GstVaapiDisplayDRMPrivate * const priv = display->priv;
GstVaapiDisplayCache * const cache = gst_vaapi_display_get_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);
} }
static gboolean static gboolean
gst_vaapi_display_drm_open_display(GstVaapiDisplay *display) gst_vaapi_display_drm_bind_display(GstVaapiDisplay *display,
gpointer native_display)
{ {
GstVaapiDisplayDRMPrivate * const priv = GstVaapiDisplayDRMPrivate * const priv =
GST_VAAPI_DISPLAY_DRM(display)->priv; GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
if (priv->create_display) { priv->drm_device = GPOINTER_TO_INT(native_display);
const gchar *device_path = get_device_path(display); priv->use_foreign_display = TRUE;
if (!device_path)
return FALSE; if (!set_device_path_from_fd(display, priv->drm_device))
priv->drm_device = open(device_path, O_RDWR|O_CLOEXEC); return FALSE;
return TRUE;
}
static gboolean
gst_vaapi_display_drm_open_display(GstVaapiDisplay *display, const gchar *name)
{
GstVaapiDisplayDRMPrivate * const priv =
GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
GstVaapiDisplayCache *cache;
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;
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) if (priv->drm_device < 0)
return FALSE; return FALSE;
priv->use_foreign_display = FALSE;
} }
if (priv->drm_device < 0)
return FALSE;
return TRUE; return TRUE;
} }
@ -337,10 +273,10 @@ static void
gst_vaapi_display_drm_close_display(GstVaapiDisplay *display) gst_vaapi_display_drm_close_display(GstVaapiDisplay *display)
{ {
GstVaapiDisplayDRMPrivate * const priv = GstVaapiDisplayDRMPrivate * const priv =
GST_VAAPI_DISPLAY_DRM(display)->priv; GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
if (priv->drm_device >= 0) { if (priv->drm_device >= 0) {
if (priv->create_display) if (!priv->use_foreign_display)
close(priv->drm_device); close(priv->drm_device);
priv->drm_device = -1; priv->drm_device = -1;
} }
@ -357,13 +293,11 @@ gst_vaapi_display_drm_close_display(GstVaapiDisplay *display)
} }
static gboolean static gboolean
gst_vaapi_display_drm_get_display_info( gst_vaapi_display_drm_get_display_info(GstVaapiDisplay *display,
GstVaapiDisplay *display, GstVaapiDisplayInfo *info)
GstVaapiDisplayInfo *info
)
{ {
GstVaapiDisplayDRMPrivate * const priv = GstVaapiDisplayDRMPrivate * const priv =
GST_VAAPI_DISPLAY_DRM(display)->priv; GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
GstVaapiDisplayCache *cache; GstVaapiDisplayCache *cache;
const GstVaapiDisplayInfo *cached_info; const GstVaapiDisplayInfo *cached_info;
@ -391,62 +325,42 @@ gst_vaapi_display_drm_get_display_info(
} }
static void static void
gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass) gst_vaapi_display_drm_init(GstVaapiDisplay *display)
{ {
GObjectClass * const object_class = G_OBJECT_CLASS(klass); GstVaapiDisplayDRMPrivate * const priv =
GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); GST_VAAPI_DISPLAY_DRM_PRIVATE(display);
g_type_class_add_private(klass, sizeof(GstVaapiDisplayDRMPrivate)); priv->drm_device = -1;
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;
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 static void
gst_vaapi_display_drm_init(GstVaapiDisplayDRM *display) gst_vaapi_display_drm_class_init(GstVaapiDisplayDRMClass *klass)
{ {
GstVaapiDisplayDRMPrivate * const priv = GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(display); GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
display->priv = priv; gst_vaapi_display_class_init(&klass->parent_class);
priv->device_path_default = NULL;
priv->device_path = NULL; object_class->size = sizeof(GstVaapiDisplayDRM);
priv->drm_device = -1; dpy_class->init = gst_vaapi_display_drm_init;
priv->create_display = TRUE; 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;
}
static inline const GstVaapiDisplayClass *
gst_vaapi_display_drm_class(void)
{
static GstVaapiDisplayDRMClass g_class;
static gsize g_class_init = FALSE;
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 * GstVaapiDisplay *
gst_vaapi_display_drm_new(const gchar *device_path) gst_vaapi_display_drm_new(const gchar *device_path)
{ {
return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, return gst_vaapi_display_new(gst_vaapi_display_drm_class(),
"device-path", device_path, GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)device_path);
NULL);
} }
/** /**
@ -487,9 +400,8 @@ gst_vaapi_display_drm_new_with_device(gint device)
{ {
g_return_val_if_fail(device >= 0, NULL); g_return_val_if_fail(device >= 0, NULL);
return g_object_new(GST_VAAPI_TYPE_DISPLAY_DRM, return gst_vaapi_display_new(gst_vaapi_display_drm_class(),
"drm-device", device, GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, GINT_TO_POINTER(device));
NULL);
} }
/** /**
@ -507,7 +419,7 @@ gst_vaapi_display_drm_get_device(GstVaapiDisplayDRM *display)
{ {
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_DRM(display), -1); 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); 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));
} }

View file

@ -26,59 +26,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DISPLAY_DRM \ #define GST_VAAPI_DISPLAY_DRM(obj) \
(gst_vaapi_display_drm_get_type()) ((GstVaapiDisplayDRM *)(obj))
#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_IS_DISPLAY_DRM(obj) \ #define GST_VAAPI_IS_DISPLAY_DRM(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_DRM)) ((obj) != NULL)
#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))
typedef struct _GstVaapiDisplayDRM GstVaapiDisplayDRM; 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 * GstVaapiDisplay *
gst_vaapi_display_drm_new(const gchar *device_path); gst_vaapi_display_drm_new(const gchar *device_path);

View file

@ -26,12 +26,14 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_DISPLAY_DRM_GET_PRIVATE(obj) \ #define GST_VAAPI_DISPLAY_DRM_CAST(display) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \ ((GstVaapiDisplayDRM *)(display))
GST_VAAPI_TYPE_DISPLAY_DRM, \
GstVaapiDisplayDRMPrivate))
#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: * GST_VAAPI_DISPLAY_DRM_DEVICE:
@ -41,13 +43,35 @@ G_BEGIN_DECLS
*/ */
#undef GST_VAAPI_DISPLAY_DRM_DEVICE #undef GST_VAAPI_DISPLAY_DRM_DEVICE
#define GST_VAAPI_DISPLAY_DRM_DEVICE(display) \ #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 { struct _GstVaapiDisplayDRMPrivate {
gchar *device_path_default; gchar *device_path_default;
gchar *device_path; gchar *device_path;
gint drm_device; gint drm_device;
guint create_display : 1; 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 G_END_DECLS

View file

@ -37,45 +37,47 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #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 static gboolean
gst_vaapi_display_glx_get_display_info( gst_vaapi_display_glx_get_display_info(
GstVaapiDisplay *display, GstVaapiDisplay *display,
GstVaapiDisplayInfo *info GstVaapiDisplayInfo *info
) )
{ {
GstVaapiDisplayClass * const dpy_class = const GstVaapiDisplayGLXClass * const klass =
GST_VAAPI_DISPLAY_CLASS(gst_vaapi_display_glx_parent_class); GST_VAAPI_DISPLAY_GLX_GET_CLASS(display);
info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display)); info->va_display = vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display));
if (!info->va_display) if (!info->va_display)
return FALSE; return FALSE;
info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX; info->display_type = GST_VAAPI_DISPLAY_TYPE_GLX;
return dpy_class->get_display(display, info); return klass->parent_get_display(display, info);
} }
static void static void
gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass) 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); 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; dpy_class->get_display = gst_vaapi_display_glx_get_display_info;
} }
static void static inline const GstVaapiDisplayClass *
gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display) 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 * GstVaapiDisplay *
gst_vaapi_display_glx_new(const gchar *display_name) gst_vaapi_display_glx_new(const gchar *display_name)
{ {
return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, return gst_vaapi_display_new(gst_vaapi_display_glx_class(),
"display-name", display_name, GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name);
NULL);
} }
/** /**
@ -110,7 +111,8 @@ gst_vaapi_display_glx_new(const gchar *display_name)
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_display_glx_new_with_display(Display *x11_display) gst_vaapi_display_glx_new_with_display(Display *x11_display)
{ {
return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX, g_return_val_if_fail(x11_display != NULL, NULL);
"x11-display", x11_display,
NULL); return gst_vaapi_display_new(gst_vaapi_display_glx_class(),
GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
} }

View file

@ -29,56 +29,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DISPLAY_GLX \ #define GST_VAAPI_DISPLAY_GLX(obj) \
(gst_vaapi_display_glx_get_type()) ((GstVaapiDisplayGLX *)(obj))
#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_IS_DISPLAY_GLX(obj) \ #define GST_VAAPI_IS_DISPLAY_GLX(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_GLX)) ((obj) != NULL)
#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))
typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX; 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 * GstVaapiDisplay *
gst_vaapi_display_glx_new(const gchar *display_name); gst_vaapi_display_glx_new(const gchar *display_name);

View file

@ -24,10 +24,42 @@
#include <gst/vaapi/gstvaapiutils_glx.h> #include <gst/vaapi/gstvaapiutils_glx.h>
#include <gst/vaapi/gstvaapidisplay_glx.h> #include <gst/vaapi/gstvaapidisplay_glx.h>
#include "gstvaapidisplay_x11_priv.h"
G_BEGIN_DECLS 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 G_END_DECLS

View file

@ -25,15 +25,45 @@
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapidisplaycache.h> #include <gst/vaapi/gstvaapidisplaycache.h>
#include "gstvaapiminiobject.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_DISPLAY_GET_PRIVATE(obj) \ #define GST_VAAPI_DISPLAY_CAST(display) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \ ((GstVaapiDisplay *)(display))
GST_VAAPI_TYPE_DISPLAY, \
GstVaapiDisplayPrivate))
#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: * GST_VAAPI_DISPLAY_VADISPLAY:
@ -44,7 +74,7 @@ G_BEGIN_DECLS
*/ */
#undef GST_VAAPI_DISPLAY_VADISPLAY #undef GST_VAAPI_DISPLAY_VADISPLAY
#define GST_VAAPI_DISPLAY_VADISPLAY(display_) \ #define GST_VAAPI_DISPLAY_VADISPLAY(display_) \
GST_VAAPI_DISPLAY_CAST(display_)->priv->display GST_VAAPI_DISPLAY_GET_PRIVATE(display_)->display
/** /**
* GST_VAAPI_DISPLAY_LOCK: * GST_VAAPI_DISPLAY_LOCK:
@ -66,11 +96,6 @@ G_BEGIN_DECLS
#define GST_VAAPI_DISPLAY_UNLOCK(display) \ #define GST_VAAPI_DISPLAY_UNLOCK(display) \
gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display)) gst_vaapi_display_unlock(GST_VAAPI_DISPLAY_CAST(display))
/**
* GstVaapiDisplayPrivate:
*
* Base class for VA displays.
*/
struct _GstVaapiDisplayPrivate { struct _GstVaapiDisplayPrivate {
GstVaapiDisplay *parent; GstVaapiDisplay *parent;
GRecMutex mutex; GRecMutex mutex;
@ -87,12 +112,95 @@ struct _GstVaapiDisplayPrivate {
GArray *image_formats; GArray *image_formats;
GArray *subpicture_formats; GArray *subpicture_formats;
GArray *properties; 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 * GstVaapiDisplayCache *
gst_vaapi_display_get_cache(void); 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 G_END_DECLS
#endif /* GST_VAAPI_DISPLAY_PRIV_H */ #endif /* GST_VAAPI_DISPLAY_PRIV_H */

View file

@ -33,17 +33,6 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #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 "WLD:"
#define NAME_PREFIX_LENGTH 4 #define NAME_PREFIX_LENGTH 4
@ -98,18 +87,13 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data)
return TRUE; 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 */ /* Reconstruct a display name without our prefix */
static const gchar * static const gchar *
get_display_name(gpointer ptr) get_display_name(GstVaapiDisplayWayland *display)
{ {
GstVaapiDisplayWayland * const display = GST_VAAPI_DISPLAY_WAYLAND(ptr); GstVaapiDisplayWaylandPrivate * const priv =
const gchar *display_name = display->priv->display_name; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
const gchar *display_name = priv->display_name;
if (!display_name) if (!display_name)
return NULL; return NULL;
@ -127,10 +111,11 @@ get_display_name(gpointer ptr)
} }
/* Mangle display name with our prefix */ /* Mangle display name with our prefix */
static void static gboolean
set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name) 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); g_free(priv->display_name);
@ -140,87 +125,7 @@ set_display_name(GstVaapiDisplayWayland *display, const gchar *display_name)
display_name = ""; display_name = "";
} }
priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name); priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name);
} return priv->display_name != NULL;
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);
} }
static void static void
@ -280,16 +185,10 @@ static const struct wl_registry_listener registry_listener = {
}; };
static gboolean static gboolean
gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display) gst_vaapi_display_wayland_setup(GstVaapiDisplay *display)
{ {
GstVaapiDisplayWaylandPrivate * const priv = GstVaapiDisplayWaylandPrivate * const priv =
GST_VAAPI_DISPLAY_WAYLAND(display)->priv; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
if (priv->create_display) {
priv->wl_display = wl_display_connect(get_display_name(display));
if (!priv->wl_display)
return FALSE;
}
wl_display_set_user_data(priv->wl_display, priv); wl_display_set_user_data(priv->wl_display, priv);
priv->registry = wl_display_get_registry(priv->wl_display); priv->registry = wl_display_get_registry(priv->wl_display);
@ -317,11 +216,58 @@ gst_vaapi_display_wayland_open_display(GstVaapiDisplay * display)
return TRUE; 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 static void
gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display) gst_vaapi_display_wayland_close_display(GstVaapiDisplay * display)
{ {
GstVaapiDisplayWaylandPrivate * const priv = GstVaapiDisplayWaylandPrivate * const priv =
GST_VAAPI_DISPLAY_WAYLAND(display)->priv; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
if (priv->compositor) { if (priv->compositor) {
wl_compositor_destroy(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->wl_display) {
if (priv->create_display) if (!priv->use_foreign_display)
wl_display_disconnect(priv->wl_display); wl_display_disconnect(priv->wl_display);
priv->wl_display = NULL; priv->wl_display = NULL;
} }
@ -347,7 +293,7 @@ gst_vaapi_display_wayland_get_display_info(
) )
{ {
GstVaapiDisplayWaylandPrivate * const priv = GstVaapiDisplayWaylandPrivate * const priv =
GST_VAAPI_DISPLAY_WAYLAND(display)->priv; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
GstVaapiDisplayCache *cache; GstVaapiDisplayCache *cache;
const GstVaapiDisplayInfo *cached_info; const GstVaapiDisplayInfo *cached_info;
@ -355,8 +301,8 @@ gst_vaapi_display_wayland_get_display_info(
cache = gst_vaapi_display_get_cache(); cache = gst_vaapi_display_get_cache();
if (!cache) if (!cache)
return FALSE; return FALSE;
cached_info = cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache,
gst_vaapi_display_cache_lookup_by_native_display(cache, priv->wl_display); priv->wl_display);
if (cached_info) { if (cached_info) {
*info = *cached_info; *info = *cached_info;
return TRUE; return TRUE;
@ -382,7 +328,7 @@ gst_vaapi_display_wayland_get_size(
) )
{ {
GstVaapiDisplayWaylandPrivate * const priv = GstVaapiDisplayWaylandPrivate * const priv =
GST_VAAPI_DISPLAY_WAYLAND(display)->priv; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
if (!priv->output) if (!priv->output)
return; return;
@ -402,7 +348,7 @@ gst_vaapi_display_wayland_get_size_mm(
) )
{ {
GstVaapiDisplayWaylandPrivate * const priv = GstVaapiDisplayWaylandPrivate * const priv =
GST_VAAPI_DISPLAY_WAYLAND(display)->priv; GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display);
if (!priv->output) if (!priv->output)
return; return;
@ -414,73 +360,45 @@ gst_vaapi_display_wayland_get_size_mm(
*pheight = priv->phys_height; *pheight = priv->phys_height;
} }
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 static void
gst_vaapi_display_wayland_class_init(GstVaapiDisplayWaylandClass * klass) 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); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDisplayWaylandPrivate)); gst_vaapi_display_class_init(&klass->parent_class);
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;
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->open_display = gst_vaapi_display_wayland_open_display;
dpy_class->close_display = gst_vaapi_display_wayland_close_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_display = gst_vaapi_display_wayland_get_display_info;
dpy_class->get_size = gst_vaapi_display_wayland_get_size; dpy_class->get_size = gst_vaapi_display_wayland_get_size;
dpy_class->get_size_mm = gst_vaapi_display_wayland_get_size_mm; 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 static inline const GstVaapiDisplayClass *
gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display) gst_vaapi_display_wayland_class(void)
{ {
GstVaapiDisplayWaylandPrivate * const priv = static GstVaapiDisplayWaylandClass g_class;
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE(display); static gsize g_class_init = FALSE;
display->priv = priv; if (g_once_init_enter(&g_class_init)) {
priv->create_display = TRUE; gst_vaapi_display_wayland_class_init(&g_class);
priv->display_name = NULL; g_once_init_leave(&g_class_init, TRUE);
priv->wl_display = NULL; }
priv->compositor = NULL; return GST_VAAPI_DISPLAY_CLASS(&g_class);
priv->shell = NULL;
priv->output = NULL;
priv->width = 0;
priv->height = 0;
priv->phys_width = 0;
priv->phys_height = 0;
priv->event_fd = -1;
} }
/** /**
@ -496,9 +414,8 @@ gst_vaapi_display_wayland_init(GstVaapiDisplayWayland *display)
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_display_wayland_new(const gchar *display_name) gst_vaapi_display_wayland_new(const gchar *display_name)
{ {
return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, return gst_vaapi_display_new(gst_vaapi_display_wayland_class(),
"display-name", display_name, GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name);
NULL);
} }
/** /**
@ -517,9 +434,8 @@ gst_vaapi_display_wayland_new_with_display(struct wl_display *wl_display)
{ {
g_return_val_if_fail(wl_display, NULL); g_return_val_if_fail(wl_display, NULL);
return g_object_new(GST_VAAPI_TYPE_DISPLAY_WAYLAND, return gst_vaapi_display_new(gst_vaapi_display_wayland_class(),
"wl-display", wl_display, GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, wl_display);
NULL);
} }
/** /**
@ -537,5 +453,5 @@ gst_vaapi_display_wayland_get_display(GstVaapiDisplayWayland *display)
{ {
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL); g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_WAYLAND(display), NULL);
return display->priv->wl_display; return GST_VAAPI_DISPLAY_WL_DISPLAY(display);
} }

View file

@ -27,58 +27,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DISPLAY_WAYLAND \ #define GST_VAAPI_DISPLAY_WAYLAND(obj) \
(gst_vaapi_display_wayland_get_type()) ((GstVaapiDisplayWayland *)(obj))
#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_IS_DISPLAY_WAYLAND(obj) \ #define GST_VAAPI_IS_DISPLAY_WAYLAND(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_WAYLAND)) ((obj) != NULL)
#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))
typedef struct _GstVaapiDisplayWayland GstVaapiDisplayWayland; 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 * GstVaapiDisplay *
gst_vaapi_display_wayland_new(const gchar *display_name); gst_vaapi_display_wayland_new(const gchar *display_name);

View file

@ -23,17 +23,19 @@
#define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H #define GST_VAAPI_DISPLAY_WAYLAND_PRIV_H
#include <gst/vaapi/gstvaapidisplay_wayland.h> #include <gst/vaapi/gstvaapidisplay_wayland.h>
#include "gstvaapidisplay_priv.h"
G_BEGIN_DECLS 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) \ #define GST_VAAPI_DISPLAY_WAYLAND_CAST(display) \
((GstVaapiDisplayWayland *)(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: * GST_VAAPI_DISPLAY_WL_DISPLAY:
* @display: a #GstVaapiDisplay * @display: a #GstVaapiDisplay
@ -43,7 +45,7 @@ G_BEGIN_DECLS
*/ */
#undef GST_VAAPI_DISPLAY_WL_DISPLAY #undef GST_VAAPI_DISPLAY_WL_DISPLAY
#define GST_VAAPI_DISPLAY_WL_DISPLAY(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 { struct _GstVaapiDisplayWaylandPrivate {
gchar *display_name; gchar *display_name;
@ -57,7 +59,29 @@ struct _GstVaapiDisplayWaylandPrivate {
guint phys_width; guint phys_width;
guint phys_height; guint phys_height;
gint event_fd; 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 G_END_DECLS

View file

@ -39,19 +39,6 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #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 "X11:"
#define NAME_PREFIX_LENGTH 4 #define NAME_PREFIX_LENGTH 4
@ -105,18 +92,12 @@ compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data)
return TRUE; 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 */ /* Reconstruct a display name without our prefix */
static const gchar * static const gchar *
get_display_name(gpointer ptr) get_display_name(GstVaapiDisplayX11 *display)
{ {
GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(ptr); GstVaapiDisplayX11Private * const priv = &display->priv;
const gchar *display_name = display->priv->display_name; const gchar *display_name = priv->display_name;
if (!display_name) if (!display_name)
return NULL; return NULL;
@ -134,10 +115,10 @@ get_display_name(gpointer ptr)
} }
/* Mangle display name with our prefix */ /* Mangle display name with our prefix */
static void static gboolean
set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name)
{ {
GstVaapiDisplayX11Private * const priv = display->priv; GstVaapiDisplayX11Private * const priv = &display->priv;
g_free(priv->display_name); g_free(priv->display_name);
@ -147,12 +128,14 @@ set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name)
display_name = ""; display_name = "";
} }
priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, 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 static void
set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous) set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous)
{ {
GstVaapiDisplayX11Private * const priv = display->priv; GstVaapiDisplayX11Private * const priv = &display->priv;
if (priv->synchronous != synchronous) { if (priv->synchronous != synchronous) {
priv->synchronous = synchronous; priv->synchronous = synchronous;
@ -161,122 +144,70 @@ set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous)
} }
} }
/* Check whether XRANDR extension is available */
static void static void
gst_vaapi_display_x11_set_property( check_xrandr(GstVaapiDisplayX11 *display)
GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec
)
{ {
GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); #ifdef HAVE_XRANDR
GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11_PRIVATE(display);
int evt_base, err_base;
switch (prop_id) { priv->use_xrandr = XRRQueryExtension(priv->x11_display,
case PROP_SYNCHRONOUS: &evt_base, &err_base);
set_synchronous(display, g_value_get_boolean(value)); #endif
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;
}
}
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;
}
}
static void
gst_vaapi_display_x11_constructed(GObject *object)
{
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;
}
}
/* Reset display-name if the user provided his own X11 display */
if (!priv->create_display)
set_display_name(display, XDisplayString(priv->x11_display));
parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
} }
static gboolean static gboolean
gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display,
gpointer native_display)
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11 * const display =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_CAST(base_display);
GstVaapiDisplayX11Private * const priv = &display->priv;
if (priv->create_display) { priv->x11_display = native_display;
priv->x11_screen = DefaultScreen(native_display);
priv->use_foreign_display = TRUE;
check_xrandr(display);
if (!set_display_name(display, XDisplayString(priv->x11_display)))
return FALSE;
return TRUE;
}
static gboolean
gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display,
const gchar *name)
{
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 (!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)); priv->x11_display = XOpenDisplay(get_display_name(display));
if (!priv->x11_display) if (!priv->x11_display)
return FALSE; return FALSE;
priv->x11_screen = DefaultScreen(priv->x11_display); priv->use_foreign_display = FALSE;
} }
if (!priv->x11_display) priv->x11_screen = DefaultScreen(priv->x11_display);
return FALSE;
if (priv->synchronous) check_xrandr(display);
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
return TRUE; return TRUE;
} }
@ -284,10 +215,10 @@ static void
gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) gst_vaapi_display_x11_close_display(GstVaapiDisplay *display)
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
if (priv->x11_display) { if (priv->x11_display) {
if (priv->create_display) if (!priv->use_foreign_display)
XCloseDisplay(priv->x11_display); XCloseDisplay(priv->x11_display);
priv->x11_display = NULL; priv->x11_display = NULL;
} }
@ -302,7 +233,7 @@ static void
gst_vaapi_display_x11_sync(GstVaapiDisplay *display) gst_vaapi_display_x11_sync(GstVaapiDisplay *display)
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
if (priv->x11_display) { if (priv->x11_display) {
GST_VAAPI_DISPLAY_LOCK(display); GST_VAAPI_DISPLAY_LOCK(display);
@ -315,7 +246,7 @@ static void
gst_vaapi_display_x11_flush(GstVaapiDisplay *display) gst_vaapi_display_x11_flush(GstVaapiDisplay *display)
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
if (priv->x11_display) { if (priv->x11_display) {
GST_VAAPI_DISPLAY_LOCK(display); GST_VAAPI_DISPLAY_LOCK(display);
@ -331,7 +262,7 @@ gst_vaapi_display_x11_get_display_info(
) )
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
GstVaapiDisplayCache *cache; GstVaapiDisplayCache *cache;
const GstVaapiDisplayInfo *cached_info; const GstVaapiDisplayInfo *cached_info;
@ -366,7 +297,7 @@ gst_vaapi_display_x11_get_size(
) )
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
if (!priv->x11_display) if (!priv->x11_display)
return; return;
@ -386,7 +317,7 @@ gst_vaapi_display_x11_get_size_mm(
) )
{ {
GstVaapiDisplayX11Private * const priv = GstVaapiDisplayX11Private * const priv =
GST_VAAPI_DISPLAY_X11(display)->priv; GST_VAAPI_DISPLAY_X11_PRIVATE(display);
guint width_mm, height_mm; guint width_mm, height_mm;
if (!priv->x11_display) if (!priv->x11_display)
@ -435,19 +366,17 @@ gst_vaapi_display_x11_get_size_mm(
*pheight = height_mm; *pheight = height_mm;
} }
static void void
gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) 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); GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); gst_vaapi_display_class_init(&klass->parent_class);
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;
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->open_display = gst_vaapi_display_x11_open_display;
dpy_class->close_display = gst_vaapi_display_x11_close_display; dpy_class->close_display = gst_vaapi_display_x11_close_display;
dpy_class->sync = gst_vaapi_display_x11_sync; 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_display = gst_vaapi_display_x11_get_display_info;
dpy_class->get_size = gst_vaapi_display_x11_get_size; dpy_class->get_size = gst_vaapi_display_x11_get_size;
dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm; 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 static inline const GstVaapiDisplayClass *
gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) gst_vaapi_display_x11_class(void)
{ {
GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); static GstVaapiDisplayX11Class g_class;
static gsize g_class_init = FALSE;
display->priv = priv; if (g_once_init_enter(&g_class_init)) {
priv->create_display = TRUE; gst_vaapi_display_x11_class_init(&g_class);
priv->x11_display = NULL; g_once_init_leave(&g_class_init, TRUE);
priv->x11_screen = 0; }
priv->display_name = NULL; return GST_VAAPI_DISPLAY_CLASS(&g_class);
priv->use_xrandr = FALSE;
} }
/** /**
@ -541,9 +412,8 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display)
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_display_x11_new(const gchar *display_name) gst_vaapi_display_x11_new(const gchar *display_name)
{ {
return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, return gst_vaapi_display_new(gst_vaapi_display_x11_class(),
"display-name", display_name, GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name);
NULL);
} }
/** /**
@ -562,10 +432,8 @@ gst_vaapi_display_x11_new_with_display(Display *x11_display)
{ {
g_return_val_if_fail(x11_display, NULL); g_return_val_if_fail(x11_display, NULL);
return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, return gst_vaapi_display_new(gst_vaapi_display_x11_class(),
"x11-display", x11_display, GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
"x11-screen", DefaultScreen(x11_display),
NULL);
} }
/** /**
@ -583,7 +451,7 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display)
{ {
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); 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); 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);
} }

View file

@ -28,59 +28,13 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DISPLAY_X11 \ #define GST_VAAPI_DISPLAY_X11(obj) \
(gst_vaapi_display_x11_get_type()) ((GstVaapiDisplayX11 *)(obj))
#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_IS_DISPLAY_X11(obj) \ #define GST_VAAPI_IS_DISPLAY_X11(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_X11)) ((obj) != NULL)
#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))
typedef struct _GstVaapiDisplayX11 GstVaapiDisplayX11; 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 * GstVaapiDisplay *
gst_vaapi_display_x11_new(const gchar *display_name); gst_vaapi_display_x11_new(const gchar *display_name);
@ -94,6 +48,10 @@ gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display);
int int
gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display); gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display);
void
gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display,
gboolean synchronous);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_DISPLAY_X11_H */ #endif /* GST_VAAPI_DISPLAY_X11_H */

View file

@ -25,15 +25,18 @@
#include <gst/vaapi/gstvaapiutils_x11.h> #include <gst/vaapi/gstvaapiutils_x11.h>
#include <gst/vaapi/gstvaapidisplay_x11.h> #include <gst/vaapi/gstvaapidisplay_x11.h>
#include "gstvaapidisplay_priv.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj) \ #define GST_VAAPI_DISPLAY_X11_CAST(display) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \ ((GstVaapiDisplayX11 *)(display))
GST_VAAPI_TYPE_DISPLAY_X11, \
GstVaapiDisplayX11Private))
#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: * GST_VAAPI_DISPLAY_XDISPLAY:
@ -43,7 +46,7 @@ G_BEGIN_DECLS
*/ */
#undef GST_VAAPI_DISPLAY_XDISPLAY #undef GST_VAAPI_DISPLAY_XDISPLAY
#define GST_VAAPI_DISPLAY_XDISPLAY(display) \ #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: * GST_VAAPI_DISPLAY_XSCREEN:
@ -53,17 +56,42 @@ G_BEGIN_DECLS
*/ */
#undef GST_VAAPI_DISPLAY_XSCREEN #undef GST_VAAPI_DISPLAY_XSCREEN
#define GST_VAAPI_DISPLAY_XSCREEN(display) \ #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 { struct _GstVaapiDisplayX11Private {
gchar *display_name; gchar *display_name;
Display *x11_display; Display *x11_display;
int x11_screen; int x11_screen;
guint create_display : 1; guint use_foreign_display : 1; // Foreign native_display?
guint synchronous : 1; guint use_xrandr : 1;
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 G_END_DECLS
#endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */ #endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */

View file

@ -47,7 +47,7 @@ gst_vaapi_object_finalize(GstVaapiObject *object)
if (klass->finalize) if (klass->finalize)
klass->finalize(object); klass->finalize(object);
g_clear_object(&object->display); gst_vaapi_display_replace(&object->display, NULL);
} }
void void
@ -89,7 +89,7 @@ gst_vaapi_object_new(const GstVaapiObjectClass *klass, GstVaapiDisplay *display)
if (!object) if (!object)
return NULL; return NULL;
object->display = g_object_ref(display); object->display = gst_vaapi_display_ref(display);
object->object_id = VA_INVALID_ID; object->object_id = VA_INVALID_ID;
sub_size = object_class->size - sizeof(*object); sub_size = object_class->size - sizeof(*object);

View file

@ -56,7 +56,7 @@ gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool)
void void
gst_vaapi_video_pool_init(GstVaapiVideoPool *pool, GstVaapiDisplay *display) 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_objects = NULL;
pool->used_count = 0; pool->used_count = 0;
pool->capacity = 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_list_free_full(pool->used_objects, gst_vaapi_object_unref);
g_queue_free_full(&pool->free_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);
} }
/** /**