reformat missing files

This commit is contained in:
Dirk Nehring 2021-12-29 12:08:12 +01:00
parent 177e44de98
commit 43135c43bc
3 changed files with 469 additions and 402 deletions

View File

@ -393,7 +393,7 @@ clean:
HDRS = $(wildcard *.h) HDRS = $(wildcard *.h)
indent: indent:
for i in $(SRCS) $(HDRS); do \ for i in $(SRCS) drm.c hdr.c $(HDRS); do \
clang-format -i $$i; \ clang-format -i $$i; \
done done

384
drm.c
View File

@ -1,30 +1,26 @@
#include <unistd.h> #include <drm_fourcc.h>
#include <gbm.h> #include <gbm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <xf86drm.h> #include <unistd.h>
#include <xf86drmMode.h>
#include <drm_fourcc.h>
#include <xf86drm.h> #include <xf86drm.h>
#include <xf86drmMode.h> #include <xf86drmMode.h>
#define DRM_DEBUG #define DRM_DEBUG
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// DRM // DRM
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
struct _Drm_Render_ struct _Drm_Render_ {
{
int fd_drm; int fd_drm;
drmModeModeInfo mode; drmModeModeInfo mode;
drmModeCrtc *saved_crtc; drmModeCrtc *saved_crtc;
// drmEventContext ev; // drmEventContext ev;
int bpp; int bpp;
uint32_t connector_id, crtc_id, video_plane; uint32_t connector_id, crtc_id, video_plane;
uint32_t hdr_metadata; uint32_t hdr_metadata;
uint32_t mmWidth,mmHeight; // Size in mm uint32_t mmWidth, mmHeight; // Size in mm
uint32_t hdr_blob_id; uint32_t hdr_blob_id;
}; };
typedef struct _Drm_Render_ VideoRender; typedef struct _Drm_Render_ VideoRender;
@ -46,10 +42,7 @@ struct type_name {
const char *name; const char *name;
}; };
static const char *util_lookup_type_name(unsigned int type, static const char *util_lookup_type_name(unsigned int type, const struct type_name *table, unsigned int count) {
const struct type_name *table,
unsigned int count)
{
unsigned int i; unsigned int i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -60,41 +53,36 @@ static const char *util_lookup_type_name(unsigned int type,
} }
static const struct type_name connector_type_names[] = { static const struct type_name connector_type_names[] = {
{ DRM_MODE_CONNECTOR_Unknown, "unknown" }, {DRM_MODE_CONNECTOR_Unknown, "unknown"},
{ DRM_MODE_CONNECTOR_VGA, "VGA" }, {DRM_MODE_CONNECTOR_VGA, "VGA"},
{ DRM_MODE_CONNECTOR_DVII, "DVI-I" }, {DRM_MODE_CONNECTOR_DVII, "DVI-I"},
{ DRM_MODE_CONNECTOR_DVID, "DVI-D" }, {DRM_MODE_CONNECTOR_DVID, "DVI-D"},
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, {DRM_MODE_CONNECTOR_DVIA, "DVI-A"},
{ DRM_MODE_CONNECTOR_Composite, "composite" }, {DRM_MODE_CONNECTOR_Composite, "composite"},
{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" }, {DRM_MODE_CONNECTOR_SVIDEO, "s-video"},
{ DRM_MODE_CONNECTOR_LVDS, "LVDS" }, {DRM_MODE_CONNECTOR_LVDS, "LVDS"},
{ DRM_MODE_CONNECTOR_Component, "component" }, {DRM_MODE_CONNECTOR_Component, "component"},
{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" }, {DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN"},
{ DRM_MODE_CONNECTOR_DisplayPort, "DP" }, {DRM_MODE_CONNECTOR_DisplayPort, "DP"},
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, {DRM_MODE_CONNECTOR_HDMIA, "HDMI-A"},
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, {DRM_MODE_CONNECTOR_HDMIB, "HDMI-B"},
{ DRM_MODE_CONNECTOR_TV, "TV" }, {DRM_MODE_CONNECTOR_TV, "TV"},
{ DRM_MODE_CONNECTOR_eDP, "eDP" }, {DRM_MODE_CONNECTOR_eDP, "eDP"},
{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, {DRM_MODE_CONNECTOR_VIRTUAL, "Virtual"},
{ DRM_MODE_CONNECTOR_DSI, "DSI" }, {DRM_MODE_CONNECTOR_DSI, "DSI"},
{ DRM_MODE_CONNECTOR_DPI, "DPI" }, {DRM_MODE_CONNECTOR_DPI, "DPI"},
}; };
const char *util_lookup_connector_type_name(unsigned int type) const char *util_lookup_connector_type_name(unsigned int type) {
{ return util_lookup_type_name(type, connector_type_names, ARRAY_SIZE(connector_type_names));
return util_lookup_type_name(type, connector_type_names,
ARRAY_SIZE(connector_type_names));
} }
static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID, static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) {
uint32_t objectType, const char *propName)
{
uint32_t i; uint32_t i;
int found = 0; int found = 0;
uint64_t value = 0; uint64_t value = 0;
drmModePropertyPtr Prop; drmModePropertyPtr Prop;
drmModeObjectPropertiesPtr objectProps = drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
drmModeObjectGetProperties(fd_drm, objectID, objectType);
for (i = 0; i < objectProps->count_props; i++) { for (i = 0; i < objectProps->count_props; i++) {
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL) if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
@ -115,20 +103,16 @@ static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID,
#ifdef DRM_DEBUG #ifdef DRM_DEBUG
if (!found) if (!found)
fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n", fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n", propName);
propName);
#endif #endif
return value; return value;
} }
static uint32_t GetPropertyID(int fd_drm, uint32_t objectID, static uint32_t GetPropertyID(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) {
uint32_t objectType, const char *propName)
{
uint32_t i; uint32_t i;
int found = 0; int found = 0;
uint32_t value = -1; uint32_t value = -1;
drmModePropertyPtr Prop; drmModePropertyPtr Prop;
drmModeObjectPropertiesPtr objectProps = drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
drmModeObjectGetProperties(fd_drm, objectID, objectType);
for (i = 0; i < objectProps->count_props; i++) { for (i = 0; i < objectProps->count_props; i++) {
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL) if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
@ -146,24 +130,21 @@ static uint32_t GetPropertyID(int fd_drm, uint32_t objectID,
#ifdef DRM_DEBUG #ifdef DRM_DEBUG
if (!found) if (!found)
Debug(3,"GetPropertyValue: Unable to find ID for property \'%s\'.\n",propName); Debug(3, "GetPropertyValue: Unable to find ID for property \'%s\'.\n", propName);
#endif #endif
return value; return value;
} }
static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, uint32_t objectID, uint32_t objectType,
uint32_t objectID, uint32_t objectType, const char *propName, uint64_t value) {
const char *propName, uint64_t value)
{
uint32_t i; uint32_t i;
uint64_t id = 0; uint64_t id = 0;
drmModePropertyPtr Prop; drmModePropertyPtr Prop;
drmModeObjectPropertiesPtr objectProps = drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
drmModeObjectGetProperties(fd_drm, objectID, objectType);
for (i = 0; i < objectProps->count_props; i++) { for (i = 0; i < objectProps->count_props; i++) {
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL) if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
printf( "SetPropertyRequest: Unable to query property.\n"); printf("SetPropertyRequest: Unable to query property.\n");
if (strcmp(propName, Prop->name) == 0) { if (strcmp(propName, Prop->name) == 0) {
id = Prop->prop_id; id = Prop->prop_id;
@ -177,15 +158,13 @@ static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm,
drmModeFreeObjectProperties(objectProps); drmModeFreeObjectProperties(objectProps);
if (id == 0) if (id == 0)
printf( "SetPropertyRequest: Unable to find value for property \'%s\'.\n", printf("SetPropertyRequest: Unable to find value for property \'%s\'.\n", propName);
propName);
return drmModeAtomicAddProperty(ModeReq, objectID, id, value); return drmModeAtomicAddProperty(ModeReq, objectID, id, value);
} }
static void CuvidSetVideoMode(void); static void CuvidSetVideoMode(void);
void set_video_mode(int width, int height) void set_video_mode(int width, int height) {
{
drmModeConnector *connector; drmModeConnector *connector;
drmModeModeInfo *mode; drmModeModeInfo *mode;
int ii; int ii;
@ -194,29 +173,25 @@ void set_video_mode(int width, int height)
connector = drmModeGetConnector(render->fd_drm, render->connector_id); connector = drmModeGetConnector(render->fd_drm, render->connector_id);
for (ii = 0; ii < connector->count_modes; ii++) { for (ii = 0; ii < connector->count_modes; ii++) {
mode = &connector->modes[ii]; mode = &connector->modes[ii];
printf("Mode %d %dx%d Rate %d\n",ii,mode->hdisplay,mode->vdisplay,mode->vrefresh); printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
if (width == mode->hdisplay && if (width == mode->hdisplay && height == mode->vdisplay && mode->vrefresh == DRMRefresh &&
height == mode->vdisplay && render->mode.hdisplay != width && render->mode.vdisplay != height &&
mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
render->mode.hdisplay != width &&
render->mode.vdisplay != height &&
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
VideoWindowWidth = mode->hdisplay; VideoWindowWidth = mode->hdisplay;
VideoWindowHeight = mode->vdisplay; VideoWindowHeight = mode->vdisplay;
eglDestroySurface (eglDisplay, eglSurface); eglDestroySurface(eglDisplay, eglSurface);
EglCheck(); EglCheck();
gbm_surface_destroy (gbm.surface); gbm_surface_destroy(gbm.surface);
InitBo(render->bpp); InitBo(render->bpp);
CuvidSetVideoMode(); CuvidSetVideoMode();
Debug(3,"Set new mode %d:%d\n",mode->hdisplay,mode->vdisplay); Debug(3, "Set new mode %d:%d\n", mode->hdisplay, mode->vdisplay);
break; break;
} }
} }
} }
static int FindDevice(VideoRender * render) static int FindDevice(VideoRender *render) {
{
drmVersion *version; drmVersion *version;
drmModeRes *resources; drmModeRes *resources;
drmModeConnector *connector; drmModeConnector *connector;
@ -228,7 +203,7 @@ static int FindDevice(VideoRender * render)
uint32_t j, k; uint32_t j, k;
uint64_t has_dumb; uint64_t has_dumb;
uint64_t has_prime; uint64_t has_prime;
int i,ii=0; int i, ii = 0;
char connectorstr[10]; char connectorstr[10];
int found = 0; int found = 0;
#ifdef RASPI #ifdef RASPI
@ -240,30 +215,27 @@ static int FindDevice(VideoRender * render)
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n"); fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
return -errno; return -errno;
} }
int ret = drmSetMaster(render->fd_drm); int ret = drmSetMaster(render->fd_drm);
if (ret < 0) if (ret < 0) {
{
drm_magic_t magic; drm_magic_t magic;
ret = drmGetMagic(render->fd_drm, &magic); ret = drmGetMagic(render->fd_drm, &magic);
if (ret < 0) if (ret < 0) {
{ Debug(3, "drm:%s - failed to get drm magic: %s\n", __FUNCTION__, strerror(errno));
Debug(3, "drm:%s - failed to get drm magic: %s\n", __FUNCTION__, strerror(errno)); return -1;
return -1;
} }
ret = drmAuthMagic(render->fd_drm, magic); ret = drmAuthMagic(render->fd_drm, magic);
if (ret < 0) if (ret < 0) {
{ Debug(3, "drm:%s - failed to authorize drm magic: %s\n", __FUNCTION__, strerror(errno));
Debug(3, "drm:%s - failed to authorize drm magic: %s\n", __FUNCTION__, strerror(errno)); return -1;
return -1;
} }
} }
version = drmGetVersion(render->fd_drm); version = drmGetVersion(render->fd_drm);
fprintf(stderr, "FindDevice: open /dev/dri/card0: %s\n", version->name); fprintf(stderr, "FindDevice: open /dev/dri/card0: %s\n", version->name);
// check capability // check capability
if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0) if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0)
@ -284,15 +256,14 @@ static int FindDevice(VideoRender * render)
if (drmGetCap(render->fd_drm, DRM_PRIME_CAP_IMPORT, &has_prime) < 0) if (drmGetCap(render->fd_drm, DRM_PRIME_CAP_IMPORT, &has_prime) < 0)
fprintf(stderr, "FindDevice: DRM_PRIME_CAP_IMPORT not available.\n"); fprintf(stderr, "FindDevice: DRM_PRIME_CAP_IMPORT not available.\n");
if ((resources = drmModeGetResources(render->fd_drm)) == NULL){ if ((resources = drmModeGetResources(render->fd_drm)) == NULL) {
fprintf(stderr, "FindDevice: cannot retrieve DRM resources (%d): %m\n", errno); fprintf(stderr, "FindDevice: cannot retrieve DRM resources (%d): %m\n", errno);
return -errno; return -errno;
} }
#ifdef DEBUG #ifdef DEBUG
Debug(3,"[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n", Debug(3, "[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n", resources->count_connectors,
resources->count_connectors, resources->count_crtcs, resources->count_crtcs, resources->count_encoders);
resources->count_encoders);
#endif #endif
// find all available connectors // find all available connectors
@ -303,49 +274,49 @@ static int FindDevice(VideoRender * render)
return -errno; return -errno;
} }
sprintf(connectorstr,"%s-%u",util_lookup_connector_type_name(connector->connector_type),connector->connector_type_id); sprintf(connectorstr, "%s-%u", util_lookup_connector_type_name(connector->connector_type),
printf("Connector >%s< is %sconnected\n",connectorstr,connector->connection == DRM_MODE_CONNECTED?"":"not "); connector->connector_type_id);
if (DRMConnector && strcmp(DRMConnector,connectorstr)) printf("Connector >%s< is %sconnected\n", connectorstr,
connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
if (DRMConnector && strcmp(DRMConnector, connectorstr))
continue; continue;
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) { if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) {
float aspect = (float)connector->mmWidth / (float)connector->mmHeight; float aspect = (float)connector->mmWidth / (float)connector->mmHeight;
if ((aspect > 1.70) && (aspect < 1.85)) { if ((aspect > 1.70) && (aspect < 1.85)) {
render->mmHeight = 90; render->mmHeight = 90;
render->mmWidth = 160; render->mmWidth = 160;
} else { } else {
render->mmHeight = connector->mmHeight; render->mmHeight = connector->mmHeight;
render->mmWidth = connector->mmWidth; render->mmWidth = connector->mmWidth;
} }
render->connector_id = connector->connector_id; render->connector_id = connector->connector_id;
// FIXME: use default encoder/crtc pair // FIXME: use default encoder/crtc pair
if ((encoder = drmModeGetEncoder(render->fd_drm, connector->encoder_id)) == NULL){ if ((encoder = drmModeGetEncoder(render->fd_drm, connector->encoder_id)) == NULL) {
fprintf(stderr, "FindDevice: cannot retrieve encoder (%d): %m\n", errno); fprintf(stderr, "FindDevice: cannot retrieve encoder (%d): %m\n", errno);
return -errno; return -errno;
} }
render->crtc_id = encoder->crtc_id; render->crtc_id = encoder->crtc_id;
render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, DRM_MODE_OBJECT_CONNECTOR,
DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA"); "HDR_OUTPUT_METADATA");
printf("ID %d of METADATA in Connector %d connected %d\n",render->hdr_metadata,connector->connector_id,connector->connection); printf("ID %d of METADATA in Connector %d connected %d\n", render->hdr_metadata, connector->connector_id,
connector->connection);
memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback
// search Modes for Connector // search Modes for Connector
for (ii = 0; ii < connector->count_modes; ii++) { for (ii = 0; ii < connector->count_modes; ii++) {
mode = &connector->modes[ii]; mode = &connector->modes[ii];
printf("Mode %d %dx%d Rate %d\n",ii,mode->hdisplay,mode->vdisplay,mode->vrefresh); printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
if (VideoWindowWidth && VideoWindowHeight) { // preset by command line if (VideoWindowWidth && VideoWindowHeight) { // preset by command line
if (VideoWindowWidth == mode->hdisplay && if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay &&
VideoWindowHeight == mode->vdisplay && mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
mode->vrefresh == DRMRefresh &&
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
break; break;
} }
} } else {
else {
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) { if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
VideoWindowWidth = mode->hdisplay; VideoWindowWidth = mode->hdisplay;
@ -355,16 +326,17 @@ static int FindDevice(VideoRender * render)
} }
} }
found = 1; found = 1;
i = resources->count_connectors; // uuuuhh i = resources->count_connectors; // uuuuhh
} }
VideoWindowWidth = render->mode.hdisplay; VideoWindowWidth = render->mode.hdisplay;
VideoWindowHeight = render->mode.vdisplay; VideoWindowHeight = render->mode.vdisplay;
if (found) if (found)
printf("Use Mode %d %dx%d Rate %d\n",ii,render->mode.hdisplay,render->mode.vdisplay,render->mode.vrefresh); printf("Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay,
render->mode.vrefresh);
drmModeFreeConnector(connector); drmModeFreeConnector(connector);
} }
if (!found) { if (!found) {
Debug(3,"Requested Connector not found or not connected\n"); Debug(3, "Requested Connector not found or not connected\n");
printf("Requested Connector not found or not connected\n"); printf("Requested Connector not found or not connected\n");
return -1; return -1;
} }
@ -384,16 +356,16 @@ static int FindDevice(VideoRender * render)
break; break;
} }
uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], DRM_MODE_OBJECT_PLANE, "type");
DRM_MODE_OBJECT_PLANE, "type");
uint64_t zpos = 0; uint64_t zpos = 0;
#ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!! #ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!!
printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", plane->plane_id,
plane->plane_id, plane->crtc_id, plane->possible_crtcs, resources->crtcs[i], plane->crtc_id, plane->possible_crtcs, resources->crtcs[i],
(type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane" : (type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane"
(type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane" : : (type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane"
(type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane" : "No plane type"); : (type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane"
: "No plane type");
#endif #endif
// test pixel format and plane caps // test pixel format and plane caps
@ -423,8 +395,7 @@ static int FindDevice(VideoRender * render)
drmModeFreeResources(resources); drmModeFreeResources(resources);
#ifdef DRM_DEBUG #ifdef DRM_DEBUG
printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n", printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n", render->crtc_id, render->video_plane);
render->crtc_id, render->video_plane);
#endif #endif
// save actual modesetting // save actual modesetting
@ -436,8 +407,7 @@ static int FindDevice(VideoRender * render)
/// ///
/// Initialize video output module. /// Initialize video output module.
/// ///
void VideoInitDrm() void VideoInitDrm() {
{
int i; int i;
if (!(render = calloc(1, sizeof(*render)))) { if (!(render = calloc(1, sizeof(*render)))) {
@ -445,25 +415,24 @@ void VideoInitDrm()
return; return;
} }
if (FindDevice(render)){ if (FindDevice(render)) {
Fatal(_( "VideoInit: FindDevice() failed\n")); Fatal(_("VideoInit: FindDevice() failed\n"));
} }
gbm.dev = gbm_create_device (render->fd_drm); gbm.dev = gbm_create_device(render->fd_drm);
assert (gbm.dev != NULL); assert(gbm.dev != NULL);
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL; PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
get_platform_display = get_platform_display = (void *)eglGetProcAddress("eglGetPlatformDisplayEXT");
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
assert(get_platform_display != NULL); assert(get_platform_display != NULL);
eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL); eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL);
EglCheck(); EglCheck();
assert (eglDisplay != NULL); assert(eglDisplay != NULL);
// return; // return;
drmModeAtomicReqPtr ModeReq; drmModeAtomicReqPtr ModeReq;
const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
@ -477,13 +446,11 @@ void VideoInitDrm()
fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno); fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno);
return; return;
} }
printf("set CRTC %d of Connector %d aktiv\n",render->crtc_id,render->connector_id); printf("set CRTC %d of Connector %d aktiv\n", render->crtc_id, render->connector_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID); SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, render->crtc_id);
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
@ -492,54 +459,51 @@ void VideoInitDrm()
fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno); fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno);
drmModeAtomicFree(ModeReq); drmModeAtomicFree(ModeReq);
} }
void get_drm_aspect(int *num,int *den) void get_drm_aspect(int *num, int *den) {
{
*num = VideoWindowWidth; *num = VideoWindowWidth;
*den = VideoWindowHeight; *den = VideoWindowHeight;
} }
struct gbm_bo *bo = NULL, *next_bo=NULL; struct gbm_bo *bo = NULL, *next_bo = NULL;
struct drm_fb *fb; struct drm_fb *fb;
static int m_need_modeset = 0; static int m_need_modeset = 0;
static int old_color=-1,old_trc=-1; static int old_color = -1, old_trc = -1;
void InitBo(int bpp) { void InitBo(int bpp) {
// create the GBM and EGL surface // create the GBM and EGL surface
render->bpp = bpp;
gbm.surface = gbm_surface_create (gbm.dev, VideoWindowWidth,VideoWindowHeight,
bpp==10?GBM_FORMAT_XRGB2101010:GBM_FORMAT_ARGB8888,
GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING);
assert(gbm.surface != NULL);
eglSurface = eglCreateWindowSurface (eglDisplay, eglConfig, gbm.surface, NULL);
assert(eglSurface != NULL);
render->bpp = bpp;
gbm.surface = gbm_surface_create(gbm.dev, VideoWindowWidth, VideoWindowHeight,
bpp == 10 ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_ARGB8888,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
assert(gbm.surface != NULL);
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL);
assert(eglSurface != NULL);
} }
static struct gbm_bo *previous_bo = NULL; static struct gbm_bo *previous_bo = NULL;
static uint32_t previous_fb; static uint32_t previous_fb;
static int has_modeset = 0; static int has_modeset = 0;
static void drm_swap_buffers () { static void drm_swap_buffers() {
uint32_t fb; uint32_t fb;
eglSwapBuffers (eglDisplay, eglSurface); eglSwapBuffers(eglDisplay, eglSurface);
struct gbm_bo *bo = gbm_surface_lock_front_buffer (gbm.surface); struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface);
#if 1 #if 1
if (bo == NULL) if (bo == NULL)
bo = gbm_surface_lock_front_buffer (gbm.surface); bo = gbm_surface_lock_front_buffer(gbm.surface);
#endif #endif
assert (bo != NULL); assert(bo != NULL);
uint32_t handle = gbm_bo_get_handle (bo).u32; uint32_t handle = gbm_bo_get_handle(bo).u32;
uint32_t pitch = gbm_bo_get_stride (bo); uint32_t pitch = gbm_bo_get_stride(bo);
drmModeAddFB(render->fd_drm, VideoWindowWidth, VideoWindowHeight, render->bpp == 10 ? 30 : 24, 32, pitch, handle,
drmModeAddFB (render->fd_drm, VideoWindowWidth,VideoWindowHeight,render->bpp==10? 30:24, 32, pitch, handle, &fb); &fb);
// drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); // drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
if (m_need_modeset) { if (m_need_modeset) {
drmModeAtomicReqPtr ModeReq; drmModeAtomicReqPtr ModeReq;
@ -556,23 +520,19 @@ static void drm_swap_buffers () {
} }
// Need to disable the CRTC in order to submit the HDR data.... // Need to disable the CRTC in order to submit the HDR data....
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace",
DRM_MODE_OBJECT_CONNECTOR, "Colorspace",old_color==AVCOL_PRI_BT2020?9:2 ); old_color == AVCOL_PRI_BT2020 ? 9 : 2);
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",
DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",old_color==AVCOL_PRI_BT2020?2:1 ); old_color == AVCOL_PRI_BT2020 ? 2 : 1);
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 0);
DRM_MODE_OBJECT_PLANE, "COLOR_RANGE",0 ); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID); render->crtc_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
fprintf(stderr, "cannot set atomic mode modeset 2 (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode modeset 2 (%d): %m\n", errno);
@ -584,33 +544,32 @@ static void drm_swap_buffers () {
m_need_modeset = 0; m_need_modeset = 0;
has_modeset = 1; has_modeset = 1;
} }
drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); drmModeSetCrtc(render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
if (previous_bo) { if (previous_bo) {
drmModeRmFB (render->fd_drm, previous_fb); drmModeRmFB(render->fd_drm, previous_fb);
gbm_surface_release_buffer (gbm.surface, previous_bo); gbm_surface_release_buffer(gbm.surface, previous_bo);
} }
previous_bo = bo; previous_bo = bo;
previous_fb = fb; previous_fb = fb;
} }
static void drm_clean_up () { static void drm_clean_up() {
// set the previous crtc // set the previous crtc
if (!render) if (!render)
return; return;
Debug(3,"drm clean up\n"); Debug(3, "drm clean up\n");
if (previous_bo) { if (previous_bo) {
drmModeRmFB (render->fd_drm, previous_fb); drmModeRmFB(render->fd_drm, previous_fb);
gbm_surface_release_buffer (gbm.surface, previous_bo); gbm_surface_release_buffer(gbm.surface, previous_bo);
} }
drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id, drmModeSetCrtc(render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id, render->saved_crtc->x,
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode); render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
drmModeFreeCrtc (render->saved_crtc); drmModeFreeCrtc(render->saved_crtc);
if (has_modeset) { if (has_modeset) {
drmModeAtomicReqPtr ModeReq; drmModeAtomicReqPtr ModeReq;
const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
@ -626,25 +585,19 @@ static void drm_clean_up () {
} }
// Need to disable the CRTC in order to submit the HDR data.... // Need to disable the CRTC in order to submit the HDR data....
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR,
DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA", 0); "HDR_OUTPUT_METADATA", 0);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace", 2);
DRM_MODE_OBJECT_CONNECTOR, "Colorspace",2 ); SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING", 1);
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 1);
DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",1 ); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
DRM_MODE_OBJECT_PLANE, "COLOR_RANGE",1 ); render->crtc_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
@ -655,27 +608,26 @@ static void drm_clean_up () {
drmModeAtomicFree(ModeReq); drmModeAtomicFree(ModeReq);
has_modeset = 0; has_modeset = 0;
} }
if (render->hdr_blob_id) if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
render->hdr_blob_id = 0; render->hdr_blob_id = 0;
eglDestroySurface (eglDisplay, eglSurface); eglDestroySurface(eglDisplay, eglSurface);
EglCheck(); EglCheck();
gbm_surface_destroy (gbm.surface); gbm_surface_destroy(gbm.surface);
eglDestroyContext (eglDisplay, eglContext); eglDestroyContext(eglDisplay, eglContext);
EglCheck(); EglCheck();
eglDestroyContext (eglDisplay, eglSharedContext); eglDestroyContext(eglDisplay, eglSharedContext);
EglCheck(); EglCheck();
eglSharedContext = NULL; eglSharedContext = NULL;
eglTerminate (eglDisplay); eglTerminate(eglDisplay);
EglCheck(); EglCheck();
gbm_device_destroy (gbm.dev); gbm_device_destroy(gbm.dev);
drmDropMaster(render->fd_drm); drmDropMaster(render->fd_drm);
close (render->fd_drm); close(render->fd_drm);
eglDisplay = NULL; eglDisplay = NULL;
free(render); free(render);
} }

485
hdr.c
View File

@ -29,7 +29,7 @@ struct hdr_metadata_infoframe {
*/ */
struct { struct {
__u16 x, y; __u16 x, y;
} display_primaries[3]; } display_primaries[3];
/** /**
* @white_point: White Point of Colorspace Data. * @white_point: White Point of Colorspace Data.
* These are coded as unsigned 16-bit values in units of * These are coded as unsigned 16-bit values in units of
@ -40,7 +40,7 @@ struct hdr_metadata_infoframe {
*/ */
struct { struct {
__u16 x, y; __u16 x, y;
} white_point; } white_point;
/** /**
* @max_display_mastering_luminance: Max Mastering Display Luminance. * @max_display_mastering_luminance: Max Mastering Display Luminance.
* This value is coded as an unsigned 16-bit value in units of 1 cd/m2, * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
@ -87,7 +87,6 @@ struct hdr_output_metadata {
}; };
#endif #endif
enum hdr_metadata_eotf { enum hdr_metadata_eotf {
EOTF_TRADITIONAL_GAMMA_SDR, EOTF_TRADITIONAL_GAMMA_SDR,
EOTF_TRADITIONAL_GAMMA_HDR, EOTF_TRADITIONAL_GAMMA_HDR,
@ -95,27 +94,15 @@ enum hdr_metadata_eotf {
EOTF_HLG, EOTF_HLG,
}; };
enum metadata_id { enum metadata_id {
METADATA_TYPE1, METADATA_TYPE1,
}; };
void void weston_hdr_metadata(void *data, uint16_t display_primary_r_x, uint16_t display_primary_r_y,
weston_hdr_metadata(void *data, uint16_t display_primary_g_x, uint16_t display_primary_g_y, uint16_t display_primary_b_x,
uint16_t display_primary_r_x, uint16_t display_primary_b_y, uint16_t white_point_x, uint16_t white_point_y,
uint16_t display_primary_r_y, uint16_t min_luminance, uint16_t max_luminance, uint16_t max_cll, uint16_t max_fall,
uint16_t display_primary_g_x, enum hdr_metadata_eotf eotf) {
uint16_t display_primary_g_y,
uint16_t display_primary_b_x,
uint16_t display_primary_b_y,
uint16_t white_point_x,
uint16_t white_point_y,
uint16_t min_luminance,
uint16_t max_luminance,
uint16_t max_cll,
uint16_t max_fall,
enum hdr_metadata_eotf eotf)
{
uint8_t *data8; uint8_t *data8;
uint16_t *data16; uint16_t *data16;
@ -124,7 +111,7 @@ weston_hdr_metadata(void *data,
*data8++ = eotf; *data8++ = eotf;
*data8++ = METADATA_TYPE1; *data8++ = METADATA_TYPE1;
data16 = (void*)data8; data16 = (void *)data8;
*data16++ = display_primary_r_x; *data16++ = display_primary_r_x;
*data16++ = display_primary_r_y; *data16++ = display_primary_r_y;
@ -155,151 +142,302 @@ struct weston_colorspace {
struct weston_colorspace hdr10; struct weston_colorspace hdr10;
static const struct weston_colorspace bt470m = { static const struct weston_colorspace bt470m = {
.r = {{ 0.670f, 0.330f, }}, .r = {{
.g = {{ 0.210f, 0.710f, }}, 0.670f,
.b = {{ 0.140f, 0.080f, }}, 0.330f,
.whitepoint = {{ 0.3101f, 0.3162f, }}, }},
.g = {{
0.210f,
0.710f,
}},
.b = {{
0.140f,
0.080f,
}},
.whitepoint = {{
0.3101f,
0.3162f,
}},
.name = "BT.470 M", .name = "BT.470 M",
.whitepoint_name = "C", .whitepoint_name = "C",
}; };
static const struct weston_colorspace bt470bg = { static const struct weston_colorspace bt470bg = {
.r = {{ 0.640f, 0.330f, }}, .r = {{
.g = {{ 0.290f, 0.600f, }}, 0.640f,
.b = {{ 0.150f, 0.060f, }}, 0.330f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.290f,
0.600f,
}},
.b = {{
0.150f,
0.060f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "BT.470 B/G", .name = "BT.470 B/G",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace smpte170m = { static const struct weston_colorspace smpte170m = {
.r = {{ 0.630f, 0.340f, }}, .r = {{
.g = {{ 0.310f, 0.595f, }}, 0.630f,
.b = {{ 0.155f, 0.070f, }}, 0.340f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.310f,
0.595f,
}},
.b = {{
0.155f,
0.070f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "SMPTE 170M", .name = "SMPTE 170M",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace smpte240m = { static const struct weston_colorspace smpte240m = {
.r = {{ 0.630f, 0.340f, }}, .r = {{
.g = {{ 0.310f, 0.595f, }}, 0.630f,
.b = {{ 0.155f, 0.070f, }}, 0.340f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.310f,
0.595f,
}},
.b = {{
0.155f,
0.070f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "SMPTE 240M", .name = "SMPTE 240M",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace bt709 = { static const struct weston_colorspace bt709 = {
.r = {{ 0.640f, 0.330f, }}, .r = {{
.g = {{ 0.300f, 0.600f, }}, 0.640f,
.b = {{ 0.150f, 0.060f, }}, 0.330f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.300f,
0.600f,
}},
.b = {{
0.150f,
0.060f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "BT.709", .name = "BT.709",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace bt2020 = { static const struct weston_colorspace bt2020 = {
.r = {{ 0.708f, 0.292f, }}, .r = {{
.g = {{ 0.170f, 0.797f, }}, 0.708f,
.b = {{ 0.131f, 0.046f, }}, 0.292f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.170f,
0.797f,
}},
.b = {{
0.131f,
0.046f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "BT.2020", .name = "BT.2020",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace srgb = { static const struct weston_colorspace srgb = {
.r = {{ 0.640f, 0.330f, }}, .r = {{
.g = {{ 0.300f, 0.600f, }}, 0.640f,
.b = {{ 0.150f, 0.060f, }}, 0.330f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.300f,
0.600f,
}},
.b = {{
0.150f,
0.060f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "sRGB", .name = "sRGB",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace adobergb = { static const struct weston_colorspace adobergb = {
.r = {{ 0.640f, 0.330f, }}, .r = {{
.g = {{ 0.210f, 0.710f, }}, 0.640f,
.b = {{ 0.150f, 0.060f, }}, 0.330f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.210f,
0.710f,
}},
.b = {{
0.150f,
0.060f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "AdobeRGB", .name = "AdobeRGB",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace dci_p3 = { static const struct weston_colorspace dci_p3 = {
.r = {{ 0.680f, 0.320f, }}, .r = {{
.g = {{ 0.265f, 0.690f, }}, 0.680f,
.b = {{ 0.150f, 0.060f, }}, 0.320f,
.whitepoint = {{ 0.3127f, 0.3290f, }}, }},
.g = {{
0.265f,
0.690f,
}},
.b = {{
0.150f,
0.060f,
}},
.whitepoint = {{
0.3127f,
0.3290f,
}},
.name = "DCI-P3 D65", .name = "DCI-P3 D65",
.whitepoint_name = "D65", .whitepoint_name = "D65",
}; };
static const struct weston_colorspace prophotorgb = { static const struct weston_colorspace prophotorgb = {
.r = {{ 0.7347f, 0.2653f, }}, .r = {{
.g = {{ 0.1596f, 0.8404f, }}, 0.7347f,
.b = {{ 0.0366f, 0.0001f, }}, 0.2653f,
.whitepoint = {{ .3457, .3585 }}, }},
.g = {{
0.1596f,
0.8404f,
}},
.b = {{
0.0366f,
0.0001f,
}},
.whitepoint = {{.3457, .3585}},
.name = "ProPhoto RGB", .name = "ProPhoto RGB",
.whitepoint_name = "D50", .whitepoint_name = "D50",
}; };
static const struct weston_colorspace ciergb = { static const struct weston_colorspace ciergb = {
.r = {{ 0.7347f, 0.2653f, }}, .r = {{
.g = {{ 0.2738f, 0.7174f, }}, 0.7347f,
.b = {{ 0.1666f, 0.0089f, }}, 0.2653f,
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }}, }},
.g = {{
0.2738f,
0.7174f,
}},
.b = {{
0.1666f,
0.0089f,
}},
.whitepoint = {{
1.0f / 3.0f,
1.0f / 3.0f,
}},
.name = "CIE RGB", .name = "CIE RGB",
.whitepoint_name = "E", .whitepoint_name = "E",
}; };
static const struct weston_colorspace ciexyz = { static const struct weston_colorspace ciexyz = {
.r = {{ 1.0f, 0.0f, }}, .r = {{
.g = {{ 0.0f, 1.0f, }}, 1.0f,
.b = {{ 0.0f, 0.0f, }}, 0.0f,
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }}, }},
.g = {{
0.0f,
1.0f,
}},
.b = {{
0.0f,
0.0f,
}},
.whitepoint = {{
1.0f / 3.0f,
1.0f / 3.0f,
}},
.name = "CIE XYZ", .name = "CIE XYZ",
.whitepoint_name = "E", .whitepoint_name = "E",
}; };
const struct weston_colorspace ap0 = { const struct weston_colorspace ap0 = {
.r = {{ 0.7347f, 0.2653f, }}, .r = {{
.g = {{ 0.0000f, 1.0000f, }}, 0.7347f,
.b = {{ 0.0001f, -0.0770f, }}, 0.2653f,
.whitepoint = {{ .32168f, .33767f, }}, }},
.g = {{
0.0000f,
1.0000f,
}},
.b = {{
0.0001f,
-0.0770f,
}},
.whitepoint = {{
.32168f,
.33767f,
}},
.name = "ACES primaries #0", .name = "ACES primaries #0",
.whitepoint_name = "D60", .whitepoint_name = "D60",
}; };
const struct weston_colorspace ap1 = { const struct weston_colorspace ap1 = {
.r = {{ 0.713f, 0.393f, }}, .r = {{
.g = {{ 0.165f, 0.830f, }}, 0.713f,
.b = {{ 0.128f, 0.044f, }}, 0.393f,
.whitepoint = {{ 0.32168f, 0.33767f, }}, }},
.g = {{
0.165f,
0.830f,
}},
.b = {{
0.128f,
0.044f,
}},
.whitepoint = {{
0.32168f,
0.33767f,
}},
.name = "ACES primaries #1", .name = "ACES primaries #1",
.whitepoint_name = "D60", .whitepoint_name = "D60",
}; };
static const struct weston_colorspace * const colorspaces[] = { static const struct weston_colorspace *const colorspaces[] = {
&bt470m, &bt470m, &bt470bg, &smpte170m, &smpte240m, &bt709, &bt2020, &srgb,
&bt470bg, &adobergb, &dci_p3, &prophotorgb, &ciergb, &ciexyz, &ap0, &ap1,
&smpte170m,
&smpte240m,
&bt709,
&bt2020,
&srgb,
&adobergb,
&dci_p3,
&prophotorgb,
&ciergb,
&ciexyz,
&ap0,
&ap1,
}; };
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0]) #define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
const struct weston_colorspace * const struct weston_colorspace *weston_colorspace_lookup(const char *name) {
weston_colorspace_lookup(const char *name)
{
unsigned i; unsigned i;
if (!name) if (!name)
@ -315,35 +453,27 @@ weston_colorspace_lookup(const char *name)
return NULL; return NULL;
} }
static int cleanup=0; static int cleanup = 0;
static uint16_t encode_xyy(float xyy) { return xyy * 50000; }
static uint16_t encode_xyy(float xyy)
{
return xyy * 50000;
}
static AVMasteringDisplayMetadata md_save = {0}; static AVMasteringDisplayMetadata md_save = {0};
static AVContentLightMetadata ld_save = {0}; static AVContentLightMetadata ld_save = {0};
static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSideData *sd2) static void set_hdr_metadata(int color, int trc, AVFrameSideData *sd1, AVFrameSideData *sd2) {
{ drmModeAtomicReqPtr ModeReq;
drmModeAtomicReqPtr ModeReq;
struct weston_colorspace *cs; struct weston_colorspace *cs;
enum hdr_metadata_eotf eotf; enum hdr_metadata_eotf eotf;
struct hdr_output_metadata data; struct hdr_output_metadata data;
int ret,MaxCLL=1500,MaxFALL=400; int ret, MaxCLL = 1500, MaxFALL = 400;
int max_lum=4000,min_lum=0050; int max_lum = 4000, min_lum = 0050;
struct AVMasteringDisplayMetadata *md = NULL; struct AVMasteringDisplayMetadata *md = NULL;
struct AVContentLightMetadata *ld = NULL; struct AVContentLightMetadata *ld = NULL;
// clean up FFMEPG stuff // clean up FFMEPG stuff
if (trc == AVCOL_TRC_BT2020_10) if (trc == AVCOL_TRC_BT2020_10)
trc = AVCOL_TRC_ARIB_STD_B67; trc = AVCOL_TRC_ARIB_STD_B67;
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata) if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
return; // nothing to do return; // nothing to do
if (sd1) if (sd1)
md = sd1->data; md = sd1->data;
@ -351,81 +481,76 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
if (sd2) if (sd2)
ld = sd2->data; ld = sd2->data;
if (md && !memcmp(md,&md_save,sizeof(md_save))) if (md && !memcmp(md, &md_save, sizeof(md_save)))
if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) { if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
return;
} else if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
return; return;
} }
else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) {
return;
}
if (ld) if (ld)
memcpy(&ld_save,ld,sizeof(ld_save)); memcpy(&ld_save, ld, sizeof(ld_save));
if (md) if (md)
memcpy(&md_save,md,sizeof(md_save)); memcpy(&md_save, md, sizeof(md_save));
Debug(3,"Update HDR to TRC %d color %d\n",trc,color); Debug(3, "Update HDR to TRC %d color %d\n", trc, color);
old_color = color; old_color = color;
old_trc = trc; old_trc = trc;
if (VulkanTargetColorSpace != 3) { // no HDR TV if (VulkanTargetColorSpace != 3) { // no HDR TV
m_need_modeset = 1; // change in colorsettings m_need_modeset = 1; // change in colorsettings
return; return;
} }
if (render->hdr_blob_id) if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
switch(trc) { switch (trc) {
case AVCOL_TRC_BT709: // 1 case AVCOL_TRC_BT709: // 1
case AVCOL_TRC_UNSPECIFIED: // 2 case AVCOL_TRC_UNSPECIFIED: // 2
eotf = EOTF_TRADITIONAL_GAMMA_SDR; eotf = EOTF_TRADITIONAL_GAMMA_SDR;
break; break;
case AVCOL_TRC_BT2020_10: // 14 case AVCOL_TRC_BT2020_10: // 14
case AVCOL_TRC_BT2020_12: case AVCOL_TRC_BT2020_12:
case AVCOL_TRC_ARIB_STD_B67: // 18 HLG case AVCOL_TRC_ARIB_STD_B67: // 18 HLG
eotf = EOTF_HLG; eotf = EOTF_HLG;
break; break;
case AVCOL_TRC_SMPTE2084: // 16 case AVCOL_TRC_SMPTE2084: // 16
eotf = EOTF_ST2084; eotf = EOTF_ST2084;
break; break;
default: default:
eotf = EOTF_TRADITIONAL_GAMMA_SDR; eotf = EOTF_TRADITIONAL_GAMMA_SDR;
break; break;
} }
switch (color) { switch (color) {
case AVCOL_PRI_BT709: // 1 case AVCOL_PRI_BT709: // 1
case AVCOL_PRI_UNSPECIFIED: // 2 case AVCOL_PRI_UNSPECIFIED: // 2
cs = weston_colorspace_lookup("BT.709"); cs = weston_colorspace_lookup("BT.709");
break; break;
case AVCOL_PRI_BT2020: // 9 case AVCOL_PRI_BT2020: // 9
cs = weston_colorspace_lookup("BT.2020"); cs = weston_colorspace_lookup("BT.2020");
break; break;
case AVCOL_PRI_BT470BG: // 5 case AVCOL_PRI_BT470BG: // 5
cs = weston_colorspace_lookup("BT.470 B/G"); // BT.601 cs = weston_colorspace_lookup("BT.470 B/G"); // BT.601
break; break;
default: default:
cs = weston_colorspace_lookup("BT.709"); cs = weston_colorspace_lookup("BT.709");
break; break;
} }
if (md) { // we got Metadata if (md) { // we got Metadata
if (md->has_primaries) { if (md->has_primaries) {
Debug(3,"Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n" Debug(3,
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) \n" "Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n"
"min_luminance=%f, max_luminance=%f\n", "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) \n"
md->has_primaries, md->has_luminance, "min_luminance=%f, max_luminance=%f\n",
av_q2d(md->display_primaries[0][0]), md->has_primaries, md->has_luminance, av_q2d(md->display_primaries[0][0]),
av_q2d(md->display_primaries[0][1]), av_q2d(md->display_primaries[0][1]), av_q2d(md->display_primaries[1][0]),
av_q2d(md->display_primaries[1][0]), av_q2d(md->display_primaries[1][1]), av_q2d(md->display_primaries[2][0]),
av_q2d(md->display_primaries[1][1]), av_q2d(md->display_primaries[2][1]), av_q2d(md->white_point[0]), av_q2d(md->white_point[1]),
av_q2d(md->display_primaries[2][0]), av_q2d(md->min_luminance), av_q2d(md->max_luminance));
av_q2d(md->display_primaries[2][1]),
av_q2d(md->white_point[0]), av_q2d(md->white_point[1]),
av_q2d(md->min_luminance), av_q2d(md->max_luminance));
cs = &hdr10; cs = &hdr10;
cs->r.f[0] = (float)md->display_primaries[0][0].num / (float)md->display_primaries[0][0].den; cs->r.f[0] = (float)md->display_primaries[0][0].num / (float)md->display_primaries[0][0].den;
@ -439,53 +564,43 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
} }
if (md->has_luminance) { if (md->has_luminance) {
max_lum = av_q2d(md->max_luminance); max_lum = av_q2d(md->max_luminance);
min_lum = av_q2d(md->min_luminance) * 10000 ; min_lum = av_q2d(md->min_luminance) * 10000;
printf("max_lum %d min_lum %d\n",max_lum,min_lum); printf("max_lum %d min_lum %d\n", max_lum, min_lum);
} }
} }
if (ld) { if (ld) {
Debug(3,"Has MaxCLL %d MaxFALL %d\n",ld->MaxCLL,ld->MaxFALL); Debug(3, "Has MaxCLL %d MaxFALL %d\n", ld->MaxCLL, ld->MaxFALL);
MaxCLL = ld->MaxCLL; MaxCLL = ld->MaxCLL;
MaxFALL = ld->MaxFALL; MaxFALL = ld->MaxFALL;
} }
data.metadata_type = 7; // ???????????????????????? data.metadata_type = 7; // ????????????????????????
weston_hdr_metadata(&data.hdmi_metadata_type1, weston_hdr_metadata(&data.hdmi_metadata_type1, encode_xyy(cs->r.f[0]), encode_xyy(cs->r.f[1]),
encode_xyy(cs->r.f[0]), encode_xyy(cs->g.f[0]), encode_xyy(cs->g.f[1]), encode_xyy(cs->b.f[0]), encode_xyy(cs->b.f[1]),
encode_xyy(cs->r.f[1]), encode_xyy(cs->whitepoint.f[0]), encode_xyy(cs->whitepoint.f[1]),
encode_xyy(cs->g.f[0]), max_lum, // max_display_mastering_luminance
encode_xyy(cs->g.f[1]), min_lum, // min_display_mastering_luminance
encode_xyy(cs->b.f[0]), MaxCLL, // Maximum Content Light Level (MaxCLL)
encode_xyy(cs->b.f[1]), MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
encode_xyy(cs->whitepoint.f[0]), eotf);
encode_xyy(cs->whitepoint.f[1]),
max_lum, // max_display_mastering_luminance
min_lum, // min_display_mastering_luminance
MaxCLL, // Maximum Content Light Level (MaxCLL)
MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
eotf);
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
if (ret) {
printf("DRM: HDR metadata: failed blob create \n");
render->hdr_blob_id = 0;
return;
}
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, render->hdr_metadata, render->hdr_blob_id);
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id); if (ret) {
if (ret) { printf("DRM: HDR metadata: failed property set %d\n", ret);
printf("DRM: HDR metadata: failed blob create \n");
render->hdr_blob_id = 0;
return;
}
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, if (render->hdr_blob_id)
render->hdr_metadata, render->hdr_blob_id); drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
if (ret) { render->hdr_blob_id = 0;
printf("DRM: HDR metadata: failed property set %d\n",ret); return;
}
if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
render->hdr_blob_id = 0;
return;
}
m_need_modeset = 1; m_need_modeset = 1;
Debug(3,"DRM: HDR metadata: prop set\n"); Debug(3, "DRM: HDR metadata: prop set\n");
} }