wayland: Add basic colorimetrie support
Using the Wayland color-management and color-representation protocols. The implementation queries supported values from the compositors and tries to convert them into GstVideoColorimetry values. It currently *does not* pass these upstream to decoders etc. as GstCaps for negotiation. On the Wayland side it uses named transfer functions, named primaries, matrices and ranges. The straight alpha mode is also set if supported by the compositor. On setting caps it translates the GstVideoColorimetry from the GstVideoInfo back to into a Wayland parametric image description and color representation for the video surface if possible. If a colorimetry is not fully support, we bail out and if wayland objects already exist they get reset or deleted. Note that not all GstVideoColorimetry values are implemented yet. Useful debug options: GST_DEBUG=wlwindow:4,wldisplay:4 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6830>
This commit is contained in:
parent
bd70a242ec
commit
abe186e466
@ -11,6 +11,6 @@ variables:
|
||||
|
||||
CHECKS_TAG: '2025-02-04.0'
|
||||
|
||||
ABI_CHECK_TAG: '2025-04-17.0'
|
||||
ABI_CHECK_TAG: '2025-06-12.0'
|
||||
|
||||
WINDOWS_TAG: '2025-05-30.0'
|
||||
|
@ -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 wp_color_manager_v1 *color;
|
||||
struct wp_color_representation_manager_v1 *color_representation;
|
||||
|
||||
GArray *shm_formats;
|
||||
GArray *dmabuf_formats;
|
||||
GArray *dmabuf_modifiers;
|
||||
|
||||
gboolean color_parametric_creator_supported;
|
||||
GArray *color_transfer_functions;
|
||||
GArray *color_primaries;
|
||||
GArray *color_alpha_modes;
|
||||
GArray *color_coefficients;
|
||||
GArray *color_coefficients_range;
|
||||
|
||||
/* 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_coefficients = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->color_coefficients_range =
|
||||
g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->color_alpha_modes = 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);
|
||||
@ -133,11 +152,24 @@ gst_wl_display_finalize (GObject * gobject)
|
||||
g_array_unref (priv->shm_formats);
|
||||
g_array_unref (priv->dmabuf_formats);
|
||||
g_array_unref (priv->dmabuf_modifiers);
|
||||
|
||||
g_array_unref (priv->color_transfer_functions);
|
||||
g_array_unref (priv->color_primaries);
|
||||
g_array_unref (priv->color_alpha_modes);
|
||||
g_array_unref (priv->color_coefficients);
|
||||
g_array_unref (priv->color_coefficients_range);
|
||||
|
||||
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)
|
||||
wp_color_manager_v1_destroy (priv->color);
|
||||
|
||||
if (priv->color_representation)
|
||||
wp_color_representation_manager_v1_destroy (priv->color_representation);
|
||||
|
||||
if (priv->viewporter)
|
||||
wp_viewporter_destroy (priv->viewporter);
|
||||
|
||||
@ -240,6 +272,100 @@ static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
|
||||
dmabuf_modifier,
|
||||
};
|
||||
|
||||
static void
|
||||
color_supported_intent (void *data,
|
||||
struct wp_color_manager_v1 *wp_color_manager_v1, uint32_t render_intent)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_feature (void *data,
|
||||
struct wp_color_manager_v1 *wp_color_manager_v1, uint32_t feature)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
if (feature == WP_COLOR_MANAGER_V1_FEATURE_PARAMETRIC) {
|
||||
GST_INFO_OBJECT (self, "New_parametric_creator supported");
|
||||
priv->color_parametric_creator_supported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_tf_named (void *data,
|
||||
struct wp_color_manager_v1 *wp_color_manager_v1, uint32_t tf)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Supported transfer function 0x%x", tf);
|
||||
g_array_append_val (priv->color_transfer_functions, tf);
|
||||
}
|
||||
|
||||
static void
|
||||
color_supported_primaries_named (void *data,
|
||||
struct wp_color_manager_v1 *wp_color_manager_v1, uint32_t primaries)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Supported primaries: 0x%x", primaries);
|
||||
g_array_append_val (priv->color_primaries, primaries);
|
||||
}
|
||||
|
||||
static void
|
||||
color_done (void *data, struct wp_color_manager_v1 *wp_color_manager_v1)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wp_color_manager_v1_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,
|
||||
.done = color_done,
|
||||
};
|
||||
|
||||
static void
|
||||
color_representation_supported_alpha_mode (void *data,
|
||||
struct wp_color_representation_manager_v1
|
||||
*wp_color_representation_manager_v1, uint32_t alpha_mode)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Supported alpha mode: 0x%x", alpha_mode);
|
||||
g_array_append_val (priv->color_alpha_modes, alpha_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
color_representation_supported_coefficients_and_ranges (void *data,
|
||||
struct wp_color_representation_manager_v1
|
||||
*wp_color_representation_manager_v1, uint32_t coefficients, uint32_t range)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Supported coefficients and range: 0x%x/0x%x",
|
||||
coefficients, range);
|
||||
g_array_append_val (priv->color_coefficients, coefficients);
|
||||
g_array_append_val (priv->color_coefficients_range, range);
|
||||
}
|
||||
|
||||
static void
|
||||
color_representation_done (void *data, struct wp_color_representation_manager_v1
|
||||
*wp_color_representation_manager_v1)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wp_color_representation_manager_v1_listener
|
||||
color_representation_listener = {
|
||||
.supported_alpha_mode = color_representation_supported_alpha_mode,
|
||||
.supported_coefficients_and_ranges =
|
||||
color_representation_supported_coefficients_and_ranges,
|
||||
.done = color_representation_done,
|
||||
};
|
||||
|
||||
gboolean
|
||||
gst_wl_display_check_format_for_shm (GstWlDisplay * self,
|
||||
const GstVideoInfo * video_info)
|
||||
@ -334,6 +460,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, wp_color_manager_v1_interface.name) == 0) {
|
||||
priv->color = wl_registry_bind (registry, id,
|
||||
&wp_color_manager_v1_interface, 1);
|
||||
wp_color_manager_v1_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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -760,3 +897,166 @@ gst_wl_display_has_own_display (GstWlDisplay * self)
|
||||
|
||||
return priv->own_display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_get_color_manager_v1:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: (transfer none): The color manager global or %NULL
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
struct wp_color_manager_v1 *
|
||||
gst_wl_display_get_color_manager_v1 (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_get_color_representation_manager_v1:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: (transfer none): The color representation global or %NULL
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_is_color_parametric_creator_supported:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: %TRUE if the compositor supports parametric image descriptions
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
gboolean
|
||||
gst_wl_display_is_color_parametric_creator_supported (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->color_parametric_creator_supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_is_color_transfer_function_supported:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: %TRUE if the compositor supports @transfer_function
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
gboolean
|
||||
gst_wl_display_is_color_transfer_function_supported (GstWlDisplay * self,
|
||||
uint32_t transfer_function)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
guint i;
|
||||
|
||||
/* A value of 0 is invalid and will never be present in the list of enums. */
|
||||
if (transfer_function == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < priv->color_transfer_functions->len; i++) {
|
||||
uint32_t candidate =
|
||||
g_array_index (priv->color_transfer_functions, uint32_t, i);
|
||||
|
||||
if (candidate == transfer_function)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_are_color_primaries_supported:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: %TRUE if the compositor supports @primaries
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
gboolean
|
||||
gst_wl_display_are_color_primaries_supported (GstWlDisplay * self,
|
||||
uint32_t primaries)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
guint i;
|
||||
|
||||
/* A value of 0 is invalid and will never be present in the list of enums. */
|
||||
if (primaries == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < priv->color_primaries->len; i++) {
|
||||
uint32_t candidate = g_array_index (priv->color_primaries, uint32_t, i);
|
||||
|
||||
if (candidate == primaries)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_is_color_alpha_mode_supported:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: %TRUE if the compositor supports @alpha_mode
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
gboolean
|
||||
gst_wl_display_is_color_alpha_mode_supported (GstWlDisplay * self,
|
||||
uint32_t alpha_mode)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->color_alpha_modes->len; i++) {
|
||||
uint32_t candidate = g_array_index (priv->color_alpha_modes, uint32_t, i);
|
||||
|
||||
if (candidate == alpha_mode)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_wl_display_are_color_coefficients_supported:
|
||||
* @self: A #GstWlDisplay
|
||||
*
|
||||
* Returns: %TRUE if the compositor supports the combination of @coefficients and @range
|
||||
*
|
||||
* Since: 1.28
|
||||
*/
|
||||
gboolean
|
||||
gst_wl_display_are_color_coefficients_supported (GstWlDisplay * self,
|
||||
uint32_t coefficients, uint32_t range)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
guint i;
|
||||
|
||||
/* A value of 0 is invalid and will never be present in the list of enums. */
|
||||
if (coefficients == 0 || range == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < priv->color_coefficients->len; i++) {
|
||||
uint32_t candidate = g_array_index (priv->color_coefficients, uint32_t, i);
|
||||
uint32_t candidate_range =
|
||||
g_array_index (priv->color_coefficients_range, uint32_t, i);
|
||||
|
||||
if (candidate == coefficients && candidate_range == range)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -121,4 +121,25 @@ 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 wp_color_manager_v1 *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
|
||||
gboolean gst_wl_display_is_color_parametric_creator_supported (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_is_color_transfer_function_supported (GstWlDisplay * self, uint32_t transfer_function);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_are_color_primaries_supported (GstWlDisplay * self, uint32_t primaries);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_is_color_alpha_mode_supported (GstWlDisplay * self, uint32_t alpha_mode);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_are_color_coefficients_supported (GstWlDisplay * self, uint32_t coefficients, uint32_t range);
|
||||
|
||||
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 wp_color_management_surface_v1 *color_management_surface;
|
||||
struct wp_color_representation_surface_v1 *color_representation_surface;
|
||||
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)
|
||||
{
|
||||
@ -210,6 +217,13 @@ gst_wl_window_finalize (GObject * gobject)
|
||||
if (priv->video_viewport)
|
||||
wp_viewport_destroy (priv->video_viewport);
|
||||
|
||||
if (priv->color_management_surface)
|
||||
wp_color_management_surface_v1_destroy (priv->color_management_surface);
|
||||
|
||||
if (priv->color_representation_surface)
|
||||
wp_color_representation_surface_v1_destroy
|
||||
(priv->color_representation_surface);
|
||||
|
||||
wl_proxy_wrapper_destroy (priv->video_surface_wrapper);
|
||||
wl_subsurface_destroy (priv->video_subsurface);
|
||||
wl_surface_destroy (priv->video_surface);
|
||||
@ -574,6 +588,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)) {
|
||||
@ -830,3 +846,260 @@ gst_wl_window_set_rotate_method (GstWlWindow * self,
|
||||
|
||||
gst_wl_window_update_geometry (self);
|
||||
}
|
||||
|
||||
enum ImageDescriptionFeedback
|
||||
{
|
||||
IMAGE_DESCRIPTION_FEEDBACK_UNKNOWN = 0,
|
||||
IMAGE_DESCRIPTION_FEEDBACK_READY,
|
||||
IMAGE_DESCRIPTION_FEEDBACK_FAILED,
|
||||
};
|
||||
|
||||
static void
|
||||
image_description_failed (void *data,
|
||||
struct wp_image_description_v1 *wp_image_description_v1, uint32_t cause,
|
||||
const char *msg)
|
||||
{
|
||||
enum ImageDescriptionFeedback *image_description_feedback = data;
|
||||
|
||||
*image_description_feedback = IMAGE_DESCRIPTION_FEEDBACK_FAILED;
|
||||
}
|
||||
|
||||
static void
|
||||
image_description_ready (void *data,
|
||||
struct wp_image_description_v1 *wp_image_description_v1, uint32_t identity)
|
||||
{
|
||||
enum ImageDescriptionFeedback *image_description_feedback = data;
|
||||
|
||||
*image_description_feedback = IMAGE_DESCRIPTION_FEEDBACK_READY;
|
||||
}
|
||||
|
||||
static const struct wp_image_description_v1_listener description_listerer = {
|
||||
.failed = image_description_failed,
|
||||
.ready = image_description_ready,
|
||||
};
|
||||
|
||||
static enum wp_color_manager_v1_transfer_function
|
||||
gst_colorimetry_tf_to_wl (GstVideoTransferFunction tf)
|
||||
{
|
||||
switch (tf) {
|
||||
case GST_VIDEO_TRANSFER_SRGB:
|
||||
return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB;
|
||||
case GST_VIDEO_TRANSFER_BT601:
|
||||
case GST_VIDEO_TRANSFER_BT709:
|
||||
case GST_VIDEO_TRANSFER_BT2020_10:
|
||||
return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886;
|
||||
case GST_VIDEO_TRANSFER_SMPTE2084:
|
||||
return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ;
|
||||
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
||||
return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG;
|
||||
default:
|
||||
GST_WARNING ("Transfer function not handled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static enum wp_color_manager_v1_primaries
|
||||
gst_colorimetry_primaries_to_wl (GstVideoColorPrimaries primaries)
|
||||
{
|
||||
switch (primaries) {
|
||||
case GST_VIDEO_COLOR_PRIMARIES_BT709:
|
||||
return WP_COLOR_MANAGER_V1_PRIMARIES_SRGB;
|
||||
case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
|
||||
return WP_COLOR_MANAGER_V1_PRIMARIES_NTSC;
|
||||
case GST_VIDEO_COLOR_PRIMARIES_BT2020:
|
||||
return WP_COLOR_MANAGER_V1_PRIMARIES_BT2020;
|
||||
default:
|
||||
GST_WARNING ("Primaries not handled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static enum wp_color_representation_surface_v1_coefficients
|
||||
gst_colorimetry_matrix_to_wl (GstVideoColorMatrix matrix)
|
||||
{
|
||||
switch (matrix) {
|
||||
case GST_VIDEO_COLOR_MATRIX_RGB:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_IDENTITY;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT709:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT709;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT601:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT601;
|
||||
case GST_VIDEO_COLOR_MATRIX_BT2020:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_COEFFICIENTS_BT2020;
|
||||
default:
|
||||
GST_WARNING ("Matrix not handled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static enum wp_color_representation_surface_v1_range
|
||||
gst_colorimetry_range_to_wl (GstVideoColorRange range)
|
||||
{
|
||||
switch (range) {
|
||||
case GST_VIDEO_COLOR_RANGE_0_255:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_FULL;
|
||||
case GST_VIDEO_COLOR_RANGE_16_235:
|
||||
return WP_COLOR_REPRESENTATION_SURFACE_V1_RANGE_LIMITED;
|
||||
default:
|
||||
GST_WARNING ("Range not handled");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_window_set_image_description (GstWlWindow * self,
|
||||
GstVideoColorimetry * colorimetry)
|
||||
{
|
||||
GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self);
|
||||
struct wl_display *wl_display;
|
||||
struct wp_color_manager_v1 *color_manager;
|
||||
struct wp_color_manager_v1 *color_manager_wrapper = NULL;
|
||||
struct wl_event_queue *color_manager_queue = NULL;
|
||||
struct wp_image_description_v1 *image_description = NULL;
|
||||
struct wp_image_description_creator_params_v1 *params;
|
||||
enum ImageDescriptionFeedback image_description_feedback =
|
||||
IMAGE_DESCRIPTION_FEEDBACK_UNKNOWN;
|
||||
uint32_t wl_transfer_function;
|
||||
uint32_t wl_primaries;
|
||||
|
||||
if (!gst_wl_display_is_color_parametric_creator_supported (priv->display)) {
|
||||
GST_INFO_OBJECT (self,
|
||||
"Color management or parametric creator not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
color_manager = gst_wl_display_get_color_manager_v1 (priv->display);
|
||||
if (!priv->color_management_surface) {
|
||||
priv->color_management_surface =
|
||||
wp_color_manager_v1_get_surface (color_manager,
|
||||
priv->video_surface_wrapper);
|
||||
}
|
||||
|
||||
wl_transfer_function = gst_colorimetry_tf_to_wl (colorimetry->transfer);
|
||||
wl_primaries = gst_colorimetry_primaries_to_wl (colorimetry->primaries);
|
||||
|
||||
if (!gst_wl_display_is_color_transfer_function_supported (priv->display,
|
||||
wl_transfer_function) ||
|
||||
!gst_wl_display_are_color_primaries_supported (priv->display,
|
||||
wl_primaries)) {
|
||||
wp_color_management_surface_v1_unset_image_description
|
||||
(priv->color_management_surface);
|
||||
|
||||
GST_INFO_OBJECT (self,
|
||||
"Can not create image description: primaries or transfer function not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
color_manager_wrapper = wl_proxy_create_wrapper (color_manager);
|
||||
wl_display = gst_wl_display_get_display (priv->display);
|
||||
color_manager_queue = wl_display_create_queue (wl_display);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) color_manager_wrapper,
|
||||
color_manager_queue);
|
||||
|
||||
params =
|
||||
wp_color_manager_v1_create_parametric_creator (color_manager_wrapper);
|
||||
|
||||
wp_image_description_creator_params_v1_set_tf_named (params,
|
||||
wl_transfer_function);
|
||||
wp_image_description_creator_params_v1_set_primaries_named (params,
|
||||
wl_primaries);
|
||||
|
||||
image_description = wp_image_description_creator_params_v1_create (params);
|
||||
wp_image_description_v1_add_listener (image_description,
|
||||
&description_listerer, &image_description_feedback);
|
||||
|
||||
while (image_description_feedback == IMAGE_DESCRIPTION_FEEDBACK_UNKNOWN) {
|
||||
if (wl_display_dispatch_queue (wl_display, color_manager_queue) == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (image_description_feedback == IMAGE_DESCRIPTION_FEEDBACK_READY) {
|
||||
wp_color_management_surface_v1_set_image_description
|
||||
(priv->color_management_surface, image_description,
|
||||
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
|
||||
|
||||
GST_INFO_OBJECT (self, "Successfully set parametric image description");
|
||||
} else {
|
||||
wp_color_management_surface_v1_unset_image_description
|
||||
(priv->color_management_surface);
|
||||
|
||||
GST_INFO_OBJECT (self, "Creating image description failed");
|
||||
}
|
||||
|
||||
/* Setting the image description has copy semantics */
|
||||
wp_image_description_v1_destroy (image_description);
|
||||
wl_proxy_wrapper_destroy (color_manager_wrapper);
|
||||
wl_event_queue_destroy (color_manager_queue);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_window_set_color_representation (GstWlWindow * self,
|
||||
GstVideoColorimetry * colorimetry)
|
||||
{
|
||||
GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self);
|
||||
struct wp_color_representation_manager_v1 *cr_manager;
|
||||
uint32_t wl_alpha_mode;
|
||||
uint32_t wl_coefficients;
|
||||
uint32_t wl_range;
|
||||
gboolean alpha_mode_supported;
|
||||
gboolean coefficients_supported;
|
||||
|
||||
cr_manager =
|
||||
gst_wl_display_get_color_representation_manager_v1 (priv->display);
|
||||
if (!cr_manager) {
|
||||
GST_INFO_OBJECT (self, "Color representation not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_alpha_mode = WP_COLOR_REPRESENTATION_SURFACE_V1_ALPHA_MODE_STRAIGHT;
|
||||
alpha_mode_supported =
|
||||
gst_wl_display_is_color_alpha_mode_supported (priv->display,
|
||||
wl_alpha_mode);
|
||||
|
||||
wl_coefficients = gst_colorimetry_matrix_to_wl (colorimetry->matrix);
|
||||
wl_range = gst_colorimetry_range_to_wl (colorimetry->range);
|
||||
coefficients_supported =
|
||||
gst_wl_display_are_color_coefficients_supported (priv->display,
|
||||
wl_coefficients, wl_range);
|
||||
|
||||
if (alpha_mode_supported || coefficients_supported) {
|
||||
if (!priv->color_representation_surface) {
|
||||
priv->color_representation_surface =
|
||||
wp_color_representation_manager_v1_get_surface (cr_manager,
|
||||
priv->video_surface_wrapper);
|
||||
}
|
||||
|
||||
if (alpha_mode_supported)
|
||||
wp_color_representation_surface_v1_set_alpha_mode
|
||||
(priv->color_representation_surface, wl_alpha_mode);
|
||||
|
||||
if (coefficients_supported)
|
||||
wp_color_representation_surface_v1_set_coefficients_and_range
|
||||
(priv->color_representation_surface, wl_coefficients, wl_range);
|
||||
|
||||
GST_INFO_OBJECT (self, "Successfully set color representation");
|
||||
} else {
|
||||
if (priv->color_representation_surface) {
|
||||
wp_color_representation_surface_v1_destroy
|
||||
(priv->color_representation_surface);
|
||||
priv->color_representation_surface = NULL;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (self, "Coefficients and range not supported");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_wl_window_set_colorimetry (GstWlWindow * self,
|
||||
GstVideoColorimetry * colorimetry)
|
||||
{
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
GST_INFO_OBJECT (self, "Trying to set colorimetry: %s",
|
||||
gst_video_colorimetry_to_string (colorimetry));
|
||||
|
||||
gst_wl_window_set_image_description (self, colorimetry);
|
||||
gst_wl_window_set_color_representation (self, colorimetry);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user