mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
Inital Support for DRM with HDR10 and HDR-HLG
This commit is contained in:
parent
f17e58c7c5
commit
3bed988b14
55
Makefile
55
Makefile
@ -11,13 +11,20 @@
|
|||||||
### Configuration (edit this for your needs)
|
### Configuration (edit this for your needs)
|
||||||
# comment out if not needed
|
# comment out if not needed
|
||||||
|
|
||||||
# what kind of driver do we make -
|
# what kind of decoder do we make -
|
||||||
# if VAAPI is enabled the drivername is softhdvaapi
|
# if VAAPI is enabled the pluginname is softhdvaapi
|
||||||
# if CUVID is enabled the drivername is softhdcuvid
|
# if CUVID is enabled the pluginname is softhdcuvid
|
||||||
|
# if DRM is enabled the pluginname is softhddrm
|
||||||
#VAAPI=1
|
#VAAPI=1
|
||||||
CUVID=1
|
CUVID=1
|
||||||
|
|
||||||
# use libplacebo - available for both drivers
|
# if you enable DRM then the plugin will only run without X server
|
||||||
|
# only valid for VAAPI
|
||||||
|
# does not work with libplacebo
|
||||||
|
#DRM=1
|
||||||
|
|
||||||
|
|
||||||
|
# use libplacebo - available for both decoders but not for DRM
|
||||||
#LIBPLACEBO=1
|
#LIBPLACEBO=1
|
||||||
|
|
||||||
# use YADIF deint - only available with cuvid
|
# use YADIF deint - only available with cuvid
|
||||||
@ -25,6 +32,7 @@ CUVID=1
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG := #-DDEBUG # remove # to enable debug output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +68,6 @@ SWRESAMPLE = 1
|
|||||||
#AVRESAMPLE = 1
|
#AVRESAMPLE = 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CONFIG := #-DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
|
||||||
CONFIG += -DHAVE_GL # needed for mpv libs
|
CONFIG += -DHAVE_GL # needed for mpv libs
|
||||||
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
||||||
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
||||||
@ -92,7 +99,7 @@ TMPDIR ?= /tmp
|
|||||||
|
|
||||||
### The compiler options:
|
### The compiler options:
|
||||||
|
|
||||||
export CFLAGS = $(call PKGCFG,cflags)
|
export CFLAGS = $(call PKGCFG,cflags)
|
||||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
export CXXFLAGS = $(call PKGCFG,cxxflags)
|
||||||
|
|
||||||
ifeq ($(CFLAGS),)
|
ifeq ($(CFLAGS),)
|
||||||
@ -136,7 +143,7 @@ endif
|
|||||||
ifeq ($(OPENGL),1)
|
ifeq ($(OPENGL),1)
|
||||||
CONFIG += -DUSE_GLX
|
CONFIG += -DUSE_GLX
|
||||||
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
|
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
|
||||||
#LIBS += $(shell pkg-config --libs glu glew)
|
#LIBS += $(shell pkg-config --libs glu glew)
|
||||||
_CFLAGS += $(shell pkg-config --cflags freetype2)
|
_CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||||
LIBS += $(shell pkg-config --libs freetype2)
|
LIBS += $(shell pkg-config --libs freetype2)
|
||||||
endif
|
endif
|
||||||
@ -152,6 +159,14 @@ ifeq ($(LIBPLACEBO),1)
|
|||||||
CONFIG += -DPLACEBO
|
CONFIG += -DPLACEBO
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(DRM),1)
|
||||||
|
PLUGIN = softhddrm
|
||||||
|
CONFIG += -DUSE_DRM -DVAAPI
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags libdrm)
|
||||||
|
LIBS += -lgbm -ldrm
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
CONFIG += -DUSE_PIP # PIP support
|
CONFIG += -DUSE_PIP # PIP support
|
||||||
CONFIG += -DCUVID # enable CUVID decoder
|
CONFIG += -DCUVID # enable CUVID decoder
|
||||||
@ -233,8 +248,8 @@ endif
|
|||||||
|
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
_CFLAGS += $(shell pkg-config --cflags x11 x11-xcb xcb xcb-icccm)
|
_CFLAGS += $(shell pkg-config --cflags x11 x11-xcb xcb xcb-icccm)
|
||||||
LIBS += -lrt $(shell pkg-config --libs x11 x11-xcb xcb xcb-icccm)
|
LIBS += -lrt $(shell pkg-config --libs x11 x11-xcb xcb xcb-icccm)
|
||||||
|
|
||||||
_CFLAGS += -I/usr/local/cuda/include
|
_CFLAGS += -I/usr/local/cuda/include
|
||||||
_CFLAGS += -I./opengl -I./
|
_CFLAGS += -I./opengl -I./
|
||||||
@ -247,7 +262,7 @@ LIBS += -lplacebo
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
LIBS += -lcuda -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -lnvcuvid
|
LIBS += -lcuda -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -lnvcuvid
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS += -lGLEW -lGLU -ldl -lglut
|
LIBS += -lGLEW -lGLU -ldl -lglut
|
||||||
@ -261,8 +276,8 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \
|
|||||||
### Make it standard
|
### Make it standard
|
||||||
|
|
||||||
override CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
override CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
||||||
-g -Wextra -Winit-self -Werror=overloaded-virtual -std=c++0x
|
-g -W -Wextra -Winit-self -Werror=overloaded-virtual -Wno-unused-parameter
|
||||||
override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
||||||
-g -W -Wextra -Winit-self -Wdeclaration-after-statement
|
-g -W -Wextra -Winit-self -Wdeclaration-after-statement
|
||||||
|
|
||||||
|
|
||||||
@ -273,7 +288,7 @@ ifeq ($(OPENGLOSD),1)
|
|||||||
OBJS += openglosd.o
|
OBJS += openglosd.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SRCS = $(wildcard $(OBJS:.o=.c)) softhdcuvid.cpp
|
SRCS = $(wildcard $(OBJS:.o=.c)) *.cpp
|
||||||
|
|
||||||
### The main target:
|
### The main target:
|
||||||
|
|
||||||
@ -290,11 +305,11 @@ $(DEPFILE): Makefile
|
|||||||
|
|
||||||
### Internationalization (I18N):
|
### Internationalization (I18N):
|
||||||
|
|
||||||
PODIR = po
|
PODIR = po
|
||||||
I18Npo = $(wildcard $(PODIR)/*.po)
|
I18Npo = $(wildcard $(PODIR)/*.po)
|
||||||
I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
|
I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
|
||||||
I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
|
I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
|
||||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||||
|
|
||||||
%.mo: %.po
|
%.mo: %.po
|
||||||
msgfmt -c -o $@ $<
|
msgfmt -c -o $@ $<
|
||||||
@ -322,7 +337,7 @@ $(OBJS): Makefile
|
|||||||
|
|
||||||
|
|
||||||
$(SOFILE): $(OBJS) shaders.h
|
$(SOFILE): $(OBJS) shaders.h
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
|
|
||||||
install-lib: $(SOFILE)
|
install-lib: $(SOFILE)
|
||||||
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
|
||||||
@ -343,11 +358,13 @@ clean:
|
|||||||
|
|
||||||
## Private Targets:
|
## Private Targets:
|
||||||
|
|
||||||
HDRS= $(wildcard *.h)
|
HDRS= $(wildcard *.h)
|
||||||
|
|
||||||
indent:
|
indent:
|
||||||
for i in $(SRCS) $(HDRS); do \
|
for i in $(SRCS) $(HDRS); do \
|
||||||
indent $$i; \
|
indent $$i; \
|
||||||
|
unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \
|
||||||
|
mv $$i.up $$i; \
|
||||||
done
|
done
|
||||||
|
|
||||||
video_test: video.c Makefile
|
video_test: video.c Makefile
|
||||||
|
471
drm.c
Normal file
471
drm.c
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <gbm.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
|
#define DRM_DEBUG
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// DRM
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct _Drm_Render_
|
||||||
|
{
|
||||||
|
int fd_drm;
|
||||||
|
drmModeModeInfo mode;
|
||||||
|
drmModeCrtc *saved_crtc;
|
||||||
|
// drmEventContext ev;
|
||||||
|
int bpp;
|
||||||
|
uint32_t connector_id, crtc_id, video_plane;
|
||||||
|
uint32_t hdr_metadata;
|
||||||
|
|
||||||
|
};
|
||||||
|
typedef struct _Drm_Render_ VideoRender;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct gbm_device *dev;
|
||||||
|
struct gbm_surface *surface;
|
||||||
|
} gbm;
|
||||||
|
|
||||||
|
VideoRender *render;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Helper functions
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID,
|
||||||
|
uint32_t objectType, const char *propName)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
int found = 0;
|
||||||
|
uint64_t value = 0;
|
||||||
|
drmModePropertyPtr Prop;
|
||||||
|
drmModeObjectPropertiesPtr objectProps =
|
||||||
|
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
|
|
||||||
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
|
fprintf(stderr, "GetPropertyValue: Unable to query property.\n");
|
||||||
|
|
||||||
|
if (strcmp(propName, Prop->name) == 0) {
|
||||||
|
value = objectProps->prop_values[i];
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeProperty(Prop);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeObjectProperties(objectProps);
|
||||||
|
|
||||||
|
#ifdef DRM_DEBUG
|
||||||
|
if (!found)
|
||||||
|
fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n",
|
||||||
|
propName);
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
static uint32_t GetPropertyID(int fd_drm, uint32_t objectID,
|
||||||
|
uint32_t objectType, const char *propName)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
int found = 0;
|
||||||
|
uint32_t value = -1;
|
||||||
|
drmModePropertyPtr Prop;
|
||||||
|
drmModeObjectPropertiesPtr objectProps =
|
||||||
|
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
|
|
||||||
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
|
fprintf(stderr, "GetPropertyValue: Unable to query property.\n");
|
||||||
|
|
||||||
|
if (strcmp(propName, Prop->name) == 0) {
|
||||||
|
value = objectProps->props[i];
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
drmModeFreeProperty(Prop);
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
drmModeFreeObjectProperties(objectProps);
|
||||||
|
|
||||||
|
#ifdef DRM_DEBUG
|
||||||
|
if (!found)
|
||||||
|
Debug(3,"GetPropertyValue: Unable to find ID for property \'%s\'.\n",propName);
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm,
|
||||||
|
uint32_t objectID, uint32_t objectType,
|
||||||
|
const char *propName, uint64_t value)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint64_t id = 0;
|
||||||
|
drmModePropertyPtr Prop;
|
||||||
|
drmModeObjectPropertiesPtr objectProps =
|
||||||
|
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
|
|
||||||
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
|
printf( "SetPropertyRequest: Unable to query property.\n");
|
||||||
|
|
||||||
|
if (strcmp(propName, Prop->name) == 0) {
|
||||||
|
id = Prop->prop_id;
|
||||||
|
drmModeFreeProperty(Prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeProperty(Prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeObjectProperties(objectProps);
|
||||||
|
|
||||||
|
if (id == 0)
|
||||||
|
printf( "SetPropertyRequest: Unable to find value for property \'%s\'.\n",
|
||||||
|
propName);
|
||||||
|
|
||||||
|
return drmModeAtomicAddProperty(ModeReq, objectID, id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FindDevice(VideoRender * render)
|
||||||
|
{
|
||||||
|
drmVersion *version;
|
||||||
|
drmModeRes *resources;
|
||||||
|
drmModeConnector *connector;
|
||||||
|
drmModeEncoder *encoder = 0;
|
||||||
|
drmModeModeInfo *mode;
|
||||||
|
drmModePlane *plane;
|
||||||
|
drmModePlaneRes *plane_res;
|
||||||
|
drmModeObjectPropertiesPtr props;
|
||||||
|
uint32_t j, k;
|
||||||
|
uint64_t has_dumb;
|
||||||
|
uint64_t has_prime;
|
||||||
|
int i,ii=0;
|
||||||
|
|
||||||
|
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
||||||
|
if (render->fd_drm < 0) {
|
||||||
|
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
version = drmGetVersion(render->fd_drm);
|
||||||
|
fprintf(stderr, "FindDevice: open /dev/dri/card0: %i %s\n", version->name_len, version->name);
|
||||||
|
|
||||||
|
// check capability
|
||||||
|
if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0)
|
||||||
|
fprintf(stderr, "FindDevice: drmGetCap DRM_CAP_DUMB_BUFFER failed or doesn't have dumb buffer\n");
|
||||||
|
|
||||||
|
if (drmSetClientCap(render->fd_drm, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
||||||
|
fprintf(stderr, "FindDevice: DRM_CLIENT_CAP_UNIVERSAL_PLANES not available.\n");
|
||||||
|
|
||||||
|
if (drmSetClientCap(render->fd_drm, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
|
||||||
|
fprintf(stderr, "FindDevice: DRM_CLIENT_CAP_ATOMIC not available.\n");
|
||||||
|
|
||||||
|
if (drmGetCap(render->fd_drm, DRM_CAP_PRIME, &has_prime) < 0)
|
||||||
|
fprintf(stderr, "FindDevice: DRM_CAP_PRIME not available.\n");
|
||||||
|
|
||||||
|
if (drmGetCap(render->fd_drm, DRM_PRIME_CAP_EXPORT, &has_prime) < 0)
|
||||||
|
fprintf(stderr, "FindDevice: DRM_PRIME_CAP_EXPORT not available.\n");
|
||||||
|
|
||||||
|
if (drmGetCap(render->fd_drm, DRM_PRIME_CAP_IMPORT, &has_prime) < 0)
|
||||||
|
fprintf(stderr, "FindDevice: DRM_PRIME_CAP_IMPORT not available.\n");
|
||||||
|
|
||||||
|
if ((resources = drmModeGetResources(render->fd_drm)) == NULL){
|
||||||
|
fprintf(stderr, "FindDevice: cannot retrieve DRM resources (%d): %m\n", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Debug(3,"[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n",
|
||||||
|
resources->count_connectors, resources->count_crtcs,
|
||||||
|
resources->count_encoders);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// find all available connectors
|
||||||
|
for (i = 0; i < resources->count_connectors; i++) {
|
||||||
|
connector = drmModeGetConnector(render->fd_drm, resources->connectors[i]);
|
||||||
|
if (!connector) {
|
||||||
|
fprintf(stderr, "FindDevice: cannot retrieve DRM connector (%d): %m\n", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) {
|
||||||
|
render->connector_id = connector->connector_id;
|
||||||
|
|
||||||
|
// FIXME: use default encoder/crtc pair
|
||||||
|
if ((encoder = drmModeGetEncoder(render->fd_drm, connector->encoder_id)) == NULL){
|
||||||
|
fprintf(stderr, "FindDevice: cannot retrieve encoder (%d): %m\n", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
render->crtc_id = encoder->crtc_id;
|
||||||
|
|
||||||
|
render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id,
|
||||||
|
DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA");
|
||||||
|
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
|
||||||
|
// search Modes for Connector
|
||||||
|
for (ii = 0; ii < connector->count_modes; ii++) {
|
||||||
|
mode = &connector->modes[ii];
|
||||||
|
printf("Mode %d %dx%d Rate %d\n",ii,mode->hdisplay,mode->vdisplay,mode->vrefresh);
|
||||||
|
if (VideoWindowWidth && VideoWindowHeight) { // preset by command line
|
||||||
|
if (VideoWindowWidth == mode->hdisplay &&
|
||||||
|
VideoWindowHeight == mode->vdisplay &&
|
||||||
|
mode->vrefresh == 50 &&
|
||||||
|
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
|
VideoWindowWidth = mode->hdisplay;
|
||||||
|
VideoWindowHeight = mode->vdisplay;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = resources->count_connectors; // uuuuhh
|
||||||
|
}
|
||||||
|
VideoWindowWidth = render->mode.hdisplay;
|
||||||
|
VideoWindowHeight = render->mode.vdisplay;
|
||||||
|
printf("Use Mode %d %dx%d Rate %d\n",ii,render->mode.hdisplay,render->mode.vdisplay,render->mode.vrefresh);
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find first plane
|
||||||
|
if ((plane_res = drmModeGetPlaneResources(render->fd_drm)) == NULL)
|
||||||
|
fprintf(stderr, "FindDevice: cannot retrieve PlaneResources (%d): %m\n", errno);
|
||||||
|
|
||||||
|
for (j = 0; j < plane_res->count_planes; j++) {
|
||||||
|
plane = drmModeGetPlane(render->fd_drm, plane_res->planes[j]);
|
||||||
|
|
||||||
|
if (plane == NULL)
|
||||||
|
fprintf(stderr, "FindDevice: cannot query DRM-KMS plane %d\n", j);
|
||||||
|
|
||||||
|
for (i = 0; i < resources->count_crtcs; i++) {
|
||||||
|
if (plane->possible_crtcs & (1 << i))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j],
|
||||||
|
DRM_MODE_OBJECT_PLANE, "type");
|
||||||
|
uint64_t zpos = 0;
|
||||||
|
|
||||||
|
#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",
|
||||||
|
plane->plane_id, plane->crtc_id, plane->possible_crtcs, resources->crtcs[i],
|
||||||
|
(type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane" :
|
||||||
|
(type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane" :
|
||||||
|
(type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane" : "No plane type");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// test pixel format and plane caps
|
||||||
|
for (k = 0; k < plane->count_formats; k++) {
|
||||||
|
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
||||||
|
switch (plane->formats[k]) {
|
||||||
|
case DRM_FORMAT_XRGB2101010:
|
||||||
|
if (!render->video_plane) {
|
||||||
|
render->video_plane = plane->plane_id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drmModeFreePlane(plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreePlaneResources(plane_res);
|
||||||
|
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
drmModeFreeResources(resources);
|
||||||
|
|
||||||
|
#ifdef DRM_DEBUG
|
||||||
|
printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n",
|
||||||
|
render->crtc_id, render->video_plane);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// save actual modesetting
|
||||||
|
render->saved_crtc = drmModeGetCrtc(render->fd_drm, render->crtc_id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initialize video output module.
|
||||||
|
///
|
||||||
|
void VideoInitDrm()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(render = calloc(1, sizeof(*render)))) {
|
||||||
|
Error(_("video/DRM: out of memory\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FindDevice(render)){
|
||||||
|
fprintf(stderr, "VideoInit: FindDevice() failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
gbm.dev = gbm_create_device (render->fd_drm);
|
||||||
|
assert (gbm.dev != NULL);
|
||||||
|
|
||||||
|
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
|
||||||
|
get_platform_display =
|
||||||
|
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||||
|
assert(get_platform_display != NULL);
|
||||||
|
|
||||||
|
eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL);
|
||||||
|
|
||||||
|
assert (eglDisplay != NULL);
|
||||||
|
// return;
|
||||||
|
|
||||||
|
drmModeAtomicReqPtr ModeReq;
|
||||||
|
const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
uint32_t modeID = 0;
|
||||||
|
|
||||||
|
if (drmModeCreatePropertyBlob(render->fd_drm, &render->mode, sizeof(render->mode), &modeID) != 0) {
|
||||||
|
fprintf(stderr, "Failed to create mode property.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(ModeReq = drmModeAtomicAlloc())) {
|
||||||
|
fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
||||||
|
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)
|
||||||
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
|
|
||||||
|
if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0)
|
||||||
|
fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno);
|
||||||
|
|
||||||
|
drmModeAtomicFree(ModeReq);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct gbm_bo *bo = NULL, *next_bo=NULL;
|
||||||
|
struct drm_fb *fb;
|
||||||
|
static int m_need_modeset = 0;
|
||||||
|
static int old_color=-1,old_trc=-1;
|
||||||
|
|
||||||
|
void InitBo(int bpp) {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gbm_bo *previous_bo = NULL;
|
||||||
|
static uint32_t previous_fb;
|
||||||
|
|
||||||
|
static void drm_swap_buffers () {
|
||||||
|
|
||||||
|
uint32_t fb;
|
||||||
|
|
||||||
|
eglSwapBuffers (eglDisplay, eglSurface);
|
||||||
|
struct gbm_bo *bo = gbm_surface_lock_front_buffer (gbm.surface);
|
||||||
|
#if 1
|
||||||
|
if (bo == NULL)
|
||||||
|
bo = gbm_surface_lock_front_buffer (gbm.surface);
|
||||||
|
#endif
|
||||||
|
assert (bo != NULL);
|
||||||
|
uint32_t handle = gbm_bo_get_handle (bo).u32;
|
||||||
|
uint32_t pitch = gbm_bo_get_stride (bo);
|
||||||
|
|
||||||
|
|
||||||
|
drmModeAddFB (render->fd_drm, VideoWindowWidth,VideoWindowHeight,render->bpp==10? 30:24, 32, pitch, handle, &fb);
|
||||||
|
// drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
|
||||||
|
|
||||||
|
if (m_need_modeset) {
|
||||||
|
drmModeAtomicReqPtr ModeReq;
|
||||||
|
const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
uint32_t modeID = 0;
|
||||||
|
|
||||||
|
if (drmModeCreatePropertyBlob(render->fd_drm, &render->mode, sizeof(render->mode), &modeID) != 0) {
|
||||||
|
fprintf(stderr, "Failed to create mode property.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(ModeReq = drmModeAtomicAlloc())) {
|
||||||
|
fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to disable the CRTC in order to submit the HDR data....
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
||||||
|
DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
|
||||||
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
|
sleep(2);
|
||||||
|
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
||||||
|
DRM_MODE_OBJECT_CONNECTOR, "Colorspace",old_color==AVCOL_PRI_BT2020?9:2 );
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
||||||
|
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)
|
||||||
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
|
|
||||||
|
if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0)
|
||||||
|
fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno);
|
||||||
|
|
||||||
|
drmModeAtomicFree(ModeReq);
|
||||||
|
m_need_modeset = 0;
|
||||||
|
}
|
||||||
|
drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
|
||||||
|
|
||||||
|
if (previous_bo) {
|
||||||
|
drmModeRmFB (render->fd_drm, previous_fb);
|
||||||
|
gbm_surface_release_buffer (gbm.surface, previous_bo);
|
||||||
|
}
|
||||||
|
previous_bo = bo;
|
||||||
|
previous_fb = fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drm_clean_up () {
|
||||||
|
// set the previous crtc
|
||||||
|
|
||||||
|
drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id,
|
||||||
|
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
|
||||||
|
drmModeFreeCrtc (render->saved_crtc);
|
||||||
|
|
||||||
|
if (previous_bo) {
|
||||||
|
drmModeRmFB (render->fd_drm, previous_fb);
|
||||||
|
gbm_surface_release_buffer (gbm.surface, previous_bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eglDestroySurface (display, eglSurface);
|
||||||
|
gbm_surface_destroy (gbm.surface);
|
||||||
|
// eglDestroyContext (display, context);
|
||||||
|
// eglTerminate (display);
|
||||||
|
gbm_device_destroy (gbm.dev);
|
||||||
|
close (render->fd_drm);
|
||||||
|
}
|
491
hdr.c
Normal file
491
hdr.c
Normal file
@ -0,0 +1,491 @@
|
|||||||
|
#include <libavutil/mastering_display_metadata.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
|
||||||
|
*
|
||||||
|
* HDR Metadata Infoframe as per CTA 861.G spec. This is expected
|
||||||
|
* to match exactly with the spec.
|
||||||
|
*
|
||||||
|
* Userspace is expected to pass the metadata information as per
|
||||||
|
* the format described in this structure.
|
||||||
|
*/
|
||||||
|
struct hdr_metadata_infoframe {
|
||||||
|
/**
|
||||||
|
* @eotf: Electro-Optical Transfer Function (EOTF)
|
||||||
|
* used in the stream.
|
||||||
|
*/
|
||||||
|
__u8 eotf;
|
||||||
|
/**
|
||||||
|
* @metadata_type: Static_Metadata_Descriptor_ID.
|
||||||
|
*/
|
||||||
|
__u8 metadata_type;
|
||||||
|
/**
|
||||||
|
* @display_primaries: Color Primaries of the Data.
|
||||||
|
* These are coded as unsigned 16-bit values in units of
|
||||||
|
* 0.00002, where 0x0000 represents zero and 0xC350
|
||||||
|
* represents 1.0000.
|
||||||
|
* @display_primaries.x: X cordinate of color primary.
|
||||||
|
* @display_primaries.y: Y cordinate of color primary.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
__u16 x, y;
|
||||||
|
} display_primaries[3];
|
||||||
|
/**
|
||||||
|
* @white_point: White Point of Colorspace Data.
|
||||||
|
* These are coded as unsigned 16-bit values in units of
|
||||||
|
* 0.00002, where 0x0000 represents zero and 0xC350
|
||||||
|
* represents 1.0000.
|
||||||
|
* @white_point.x: X cordinate of whitepoint of color primary.
|
||||||
|
* @white_point.y: Y cordinate of whitepoint of color primary.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
__u16 x, y;
|
||||||
|
} white_point;
|
||||||
|
/**
|
||||||
|
* @max_display_mastering_luminance: Max Mastering Display Luminance.
|
||||||
|
* This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||||
|
* where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||||
|
*/
|
||||||
|
__u16 max_display_mastering_luminance;
|
||||||
|
/**
|
||||||
|
* @min_display_mastering_luminance: Min Mastering Display Luminance.
|
||||||
|
* This value is coded as an unsigned 16-bit value in units of
|
||||||
|
* 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
|
||||||
|
* represents 6.5535 cd/m2.
|
||||||
|
*/
|
||||||
|
__u16 min_display_mastering_luminance;
|
||||||
|
/**
|
||||||
|
* @max_cll: Max Content Light Level.
|
||||||
|
* This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||||
|
* where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||||
|
*/
|
||||||
|
__u16 max_cll;
|
||||||
|
/**
|
||||||
|
* @max_fall: Max Frame Average Light Level.
|
||||||
|
* This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||||
|
* where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||||
|
*/
|
||||||
|
__u16 max_fall;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct hdr_output_metadata - HDR output metadata
|
||||||
|
*
|
||||||
|
* Metadata Information to be passed from userspace
|
||||||
|
*/
|
||||||
|
struct hdr_output_metadata {
|
||||||
|
/**
|
||||||
|
* @metadata_type: Static_Metadata_Descriptor_ID.
|
||||||
|
*/
|
||||||
|
__u32 metadata_type;
|
||||||
|
/**
|
||||||
|
* @hdmi_metadata_type1: HDR Metadata Infoframe.
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
struct hdr_metadata_infoframe hdmi_metadata_type1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum hdr_metadata_eotf {
|
||||||
|
EOTF_TRADITIONAL_GAMMA_SDR,
|
||||||
|
EOTF_TRADITIONAL_GAMMA_HDR,
|
||||||
|
EOTF_ST2084,
|
||||||
|
EOTF_HLG,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum metadata_id {
|
||||||
|
METADATA_TYPE1,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
weston_hdr_metadata(void *data,
|
||||||
|
uint16_t display_primary_r_x,
|
||||||
|
uint16_t display_primary_r_y,
|
||||||
|
uint16_t display_primary_g_x,
|
||||||
|
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;
|
||||||
|
uint16_t *data16;
|
||||||
|
|
||||||
|
data8 = data;
|
||||||
|
|
||||||
|
*data8++ = eotf;
|
||||||
|
*data8++ = METADATA_TYPE1;
|
||||||
|
|
||||||
|
data16 = (void*)data8;
|
||||||
|
|
||||||
|
*data16++ = display_primary_r_x;
|
||||||
|
*data16++ = display_primary_r_y;
|
||||||
|
*data16++ = display_primary_g_x;
|
||||||
|
*data16++ = display_primary_g_y;
|
||||||
|
*data16++ = display_primary_b_x;
|
||||||
|
*data16++ = display_primary_b_y;
|
||||||
|
*data16++ = white_point_x;
|
||||||
|
*data16++ = white_point_y;
|
||||||
|
|
||||||
|
*data16++ = max_luminance;
|
||||||
|
*data16++ = min_luminance;
|
||||||
|
*data16++ = max_cll;
|
||||||
|
*data16++ = max_fall;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct weston_vector {
|
||||||
|
float f[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct weston_colorspace {
|
||||||
|
struct weston_vector r, g, b;
|
||||||
|
struct weston_vector whitepoint;
|
||||||
|
const char *name;
|
||||||
|
const char *whitepoint_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct weston_colorspace hdr10;
|
||||||
|
|
||||||
|
static const struct weston_colorspace bt470m = {
|
||||||
|
.r = {{ 0.670f, 0.330f, }},
|
||||||
|
.g = {{ 0.210f, 0.710f, }},
|
||||||
|
.b = {{ 0.140f, 0.080f, }},
|
||||||
|
.whitepoint = {{ 0.3101f, 0.3162f, }},
|
||||||
|
.name = "BT.470 M",
|
||||||
|
.whitepoint_name = "C",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace bt470bg = {
|
||||||
|
.r = {{ 0.640f, 0.330f, }},
|
||||||
|
.g = {{ 0.290f, 0.600f, }},
|
||||||
|
.b = {{ 0.150f, 0.060f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "BT.470 B/G",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace smpte170m = {
|
||||||
|
.r = {{ 0.630f, 0.340f, }},
|
||||||
|
.g = {{ 0.310f, 0.595f, }},
|
||||||
|
.b = {{ 0.155f, 0.070f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "SMPTE 170M",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace smpte240m = {
|
||||||
|
.r = {{ 0.630f, 0.340f, }},
|
||||||
|
.g = {{ 0.310f, 0.595f, }},
|
||||||
|
.b = {{ 0.155f, 0.070f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "SMPTE 240M",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace bt709 = {
|
||||||
|
.r = {{ 0.640f, 0.330f, }},
|
||||||
|
.g = {{ 0.300f, 0.600f, }},
|
||||||
|
.b = {{ 0.150f, 0.060f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "BT.709",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace bt2020 = {
|
||||||
|
.r = {{ 0.708f, 0.292f, }},
|
||||||
|
.g = {{ 0.170f, 0.797f, }},
|
||||||
|
.b = {{ 0.131f, 0.046f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "BT.2020",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace srgb = {
|
||||||
|
.r = {{ 0.640f, 0.330f, }},
|
||||||
|
.g = {{ 0.300f, 0.600f, }},
|
||||||
|
.b = {{ 0.150f, 0.060f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "sRGB",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace adobergb = {
|
||||||
|
.r = {{ 0.640f, 0.330f, }},
|
||||||
|
.g = {{ 0.210f, 0.710f, }},
|
||||||
|
.b = {{ 0.150f, 0.060f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "AdobeRGB",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace dci_p3 = {
|
||||||
|
.r = {{ 0.680f, 0.320f, }},
|
||||||
|
.g = {{ 0.265f, 0.690f, }},
|
||||||
|
.b = {{ 0.150f, 0.060f, }},
|
||||||
|
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
||||||
|
.name = "DCI-P3 D65",
|
||||||
|
.whitepoint_name = "D65",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace prophotorgb = {
|
||||||
|
.r = {{ 0.7347f, 0.2653f, }},
|
||||||
|
.g = {{ 0.1596f, 0.8404f, }},
|
||||||
|
.b = {{ 0.0366f, 0.0001f, }},
|
||||||
|
.whitepoint = {{ .3457, .3585 }},
|
||||||
|
.name = "ProPhoto RGB",
|
||||||
|
.whitepoint_name = "D50",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace ciergb = {
|
||||||
|
.r = {{ 0.7347f, 0.2653f, }},
|
||||||
|
.g = {{ 0.2738f, 0.7174f, }},
|
||||||
|
.b = {{ 0.1666f, 0.0089f, }},
|
||||||
|
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }},
|
||||||
|
.name = "CIE RGB",
|
||||||
|
.whitepoint_name = "E",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace ciexyz = {
|
||||||
|
.r = {{ 1.0f, 0.0f, }},
|
||||||
|
.g = {{ 0.0f, 1.0f, }},
|
||||||
|
.b = {{ 0.0f, 0.0f, }},
|
||||||
|
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }},
|
||||||
|
.name = "CIE XYZ",
|
||||||
|
.whitepoint_name = "E",
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct weston_colorspace ap0 = {
|
||||||
|
.r = {{ 0.7347f, 0.2653f, }},
|
||||||
|
.g = {{ 0.0000f, 1.0000f, }},
|
||||||
|
.b = {{ 0.0001f, -0.0770f, }},
|
||||||
|
.whitepoint = {{ .32168f, .33767f, }},
|
||||||
|
.name = "ACES primaries #0",
|
||||||
|
.whitepoint_name = "D60",
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct weston_colorspace ap1 = {
|
||||||
|
.r = {{ 0.713f, 0.393f, }},
|
||||||
|
.g = {{ 0.165f, 0.830f, }},
|
||||||
|
.b = {{ 0.128f, 0.044f, }},
|
||||||
|
.whitepoint = {{ 0.32168f, 0.33767f, }},
|
||||||
|
.name = "ACES primaries #1",
|
||||||
|
.whitepoint_name = "D60",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_colorspace * const colorspaces[] = {
|
||||||
|
&bt470m,
|
||||||
|
&bt470bg,
|
||||||
|
&smpte170m,
|
||||||
|
&smpte240m,
|
||||||
|
&bt709,
|
||||||
|
&bt2020,
|
||||||
|
&srgb,
|
||||||
|
&adobergb,
|
||||||
|
&dci_p3,
|
||||||
|
&prophotorgb,
|
||||||
|
&ciergb,
|
||||||
|
&ciexyz,
|
||||||
|
&ap0,
|
||||||
|
&ap1,
|
||||||
|
};
|
||||||
|
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
|
||||||
|
const struct weston_colorspace *
|
||||||
|
weston_colorspace_lookup(const char *name)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_LENGTH(colorspaces); i++) {
|
||||||
|
const struct weston_colorspace *c = colorspaces[i];
|
||||||
|
|
||||||
|
if (!strcmp(c->name, name))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cleanup=0;
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t encode_xyy(float xyy)
|
||||||
|
{
|
||||||
|
return xyy * 50000;
|
||||||
|
}
|
||||||
|
static AVMasteringDisplayMetadata md_save = {0};
|
||||||
|
static AVContentLightMetadata ld_save = {0};
|
||||||
|
static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSideData *sd2)
|
||||||
|
{
|
||||||
|
drmModeAtomicReqPtr ModeReq;
|
||||||
|
struct weston_colorspace *cs;
|
||||||
|
enum hdr_metadata_eotf eotf;
|
||||||
|
struct hdr_output_metadata data;
|
||||||
|
static uint32_t blob_id = 0;
|
||||||
|
int ret,MaxCLL=1500,MaxFALL=400;
|
||||||
|
int max_lum=4000,min_lum=0050;
|
||||||
|
struct AVMasteringDisplayMetadata *md = NULL;
|
||||||
|
struct AVContentLightMetadata *ld = NULL;
|
||||||
|
|
||||||
|
if (render->hdr_metadata == -1) { // Metadata not supported
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up FFMEPG stuff
|
||||||
|
if (trc == AVCOL_TRC_BT2020_10)
|
||||||
|
trc = AVCOL_TRC_ARIB_STD_B67;
|
||||||
|
if (trc == AVCOL_TRC_UNSPECIFIED)
|
||||||
|
trc = AVCOL_TRC_BT709;
|
||||||
|
if (color == AVCOL_PRI_UNSPECIFIED)
|
||||||
|
color = AVCOL_PRI_BT709;
|
||||||
|
|
||||||
|
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
|
||||||
|
return; // nothing to do
|
||||||
|
|
||||||
|
if (sd1)
|
||||||
|
md = sd1->data;
|
||||||
|
|
||||||
|
if (sd2)
|
||||||
|
ld = sd2->data;
|
||||||
|
|
||||||
|
if (md && !memcmp(md,&md_save,sizeof(md_save)))
|
||||||
|
if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ld)
|
||||||
|
memcpy(&ld_save,ld,sizeof(ld_save));
|
||||||
|
if (md)
|
||||||
|
memcpy(&md_save,md,sizeof(md_save));
|
||||||
|
|
||||||
|
printf("Update HDR to TRC %d color %d\n",trc,color);
|
||||||
|
|
||||||
|
if (trc == AVCOL_TRC_BT2020_10)
|
||||||
|
trc = AVCOL_TRC_ARIB_STD_B67;
|
||||||
|
|
||||||
|
old_color = color;
|
||||||
|
old_trc = trc;
|
||||||
|
|
||||||
|
if (blob_id)
|
||||||
|
drmModeDestroyPropertyBlob(render->fd_drm, blob_id);
|
||||||
|
|
||||||
|
switch(trc) {
|
||||||
|
case AVCOL_TRC_BT709: // 1
|
||||||
|
case AVCOL_TRC_UNSPECIFIED: // 2
|
||||||
|
eotf = EOTF_TRADITIONAL_GAMMA_SDR;
|
||||||
|
break;
|
||||||
|
case AVCOL_TRC_BT2020_10: // 14
|
||||||
|
case AVCOL_TRC_BT2020_12:
|
||||||
|
case AVCOL_TRC_ARIB_STD_B67: // 18 HLG
|
||||||
|
eotf = EOTF_HLG;
|
||||||
|
break;
|
||||||
|
case AVCOL_TRC_SMPTE2084: // 16
|
||||||
|
eotf = EOTF_ST2084;
|
||||||
|
default:
|
||||||
|
eotf = EOTF_TRADITIONAL_GAMMA_SDR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (color) {
|
||||||
|
case AVCOL_PRI_BT709: // 1
|
||||||
|
case AVCOL_PRI_UNSPECIFIED: // 2
|
||||||
|
cs = weston_colorspace_lookup("BT.709");
|
||||||
|
break;
|
||||||
|
case AVCOL_PRI_BT2020: // 9
|
||||||
|
cs = weston_colorspace_lookup("BT.2020");
|
||||||
|
break;
|
||||||
|
case AVCOL_PRI_BT470BG: // 5
|
||||||
|
cs = weston_colorspace_lookup("BT.470 B/G"); // BT.601
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cs = weston_colorspace_lookup("BT.709");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md) { // we got Metadata
|
||||||
|
if (md->has_primaries) {
|
||||||
|
Debug(3,"Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n"
|
||||||
|
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) \n"
|
||||||
|
"min_luminance=%f, max_luminance=%f\n",
|
||||||
|
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[1][0]),
|
||||||
|
av_q2d(md->display_primaries[1][1]),
|
||||||
|
av_q2d(md->display_primaries[2][0]),
|
||||||
|
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->r.f[0] = (float)md->display_primaries[0][0].num / (float)md->display_primaries[0][0].den;
|
||||||
|
cs->r.f[1] = (float)md->display_primaries[0][1].num / (float)md->display_primaries[0][1].den;
|
||||||
|
cs->g.f[0] = (float)md->display_primaries[1][0].num / (float)md->display_primaries[1][0].den;
|
||||||
|
cs->g.f[1] = (float)md->display_primaries[1][1].num / (float)md->display_primaries[1][1].den;
|
||||||
|
cs->b.f[0] = (float)md->display_primaries[2][0].num / (float)md->display_primaries[2][0].den;
|
||||||
|
cs->b.f[1] = (float)md->display_primaries[2][1].num / (float)md->display_primaries[2][1].den;
|
||||||
|
cs->whitepoint.f[0] = (float)md->white_point[0].num / (float)md->white_point[0].den;
|
||||||
|
cs->whitepoint.f[1] = (float)md->white_point[1].num / (float)md->white_point[1].den;
|
||||||
|
}
|
||||||
|
if (md->has_luminance) {
|
||||||
|
max_lum = av_q2d(md->max_luminance);
|
||||||
|
min_lum = av_q2d(md->min_luminance) * 10000 ;
|
||||||
|
printf("max_lum %d min_lum %d\n",max_lum,min_lum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ld) {
|
||||||
|
Debug(3,"Has MaxCLL %d MaxFALL %d\n",ld->MaxCLL,ld->MaxFALL);
|
||||||
|
MaxCLL = ld->MaxCLL;
|
||||||
|
MaxFALL = ld->MaxFALL;
|
||||||
|
}
|
||||||
|
data.metadata_type = 7; // ????????????????????????
|
||||||
|
weston_hdr_metadata(&data.hdmi_metadata_type1,
|
||||||
|
encode_xyy(cs->r.f[0]),
|
||||||
|
encode_xyy(cs->r.f[1]),
|
||||||
|
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->whitepoint.f[0]),
|
||||||
|
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), &blob_id);
|
||||||
|
if (ret) {
|
||||||
|
printf("DRM: HDR metadata: failed blob create \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
|
||||||
|
render->hdr_metadata, blob_id);
|
||||||
|
if (ret) {
|
||||||
|
printf("DRM: HDR metadata: failed property set %d\n",ret);
|
||||||
|
|
||||||
|
if (blob_id)
|
||||||
|
drmModeDestroyPropertyBlob(render->fd_drm, blob_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_need_modeset = 1;
|
||||||
|
|
||||||
|
printf("DRM: HDR metadata: prop set\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -220,6 +220,18 @@ void main() \
|
|||||||
} \
|
} \
|
||||||
";
|
";
|
||||||
#endif
|
#endif
|
||||||
|
///
|
||||||
|
/// GLX check error.
|
||||||
|
///
|
||||||
|
#define GlxCheck(void)\
|
||||||
|
{\
|
||||||
|
GLenum err;\
|
||||||
|
\
|
||||||
|
if ((err = glGetError()) != GL_NO_ERROR) {\
|
||||||
|
esyslog( "video/glx: error %s:%d %d '%s'\n",__FILE__,__LINE__, err, gluErrorString(err));\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
static cShader *Shaders[stCount];
|
static cShader *Shaders[stCount];
|
||||||
|
|
||||||
void cShader::Use(void) {
|
void cShader::Use(void) {
|
||||||
@ -322,14 +334,14 @@ bool cShader::CheckCompileErrors(GLuint object, bool program) {
|
|||||||
glGetShaderiv(object, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(object, GL_COMPILE_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetShaderInfoLog(object, 1024, NULL, infoLog);
|
glGetShaderInfoLog(object, 1024, NULL, infoLog);
|
||||||
esyslog("[softhddev]:SHADER: Compile-time error: Type: %d - \n%s\n", type, infoLog);
|
esyslog("\n[softhddev]:SHADER: Compile-time error: Type: %d - \n>%s<\n", type, infoLog);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
glGetProgramiv(object, GL_LINK_STATUS, &success);
|
glGetProgramiv(object, GL_LINK_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetProgramInfoLog(object, 1024, NULL, infoLog);
|
glGetProgramInfoLog(object, 1024, NULL, infoLog);
|
||||||
esyslog("[softhddev]:SHADER: Link-time error: Type: %d - \n%s\n", type, infoLog);
|
esyslog("[softhddev]:SHADER: Link-time error: Type: %d - \n>%s<\n", type, infoLog);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +410,8 @@ void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void GlxInitopengl();
|
||||||
|
extern "C" void GlxDrawopengl();
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglFont
|
* cOglFont
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
@ -1273,8 +1286,9 @@ bool cOglCmdDrawText::Execute(void) {
|
|||||||
esyslog("[softhddev]ERROR: could not load glyph %x", sym);
|
esyslog("[softhddev]ERROR: could not load glyph %x", sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( limitX && xGlyph + g->AdvanceX() > limitX )
|
if ( limitX && xGlyph + g->AdvanceX() > limitX ) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
kerning = f->Kerning(g, prevSym);
|
kerning = f->Kerning(g, prevSym);
|
||||||
prevSym = sym;
|
prevSym = sym;
|
||||||
@ -1320,6 +1334,7 @@ cOglCmdDrawImage::cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint
|
|||||||
this->overlay = overlay;
|
this->overlay = overlay;
|
||||||
this->scaleX = scaleX;
|
this->scaleX = scaleX;
|
||||||
this->scaleY = scaleY;
|
this->scaleY = scaleY;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cOglCmdDrawImage::~cOglCmdDrawImage(void) {
|
cOglCmdDrawImage::~cOglCmdDrawImage(void) {
|
||||||
@ -1328,7 +1343,10 @@ cOglCmdDrawImage::~cOglCmdDrawImage(void) {
|
|||||||
|
|
||||||
bool cOglCmdDrawImage::Execute(void) {
|
bool cOglCmdDrawImage::Execute(void) {
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
#ifdef USE_DRM
|
||||||
|
GlxDrawopengl(); // here we need the Shared Context for upload
|
||||||
|
GlxCheck();
|
||||||
|
#endif
|
||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
@ -1347,7 +1365,10 @@ bool cOglCmdDrawImage::Execute(void) {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
#ifdef USE_DRM
|
||||||
|
GlxInitopengl(); // Reset Context
|
||||||
|
GlxCheck();
|
||||||
|
#endif
|
||||||
|
|
||||||
GLfloat x1 = x; //left
|
GLfloat x1 = x; //left
|
||||||
GLfloat y1 = y; //top
|
GLfloat y1 = y; //top
|
||||||
@ -1479,6 +1500,7 @@ bool cOglCmdDropImage::Execute(void) {
|
|||||||
cOglThread::cOglThread(cCondWait *startWait, int maxCacheSize) : cThread("oglThread") {
|
cOglThread::cOglThread(cCondWait *startWait, int maxCacheSize) : cThread("oglThread") {
|
||||||
stalled = false;
|
stalled = false;
|
||||||
memCached = 0;
|
memCached = 0;
|
||||||
|
|
||||||
this->maxCacheSize = maxCacheSize * 1024 * 1024;
|
this->maxCacheSize = maxCacheSize * 1024 * 1024;
|
||||||
this->startWait = startWait;
|
this->startWait = startWait;
|
||||||
wait = new cCondWait();
|
wait = new cCondWait();
|
||||||
@ -1491,6 +1513,7 @@ cOglThread::cOglThread(cCondWait *startWait, int maxCacheSize) : cThread("oglThr
|
|||||||
}
|
}
|
||||||
|
|
||||||
Start();
|
Start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cOglThread::~cOglThread() {
|
cOglThread::~cOglThread() {
|
||||||
@ -1689,13 +1712,12 @@ void cOglThread::Action(void) {
|
|||||||
dsyslog("[softhddev]OpenGL Worker Thread Ended");
|
dsyslog("[softhddev]OpenGL Worker Thread Ended");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int GlxInitopengl();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cOglThread::InitOpenGL(void) {
|
bool cOglThread::InitOpenGL(void) {
|
||||||
|
#ifdef USE_DRM
|
||||||
|
GlxInitopengl();
|
||||||
|
#else
|
||||||
const char *displayName = X11DisplayName;
|
const char *displayName = X11DisplayName;
|
||||||
if (!displayName) {
|
if (!displayName) {
|
||||||
displayName = getenv("DISPLAY");
|
displayName = getenv("DISPLAY");
|
||||||
@ -1728,6 +1750,7 @@ bool cOglThread::InitOpenGL(void) {
|
|||||||
esyslog("[softhddev]glewInit failed, aborting\n");
|
esyslog("[softhddev]glewInit failed, aborting\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
VertexBuffers[vbText]->EnableBlending();
|
VertexBuffers[vbText]->EnableBlending();
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@ -1790,8 +1813,9 @@ void cOglThread::Cleanup(void) {
|
|||||||
DeleteShaders();
|
DeleteShaders();
|
||||||
// glVDPAUFiniNV();
|
// glVDPAUFiniNV();
|
||||||
cOglFont::Cleanup();
|
cOglFont::Cleanup();
|
||||||
|
#ifndef USE_DRM
|
||||||
glutExit();
|
glutExit();
|
||||||
|
#endif
|
||||||
pthread_mutex_unlock(&OSDMutex);
|
pthread_mutex_unlock(&OSDMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ extern "C"
|
|||||||
/// vdr-plugin version number.
|
/// vdr-plugin version number.
|
||||||
/// Makefile extracts the version number for generating the file name
|
/// Makefile extracts the version number for generating the file name
|
||||||
/// for the distribution archive.
|
/// for the distribution archive.
|
||||||
static const char *const VERSION = "2.1.0"
|
static const char *const VERSION = "3.0.0"
|
||||||
#ifdef GIT_REV
|
#ifdef GIT_REV
|
||||||
"-GIT" GIT_REV
|
"-GIT" GIT_REV
|
||||||
#endif
|
#endif
|
||||||
@ -2472,11 +2472,17 @@ class cSoftHdDevice:public cDevice
|
|||||||
return "softhdcuvid";
|
return "softhdcuvid";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef VAAPI
|
#if defined (VAAPI) && !defined (USE_DRM)
|
||||||
virtual cString DeviceName(void) const
|
virtual cString DeviceName(void) const
|
||||||
{
|
{
|
||||||
return "softhdvaapi";
|
return "softhdvaapi";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined (VAAPI) && defined (USE_DRM)
|
||||||
|
virtual cString DeviceName(void) const
|
||||||
|
{
|
||||||
|
return "softhddrm";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
|
282
video.c
282
video.c
@ -491,7 +491,7 @@ static void GlxSetupWindow(xcb_window_t window, int width, int height, GLXContex
|
|||||||
GLXContext OSDcontext;
|
GLXContext OSDcontext;
|
||||||
#else
|
#else
|
||||||
static EGLContext eglSharedContext; ///< shared gl context
|
static EGLContext eglSharedContext; ///< shared gl context
|
||||||
|
static EGLContext eglOSDContext = NULL; ///< our gl context for the thread
|
||||||
static EGLContext eglContext; ///< our gl context
|
static EGLContext eglContext; ///< our gl context
|
||||||
static EGLConfig eglConfig;
|
static EGLConfig eglConfig;
|
||||||
static EGLDisplay eglDisplay;
|
static EGLDisplay eglDisplay;
|
||||||
@ -501,6 +501,11 @@ static int eglVersion = 2;
|
|||||||
static EGLImageKHR(EGLAPIENTRY * CreateImageKHR) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *);
|
static EGLImageKHR(EGLAPIENTRY * CreateImageKHR) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *);
|
||||||
static EGLBoolean(EGLAPIENTRY * DestroyImageKHR) (EGLDisplay, EGLImageKHR);
|
static EGLBoolean(EGLAPIENTRY * DestroyImageKHR) (EGLDisplay, EGLImageKHR);
|
||||||
static void (EGLAPIENTRY * EGLImageTargetTexture2DOES) (GLenum, GLeglImageOES);
|
static void (EGLAPIENTRY * EGLImageTargetTexture2DOES) (GLenum, GLeglImageOES);
|
||||||
|
PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
|
||||||
|
PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
|
||||||
|
PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
|
||||||
|
PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
|
||||||
|
PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
|
||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD
|
#ifdef USE_VIDEO_THREAD
|
||||||
static EGLContext eglThreadContext; ///< our gl context for the thread
|
static EGLContext eglThreadContext; ///< our gl context for the thread
|
||||||
@ -527,6 +532,14 @@ static void X11DPMSReenable(xcb_connection_t *);
|
|||||||
static void X11DPMSDisable(xcb_connection_t *);
|
static void X11DPMSDisable(xcb_connection_t *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// DRM Helper Functions
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
#ifdef USE_DRM
|
||||||
|
#include "drm.c"
|
||||||
|
#include "hdr.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Update video pts.
|
/// Update video pts.
|
||||||
///
|
///
|
||||||
@ -611,6 +624,7 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in
|
|||||||
input_aspect_ratio.num = 1;
|
input_aspect_ratio.num = 1;
|
||||||
input_aspect_ratio.den = 1;
|
input_aspect_ratio.den = 1;
|
||||||
Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num, input_aspect_ratio.den);
|
Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num, input_aspect_ratio.den);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
av_reduce(&input_aspect_ratio.num, &input_aspect_ratio.den, input_width * input_aspect_ratio.num,
|
av_reduce(&input_aspect_ratio.num, &input_aspect_ratio.den, input_width * input_aspect_ratio.num,
|
||||||
@ -621,10 +635,13 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in
|
|||||||
input_aspect_ratio.num = 1;
|
input_aspect_ratio.num = 1;
|
||||||
input_aspect_ratio.den = 1;
|
input_aspect_ratio.den = 1;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_DRM
|
||||||
|
display_aspect_ratio.num = 16;VideoWindowWidth;
|
||||||
|
display_aspect_ratio.den = 9; VideoWindowHeight;
|
||||||
|
#else
|
||||||
display_aspect_ratio.num = VideoScreen->width_in_pixels * VideoScreen->height_in_millimeters;
|
display_aspect_ratio.num = VideoScreen->width_in_pixels * VideoScreen->height_in_millimeters;
|
||||||
display_aspect_ratio.den = VideoScreen->height_in_pixels * VideoScreen->width_in_millimeters;
|
display_aspect_ratio.den = VideoScreen->height_in_pixels * VideoScreen->width_in_millimeters;
|
||||||
|
#endif
|
||||||
display_aspect_ratio = av_mul_q(input_aspect_ratio, display_aspect_ratio);
|
display_aspect_ratio = av_mul_q(input_aspect_ratio, display_aspect_ratio);
|
||||||
Debug(3, "video: aspect %d:%d Resolution %d\n", display_aspect_ratio.num, display_aspect_ratio.den, resolution);
|
Debug(3, "video: aspect %d:%d Resolution %d\n", display_aspect_ratio.num, display_aspect_ratio.den, resolution);
|
||||||
|
|
||||||
@ -843,27 +860,7 @@ char *eglErrorString(EGLint error)
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VAAPI
|
|
||||||
|
|
||||||
void OSD_get_shared_context()
|
|
||||||
{
|
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
|
||||||
EglCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSD_get_context()
|
|
||||||
{
|
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, OSDcontext);
|
|
||||||
EglCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSD_release_context()
|
|
||||||
{
|
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
||||||
// EglCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// GLX check if a GLX extension is supported.
|
/// GLX check if a GLX extension is supported.
|
||||||
@ -950,7 +947,7 @@ static void GlxSetupWindow(xcb_window_t window, int width, int height, EGLContex
|
|||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
OSD_release_context();
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1706,9 +1703,10 @@ static void CuvidPrintFrames(const CuvidDecoder * decoder)
|
|||||||
|
|
||||||
int CuvidTestSurfaces()
|
int CuvidTestSurfaces()
|
||||||
{
|
{
|
||||||
|
int i=0;
|
||||||
if (CuvidDecoders[0] != NULL) {
|
if (CuvidDecoders[0] != NULL) {
|
||||||
if (atomic_read(&CuvidDecoders[0]->SurfacesFilled) < VIDEO_SURFACES_MAX)
|
if (i = atomic_read(&CuvidDecoders[0]->SurfacesFilled) < VIDEO_SURFACES_MAX-1)
|
||||||
return 1;
|
return i;
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
@ -1749,13 +1747,14 @@ const int mpgl_preferred_gl_versions[] = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * out_context, EGLConfig * out_config)
|
static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * out_context, EGLConfig * out_config, int *bpp)
|
||||||
{
|
{
|
||||||
|
|
||||||
EGLenum api;
|
EGLenum api;
|
||||||
EGLint rend, *attribs;
|
EGLint rend, *attribs;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
|
||||||
switch (es_version) {
|
switch (es_version) {
|
||||||
case 0:
|
case 0:
|
||||||
api = EGL_OPENGL_API;
|
api = EGL_OPENGL_API;
|
||||||
@ -1803,10 +1802,11 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o
|
|||||||
EGLint num_configs;
|
EGLint num_configs;
|
||||||
|
|
||||||
attribs = attributes10;
|
attribs = attributes10;
|
||||||
|
*bpp = 10;
|
||||||
if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit
|
if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit
|
||||||
Debug(3, " 10 Bit egl Failed\n");
|
Debug(3, " 10 Bit egl Failed\n");
|
||||||
attribs = attributes8;
|
attribs = attributes8;
|
||||||
|
*bpp = 8;
|
||||||
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
||||||
num_configs = 0;
|
num_configs = 0;
|
||||||
}
|
}
|
||||||
@ -1814,6 +1814,7 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o
|
|||||||
EglCheck();
|
EglCheck();
|
||||||
Debug(3, " 10 Bit egl Failed\n");
|
Debug(3, " 10 Bit egl Failed\n");
|
||||||
attribs = attributes8;
|
attribs = attributes8;
|
||||||
|
*bpp = 8;
|
||||||
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit
|
||||||
num_configs = 0;
|
num_configs = 0;
|
||||||
}
|
}
|
||||||
@ -1873,34 +1874,41 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o
|
|||||||
|
|
||||||
make_egl()
|
make_egl()
|
||||||
{
|
{
|
||||||
|
int bpp;
|
||||||
CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
|
CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
|
||||||
DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
|
DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
|
||||||
EGLImageTargetTexture2DOES = (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
EGLImageTargetTexture2DOES = (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||||
|
eglCreateSyncKHR = (void *)eglGetProcAddress("eglCreateSyncKHR");
|
||||||
|
eglDestroySyncKHR = (void *)eglGetProcAddress("eglDestroySyncKHR");
|
||||||
|
eglWaitSyncKHR = (void *)eglGetProcAddress("eglWaitSyncKHR");
|
||||||
|
eglClientWaitSyncKHR = (void *)eglGetProcAddress("eglClientWaitSyncKHR");
|
||||||
|
eglDupNativeFenceFDANDROID = (void *)eglGetProcAddress("eglDupNativeFenceFDANDROID");
|
||||||
|
|
||||||
if (!CreateImageKHR || !DestroyImageKHR || !EGLImageTargetTexture2DOES)
|
if (!CreateImageKHR || !DestroyImageKHR || !EGLImageTargetTexture2DOES || !eglCreateSyncKHR)
|
||||||
Fatal(_("Can't get EGL Extentions\n"));
|
Fatal(_("Can't get EGL Extentions\n"));
|
||||||
|
#ifndef USE_DRM
|
||||||
eglDisplay = eglGetDisplay(XlibDisplay);
|
eglDisplay = eglGetDisplay(XlibDisplay);
|
||||||
|
#endif
|
||||||
if (!eglInitialize(eglDisplay, NULL, NULL)) {
|
if (!eglInitialize(eglDisplay, NULL, NULL)) {
|
||||||
Fatal(_("Could not initialize EGL.\n"));
|
Fatal(_("Could not initialize EGL.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create_context_cb(eglDisplay, 0, &eglContext, &eglConfig)) {
|
if (!create_context_cb(eglDisplay, 0, &eglContext, &eglConfig, &bpp)) {
|
||||||
Fatal(_("Could not create EGL Context\n"));
|
Fatal(_("Could not create EGL Context\n"));
|
||||||
}
|
}
|
||||||
int vID, n;
|
int vID, n;
|
||||||
|
|
||||||
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &vID);
|
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &vID);
|
||||||
Debug(3, "chose visual 0x%x\n", vID);
|
Debug(3, "chose visual 0x%x\n", vID);
|
||||||
|
#ifdef USE_DRM
|
||||||
|
InitBo(bpp);
|
||||||
|
#else
|
||||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType) VideoWindow, NULL);
|
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType) VideoWindow, NULL);
|
||||||
|
|
||||||
if (eglSurface == EGL_NO_SURFACE) {
|
if (eglSurface == EGL_NO_SURFACE) {
|
||||||
Fatal(_("Could not create EGL surface!\n"));
|
Fatal(_("Could not create EGL surface!\n"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
|
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
|
||||||
Fatal(_("Could not make context current!\n"));
|
Fatal(_("Could not make context current!\n"));
|
||||||
}
|
}
|
||||||
@ -2108,6 +2116,7 @@ static void CuvidExit(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CuvidDecoderN = 0;
|
CuvidDecoderN = 0;
|
||||||
|
|
||||||
Debug(3, "CuvidExit\n");
|
Debug(3, "CuvidExit\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2223,6 +2232,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi
|
|||||||
pl->component_mapping[2] = -1;
|
pl->component_mapping[2] = -1;
|
||||||
pl->component_mapping[3] = -1;
|
pl->component_mapping[3] = -1;
|
||||||
} else {
|
} else {
|
||||||
|
pl->shift_x = -0.5f; // PL_CHROMA_LEFT
|
||||||
pl->component_mapping[0] = PL_CHANNEL_U;
|
pl->component_mapping[0] = PL_CHANNEL_U;
|
||||||
pl->component_mapping[1] = PL_CHANNEL_V;
|
pl->component_mapping[1] = PL_CHANNEL_V;
|
||||||
pl->component_mapping[2] = -1;
|
pl->component_mapping[2] = -1;
|
||||||
@ -2347,7 +2357,7 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else // no PLACEBO
|
||||||
|
|
||||||
void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsigned int size_y,
|
void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsigned int size_y,
|
||||||
enum AVPixelFormat PixFmt)
|
enum AVPixelFormat PixFmt)
|
||||||
@ -2362,7 +2372,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi
|
|||||||
glXMakeCurrent(XlibDisplay, VideoWindow, glxSharedContext);
|
glXMakeCurrent(XlibDisplay, VideoWindow, glxSharedContext);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
#else
|
#else
|
||||||
OSD_get_shared_context();
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glGenBuffers(1, &vao_buffer);
|
glGenBuffers(1, &vao_buffer);
|
||||||
@ -2402,7 +2412,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
OSD_release_context();
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2442,10 +2452,10 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]);
|
vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]);
|
||||||
|
//#ifndef USE_DRM
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
|
//#endif
|
||||||
for (int n = 0; n < 2; n++) {
|
for (int n = 0; n < 2; n++) {
|
||||||
int attribs[20] = { EGL_NONE };
|
int attribs[20] = { EGL_NONE };
|
||||||
int num_attribs = 0;
|
int num_attribs = 0;
|
||||||
@ -2456,7 +2466,7 @@ void generateVAAPIImage(CuvidDecoder * decoder, int index, const AVFrame * frame
|
|||||||
ADD_PLANE_ATTRIBS(0);
|
ADD_PLANE_ATTRIBS(0);
|
||||||
|
|
||||||
decoder->images[index * 2 + n] =
|
decoder->images[index * 2 + n] =
|
||||||
CreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
CreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||||
|
|
||||||
if (!decoder->images[index * 2 + n])
|
if (!decoder->images[index * 2 + n])
|
||||||
goto esh_failed;
|
goto esh_failed;
|
||||||
@ -2519,6 +2529,7 @@ static void CuvidSyncRenderFrame(CuvidDecoder * decoder, const AVCodecContext *
|
|||||||
|
|
||||||
int push_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * frame)
|
int push_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * frame)
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret, i = 0;
|
int ret, i = 0;
|
||||||
AVFrame *filt_frame = av_frame_alloc();
|
AVFrame *filt_frame = av_frame_alloc();
|
||||||
|
|
||||||
@ -2527,12 +2538,12 @@ int push_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * fra
|
|||||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("Interlaced %d tff %d\n",frame->interlaced_frame,frame->top_field_first);
|
// printf("Interlaced %d tff %d\n",frame->interlaced_frame,frame->top_field_first);
|
||||||
/* pull filtered frames from the filtergraph */
|
/* pull filtered frames from the filtergraph */
|
||||||
while ((ret = av_buffersink_get_frame(decoder->buffersink_ctx, filt_frame)) >= 0) {
|
while ((ret = av_buffersink_get_frame(decoder->buffersink_ctx, filt_frame)) >= 0 ) {
|
||||||
filt_frame->pts /= 2;
|
filt_frame->pts /= 2;
|
||||||
decoder->Interlaced = 0;
|
decoder->Interlaced = 0;
|
||||||
// printf("vaapideint video:new %#012" PRIx64 " old %#012" PRIx64 "\n",filt_frame->pts,frame->pts);
|
// printf("vaapideint video:new %#012" PRIx64 " old %#012" PRIx64 "\n",filt_frame->pts,frame->pts);
|
||||||
CuvidSyncRenderFrame(decoder, dec_ctx, filt_frame);
|
CuvidSyncRenderFrame(decoder, dec_ctx, filt_frame);
|
||||||
filt_frame = av_frame_alloc(); // get new frame
|
filt_frame = av_frame_alloc(); // get new frame
|
||||||
|
|
||||||
@ -2744,8 +2755,7 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, AVCodecContex
|
|||||||
CuvidSetupOutput(decoder);
|
CuvidSetupOutput(decoder);
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
#endif
|
// dont show first frame
|
||||||
#ifdef PLACEBO // dont show first frame
|
|
||||||
decoder->newchannel = 1;
|
decoder->newchannel = 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
@ -3390,6 +3400,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
struct pl_color_adjustment colors;
|
struct pl_color_adjustment colors;
|
||||||
struct pl_cone_params cone;
|
struct pl_cone_params cone;
|
||||||
struct pl_tex_vk *vkp;
|
struct pl_tex_vk *vkp;
|
||||||
|
struct pl_plane *pl;
|
||||||
const struct pl_fmt *fmt;
|
const struct pl_fmt *fmt;
|
||||||
VkImage Image;
|
VkImage Image;
|
||||||
struct pl_image *img;
|
struct pl_image *img;
|
||||||
@ -3404,6 +3415,8 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
int y;
|
int y;
|
||||||
float xcropf, ycropf;
|
float xcropf, ycropf;
|
||||||
GLint texLoc;
|
GLint texLoc;
|
||||||
|
AVFrame *frame;
|
||||||
|
AVFrameSideData *FrameSideData = NULL;
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
if (level) {
|
if (level) {
|
||||||
@ -3433,9 +3446,14 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
ycropf = (float)decoder->CropY / (float)decoder->InputHeight;
|
ycropf = (float)decoder->CropY / (float)decoder->InputHeight;
|
||||||
|
|
||||||
current = decoder->SurfacesRb[decoder->SurfaceRead];
|
current = decoder->SurfacesRb[decoder->SurfaceRead];
|
||||||
|
|
||||||
if (!decoder->Closing) {
|
if (!decoder->Closing) {
|
||||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, 0, decoder->frames[current]);
|
frame = decoder->frames[current];
|
||||||
|
VideoSetPts(&decoder->PTS, decoder->Interlaced, 0, frame);
|
||||||
|
#ifdef USE_DRM
|
||||||
|
AVFrameSideData *sd1 = av_frame_get_side_data (frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
AVFrameSideData *sd2 = av_frame_get_side_data (frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
||||||
|
set_hdr_metadata(frame->color_primaries,frame->color_trc,sd1,sd2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Progressive frame
|
// Render Progressive frame
|
||||||
@ -3466,6 +3484,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
img = &decoder->pl_images[current];
|
img = &decoder->pl_images[current];
|
||||||
|
pl = &decoder->pl_images[current].planes[1];
|
||||||
|
|
||||||
memcpy(&deband, &pl_deband_default_params, sizeof(deband));
|
memcpy(&deband, &pl_deband_default_params, sizeof(deband));
|
||||||
memcpy(&render_params, &pl_render_default_params, sizeof(render_params));
|
memcpy(&render_params, &pl_render_default_params, sizeof(render_params));
|
||||||
@ -3476,6 +3495,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
img->color.primaries = PL_COLOR_PRIM_BT_601_625;
|
img->color.primaries = PL_COLOR_PRIM_BT_601_625;
|
||||||
img->color.transfer = PL_COLOR_TRC_BT_1886;
|
img->color.transfer = PL_COLOR_TRC_BT_1886;
|
||||||
img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
||||||
|
pl->shift_x = 0.0f;
|
||||||
break;
|
break;
|
||||||
case AVCOL_SPC_BT709:
|
case AVCOL_SPC_BT709:
|
||||||
case AVCOL_SPC_UNSPECIFIED: // comes with UHD
|
case AVCOL_SPC_UNSPECIFIED: // comes with UHD
|
||||||
@ -3485,6 +3505,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
// img->color.transfer = PL_COLOR_TRC_BT_1886;
|
// img->color.transfer = PL_COLOR_TRC_BT_1886;
|
||||||
// img->color.light = PL_COLOR_LIGHT_SCENE_709_1886;
|
// img->color.light = PL_COLOR_LIGHT_SCENE_709_1886;
|
||||||
// img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
// img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
||||||
|
pl->shift_x = -0.5f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVCOL_SPC_BT2020_NCL:
|
case AVCOL_SPC_BT2020_NCL:
|
||||||
@ -3492,7 +3513,8 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
memcpy(&img->repr, &pl_color_repr_uhdtv, sizeof(struct pl_color_repr));
|
memcpy(&img->repr, &pl_color_repr_uhdtv, sizeof(struct pl_color_repr));
|
||||||
memcpy(&img->color, &pl_color_space_bt2020_hlg, sizeof(struct pl_color_space));
|
memcpy(&img->color, &pl_color_space_bt2020_hlg, sizeof(struct pl_color_space));
|
||||||
deband.grain = 0.0f; // no grain in HDR
|
deband.grain = 0.0f; // no grain in HDR
|
||||||
img->color.sig_scale = 2.0f;
|
img->color.sig_scale = 1.0f;
|
||||||
|
pl->shift_x = -0.5f;
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
render_params.peak_detect_params = NULL;
|
render_params.peak_detect_params = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -3507,6 +3529,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
|
|||||||
// img->color.primaries = PL_COLOR_PRIM_BT_709;
|
// img->color.primaries = PL_COLOR_PRIM_BT_709;
|
||||||
// img->color.transfer = PL_COLOR_TRC_BT_1886;
|
// img->color.transfer = PL_COLOR_TRC_BT_1886;
|
||||||
// img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
// img->color.light = PL_COLOR_LIGHT_DISPLAY;
|
||||||
|
pl->shift_x = -0.5f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Source crop
|
// Source crop
|
||||||
@ -3696,6 +3719,8 @@ static void CuvidDisplayFrame(void)
|
|||||||
int RTS_flag;
|
int RTS_flag;
|
||||||
int valid_frame = 0;
|
int valid_frame = 0;
|
||||||
float ldiff;
|
float ldiff;
|
||||||
|
static int first = 1;
|
||||||
|
float turnaround;
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
@ -3703,13 +3728,14 @@ static void CuvidDisplayFrame(void)
|
|||||||
struct pl_swapchain_frame frame;
|
struct pl_swapchain_frame frame;
|
||||||
struct pl_render_target target;
|
struct pl_render_target target;
|
||||||
bool ok;
|
bool ok;
|
||||||
static int first = 1;
|
|
||||||
VkImage Image;
|
VkImage Image;
|
||||||
const struct pl_fmt *fmt;
|
const struct pl_fmt *fmt;
|
||||||
const float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
const float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PLACEBO
|
#ifndef PLACEBO
|
||||||
|
|
||||||
if (CuvidDecoderN)
|
if (CuvidDecoderN)
|
||||||
CuvidDecoders[0]->Frameproc = (float)(GetusTicks() - last_time) / 1000000.0;
|
CuvidDecoders[0]->Frameproc = (float)(GetusTicks() - last_time) / 1000000.0;
|
||||||
|
|
||||||
@ -3723,7 +3749,7 @@ static void CuvidDisplayFrame(void)
|
|||||||
#endif
|
#endif
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
#else
|
#else // PLACEBO
|
||||||
|
|
||||||
if (CuvidDecoderN) {
|
if (CuvidDecoderN) {
|
||||||
ldiff = (float)(GetusTicks() - round_time) / 1000000.0;
|
ldiff = (float)(GetusTicks() - round_time) / 1000000.0;
|
||||||
@ -3826,7 +3852,7 @@ static void CuvidDisplayFrame(void)
|
|||||||
decoder->StartCounter++;
|
decoder->StartCounter++;
|
||||||
|
|
||||||
filled = atomic_read(&decoder->SurfacesFilled);
|
filled = atomic_read(&decoder->SurfacesFilled);
|
||||||
|
//printf("Filled %d\n",filled);
|
||||||
// need 1 frame for progressive, 3 frames for interlaced
|
// need 1 frame for progressive, 3 frames for interlaced
|
||||||
if (filled < 1 + 2 * decoder->Interlaced) {
|
if (filled < 1 + 2 * decoder->Interlaced) {
|
||||||
// FIXME: rewrite MixVideo to support less surfaces
|
// FIXME: rewrite MixVideo to support less surfaces
|
||||||
@ -3882,6 +3908,8 @@ static void CuvidDisplayFrame(void)
|
|||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
GlxCheck();
|
||||||
|
|
||||||
if (OsdShown == 1) {
|
if (OsdShown == 1) {
|
||||||
if (OSDtexture)
|
if (OSDtexture)
|
||||||
glDeleteTextures(1, &OSDtexture);
|
glDeleteTextures(1, &OSDtexture);
|
||||||
@ -3889,15 +3917,19 @@ static void CuvidDisplayFrame(void)
|
|||||||
glGenTextures(1, &OSDtexture);
|
glGenTextures(1, &OSDtexture);
|
||||||
glBindTexture(GL_TEXTURE_2D, OSDtexture);
|
glBindTexture(GL_TEXTURE_2D, OSDtexture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, OSDxsize, OSDysize, 0, GL_RGBA, GL_UNSIGNED_BYTE, posd);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, OSDxsize, OSDysize, 0, GL_RGBA, GL_UNSIGNED_BYTE, posd);
|
||||||
|
GlxCheck();
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
GlxCheck();
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glFlush();
|
glFlush();
|
||||||
pthread_mutex_unlock(&OSDMutex);
|
pthread_mutex_unlock(&OSDMutex);
|
||||||
OsdShown = 2;
|
OsdShown = 2;
|
||||||
}
|
}
|
||||||
|
GlxCheck();
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
GlxCheck();
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
@ -3925,6 +3957,7 @@ static void CuvidDisplayFrame(void)
|
|||||||
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -3938,14 +3971,18 @@ static void CuvidDisplayFrame(void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
#else
|
#else // not PLACEBO
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
glXGetVideoSyncSGI(&Count); // get current frame
|
glXGetVideoSyncSGI(&Count); // get current frame
|
||||||
glXSwapBuffers(XlibDisplay, VideoWindow);
|
glXSwapBuffers(XlibDisplay, VideoWindow);
|
||||||
glXMakeCurrent(XlibDisplay, None, NULL);
|
glXMakeCurrent(XlibDisplay, None, NULL);
|
||||||
#else
|
#else
|
||||||
|
#ifndef USE_DRM
|
||||||
eglSwapBuffers(eglDisplay, eglSurface);
|
eglSwapBuffers(eglDisplay, eglSurface);
|
||||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
#else
|
||||||
|
drm_swap_buffers();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4326,9 +4363,7 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
allfull = 1;
|
allfull = 1;
|
||||||
decoded = 0;
|
decoded = 0;
|
||||||
|
|
||||||
#ifndef PLACEBO
|
|
||||||
VideoThreadLock();
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < CuvidDecoderN; ++i) {
|
for (i = 0; i < CuvidDecoderN; ++i) {
|
||||||
|
|
||||||
decoder = CuvidDecoders[i];
|
decoder = CuvidDecoders[i];
|
||||||
@ -4343,9 +4378,9 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
allfull = 0;
|
allfull = 0;
|
||||||
err = VideoDecodeInput(decoder->Stream);
|
err = VideoDecodeInput(decoder->Stream);
|
||||||
} else {
|
} else {
|
||||||
#ifdef PLACEBO
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
#endif
|
|
||||||
err = VideoPollInput(decoder->Stream);
|
err = VideoPollInput(decoder->Stream);
|
||||||
}
|
}
|
||||||
// decoder can be invalid here
|
// decoder can be invalid here
|
||||||
@ -4358,26 +4393,24 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
decoder->Closing = -1;
|
decoder->Closing = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef PLACEBO
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
#endif
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
decoded = 1;
|
decoded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PLACEBO
|
|
||||||
VideoThreadUnlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!decoded) { // nothing decoded, sleep
|
if (!decoded) { // nothing decoded, sleep
|
||||||
// FIXME: sleep on wakeup
|
// FIXME: sleep on wakeup
|
||||||
usleep(1 * 1000);
|
usleep(1 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLACEBO
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
#endif
|
|
||||||
|
|
||||||
// all decoder buffers are full
|
// all decoder buffers are full
|
||||||
// and display is not preempted
|
// and display is not preempted
|
||||||
@ -4390,11 +4423,6 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef PLACEBO
|
|
||||||
VideoThreadLock();
|
|
||||||
CuvidSyncDisplayFrame();
|
|
||||||
VideoThreadUnlock();
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5103,15 +5131,15 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
glxThreadContext = glXCreateContext(XlibDisplay, GlxVisualInfo, glxSharedContext, GL_TRUE);
|
glxThreadContext = glXCreateContext(XlibDisplay, GlxVisualInfo, glxSharedContext, GL_TRUE);
|
||||||
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight, glxThreadContext);
|
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight, glxThreadContext);
|
||||||
#else
|
#else
|
||||||
|
#if 0
|
||||||
eglThreadContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);
|
eglThreadContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);
|
||||||
|
|
||||||
if (!eglThreadContext) {
|
if (!eglThreadContext) {
|
||||||
EglCheck();
|
EglCheck();
|
||||||
Fatal(_("video/egl: can't create thread egl context\n"));
|
Fatal(_("video/egl: can't create thread egl context\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
sleep(2);
|
sleep(2);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -5119,26 +5147,34 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
#ifndef PLACEBO
|
|
||||||
VideoPollEvent();
|
|
||||||
#endif
|
|
||||||
VideoUsedModule->DisplayHandlerThread();
|
VideoUsedModule->DisplayHandlerThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLACEBO
|
|
||||||
static void *VideoHandlerThread(void *dummy)
|
static void *VideoHandlerThread(void *dummy)
|
||||||
{
|
{
|
||||||
|
EGLint contextAttrs[] = {
|
||||||
uint64_t first_time;
|
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
prctl(PR_SET_NAME, "cuvid video display", 0, 0, 0);
|
prctl(PR_SET_NAME, "cuvid video display", 0, 0, 0);
|
||||||
|
#ifdef PLACEBO
|
||||||
InitPlacebo();
|
InitPlacebo();
|
||||||
|
|
||||||
pthread_cleanup_push(delete_placebo, NULL);
|
pthread_cleanup_push(delete_placebo, NULL);
|
||||||
|
|
||||||
|
#else
|
||||||
|
eglThreadContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);
|
||||||
|
if (!eglThreadContext) {
|
||||||
|
EglCheck();
|
||||||
|
Fatal(_("video/egl: can't create thread egl context\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext);
|
||||||
|
#endif
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
@ -5149,15 +5185,14 @@ static void *VideoHandlerThread(void *dummy)
|
|||||||
|
|
||||||
// first_time = GetusTicks();
|
// first_time = GetusTicks();
|
||||||
CuvidSyncDisplayFrame();
|
CuvidSyncDisplayFrame();
|
||||||
|
|
||||||
// printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000);
|
// printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000);
|
||||||
}
|
}
|
||||||
|
#ifdef PLACEBO
|
||||||
pthread_cleanup_pop(NULL);
|
pthread_cleanup_pop(NULL);
|
||||||
|
#endif
|
||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
///
|
///
|
||||||
/// Initialize video threads.
|
/// Initialize video threads.
|
||||||
///
|
///
|
||||||
@ -5176,12 +5211,9 @@ static void VideoThreadInit(void)
|
|||||||
pthread_mutex_init(&OSDMutex, NULL);
|
pthread_mutex_init(&OSDMutex, NULL);
|
||||||
pthread_cond_init(&VideoWakeupCond, NULL);
|
pthread_cond_init(&VideoWakeupCond, NULL);
|
||||||
pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
|
pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
|
||||||
#ifdef PLACEBO
|
|
||||||
pthread_create(&VideoDisplayThread, NULL, VideoHandlerThread, NULL);
|
|
||||||
#else
|
|
||||||
|
|
||||||
VideoDisplayThread = 0;
|
pthread_create(&VideoDisplayThread, NULL, VideoHandlerThread, NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -5241,9 +5273,11 @@ static void VideoThreadExit(void)
|
|||||||
///
|
///
|
||||||
void VideoDisplayWakeup(void)
|
void VideoDisplayWakeup(void)
|
||||||
{
|
{
|
||||||
|
#ifndef USE_DRM
|
||||||
if (!XlibDisplay) { // not yet started
|
if (!XlibDisplay) { // not yet started
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!VideoThread) { // start video thread, if needed
|
if (!VideoThread) { // start video thread, if needed
|
||||||
VideoThreadInit();
|
VideoThreadInit();
|
||||||
@ -6444,6 +6478,10 @@ void VideoInit(const char *display_name)
|
|||||||
xcb_screen_iterator_t screen_iter;
|
xcb_screen_iterator_t screen_iter;
|
||||||
xcb_screen_t const *screen;
|
xcb_screen_t const *screen;
|
||||||
|
|
||||||
|
#ifdef USE_DRM
|
||||||
|
VideoInitDrm();
|
||||||
|
#else
|
||||||
|
|
||||||
if (XlibDisplay) { // allow multiple calls
|
if (XlibDisplay) { // allow multiple calls
|
||||||
Debug(3, "video: x11 already setup\n");
|
Debug(3, "video: x11 already setup\n");
|
||||||
return;
|
return;
|
||||||
@ -6526,7 +6564,7 @@ void VideoInit(const char *display_name)
|
|||||||
VideoCreateWindow(screen->root, screen->root_visual, screen->root_depth);
|
VideoCreateWindow(screen->root, screen->root_visual, screen->root_depth);
|
||||||
|
|
||||||
Debug(3, "video: window prepared\n");
|
Debug(3, "video: window prepared\n");
|
||||||
|
#endif
|
||||||
//
|
//
|
||||||
// prepare hardware decoder
|
// prepare hardware decoder
|
||||||
//
|
//
|
||||||
@ -6545,6 +6583,8 @@ void VideoInit(const char *display_name)
|
|||||||
VideoUsedModule = &NoopModule;
|
VideoUsedModule = &NoopModule;
|
||||||
|
|
||||||
found:
|
found:
|
||||||
|
;
|
||||||
|
#ifndef USE_DRM
|
||||||
// FIXME: make it configurable from gui
|
// FIXME: make it configurable from gui
|
||||||
if (getenv("NO_MPEG_HW")) {
|
if (getenv("NO_MPEG_HW")) {
|
||||||
VideoHardwareDecoder = 1;
|
VideoHardwareDecoder = 1;
|
||||||
@ -6558,7 +6598,7 @@ void VideoInit(const char *display_name)
|
|||||||
|
|
||||||
//xcb_prefetch_maximum_request_length(Connection);
|
//xcb_prefetch_maximum_request_length(Connection);
|
||||||
xcb_flush(Connection);
|
xcb_flush(Connection);
|
||||||
|
#endif
|
||||||
#ifdef PLACEBO_
|
#ifdef PLACEBO_
|
||||||
InitPlacebo();
|
InitPlacebo();
|
||||||
#endif
|
#endif
|
||||||
@ -6570,6 +6610,7 @@ void VideoInit(const char *display_name)
|
|||||||
///
|
///
|
||||||
void VideoExit(void)
|
void VideoExit(void)
|
||||||
{
|
{
|
||||||
|
#ifndef USE_DRM
|
||||||
if (!XlibDisplay) { // no init or failed
|
if (!XlibDisplay) { // no init or failed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -6578,7 +6619,7 @@ void VideoExit(void)
|
|||||||
//
|
//
|
||||||
X11DPMSReenable(Connection);
|
X11DPMSReenable(Connection);
|
||||||
X11SuspendScreenSaver(Connection, 0);
|
X11SuspendScreenSaver(Connection, 0);
|
||||||
|
#endif
|
||||||
VideoUsedModule->Exit();
|
VideoUsedModule->Exit();
|
||||||
VideoUsedModule = &NoopModule;
|
VideoUsedModule = &NoopModule;
|
||||||
|
|
||||||
@ -6591,7 +6632,7 @@ void VideoExit(void)
|
|||||||
EglExit(); // delete all contexts
|
EglExit(); // delete all contexts
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef USE_DRM
|
||||||
//
|
//
|
||||||
// FIXME: cleanup.
|
// FIXME: cleanup.
|
||||||
//
|
//
|
||||||
@ -6624,43 +6665,34 @@ void VideoExit(void)
|
|||||||
XlibDisplay = NULL;
|
XlibDisplay = NULL;
|
||||||
Connection = 0;
|
Connection = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_DRM
|
||||||
|
drm_clean_up();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int GlxInitopengl()
|
#ifdef USE_DRM
|
||||||
{
|
int GlxInitopengl () {
|
||||||
#ifndef PLACEBO
|
|
||||||
#ifdef VAAPI
|
|
||||||
EGLint contextAttrs[] = {
|
EGLint contextAttrs[] = {
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
while (eglSharedContext == NULL || eglContext == NULL) {
|
if (!eglOSDContext) {
|
||||||
sleep(1); // wait until Init from video thread is ready
|
eglOSDContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);
|
||||||
|
if (!eglOSDContext) {
|
||||||
|
EglCheck();
|
||||||
|
Fatal(_("video/egl: can't create thread egl context\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglOSDContext);
|
||||||
#ifdef CUVID
|
return;
|
||||||
while (glxSharedContext == NULL || glxContext == NULL) {
|
|
||||||
sleep(1); // wait until Init from video thread is ready
|
|
||||||
}
|
|
||||||
OSDcontext = glXCreateContext(XlibDisplay, GlxVisualInfo, glxSharedContext, GL_TRUE);
|
|
||||||
#else
|
|
||||||
OSDcontext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);
|
|
||||||
#endif
|
|
||||||
if (!OSDcontext) {
|
|
||||||
Debug(3, "video/osd: can't create OSD egl context\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Debug(3, "Create OSD egl context\n");
|
|
||||||
#ifdef VAAPI
|
|
||||||
// eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, OSDcontext);
|
|
||||||
// EglCheck();
|
|
||||||
#else
|
|
||||||
glXMakeCurrent(XlibDisplay, VideoWindow, OSDcontext);
|
|
||||||
GlxCheck();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GlxDrawopengl () {
|
||||||
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user