From afb18e0e31cbef821840828c689a94868e3fd0d9 Mon Sep 17 00:00:00 2001 From: Bill Hofmann Date: Fri, 18 Nov 2022 13:32:10 -0800 Subject: [PATCH] kmssink: add HDR10 infoframe support If stream has HDR10 metadata and HDMI device EDID supports it, this patch will set the DRM properties accordingly. Part-of: --- subprojects/gst-plugins-bad/sys/kms/gstkmsedid.c | 111 ++++++++ subprojects/gst-plugins-bad/sys/kms/gstkmsedid.h | 55 ++++ subprojects/gst-plugins-bad/sys/kms/gstkmssink.c | 322 +++++++++++++++++++++++ subprojects/gst-plugins-bad/sys/kms/gstkmssink.h | 14 + subprojects/gst-plugins-bad/sys/kms/meson.build | 13 +- 5 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 subprojects/gst-plugins-bad/sys/kms/gstkmsedid.c create mode 100644 subprojects/gst-plugins-bad/sys/kms/gstkmsedid.h diff --git a/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.c b/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.c new file mode 100644 index 0000000..7c5221a --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.c @@ -0,0 +1,111 @@ +/* +* Copyright © 2008-2011 Kristian Høgsberg +* Copyright © 2011 Intel Corporation +* Copyright © 2017, 2018 Collabora, Ltd. +* Copyright © 2017, 2018 General Electric Company +* Copyright (c) 2018 DisplayLink (UK) Ltd. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial +* portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +#include +#include "gstkmsedid.h" + +/* from libweston/backend-drm/modes.c unaccepted merge, modified slightly to + remove non HDR stuff, return -1 if no HDR in EDID. + https://gitlab.freedesktop.org/jcline/weston/-/commit/b3fa65d19ca60a45d0cc0fc1bfa68eea970344ee + */ +#define EDID_OFFSET_EXT_COUNT 0x7E +#define EDID_EXTENSION_SIZE 0x80 +// Indicates the EDID extension is a CTA extension +#define EDID_CTA_EXTENSION_TAG 0x02 +// Indicates the data block uses the extended tag field +#define EDID_CTA_EXTENDED_TAG 0x07 +// Value of the extended tag field for HDR static metadata blocks +#define EDID_CTA_STATIC_HDR_TAG 0x06 + +/* Extract the HDR static metadata from a CTA EDID extension. */ +static int +gst_kms_parse_hdr_metadata (const uint8_t * cta_ext_data, + struct gst_kms_hdr_static_metadata *metadata) +{ + int i, block_len; + uint8_t cta_revision = cta_ext_data[1]; + uint8_t dtd_offset = cta_ext_data[2]; + const uint8_t *data_blocks = cta_ext_data + 4; + + if (cta_revision != 3) { + return -1; + } + // The data block collection ranges from byte 4 to the dtd_offset; each + // block begins with the block size (in bytes) in bits 0-4 of the first byte. + for (i = 0; i < dtd_offset; i += (data_blocks[i] & 0x1f) + 1) { + if ((data_blocks[i] & 0xe0) >> 5 == EDID_CTA_EXTENDED_TAG) { + block_len = data_blocks[i] & 0x1f; + + if (data_blocks[i + 1] == EDID_CTA_STATIC_HDR_TAG) { + if (block_len < 2) + continue; + + metadata->eotf = data_blocks[i + 2]; + metadata->metadata_type = data_blocks[i + 3]; + + if (block_len > 3 && data_blocks[i + 4]) + metadata->max_cll = 50.0 * pow (2, data_blocks[i + 4] / 32.0); + if (block_len > 4 && data_blocks[i + 5]) + metadata->max_fall = 50.0 * pow (2, data_blocks[i + 5] / 32.0); + if (block_len > 5) + metadata->min_cll = + metadata->max_cll * pow (data_blocks[i + 6] / 255.0, 2) / 100.0; + return 0; + } + } + } + return -1; +} + +int +gst_kms_edid_parse (struct gst_kms_hdr_static_metadata *metadata, + const uint8_t * data, size_t length) +{ + int i; + const uint8_t *edid_extension; + + /* check header */ + if (length < 128 || length < ((size_t) data[EDID_OFFSET_EXT_COUNT] + 1) * 128) + return -1; + if (data[0] != 0x00 || data[1] != 0xff) + return -1; + + edid_extension = data + 128; + for (i = 0; i < data[EDID_OFFSET_EXT_COUNT]; i++) { + switch (edid_extension[0]) { + case EDID_CTA_EXTENSION_TAG: + return gst_kms_parse_hdr_metadata (edid_extension, metadata); + } + edid_extension += 128; + } + + return 0; +} + +/* END from libweston/backend-drm/modes.c unaccepted merge */ diff --git a/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.h b/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.h new file mode 100644 index 0000000..1907ae2 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/kms/gstkmsedid.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2011 Intel Corporation + * Copyright © 2017, 2018 Collabora, Ltd. + * Copyright © 2017, 2018 General Electric Company + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __GST_KMS_EDID_H__ +#define __GST_KMS_EDID_H__ + +/* from libweston/backend-drm/modes.c unaccepted merge, modified slightly to + remove non HDR stuff, return -1 if no HDR in EDID. + https://gitlab.freedesktop.org/jcline/weston/-/commit/b3fa65d19ca60a45d0cc0fc1bfa68eea970344ee + */ + +#include +#include + +/* HDR Metadata as per 861.G spec from linux/hdmi.h, modified for stdint.h */ +struct gst_kms_hdr_static_metadata +{ + uint8_t eotf; + uint8_t metadata_type; + uint16_t max_cll; + uint16_t max_fall; + uint16_t min_cll; +}; + +int +gst_kms_edid_parse (struct gst_kms_hdr_static_metadata *metadata, const uint8_t * data, + size_t length); + +#endif /* __GST_KMS_EDID_H__ */ diff --git a/subprojects/gst-plugins-bad/sys/kms/gstkmssink.c b/subprojects/gst-plugins-bad/sys/kms/gstkmssink.c index e929d28..16d4afb 100644 --- a/subprojects/gst-plugins-bad/sys/kms/gstkmssink.c +++ b/subprojects/gst-plugins-bad/sys/kms/gstkmssink.c @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -62,6 +63,11 @@ #include "gstkmsbufferpool.h" #include "gstkmsallocator.h" +#ifdef HAVE_DRM_HDR +#include +#include "gstkmsedid.h" +#endif + #define GST_PLUGIN_NAME "kmssink" #define GST_PLUGIN_DESC "Video sink using the Linux kernel mode setting API" @@ -104,6 +110,303 @@ enum static GParamSpec *g_properties[PROP_N] = { NULL, }; +#ifdef HAVE_DRM_HDR +enum hdmi_metadata_type +{ + HDMI_STATIC_METADATA_TYPE1 = 0, +}; +enum hdmi_eotf +{ + HDMI_EOTF_TRADITIONAL_GAMMA_SDR = 0, + HDMI_EOTF_TRADITIONAL_GAMMA_HDR, + HDMI_EOTF_SMPTE_ST2084, + HDMI_EOTF_BT_2100_HLG, +}; + +static void +gst_kms_populate_infoframe (struct hdr_output_metadata *pinfo_frame, + GstVideoMasteringDisplayInfo * p_hdr_minfo, + GstVideoContentLightLevel * p_hdr_cll, + gchar colorimetry, gboolean clear_it_out) +{ + /* From CTA-861.3: + * When a source is transmitting the Dynamic Range and Mastering InfoFrame, + * it shall signal the end of Dynamic Range... by sending a ... InfoFrame with + * the EOTF field to '0', the Static_Metadata_Descriptor_ID field set to '0', + * and the fields of the Static_Metadata_Descriptor set to unknown (0)... + * + * See also https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html + */ + if (clear_it_out) { + /* Static_Metadata_Descriptor_ID */ + pinfo_frame->metadata_type = 0; + (void) memset ((void *) &pinfo_frame->hdmi_metadata_type1, 0, + sizeof (pinfo_frame->hdmi_metadata_type1)); + return; + } else { + pinfo_frame->metadata_type = HDMI_STATIC_METADATA_TYPE1; + pinfo_frame->hdmi_metadata_type1.eotf = colorimetry; + pinfo_frame->hdmi_metadata_type1.metadata_type = HDMI_STATIC_METADATA_TYPE1; + } + + /* For HDR Infoframe see CTA-861-G, Section 6.9.1 + * SEI message is in units of 0.0001 cd/m2, HDMI is units of 1 cd/m2 - see + * x265 specs */ + pinfo_frame->hdmi_metadata_type1.max_display_mastering_luminance = + round (p_hdr_minfo->max_display_mastering_luminance / 10000.0); + pinfo_frame->hdmi_metadata_type1.min_display_mastering_luminance = + p_hdr_minfo->min_display_mastering_luminance; + + pinfo_frame->hdmi_metadata_type1.max_cll = p_hdr_cll->max_content_light_level; + pinfo_frame->hdmi_metadata_type1.max_fall = + p_hdr_cll->max_frame_average_light_level; + + for (int i = 0; i < 3; i++) { + pinfo_frame->hdmi_metadata_type1.display_primaries[i].x = + p_hdr_minfo->display_primaries[i].x; + pinfo_frame->hdmi_metadata_type1.display_primaries[i].y = + p_hdr_minfo->display_primaries[i].y; + } + + pinfo_frame->hdmi_metadata_type1.white_point.x = p_hdr_minfo->white_point.x; + pinfo_frame->hdmi_metadata_type1.white_point.y = p_hdr_minfo->white_point.y; +} + +static void +gst_kms_push_hdr_infoframe (GstKMSSink * self, gboolean clear_it_out) +{ + struct hdr_output_metadata info_frame; + drmModeObjectPropertiesPtr props; + uint32_t hdrBlobID; + int drm_fd = self->fd; + uint32_t conn_id = self->conn_id; + int ret = 0; + + if (self->no_infoframe || !self->has_hdr_info || (!clear_it_out + && self->has_sent_hdrif)) { + return; + } + + /* Check to see if the connection has the HDR_OUTPUT_METADATA property if + * we haven't already found it */ + if (self->hdrPropID == 0 || self->edidPropID == 0) { + props = + drmModeObjectGetProperties (drm_fd, conn_id, DRM_MODE_OBJECT_CONNECTOR); + + if (!props) { + GST_ERROR_OBJECT (self, "Error on drmModeObjectGetProperties %d %s", + errno, g_strerror (errno)); + return; + } + + struct gst_kms_hdr_static_metadata hdr_edid_info = { 0, 0, 0, 0, 0 }; + for (uint32_t i = 0; + i < props->count_props && (self->hdrPropID == 0 + || self->edidPropID == 0); i++) { + drmModePropertyPtr pprop = drmModeGetProperty (drm_fd, props->props[i]); + + if (pprop) { + /* 7 16 DRM_MODE_PROP_BLOB HDR_OUTPUT_METADATA */ + if (!strncmp ("HDR_OUTPUT_METADATA", pprop->name, + strlen ("HDR_OUTPUT_METADATA"))) { + self->hdrPropID = pprop->prop_id; + GST_DEBUG_OBJECT (self, "HDR prop ID = %d", self->hdrPropID); + } + + if (!strncmp ("EDID", pprop->name, strlen ("EDID"))) { + self->edidPropID = pprop->prop_id; + + /* Check if EDID indicates device supports HDR */ + drmModePropertyBlobPtr blob; + blob = drmModeGetPropertyBlob (drm_fd, props->prop_values[i]); + if (blob) { + int res = + gst_kms_edid_parse (&hdr_edid_info, blob->data, blob->length); + if (res != 0) { + hdr_edid_info.eotf = 0; + hdr_edid_info.metadata_type = 0; + } + } + + drmModeFreePropertyBlob (blob); + + GST_DEBUG_OBJECT (self, "EDID prop ID = %d", self->edidPropID); + /* only these two values are guaranteed to be populated for HDR */ + GST_DEBUG_OBJECT (self, "EDID EOTF = %u, metadata type = %u", + hdr_edid_info.eotf, hdr_edid_info.metadata_type); + } + + drmModeFreeProperty (pprop); + } else { + GST_ERROR_OBJECT (self, "Error on drmModeGetProperty(%d)", i); + } + } + + drmModeFreeObjectProperties (props); + + if (self->hdrPropID == 0 || self->edidPropID == 0 + || hdr_edid_info.eotf == 0) { + GST_DEBUG_OBJECT (self, "No HDR support on target display"); + self->no_infoframe = TRUE; + /* FIXME: maybe not the right flag here... */ + self->has_sent_hdrif = TRUE; + return; + } + } + + if (clear_it_out) + GST_INFO ("Clearing HDR Infoframe on connector %d", self->conn_id); + else + GST_INFO ("Setting HDR Infoframe, if available on connector %d", + self->conn_id); + + gst_kms_populate_infoframe (&info_frame, &self->hdr_minfo, &self->hdr_cll, + self->colorimetry, clear_it_out); + + /* Use non-atomic property setting */ + ret = drmModeCreatePropertyBlob (drm_fd, &info_frame, + sizeof (struct hdr_output_metadata), &hdrBlobID); + if (!ret) { + ret = + drmModeObjectSetProperty (drm_fd, conn_id, DRM_MODE_OBJECT_CONNECTOR, + self->hdrPropID, hdrBlobID); + if (ret) { + GST_ERROR_OBJECT (self, "drmModeObjectSetProperty result %d %d %s", ret, + errno, g_strerror (errno)); + } + drmModeDestroyPropertyBlob (drm_fd, hdrBlobID); + } else { + GST_ERROR_OBJECT (self, "Failed to drmModeCreatePropertyBlob %d %s", errno, + g_strerror (errno)); + } + + if (!ret) { + GST_INFO ("Set HDR Infoframe on connector %d", conn_id); + self->has_sent_hdrif = TRUE; // Hooray! + } +} + + +/* From an HDR10 stream caps: + * + * colorimetry=(string)bt2100-pq + * content-light-level=(string)10000:166 + * mastering-display-info=(string)35400:14600:8500:39850:6550:2300:15635:16450:10000000:1 + */ +static void +gst_kms_sink_set_hdr10_caps (GstKMSSink * self, GstCaps * caps) +{ + GstVideoMasteringDisplayInfo hdr_minfo; + GstVideoContentLightLevel hdr_cll; + GstStructure *structure; + const gchar *colorimetry_s; + GstVideoColorimetry colorimetry; + gboolean has_hdr_eotf = FALSE; + gboolean has_cll = FALSE; + + structure = gst_caps_get_structure (caps, 0); + if ((colorimetry_s = gst_structure_get_string (structure, + "colorimetry")) != NULL && + gst_video_colorimetry_from_string (&colorimetry, colorimetry_s)) { + switch (colorimetry.transfer) { + case GST_VIDEO_TRANSFER_SMPTE2084: + self->colorimetry = HDMI_EOTF_SMPTE_ST2084; + has_hdr_eotf = TRUE; + GST_DEBUG ("Got HDR transfer value GST_VIDEO_TRANSFER_SMPTE2084: %u", + self->colorimetry); + break; + case GST_VIDEO_TRANSFER_BT2020_10: + case GST_VIDEO_TRANSFER_ARIB_STD_B67: + self->colorimetry = HDMI_EOTF_BT_2100_HLG; + has_hdr_eotf = TRUE; + GST_DEBUG ("Got HDR transfer value HDMI_EOTF_BT_2100_HLG: %u", + self->colorimetry); + break; + case GST_VIDEO_TRANSFER_BT709: + self->colorimetry = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; + GST_DEBUG ("Got HDR transfer value GST_VIDEO_TRANSFER_BT709, " + "not HDR: %u", self->colorimetry); + break; + default: + /* not an HDMI and/or HDR colorimetry, we will ignore */ + GST_DEBUG ("Unsupported transfer function, no HDR: %u", + colorimetry.transfer); + self->no_infoframe = TRUE; + self->has_hdr_info = FALSE; + break; + } + } + + if (gst_video_mastering_display_info_from_caps (&hdr_minfo, caps)) { + if (!gst_video_mastering_display_info_is_equal (&hdr_minfo, + &self->hdr_minfo)) { + self->hdr_minfo = hdr_minfo; + self->no_infoframe = FALSE; + self->has_hdr_info = TRUE; + /* to send again */ + self->has_sent_hdrif = FALSE; + } + + GST_DEBUG ("Got mastering info: " + "min %u max %u wp %u %u dp[0] %u %u dp[1] %u %u dp[2] %u %u", + self->hdr_minfo.min_display_mastering_luminance, + self->hdr_minfo.max_display_mastering_luminance, + self->hdr_minfo.white_point.x, self->hdr_minfo.white_point.y, + self->hdr_minfo.display_primaries[0].x, + self->hdr_minfo.display_primaries[0].y, + self->hdr_minfo.display_primaries[1].x, + self->hdr_minfo.display_primaries[1].y, + self->hdr_minfo.display_primaries[2].x, + self->hdr_minfo.display_primaries[2].y); + + } else { + if (self->has_hdr_info == TRUE) { + GST_WARNING ("Missing mastering display info"); + } else { + self->no_infoframe = TRUE; + self->has_hdr_info = FALSE; + } + + gst_video_mastering_display_info_init (&self->hdr_minfo); + } + + if (gst_video_content_light_level_from_caps (&hdr_cll, caps)) { + GST_DEBUG ("Got content light level information: Max CLL: %u Max FALL: %u", + hdr_cll.max_content_light_level, hdr_cll.max_frame_average_light_level); + + if (!gst_video_content_light_level_is_equal (&hdr_cll, &self->hdr_cll)) { + self->hdr_cll = hdr_cll; + self->no_infoframe = FALSE; + self->has_hdr_info = TRUE; + /* to send again */ + self->has_sent_hdrif = FALSE; + } + + has_cll = TRUE; + } else { + gst_video_content_light_level_init (&self->hdr_cll); + + if (self->has_hdr_info == TRUE) { + GST_WARNING ("Missing content light level info"); + } + + self->no_infoframe = TRUE; + self->has_hdr_info = FALSE; + } + + /* need all caps set */ + if ((has_hdr_eotf || has_cll) && !(has_hdr_eotf && has_cll)) { + GST_ELEMENT_WARNING (self, STREAM, FORMAT, + ("Stream doesn't have all HDR components needed"), + ("Check stream caps")); + + self->no_infoframe = TRUE; + self->has_hdr_info = FALSE; + } +} + +#endif /* HAVE_DRM_HDR */ + static void gst_kms_sink_set_render_rectangle (GstVideoOverlay * overlay, gint x, gint y, gint width, gint height) @@ -1148,6 +1451,10 @@ gst_kms_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (GST_VIDEO_SINK_WIDTH (self) <= 0 || GST_VIDEO_SINK_HEIGHT (self) <= 0) goto invalid_size; +#ifdef HAVE_DRM_HDR + gst_kms_sink_set_hdr10_caps (self, caps); +#endif + /* discard dumb buffer pool */ if (self->pool) { gst_buffer_pool_set_active (self->pool, FALSE); @@ -1665,6 +1972,10 @@ retry_set_plane: src.w = result.w; src.h = result.h; } +#ifdef HAVE_DRM_HDR + /* Send the HDR infoframes if appropriate */ + gst_kms_push_hdr_infoframe (self, FALSE); +#endif GST_TRACE_OBJECT (self, "drmModeSetPlane at (%i,%i) %ix%i sourcing at (%i,%i) %ix%i", @@ -1981,6 +2292,17 @@ gst_kms_sink_init (GstKMSSink * sink) sink->poll = gst_poll_new (TRUE); gst_video_info_init (&sink->vinfo); sink->skip_vsync = FALSE; + +#ifdef HAVE_DRM_HDR + sink->no_infoframe = FALSE; + sink->has_hdr_info = FALSE; + sink->has_sent_hdrif = FALSE; + sink->edidPropID = 0; + sink->hdrPropID = 0; + sink->colorimetry = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; + gst_video_mastering_display_info_init (&sink->hdr_minfo); + gst_video_content_light_level_init (&sink->hdr_cll); +#endif } static void diff --git a/subprojects/gst-plugins-bad/sys/kms/gstkmssink.h b/subprojects/gst-plugins-bad/sys/kms/gstkmssink.h index e20e2c3..9c33e1f 100644 --- a/subprojects/gst-plugins-bad/sys/kms/gstkmssink.h +++ b/subprojects/gst-plugins-bad/sys/kms/gstkmssink.h @@ -27,6 +27,8 @@ #define __GST_KMS_SINK_H__ #include +#include +#include G_BEGIN_DECLS @@ -96,6 +98,18 @@ struct _GstKMSSink { gboolean is_internal_fd; gboolean skip_vsync; + +#ifdef HAVE_DRM_HDR + /* HDR mastering related structure */ + gboolean no_infoframe; + gboolean has_hdr_info; + gboolean has_sent_hdrif; + guint32 edidPropID; + guint32 hdrPropID; + gchar colorimetry; + GstVideoMasteringDisplayInfo hdr_minfo; + GstVideoContentLightLevel hdr_cll; +#endif }; struct _GstKMSSinkClass { diff --git a/subprojects/gst-plugins-bad/sys/kms/meson.build b/subprojects/gst-plugins-bad/sys/kms/meson.build index 5468870..2f960c8 100644 --- a/subprojects/gst-plugins-bad/sys/kms/meson.build +++ b/subprojects/gst-plugins-bad/sys/kms/meson.build @@ -4,6 +4,7 @@ kmssink_sources = [ 'gstkmssink.c', 'gstkmsutils.c', ] +extra_deps = [] if host_system != 'linux' subdir_done() @@ -12,12 +13,22 @@ endif libdrm_dep = dependency('libdrm', version : '>= 2.4.98', required : get_option('kms'), fallback: ['libdrm', 'ext_libdrm']) +libdrm_hdr_dep = dependency('libdrm', version : '>= 2.4.104', + required : false, + fallback: ['libdrm', 'ext_libdrm']) +mathlib = cc.find_library('m', required : false) + +if libdrm_hdr_dep.found() and mathlib.found() + cdata.set('HAVE_DRM_HDR', 1) + kmssink_sources += 'gstkmsedid.c' +endif + if libdrm_dep.found() gstkmssink = library('gstkms', kmssink_sources, c_args : gst_plugins_bad_args, include_directories : [configinc], - dependencies : [gstbase_dep, gstvideo_dep, gstallocators_dep, libdrm_dep], + dependencies : [gstbase_dep, gstvideo_dep, gstallocators_dep, libdrm_dep, mathlib], install : true, install_dir : plugins_install_dir, ) -- 2.7.4