mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-10-15 09:28:34 +00:00
backend-drm: forward HDR metadata
Forward the HDR Static Metadata Type 1 to the video sink. This makes the sink aware of our video content parameters and may be able to produce a better picture. This type of metadata is used only with the ST 2084 HDR mode a.k.a PQ. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
c4fedd503f
commit
c217453c85
|
@ -29,13 +29,86 @@
|
||||||
#include <libweston/libweston.h>
|
#include <libweston/libweston.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "drm-internal.h"
|
#include "drm-internal.h"
|
||||||
#include "libdrm-updates.h"
|
#include "libdrm-updates.h"
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
color_xy_to_u16(float v)
|
||||||
|
{
|
||||||
|
assert(v >= 0.0f);
|
||||||
|
assert(v <= 1.0f);
|
||||||
|
/*
|
||||||
|
* CTA-861-G
|
||||||
|
* 6.9.1 Static Metadata Type 1
|
||||||
|
* chromaticity coordinate encoding
|
||||||
|
*/
|
||||||
|
return (uint16_t)round(v * 50000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
nits_to_u16(float nits)
|
||||||
|
{
|
||||||
|
assert(nits >= 1.0f);
|
||||||
|
assert(nits <= 65535.0f);
|
||||||
|
/*
|
||||||
|
* CTA-861-G
|
||||||
|
* 6.9.1 Static Metadata Type 1
|
||||||
|
* max display mastering luminance, max content light level,
|
||||||
|
* max frame-average light level
|
||||||
|
*/
|
||||||
|
return (uint16_t)round(nits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
nits_to_u16_dark(float nits)
|
||||||
|
{
|
||||||
|
assert(nits >= 0.0001f);
|
||||||
|
assert(nits <= 6.5535f);
|
||||||
|
/*
|
||||||
|
* CTA-861-G
|
||||||
|
* 6.9.1 Static Metadata Type 1
|
||||||
|
* min display mastering luminance
|
||||||
|
*/
|
||||||
|
return (uint16_t)round(nits * 10000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
weston_hdr_metadata_type1_to_kms(struct hdr_metadata_infoframe *dst,
|
||||||
|
const struct weston_hdr_metadata_type1 *src)
|
||||||
|
{
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_PRIMARIES) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
dst->display_primaries[i].x = color_xy_to_u16(src->primary[i].x);
|
||||||
|
dst->display_primaries[i].y = color_xy_to_u16(src->primary[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_WHITE) {
|
||||||
|
dst->white_point.x = color_xy_to_u16(src->white.x);
|
||||||
|
dst->white_point.y = color_xy_to_u16(src->white.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXDML)
|
||||||
|
dst->max_display_mastering_luminance = nits_to_u16(src->maxDML);
|
||||||
|
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MINDML)
|
||||||
|
dst->min_display_mastering_luminance = nits_to_u16_dark(src->minDML);
|
||||||
|
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXCLL)
|
||||||
|
dst->max_cll = nits_to_u16(src->maxCLL);
|
||||||
|
|
||||||
|
if (src->group_mask & WESTON_HDR_METADATA_TYPE1_GROUP_MAXFALL)
|
||||||
|
dst->max_fall = nits_to_u16(src->maxFALL);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
||||||
{
|
{
|
||||||
|
const struct weston_hdr_metadata_type1 *src;
|
||||||
struct hdr_output_metadata meta;
|
struct hdr_output_metadata meta;
|
||||||
uint32_t blob_id = 0;
|
uint32_t blob_id = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -43,6 +116,8 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
||||||
if (output->hdr_output_metadata_blob_id)
|
if (output->hdr_output_metadata_blob_id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
src = weston_output_get_hdr_metadata_type1(&output->base);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the data for Dynamic Range and Mastering InfoFrame,
|
* Set up the data for Dynamic Range and Mastering InfoFrame,
|
||||||
* CTA-861-G, a.k.a the static HDR metadata.
|
* CTA-861-G, a.k.a the static HDR metadata.
|
||||||
|
@ -72,6 +147,7 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
||||||
break;
|
break;
|
||||||
case WESTON_EOTF_MODE_ST2084:
|
case WESTON_EOTF_MODE_ST2084:
|
||||||
meta.hdmi_metadata_type1.eotf = 2; /* from CTA-861-G */
|
meta.hdmi_metadata_type1.eotf = 2; /* from CTA-861-G */
|
||||||
|
weston_hdr_metadata_type1_to_kms(&meta.hdmi_metadata_type1, src);
|
||||||
break;
|
break;
|
||||||
case WESTON_EOTF_MODE_HLG:
|
case WESTON_EOTF_MODE_HLG:
|
||||||
meta.hdmi_metadata_type1.eotf = 3; /* from CTA-861-G */
|
meta.hdmi_metadata_type1.eotf = 3; /* from CTA-861-G */
|
||||||
|
@ -83,8 +159,6 @@ drm_output_ensure_hdr_output_metadata_blob(struct drm_output *output)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The other fields are intentionally left as zeroes. */
|
|
||||||
|
|
||||||
ret = drmModeCreatePropertyBlob(output->backend->drm.fd,
|
ret = drmModeCreatePropertyBlob(output->backend->drm.fd,
|
||||||
&meta, sizeof meta, &blob_id);
|
&meta, sizeof meta, &blob_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ srcs_drm = [
|
||||||
]
|
]
|
||||||
|
|
||||||
deps_drm = [
|
deps_drm = [
|
||||||
|
dep_libm,
|
||||||
dep_libdl,
|
dep_libdl,
|
||||||
dep_libweston_private,
|
dep_libweston_private,
|
||||||
dep_session_helper,
|
dep_session_helper,
|
||||||
|
|
Loading…
Reference in a new issue