mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-06-01 07:08:12 +00:00
wayland: Add basic colorimetrie support
Using the Wayland color-management and color-representation protocol drafts. On the Gst caps side it is currently limited to a subset of predefined GstVideoColorimetrys: sRGB, bt601, bt709, bt2020-10, bt2100-pq and bt2100-hlq. On the Wayland side it uses named transfer functions, named primaries, matrices, ranges and chroma locations - hopefully with a correct matching. The implementation queries supported values from the compositors, tries to convert them into known GstVideoColorimetrys and passes these upstream to decoders etc. as GstCaps for negotiation. If the negotiation succeeds, the it translates the GstVideoColorimetry from the resulting GstVideoInfo back to into a Wayland parametric image description and color representation for the video surface.
This commit is contained in:
parent
765f8767ef
commit
6b7f8be3da
|
@ -539,6 +539,7 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
GValue shm_list = G_VALUE_INIT, dmabuf_list = G_VALUE_INIT;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GArray *formats, *modifiers;
|
||||
GList *colorimetries;
|
||||
gint i;
|
||||
guint fmt;
|
||||
GstVideoFormat gfmt;
|
||||
|
@ -579,6 +580,23 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "drm-format",
|
||||
&dmabuf_list);
|
||||
|
||||
colorimetries = gst_wl_display_get_colorimetries (self->display);
|
||||
if (g_list_length (colorimetries) > 0) {
|
||||
GValue colorimentry_list = G_VALUE_INIT;
|
||||
GList *l;
|
||||
|
||||
g_value_init (&colorimentry_list, GST_TYPE_LIST);
|
||||
|
||||
for (l = colorimetries; l; l = l->next) {
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, (char *) l->data);
|
||||
gst_value_list_append_and_take_value (&colorimentry_list, &value);
|
||||
}
|
||||
|
||||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "colorimetry",
|
||||
&colorimentry_list);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "display caps: %" GST_PTR_FORMAT, caps);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "gstwldisplay.h"
|
||||
|
||||
#include "color-management-v1-client-protocol.h"
|
||||
#include "color-representation-v1-client-protocol.h"
|
||||
#include "fullscreen-shell-unstable-v1-client-protocol.h"
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
#include "single-pixel-buffer-v1-client-protocol.h"
|
||||
|
@ -53,10 +55,20 @@ typedef struct _GstWlDisplayPrivate
|
|||
struct wl_shm *shm;
|
||||
struct wp_viewporter *viewporter;
|
||||
struct zwp_linux_dmabuf_v1 *dmabuf;
|
||||
struct xx_color_manager_v2 *color;
|
||||
struct wp_color_representation_manager_v1 *color_representation;
|
||||
|
||||
GArray *shm_formats;
|
||||
GArray *dmabuf_formats;
|
||||
GArray *dmabuf_modifiers;
|
||||
|
||||
gboolean color_parametric_creator_supported;
|
||||
GList *colorimetries;
|
||||
GArray *color_transfer_functions;
|
||||
GArray *color_primaries;
|
||||
GArray *color_representation_coefficients;
|
||||
GArray *color_representation_chroma_locations;
|
||||
|
||||
/* private */
|
||||
gboolean own_display;
|
||||
GThread *thread;
|
||||
|
@ -92,6 +104,13 @@ gst_wl_display_init (GstWlDisplay * self)
|
|||
priv->shm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->dmabuf_modifiers = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
priv->color_transfer_functions =
|
||||
g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->color_primaries = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->color_representation_coefficients =
|
||||
g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->color_representation_chroma_locations =
|
||||
g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->wl_fd_poll = gst_poll_new (TRUE);
|
||||
priv->buffers = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
g_mutex_init (&priv->buffers_mutex);
|
||||
|
@ -132,11 +151,25 @@ gst_wl_display_finalize (GObject * gobject)
|
|||
g_array_unref (priv->shm_formats);
|
||||
g_array_unref (priv->dmabuf_formats);
|
||||
g_array_unref (priv->dmabuf_modifiers);
|
||||
|
||||
if (priv->colorimetries)
|
||||
g_list_free (priv->colorimetries);
|
||||
g_array_unref (priv->color_transfer_functions);
|
||||
g_array_unref (priv->color_primaries);
|
||||
g_array_unref (priv->color_representation_coefficients);
|
||||
g_array_unref (priv->color_representation_chroma_locations);
|
||||
|
||||
gst_poll_free (priv->wl_fd_poll);
|
||||
g_hash_table_unref (priv->buffers);
|
||||
g_mutex_clear (&priv->buffers_mutex);
|
||||
g_rec_mutex_clear (&priv->sync_mutex);
|
||||
|
||||
if (priv->color)
|
||||
xx_color_manager_v2_destroy (priv->color);
|
||||
|
||||
if (priv->color_representation)
|
||||
wp_color_representation_manager_v1_destroy (priv->color_representation);
|
||||
|
||||
if (priv->viewporter)
|
||||
wp_viewporter_destroy (priv->viewporter);
|
||||
|
||||
|
@ -242,6 +275,256 @@ static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
|
|||
dmabuf_modifier,
|
||||
};
|
||||
|
||||
#define FULL_RANGE_FLAG (1 << 8)
|
||||
|
||||
static gboolean
|
||||
not_contained_in (gpointer key, gpointer value, gpointer other)
|
||||
{
|
||||
return !g_hash_table_contains (other, key);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_display_compute_colorimetrie (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
GHashTable *candidates;
|
||||
GHashTable *candidates_tmp;
|
||||
guint i;
|
||||
|
||||
if (!priv->color) {
|
||||
g_warning ("Server does not support color management");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->color_representation) {
|
||||
g_warning ("Server does not support color representation");
|
||||
return;
|
||||
}
|
||||
|
||||
candidates_tmp = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < priv->color_transfer_functions->len; i++) {
|
||||
uint32_t transfer_function =
|
||||
g_array_index (priv->color_transfer_functions, uint32_t, i);
|
||||
|
||||
switch (transfer_function) {
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT709:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT601);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT709);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2020_10);
|
||||
break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_SRGB);
|
||||
break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_PQ);
|
||||
break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_HLG);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
candidates = candidates_tmp;
|
||||
candidates_tmp = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < priv->color_primaries->len; i++) {
|
||||
uint32_t primarie = g_array_index (priv->color_primaries, uint32_t, i);
|
||||
|
||||
switch (primarie) {
|
||||
case WP_COLOR_MANAGER_V1_PRIMARIES_SRGB:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_SRGB);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT709);
|
||||
break;
|
||||
case WP_COLOR_MANAGER_V1_PRIMARIES_NTSC:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT601);
|
||||
break;
|
||||
case WP_COLOR_MANAGER_V1_PRIMARIES_BT2020:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2020_10);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_PQ);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_HLG);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_foreach_remove (candidates, not_contained_in, candidates_tmp);
|
||||
g_hash_table_remove_all (candidates_tmp);
|
||||
|
||||
for (i = 0; i < priv->color_representation_coefficients->len; i++) {
|
||||
uint32_t coefficient =
|
||||
g_array_index (priv->color_representation_coefficients, uint32_t, i);
|
||||
GstVideoColorRange range;
|
||||
|
||||
range = (coefficient & FULL_RANGE_FLAG) ?
|
||||
GST_VIDEO_COLOR_RANGE_0_255 : GST_VIDEO_COLOR_RANGE_16_235;
|
||||
coefficient %= FULL_RANGE_FLAG;
|
||||
|
||||
switch (coefficient) {
|
||||
case 0:
|
||||
if (range == GST_VIDEO_COLOR_RANGE_0_255)
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_SRGB);
|
||||
break;
|
||||
case 1:
|
||||
if (range == GST_VIDEO_COLOR_RANGE_16_235)
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT709);
|
||||
break;
|
||||
case 6:
|
||||
if (range == GST_VIDEO_COLOR_RANGE_16_235)
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT601);
|
||||
break;
|
||||
case 9:
|
||||
if (range == GST_VIDEO_COLOR_RANGE_16_235) {
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2020_10);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_PQ);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_HLG);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_foreach_remove (candidates, not_contained_in, candidates_tmp);
|
||||
g_hash_table_remove_all (candidates_tmp);
|
||||
|
||||
for (i = 0; i < priv->color_representation_chroma_locations->len; i++) {
|
||||
uint32_t chroma_location =
|
||||
g_array_index (priv->color_representation_chroma_locations, uint32_t,
|
||||
i);
|
||||
|
||||
switch (chroma_location) {
|
||||
case 0:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_SRGB);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT601);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT709);
|
||||
break;
|
||||
case 2:
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2020_10);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_PQ);
|
||||
g_hash_table_add (candidates_tmp,
|
||||
(gpointer) GST_VIDEO_COLORIMETRY_BT2100_HLG);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_foreach_remove (candidates, not_contained_in, candidates_tmp);
|
||||
g_hash_table_remove_all (candidates_tmp);
|
||||
|
||||
g_warning ("%s supported geometries: %d", __func__,
|
||||
g_hash_table_size (candidates));
|
||||
priv->colorimetries = g_hash_table_get_keys (candidates);
|
||||
|
||||
g_hash_table_unref (candidates);
|
||||
g_hash_table_unref (candidates_tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_intent (void *data,
|
||||
struct xx_color_manager_v2 *xx_color_manager_v2, uint32_t render_intent)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_feature (void *data,
|
||||
struct xx_color_manager_v2 *xx_color_manager_v2, uint32_t feature)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
if (feature == WP_COLOR_MANAGER_V1_FEATURE_PARAMETRIC) {
|
||||
g_warning ("%s new_parametric_creator supported", __func__);
|
||||
priv->color_parametric_creator_supported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_tf_named (void *data,
|
||||
struct xx_color_manager_v2 *xx_color_manager_v2, uint32_t tf)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
g_warning ("%s: %u", __func__, tf);
|
||||
g_array_append_val (priv->color_transfer_functions, tf);
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_primaries_named (void *data,
|
||||
struct xx_color_manager_v2 *xx_color_manager_v2, uint32_t primaries)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
g_warning ("%s: %u", __func__, primaries);
|
||||
g_array_append_val (priv->color_primaries, primaries);
|
||||
}
|
||||
|
||||
static const struct xx_color_manager_v2_listener color_listener = {
|
||||
.supported_intent = color_supported_intent,
|
||||
.supported_feature = color_supported_feature,
|
||||
.supported_tf_named = color_supported_tf_named,
|
||||
.supported_primaries_named = color_supported_primaries_named,
|
||||
};
|
||||
|
||||
static void
|
||||
color_representation_coefficients (void *data,
|
||||
struct wp_color_representation_manager_v1
|
||||
*wp_color_representation_manager_v1, uint32_t code_point)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
g_warning ("%s: %u", __func__, code_point);
|
||||
g_array_append_val (priv->color_representation_coefficients, code_point);
|
||||
}
|
||||
|
||||
static void
|
||||
color_representation_chroma_location (void *data,
|
||||
struct wp_color_representation_manager_v1
|
||||
*wp_color_representation_manager_v1, uint32_t code_point)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
g_warning ("%s: %u", __func__, code_point);
|
||||
g_array_append_val (priv->color_representation_chroma_locations, code_point);
|
||||
}
|
||||
|
||||
static const struct wp_color_representation_manager_v1_listener
|
||||
color_representation_listener = {
|
||||
color_representation_coefficients,
|
||||
color_representation_chroma_location,
|
||||
};
|
||||
|
||||
gboolean
|
||||
gst_wl_display_check_format_for_shm (GstWlDisplay * self,
|
||||
const GstVideoInfo * video_info)
|
||||
|
@ -336,6 +619,17 @@ registry_handle_global (void *data, struct wl_registry *registry,
|
|||
priv->single_pixel_buffer =
|
||||
wl_registry_bind (registry, id,
|
||||
&wp_single_pixel_buffer_manager_v1_interface, 1);
|
||||
} else if (g_strcmp0 (interface, xx_color_manager_v2_interface.name) == 0) {
|
||||
priv->color = wl_registry_bind (registry, id,
|
||||
&xx_color_manager_v2_interface, 1);
|
||||
xx_color_manager_v2_add_listener (priv->color, &color_listener, self);
|
||||
} else if (g_strcmp0 (interface,
|
||||
wp_color_representation_manager_v1_interface.name) == 0) {
|
||||
priv->color_representation =
|
||||
wl_registry_bind (registry, id,
|
||||
&wp_color_representation_manager_v1_interface, 1);
|
||||
wp_color_representation_manager_v1_add_listener (priv->color_representation,
|
||||
&color_representation_listener, self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,6 +773,8 @@ gst_wl_display_new_existing (struct wl_display *display,
|
|||
"video display may not work properly.");
|
||||
}
|
||||
|
||||
gst_wl_display_compute_colorimetrie (self);
|
||||
|
||||
priv->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run,
|
||||
self, &err);
|
||||
if (err) {
|
||||
|
@ -688,3 +984,35 @@ gst_wl_display_has_own_display (GstWlDisplay * self)
|
|||
|
||||
return priv->own_display;
|
||||
}
|
||||
|
||||
struct xx_color_manager_v2 *
|
||||
gst_wl_display_get_color_manager_v1 (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->color;
|
||||
}
|
||||
|
||||
struct wp_color_representation_manager_v1 *
|
||||
gst_wl_display_get_color_representation_manager_v1 (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->color_representation;
|
||||
}
|
||||
|
||||
GList*
|
||||
gst_wl_display_get_colorimetries (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->colorimetries;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_wl_display_get_color_parametric_creator_supported (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->color_parametric_creator_supported;
|
||||
}
|
||||
|
|
|
@ -112,4 +112,16 @@ struct wp_single_pixel_buffer_manager_v1 * gst_wl_display_get_single_pixel_buffe
|
|||
GST_WL_API
|
||||
gboolean gst_wl_display_has_own_display (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
struct xx_color_manager_v2 *gst_wl_display_get_color_manager_v1 (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
struct wp_color_representation_manager_v1 *gst_wl_display_get_color_representation_manager_v1 (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
GList *gst_wl_display_get_colorimetries (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_get_color_parametric_creator_supported (GstWlDisplay * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "gstwlwindow.h"
|
||||
|
||||
#include "color-management-v1-client-protocol.h"
|
||||
#include "color-representation-v1-client-protocol.h"
|
||||
#include "fullscreen-shell-unstable-v1-client-protocol.h"
|
||||
#include "single-pixel-buffer-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
|
@ -51,6 +53,8 @@ typedef struct _GstWlWindowPrivate
|
|||
struct wp_viewport *video_viewport;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
struct xx_color_management_surface_v2 *color_management_surface;
|
||||
struct wp_color_representation_v1 *color_representation;
|
||||
gboolean configured;
|
||||
GCond configure_cond;
|
||||
GMutex configure_mutex;
|
||||
|
@ -104,6 +108,9 @@ static void gst_wl_window_update_borders (GstWlWindow * self);
|
|||
static void gst_wl_window_commit_buffer (GstWlWindow * self,
|
||||
GstWlBuffer * buffer);
|
||||
|
||||
static void gst_wl_window_set_colorimetry (GstWlWindow *self,
|
||||
GstVideoColorimetry *colorimetry);
|
||||
|
||||
static void
|
||||
handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel)
|
||||
{
|
||||
|
@ -211,6 +218,12 @@ gst_wl_window_finalize (GObject * gobject)
|
|||
if (priv->video_viewport)
|
||||
wp_viewport_destroy (priv->video_viewport);
|
||||
|
||||
if (priv->color_management_surface)
|
||||
xx_color_management_surface_v2_destroy (priv->color_management_surface);
|
||||
|
||||
if (priv->color_representation)
|
||||
wp_color_representation_v1_destroy (priv->color_representation);
|
||||
|
||||
wl_proxy_wrapper_destroy (priv->video_surface_wrapper);
|
||||
wl_subsurface_destroy (priv->video_subsurface);
|
||||
wl_surface_destroy (priv->video_surface);
|
||||
|
@ -565,6 +578,8 @@ gst_wl_window_commit_buffer (GstWlWindow * self, GstWlBuffer * buffer)
|
|||
wl_subsurface_set_sync (priv->video_subsurface);
|
||||
gst_wl_window_resize_video_surface (self, FALSE);
|
||||
gst_wl_window_set_opaque (self, info);
|
||||
|
||||
gst_wl_window_set_colorimetry (self, &info->colorimetry);
|
||||
}
|
||||
|
||||
if (G_LIKELY (buffer)) {
|
||||
|
@ -821,3 +836,216 @@ gst_wl_window_set_rotate_method (GstWlWindow * self,
|
|||
|
||||
gst_wl_window_update_geometry (self);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean ready;
|
||||
gboolean failed;
|
||||
} ImageDescriptionFeedback;
|
||||
|
||||
static void
|
||||
image_description_failed (void *data,
|
||||
struct xx_image_description_v2 *xx_image_description_v2, uint32_t cause,
|
||||
const char *msg)
|
||||
{
|
||||
ImageDescriptionFeedback *image_description_feedback = data;
|
||||
|
||||
image_description_feedback->failed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
image_description_ready (void *data,
|
||||
struct xx_image_description_v2 *xx_image_description_v2, uint32_t identity)
|
||||
{
|
||||
ImageDescriptionFeedback *image_description_feedback = data;
|
||||
|
||||
image_description_feedback->ready = TRUE;
|
||||
}
|
||||
|
||||
static const struct xx_image_description_v2_listener description_listerer = {
|
||||
.failed = image_description_failed,
|
||||
.ready = image_description_ready,
|
||||
};
|
||||
|
||||
static void
|
||||
gst_wl_window_set_colorimetry (GstWlWindow *self,
|
||||
GstVideoColorimetry *colorimetry)
|
||||
{
|
||||
GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self);
|
||||
struct xx_color_manager_v2 *color_manager;
|
||||
struct wp_color_representation_manager_v1 *cr_manager;
|
||||
struct wl_display *wl_display;
|
||||
struct xx_color_manager_v2 *color_manager_wrapper = NULL;
|
||||
struct wl_event_queue *color_manager_queue = NULL;
|
||||
struct xx_image_description_creator_params_v2 *params;
|
||||
struct xx_image_description_v2 *image_description = NULL;
|
||||
ImageDescriptionFeedback image_description_feedback = { 0 };
|
||||
gboolean colorimetry_supported = FALSE;
|
||||
GList *colorimetries, *l;
|
||||
uint32_t wl_transfer_function;
|
||||
uint32_t wl_primaries;
|
||||
uint32_t wl_coefficients;
|
||||
uint32_t wl_chroma_location;
|
||||
|
||||
wl_display = gst_wl_display_get_display (priv->display);
|
||||
color_manager = gst_wl_display_get_color_manager_v1 (priv->display);
|
||||
cr_manager =
|
||||
gst_wl_display_get_color_representation_manager_v1 (priv->display);
|
||||
|
||||
if (!color_manager) {
|
||||
g_warning ("%s can't set colorimetry: color management not supported",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cr_manager) {
|
||||
g_warning ("%s can't set colorimetry: color representation not supported",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gst_wl_display_get_color_parametric_creator_supported (priv->display)) {
|
||||
g_warning ("%s can't set colorimetry: parametric creator not supported",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
colorimetries = gst_wl_display_get_colorimetries (priv->display);
|
||||
for (l = colorimetries; l; l = l->next) {
|
||||
if (g_strcmp0 (gst_video_colorimetry_to_string (colorimetry),
|
||||
(char *) l->data) == 0) {
|
||||
colorimetry_supported = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!colorimetry_supported) {
|
||||
g_warning
|
||||
("%s can't set colorimetry: colorimetry %s not supported by display",
|
||||
__func__, gst_video_colorimetry_to_string (colorimetry));
|
||||
return;
|
||||
}
|
||||
|
||||
g_warning ("%s setting colorimetry: %s", __func__,
|
||||
gst_video_colorimetry_to_string (colorimetry));
|
||||
|
||||
color_manager_wrapper = wl_proxy_create_wrapper (color_manager);
|
||||
color_manager_queue = wl_display_create_queue (wl_display);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) color_manager_wrapper,
|
||||
color_manager_queue);
|
||||
|
||||
params = xx_color_manager_v2_new_parametric_creator (color_manager_wrapper);
|
||||
|
||||
switch (colorimetry->transfer) {
|
||||
case GST_VIDEO_TRANSFER_SRGB:
|
||||
wl_transfer_function = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB;
|
||||
break;
|
||||
case GST_VIDEO_TRANSFER_BT601:
|
||||
case GST_VIDEO_TRANSFER_BT709:
|
||||
case GST_VIDEO_TRANSFER_BT2020_10:
|
||||
wl_transfer_function = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT709;
|
||||
break;
|
||||
case GST_VIDEO_TRANSFER_SMPTE2084:
|
||||
wl_transfer_function = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ;
|
||||
break;
|
||||
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
||||
wl_transfer_function = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
xx_image_description_creator_params_v2_set_tf_named (params,
|
||||
wl_transfer_function);
|
||||
|
||||
switch (colorimetry->primaries) {
|
||||
case GST_VIDEO_COLOR_PRIMARIES_BT709:
|
||||
wl_primaries = WP_COLOR_MANAGER_V1_PRIMARIES_SRGB;
|
||||
break;
|
||||
case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
|
||||
wl_primaries = WP_COLOR_MANAGER_V1_PRIMARIES_NTSC;
|
||||
break;
|
||||
case GST_VIDEO_COLOR_PRIMARIES_BT2020:
|
||||
wl_primaries = WP_COLOR_MANAGER_V1_PRIMARIES_BT2020;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
xx_image_description_creator_params_v2_set_primaries_named (params,
|
||||
wl_primaries);
|
||||
|
||||
image_description = xx_image_description_creator_params_v2_create (params);
|
||||
xx_image_description_v2_add_listener (image_description,
|
||||
&description_listerer, &image_description_feedback);
|
||||
|
||||
while (!image_description_feedback.ready &&
|
||||
!image_description_feedback.failed) {
|
||||
if (wl_display_dispatch_queue (wl_display, color_manager_queue) == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!image_description_feedback.ready) {
|
||||
g_warning ("%s creating image description failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!priv->color_management_surface) {
|
||||
priv->color_management_surface =
|
||||
xx_color_manager_v2_get_surface (color_manager,
|
||||
priv->video_surface_wrapper);
|
||||
}
|
||||
|
||||
xx_color_management_surface_v2_set_image_description
|
||||
(priv->color_management_surface, image_description,
|
||||
XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL);
|
||||
|
||||
switch (colorimetry->matrix) {
|
||||
case GST_VIDEO_COLOR_MATRIX_RGB:
|
||||
wl_coefficients = 0;
|
||||
break;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT709:
|
||||
wl_coefficients = 1;
|
||||
break;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT601:
|
||||
wl_coefficients = 6;
|
||||
break;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT2020:
|
||||
wl_coefficients = 9;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255)
|
||||
wl_coefficients |= (1 << 8);
|
||||
|
||||
if (g_strcmp0 (gst_video_colorimetry_to_string (colorimetry),
|
||||
GST_VIDEO_COLORIMETRY_BT2020_10) == 0 ||
|
||||
g_strcmp0 (gst_video_colorimetry_to_string (colorimetry),
|
||||
GST_VIDEO_COLORIMETRY_BT2100_PQ) == 0 ||
|
||||
g_strcmp0 (gst_video_colorimetry_to_string (colorimetry),
|
||||
GST_VIDEO_COLORIMETRY_BT2100_HLG) == 0) {
|
||||
wl_chroma_location = 2;
|
||||
} else {
|
||||
wl_chroma_location = 0;
|
||||
}
|
||||
|
||||
if (!priv->color_representation) {
|
||||
priv->color_representation =
|
||||
wp_color_representation_manager_v1_create (cr_manager,
|
||||
priv->video_surface_wrapper);
|
||||
}
|
||||
|
||||
wp_color_representation_v1_set_coefficients (priv->color_representation,
|
||||
wl_coefficients);
|
||||
wp_color_representation_v1_set_chroma_location (priv->color_representation,
|
||||
wl_chroma_location);
|
||||
|
||||
out:
|
||||
if (image_description)
|
||||
xx_image_description_v2_destroy (image_description);
|
||||
if (color_manager_wrapper)
|
||||
wl_proxy_wrapper_destroy (color_manager_wrapper);
|
||||
if (color_manager_queue)
|
||||
wl_event_queue_destroy (color_manager_queue);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ if use_wayland
|
|||
['fullscreen-shell', 'unstable', 'v1', ],
|
||||
['xdg-shell', 'stable', ],
|
||||
['single-pixel-buffer', 'staging', 'v1' ],
|
||||
['color-management', 'staging', 'v1' ],
|
||||
['color-representation', 'staging', 'v1' ],
|
||||
]
|
||||
protocols_files = []
|
||||
|
||||
|
|
Loading…
Reference in a new issue