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:
Robert Mader 2024-05-10 18:24:06 +02:00 committed by Robert Mader
parent 765f8767ef
commit 6b7f8be3da
5 changed files with 588 additions and 0 deletions

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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 = []