mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2025-03-01 10:39:28 +00:00
Compare commits
97 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
20f1bd45e6 | ||
|
7a7e09ff7a | ||
|
c4a660ede2 | ||
|
8e495266e2 | ||
|
f27e4fb35f | ||
|
e14ea73a00 | ||
|
72cb77f771 | ||
|
c679d812d1 | ||
|
47b461ab46 | ||
|
8629946041 | ||
|
a222f6a1d5 | ||
|
b51589aaa9 | ||
|
c3af54aae0 | ||
|
7e387fa3f1 | ||
|
f3e5a14fdf | ||
|
aa0c2f80e4 | ||
|
215f251572 | ||
|
a425ec94e0 | ||
|
91961bdffe | ||
|
f741dff042 | ||
|
7a31761c89 | ||
|
d5ca73c22f | ||
|
6704b2ca5a | ||
|
e0bbaceec0 | ||
|
45043b9ffc | ||
|
a56b3737c7 | ||
|
e59eeba0d2 | ||
|
838dfab45b | ||
|
ddd44e6f62 | ||
|
1390139cbd | ||
|
f72653c3c1 | ||
|
4b9cd22405 | ||
|
38bda0c834 | ||
|
45c86f12dd | ||
|
e2e9ae94d7 | ||
|
4837f7fa35 | ||
|
7f054f8320 | ||
|
ad7acde1f4 | ||
|
e5c48a4bb7 | ||
|
fb67617d63 | ||
|
8aa807eec6 | ||
|
0621ed064d | ||
|
9219f06c5a | ||
|
4e96489e35 | ||
|
65017da5ac | ||
|
7b41b9b45a | ||
|
58c39d51f4 | ||
|
d78e905411 | ||
|
7b10c2d0a3 | ||
|
9714824a5a | ||
|
3e9b909685 | ||
|
464f7de014 | ||
|
da33b90f94 | ||
|
90194d4b6c | ||
|
45a83eaa3f | ||
|
37f87e2511 | ||
|
bd9184db01 | ||
|
101bffd01f | ||
|
43085a3608 | ||
|
3de7a17105 | ||
|
c229e77151 | ||
|
af370721d4 | ||
|
79fa8efc6a | ||
|
d5dec38d62 | ||
|
74847c9bed | ||
|
115f3b1fce | ||
|
ff16beb515 | ||
|
25f70cd820 | ||
|
16c734b9e3 | ||
|
6e2bcd73de | ||
|
fefd3e83f6 | ||
|
5c6514929d | ||
|
ce71019f44 | ||
|
f24ae68a8d | ||
|
cf1a661c7b | ||
|
a072caf133 | ||
|
43135c43bc | ||
|
177e44de98 | ||
|
987ff6ba12 | ||
|
1878eaec88 | ||
|
3ca2a06e9d | ||
|
cc099e24ea | ||
|
59a82d409e | ||
|
eabbbcb442 | ||
|
8f96c06595 | ||
|
267dccf87a | ||
|
2562c4eac5 | ||
|
017ad3f61b | ||
|
dfeb75cc51 | ||
|
b2247ebb9b | ||
|
8c89787269 | ||
|
a4fe3aa31c | ||
|
fde863adaf | ||
|
891d432536 | ||
|
c09bad125d | ||
|
e9cfe530ba | ||
|
8018f7d921 |
6
.clang-format
Normal file
6
.clang-format
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
UseTab: Never
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentCaseLabels: true
|
||||||
|
ColumnLimit: 119
|
37
.indent.pro
vendored
37
.indent.pro
vendored
@@ -1,37 +0,0 @@
|
|||||||
--blank-lines-before-block-comments
|
|
||||||
--blank-lines-after-declarations
|
|
||||||
--blank-lines-after-procedures
|
|
||||||
--no-blank-lines-after-commas
|
|
||||||
--braces-on-if-line
|
|
||||||
--no-blank-before-sizeof
|
|
||||||
--comment-indentation41
|
|
||||||
--declaration-comment-column41
|
|
||||||
--no-comment-delimiters-on-blank-lines
|
|
||||||
--swallow-optional-blank-lines
|
|
||||||
--dont-format-comments
|
|
||||||
--parameter-indentation4
|
|
||||||
--indent-level4
|
|
||||||
--line-comments-indentation0
|
|
||||||
--cuddle-else
|
|
||||||
--cuddle-do-while
|
|
||||||
--brace-indent0
|
|
||||||
--case-brace-indentation0
|
|
||||||
//--start-left-side-of-comments
|
|
||||||
--leave-preprocessor-space
|
|
||||||
//--continuation-indentation8
|
|
||||||
--case-indentation4
|
|
||||||
--else-endif-column0
|
|
||||||
--no-space-after-casts
|
|
||||||
--declaration-indentation1
|
|
||||||
--dont-line-up-parentheses
|
|
||||||
--no-space-after-function-call-names
|
|
||||||
--space-special-semicolon
|
|
||||||
--tab-size4
|
|
||||||
--no-tabs
|
|
||||||
--line-length119
|
|
||||||
--comment-line-length119
|
|
||||||
--honour-newlines
|
|
||||||
--dont-break-procedure-type
|
|
||||||
--break-before-boolean-operator
|
|
||||||
--continuation-indentation4
|
|
||||||
--ignore-newlines
|
|
119
Makefile
119
Makefile
@@ -22,26 +22,18 @@ CUVID ?= 0
|
|||||||
# only valid for VAAPI
|
# only valid for VAAPI
|
||||||
DRM ?= 0
|
DRM ?= 0
|
||||||
|
|
||||||
|
|
||||||
# use libplacebo -
|
# use libplacebo -
|
||||||
# available for all decoders but for DRM you need LIBPLACEBO_GL
|
# available for all decoders but for DRM you need LIBPLACEBO_GL
|
||||||
LIBPLACEBO ?= 1
|
LIBPLACEBO ?= 0
|
||||||
LIBPLACEBO_GL ?= 0
|
LIBPLACEBO_GL ?= 0
|
||||||
|
|
||||||
# use YADIF deint - only available with cuvid
|
# use YADIF deint - only available with cuvid
|
||||||
#YADIF=1
|
YADIF = 1
|
||||||
|
|
||||||
# use gamma correction
|
# use gamma correction
|
||||||
#GAMMA ?= 0
|
#GAMMA ?= 0
|
||||||
|
|
||||||
|
CONFIG := -DDEBUG # remove '#' to enable debug output
|
||||||
|
|
||||||
CONFIG := #-DDEBUG # remove # to enable debug output
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------- no more config needed past this point--------------------------------
|
#--------------------- no more config needed past this point--------------------------------
|
||||||
|
|
||||||
@@ -61,7 +53,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
ifeq ($(DRM),1)
|
ifeq ($(DRM),1)
|
||||||
$(error Missmatch in Plugin selection)
|
$(error Mismatch in Plugin selection)
|
||||||
exit 1;
|
exit 1;
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -69,42 +61,27 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
ifeq ($(VAAPI),1)
|
ifeq ($(VAAPI),1)
|
||||||
$(error Missmatch in Plugin selection)
|
$(error Mismatch in Plugin selection)
|
||||||
exit 1;
|
exit 1;
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif # MAKECMDGOALS!=indent
|
endif # MAKECMDGOALS!=indent
|
||||||
endif # MAKECMDGOALS!=clean
|
endif # MAKECMDGOALS!=clean
|
||||||
|
|
||||||
|
|
||||||
#--------------------------
|
#--------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PLUGIN = softhdcuvid
|
PLUGIN = softhdcuvid
|
||||||
|
|
||||||
# support OPENGLOSD always needed
|
# support OPENGLOSD always needed
|
||||||
OPENGLOSD=1
|
OPENGLOSD=1
|
||||||
|
|
||||||
# support alsa audio output module
|
|
||||||
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
|
|
||||||
# support OSS audio output module
|
|
||||||
OSS ?= 1
|
|
||||||
|
|
||||||
# use DMPS
|
# use DMPS
|
||||||
SCREENSAVER=1
|
SCREENSAVER=1
|
||||||
|
|
||||||
OPENGL=1
|
OPENGL=1
|
||||||
|
|
||||||
# use ffmpeg libswresample
|
|
||||||
SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1)
|
|
||||||
SWRESAMPLE = 1
|
|
||||||
|
|
||||||
# use libav libavresample
|
|
||||||
#ifneq ($(SWRESAMPLE),1)
|
|
||||||
#AVRESAMPLE ?= $(shell pkg-config --exists libavresample && echo 1#)
|
|
||||||
#AVRESAMPLE = 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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
|
||||||
@@ -154,20 +131,8 @@ APIVERSION = $(call PKGCFG,apiversion)
|
|||||||
|
|
||||||
-include $(PLGCFG)
|
-include $(PLGCFG)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Parse softhddevice config
|
### Parse softhddevice config
|
||||||
|
|
||||||
ifeq ($(ALSA),1)
|
|
||||||
CONFIG += -DUSE_ALSA
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags alsa)
|
|
||||||
LIBS += $(shell pkg-config --libs alsa)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OSS),1)
|
|
||||||
CONFIG += -DUSE_OSS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OPENGL),1)
|
ifeq ($(OPENGL),1)
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
#_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||||
#LIBS += $(shell pkg-config --libs libva-glx)
|
#LIBS += $(shell pkg-config --libs libva-glx)
|
||||||
@@ -193,30 +158,29 @@ endif
|
|||||||
|
|
||||||
ifeq ($(LIBPLACEBO_GL),1)
|
ifeq ($(LIBPLACEBO_GL),1)
|
||||||
CONFIG += -DPLACEBO_GL -DPLACEBO
|
CONFIG += -DPLACEBO_GL -DPLACEBO
|
||||||
LIBS += -lepoxy
|
_CFLAGS += $(shell pkg-config --cflags libplacebo)
|
||||||
LIBS += -lplacebo
|
LIBS += $(shell pkg-config --libs epoxy libplacebo)
|
||||||
else
|
else
|
||||||
LIBS += -lEGL
|
LIBS += $(shell pkg-config --libs egl)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(LIBPLACEBO),1)
|
ifeq ($(LIBPLACEBO),1)
|
||||||
CONFIG += -DPLACEBO
|
CONFIG += -DPLACEBO
|
||||||
LIBS += -lEGL
|
_CFLAGS += $(shell pkg-config --cflags libplacebo)
|
||||||
LIBS += -lplacebo
|
LIBS += $(shell pkg-config --libs egl libplacebo)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DRM),1)
|
ifeq ($(DRM),1)
|
||||||
PLUGIN = softhddrm
|
PLUGIN = softhddrm
|
||||||
CONFIG += -DUSE_DRM -DVAAPI
|
CONFIG += -DUSE_DRM -DVAAPI
|
||||||
_CFLAGS += $(shell pkg-config --cflags libdrm)
|
_CFLAGS += $(shell pkg-config --cflags libdrm)
|
||||||
LIBS += -lgbm -ldrm -lEGL
|
LIBS += $(shell pkg-config --libs egl gbm libdrm)
|
||||||
endif
|
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
|
||||||
LIBS += -lEGL -lGL
|
LIBS += $(shell pkg-config --libs egl gl)
|
||||||
ifeq ($(YADIF),1)
|
ifeq ($(YADIF),1)
|
||||||
CONFIG += -DYADIF # Yadif only with CUVID
|
CONFIG += -DYADIF # Yadif only with CUVID
|
||||||
endif
|
endif
|
||||||
@@ -226,7 +190,6 @@ ifeq ($(GAMMA),1)
|
|||||||
CONFIG += -DGAMMA
|
CONFIG += -DGAMMA
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||||
PACKAGE = vdr-$(ARCHIVE)
|
PACKAGE = vdr-$(ARCHIVE)
|
||||||
|
|
||||||
@@ -234,15 +197,16 @@ PACKAGE = vdr-$(ARCHIVE)
|
|||||||
|
|
||||||
SOFILE = libvdr-$(PLUGIN).so
|
SOFILE = libvdr-$(PLUGIN).so
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that libswresample is available
|
# Test that libswresample is available
|
||||||
#
|
#
|
||||||
#ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
||||||
# $(warning ******************************************************************)
|
$(warning ******************************************************************)
|
||||||
# $(warning 'libswresample' not found!)
|
$(warning 'libswresample' not found!)
|
||||||
# $(error ******************************************************************)
|
$(error ******************************************************************)
|
||||||
#endif
|
endif
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
||||||
|
LIBS += $(shell pkg-config --libs libswresample)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test and set config for libavutil
|
# Test and set config for libavutil
|
||||||
@@ -277,22 +241,22 @@ endif
|
|||||||
_CFLAGS += $(shell pkg-config --cflags libavcodec)
|
_CFLAGS += $(shell pkg-config --cflags libavcodec)
|
||||||
LIBS += $(shell pkg-config --libs libavcodec libavfilter)
|
LIBS += $(shell pkg-config --libs libavcodec libavfilter)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test and set config for alsa
|
||||||
|
#
|
||||||
|
ifneq (exists, $(shell pkg-config alsa && echo exists))
|
||||||
|
$(warning ******************************************************************)
|
||||||
|
$(warning 'alsa' not found!)
|
||||||
|
$(error ******************************************************************)
|
||||||
|
endif
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags alsa)
|
||||||
|
LIBS += $(shell pkg-config --libs alsa)
|
||||||
|
|
||||||
ifeq ($(SCREENSAVER),1)
|
ifeq ($(SCREENSAVER),1)
|
||||||
CONFIG += -DUSE_SCREENSAVER
|
CONFIG += -DUSE_SCREENSAVER
|
||||||
_CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms)
|
_CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms)
|
||||||
LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms)
|
LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms)
|
||||||
endif
|
endif
|
||||||
ifeq ($(SWRESAMPLE),1)
|
|
||||||
CONFIG += -DUSE_SWRESAMPLE
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
|
||||||
LIBS += $(shell pkg-config --libs libswresample)
|
|
||||||
endif
|
|
||||||
ifeq ($(AVRESAMPLE),1)
|
|
||||||
CONFIG += -DUSE_AVRESAMPLE
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags libavresample)
|
|
||||||
LIBS += $(shell pkg-config --libs libavresample)
|
|
||||||
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)
|
||||||
@@ -309,6 +273,8 @@ LIBS += -lcuda -lnvcuvid
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS += -lGLEW -lGLU -ldl -lglut
|
LIBS += -lGLEW -lGLU -ldl -lglut
|
||||||
|
#LIBS += -ldl $(shell pkg-config --libs glew glu glut)
|
||||||
|
|
||||||
### Includes and Defines (add further entries here):
|
### Includes and Defines (add further entries here):
|
||||||
|
|
||||||
INCLUDES +=
|
INCLUDES +=
|
||||||
@@ -319,10 +285,9 @@ 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 -W -Wextra -Winit-self -Werror=overloaded-virtual -Wno-unused-parameter
|
-g -W -Wextra -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
|
||||||
|
|
||||||
|
|
||||||
### The object files (add further files here):
|
### The object files (add further files here):
|
||||||
|
|
||||||
@@ -383,7 +348,6 @@ install-i18n: $(I18Nmsgs)
|
|||||||
|
|
||||||
$(OBJS): Makefile
|
$(OBJS): Makefile
|
||||||
|
|
||||||
|
|
||||||
$(SOFILE): $(OBJS) shaders.h
|
$(SOFILE): $(OBJS) shaders.h
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
|
|
||||||
@@ -404,17 +368,14 @@ clean:
|
|||||||
@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot
|
@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot
|
||||||
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
||||||
|
|
||||||
## Private Targets:
|
|
||||||
|
|
||||||
HDRS = $(wildcard *.h)
|
HDRS = $(wildcard *.h)
|
||||||
|
|
||||||
indent:
|
indent:
|
||||||
for i in $(SRCS) $(HDRS); do \
|
for i in $(SRCS) drm.c hdr.c $(HDRS); do \
|
||||||
indent $$i; \
|
clang-format -i $$i; \
|
||||||
unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \
|
|
||||||
mv $$i.up $$i; \
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
## Private Targets:
|
||||||
|
|
||||||
video_test: video.c Makefile
|
video_test: video.c Makefile
|
||||||
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \
|
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \
|
||||||
$(LIBS) -o $@
|
$(LIBS) -o $@
|
||||||
|
71
README.md
71
README.md
@@ -25,20 +25,18 @@ A software and GPU emulated UHD output device plugin for VDR.
|
|||||||
|
|
||||||
o Video decoder CUVID or VAAPI
|
o Video decoder CUVID or VAAPI
|
||||||
o Video output opengl or DRM
|
o Video output opengl or DRM
|
||||||
o Audio FFMpeg / Alsa / Analog
|
o Audio FFMpeg / ALSA / Analog
|
||||||
o Audio FFMpeg / Alsa / Digital
|
o Audio FFMpeg / ALSA / Digital
|
||||||
o Audio FFMpeg / OSS / Analog
|
|
||||||
o HDMI/SPDIF pass-through
|
o HDMI/SPDIF pass-through
|
||||||
o Software volume, compression, normalize and channel resample
|
o Software volume, compression, normalize and channel resample
|
||||||
o VDR ScaleVideo API
|
o VDR ScaleVideo API
|
||||||
o CUDA deinterlacer
|
o CUDA deinterlacer
|
||||||
o Suspend / Dettach
|
o Suspend / Detach
|
||||||
o Support for ambilight
|
o Support for ambilight
|
||||||
o Support for Screencopy
|
o Support for Screencopy
|
||||||
o PIP (Picture-in-Picture) (only for CUVID)
|
o PIP (Picture-in-Picture) (only for CUVID)
|
||||||
|
|
||||||
|
|
||||||
To compile you must have the 'requires' installed.
|
|
||||||
|
|
||||||
|
|
||||||
This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output.
|
This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output.
|
||||||
@@ -71,15 +69,20 @@ Quickstart:
|
|||||||
|
|
||||||
You have to adapt the Makefile. There are 3 possible Version that you can build:
|
You have to adapt the Makefile. There are 3 possible Version that you can build:
|
||||||
|
|
||||||
softhdcuvid
|
softhdcuvid (CUVID=1)
|
||||||
This is for NVIDA cards and uses cuvid as decoder. It uses xcb for output and needs a X Server to run.
|
This is for NVIDA cards and uses cuvid as decoder. It uses xcb for output and needs a X Server to run.
|
||||||
|
I recommend to use libplacebo and set LIBPLACEBO=1 in the Makefile
|
||||||
|
|
||||||
softhdvaapi
|
softhdvaapi (VAAPI=1)
|
||||||
This is for INTEL cards and uses Vaapi as decoder. It uses xcb for output and needs a X Server to run.
|
This is for INTEL cards and uses Vaapi as decoder. It uses xcb for output and needs a X Server to run.
|
||||||
|
I recommend to use libplacebo and set LIBPLACEBO=1 in the Makefile. Also LIBPLACEBO_GL is supportet here.
|
||||||
|
|
||||||
softhddrm
|
softhddrm (DRM=1)
|
||||||
This is for INTEL cards and also uses Vaapi as decoder. It uses the DRM API for output and
|
This is for INTEL cards and also uses Vaapi as decoder. It uses the DRM API for output and
|
||||||
runs without X Server. There are several commandline options to select the resolution and refresh rate.
|
runs without X Server. There are several commandline options to select the resolution and refresh rate.
|
||||||
|
I recommend to use libplacebo and set LIBPLACEBO_GL=1 in the Makefile.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Install:
|
Install:
|
||||||
--------
|
--------
|
||||||
@@ -90,9 +93,6 @@ Install:
|
|||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|
||||||
You can edit Makefile to enable/disable Alsa / OSS
|
|
||||||
support. The default is to autodetect as much as possible.
|
|
||||||
|
|
||||||
You have to start vdr with -P 'softhdcuvid -d :0.0 ..<more option>.. '
|
You have to start vdr with -P 'softhdcuvid -d :0.0 ..<more option>.. '
|
||||||
|
|
||||||
Beginners Guide for libplacebo:
|
Beginners Guide for libplacebo:
|
||||||
@@ -100,27 +100,43 @@ Beginners Guide for libplacebo:
|
|||||||
When using libplacebo you will find several config options.
|
When using libplacebo you will find several config options.
|
||||||
|
|
||||||
First of all you need to set the right scaler for each resolution:
|
First of all you need to set the right scaler for each resolution:
|
||||||
Best you beginn with setting all to "bilinear". If that works ok for you, you can try to change them
|
Best you begin with setting all to "bilinear". If that works ok for you, you can try to change them
|
||||||
for more advanced scaler. I use ewa_robidouxsharp on my GTX1050, but your mileage may vary.
|
for more advanced scaler. I use ewa_robidouxsharp on my GTX1050, but your mileage may vary.
|
||||||
Unfortunatly on INTEL not all scalers may work or crash.
|
Unfortunatly on INTEL not all scalers may work or crash.
|
||||||
|
The Intel GPU is much slower than NVIDIA and for UHD you most likly need to set the scaler to bilinear.
|
||||||
|
|
||||||
You can enable a Scaler Test feature. When enabled then the screen is split.On the left half you will
|
You can enable a Scaler Test feature. When enabled then the screen is split.On the left half you will
|
||||||
see the scaler defined by Scaler Test and on the right side you will see the scaler defined at the
|
see the scaler defined by Scaler Test and on the right side you will see the scaler defined at the
|
||||||
Resolution setting. There is as small black line between the halfs to remaind you that Scaler Test
|
Resolution setting. There is as small black line between the halfs to remaind you that Scaler Test
|
||||||
is activ.
|
is activ.
|
||||||
|
|
||||||
Then you should set the Monitor Colorspace to "sRGB". This guarantees you the best colors on your screen.
|
Then you should set the Monitor Type to "sRGB". This guarantees you the best colors on your screen.
|
||||||
At the moment all calculations internaly are done in RGB space and all cards output also RGB.
|
At the moment all calculations internaly are done in RGB space and all cards output also RGB.
|
||||||
|
If you use the softhddrm Version then you should set the Monitor Type to HD TV or UHD-HDR TV if you have
|
||||||
|
connected one of those.
|
||||||
|
|
||||||
If you are colorblind you could try to remedy this with the Colorblind Settings. Realy only needed
|
If you are colorblind you could try to remedy this with the Colorblind Settings. Realy only needed
|
||||||
in rare cases.
|
in rare cases.
|
||||||
|
|
||||||
All other settings can be in their default state.
|
All other settings can be in their default state.
|
||||||
|
|
||||||
|
Note for NUC11/12 Users:
|
||||||
|
Provide paramete -w alsa-no-test to get Audio working.
|
||||||
|
|
||||||
Beginning with libplacebo API 58 user shaders from mpv are supported. Use -S parameter to set the shader.
|
Beginning with libplacebo API 58 user shaders from mpv are supported. Use -S parameter to set the shader.
|
||||||
The plugins searches the shaders in $ConfigDir/plugins/shaders for the shaders. One example shader is
|
The plugins searches the shaders in $ConfigDir/plugins/shaders for the shaders. One example shader is
|
||||||
provided in the shader subdirectory. Copy it to e.g.: /etc/vdr/plugins/shaders and then start
|
provided in the shader subdirectory. Copy it to e.g.: /etc/vdr/plugins/shaders and then start
|
||||||
vdr -P 'softhdcuvid -S filmgrain.glsl ...'
|
vdr -P 'softhdcuvid -S filmgrain.glsl ...'
|
||||||
|
I use KrigBilateral for UV scaling and then adaptive-sharpen for sharpening. This results in a perfect
|
||||||
|
picture for me.
|
||||||
|
|
||||||
|
You can also use a custon LUT File. It is located in $ConfigDir/shaders/lut/lut.cube. If you provide there
|
||||||
|
a lut file it will be automaticly used. In the Mainmenue you can switch LUT on and off.
|
||||||
|
|
||||||
|
Konfig Guide for softhddrm Version
|
||||||
|
----------------------------------
|
||||||
|
You should set the Monitor Type to HD TV or UHD-HDR TV depending on your TV Set
|
||||||
|
With softhddrm and a HDR TV Set you can view HDR-HLG content. This is tested with Kernel 5.12 and a Intel NUC.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -129,27 +145,17 @@ Setup: environment
|
|||||||
Following is supported:
|
Following is supported:
|
||||||
|
|
||||||
DISPLAY=:0.0
|
DISPLAY=:0.0
|
||||||
x11 display name
|
X11 display name
|
||||||
|
|
||||||
only if alsa is configured
|
ALSA configuration:
|
||||||
ALSA_DEVICE=default
|
ALSA_DEVICE=default
|
||||||
alsa PCM device name
|
ALSA PCM device name
|
||||||
ALSA_PASSTHROUGH_DEVICE=
|
ALSA_PASSTHROUGH_DEVICE=
|
||||||
alsa pass-though (AC-3,E-AC-3,DTS,...) device name
|
ALSA pass-though (AC-3,E-AC-3,DTS,...) device name
|
||||||
ALSA_MIXER=default
|
ALSA_MIXER=default
|
||||||
alsa control device name
|
ALSA control device name
|
||||||
ALSA_MIXER_CHANNEL=PCM
|
ALSA_MIXER_CHANNEL=PCM
|
||||||
alsa control channel name
|
ALSA control channel name
|
||||||
|
|
||||||
only if oss is configured
|
|
||||||
OSS_AUDIODEV=/dev/dsp
|
|
||||||
oss dsp device name
|
|
||||||
OSS_PASSTHROUGHDEV=
|
|
||||||
oss pass-though (AC-3,E-AC-3,DTS,...) device name
|
|
||||||
OSS_MIXERDEV=/dev/mixer
|
|
||||||
oss mixer device name
|
|
||||||
OSS_MIXER_CHANNEL=pcm
|
|
||||||
oss mixer channel name
|
|
||||||
|
|
||||||
Setup: /etc/vdr/setup.conf
|
Setup: /etc/vdr/setup.conf
|
||||||
------
|
------
|
||||||
@@ -178,7 +184,7 @@ Setup: /etc/vdr/setup.conf
|
|||||||
(only 0, 1, 4 supported with VA-API)
|
(only 0, 1, 4 supported with VA-API)
|
||||||
|
|
||||||
softhddevice.<res>.SkipChromaDeinterlace = 0
|
softhddevice.<res>.SkipChromaDeinterlace = 0
|
||||||
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
||||||
|
|
||||||
softhddevice.<res>.InverseTelecine = 0
|
softhddevice.<res>.InverseTelecine = 0
|
||||||
0 = disabled, 1 = enabled
|
0 = disabled, 1 = enabled
|
||||||
@@ -317,10 +323,7 @@ Commandline:
|
|||||||
|
|
||||||
Selects audio output module and device.
|
Selects audio output module and device.
|
||||||
"" to disable audio output
|
"" to disable audio output
|
||||||
/... to use oss audio module (if compiled with oss
|
other to use ALSA audio module
|
||||||
support)
|
|
||||||
other to use alsa audio module (if compiled with alsa
|
|
||||||
support)
|
|
||||||
|
|
||||||
SVDRP:
|
SVDRP:
|
||||||
------
|
------
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
Version 3, 19 November 2007
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The GNU Affero General Public License is a free, copyleft license
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
for software and other kinds of works, specifically designed to ensure
|
software and other kinds of works, specifically designed to ensure
|
||||||
cooperation with the community in the case of network server software.
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
The licenses for most software and other practical works are
|
The licenses for most software and other practical works are designed
|
||||||
designed to take away your freedom to share and change the works. By
|
to take away your freedom to share and change the works. By contrast,
|
||||||
contrast, our General Public Licenses are intended to guarantee your
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
freedom to share and change all versions of a program--to make sure it
|
share and change all versions of a program--to make sure it remains free
|
||||||
remains free software for all its users.
|
software for all its users.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
@@ -60,11 +60,10 @@ modification follow.
|
|||||||
|
|
||||||
0. Definitions.
|
0. Definitions.
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU Affero General Public
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
of works, such as semiconductor masks.
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
@@ -377,12 +376,12 @@ that material) supplement the terms of this License with terms:
|
|||||||
All other non-permissive additional terms are considered "further
|
All other non-permissive additional terms are considered "further
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
received it, or any part of it, contains a notice stating that it is
|
received it, or any part of it, contains a notice stating that it is
|
||||||
governed by this License along with a term that is a further restriction,
|
governed by this License along with a term that is a further
|
||||||
you may remove that term. If a license document contains a further
|
restriction, you may remove that term. If a license document contains
|
||||||
restriction but permits relicensing or conveying under this License, you
|
a further restriction but permits relicensing or conveying under this
|
||||||
may add to a covered work material governed by the terms of that license
|
License, you may add to a covered work material governed by the terms
|
||||||
document, provided that the further restriction does not survive such
|
of that license document, provided that the further restriction does
|
||||||
relicensing or conveying.
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
If you add terms to a covered work in accord with this section, you
|
||||||
must place, in the relevant source files, a statement of the
|
must place, in the relevant source files, a statement of the
|
||||||
@@ -551,34 +550,34 @@ shall include the Corresponding Source for any work covered by version 3
|
|||||||
of the GNU General Public License that is incorporated pursuant to the
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
following paragraph.
|
following paragraph.
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have permission
|
Notwithstanding any other provision of this License, you have
|
||||||
to link or combine any covered work with a work licensed under version 3
|
permission to link or combine any covered work with a work licensed
|
||||||
of the GNU General Public License into a single combined work, and to
|
under version 3 of the GNU General Public License into a single
|
||||||
convey the resulting work. The terms of this License will continue to
|
combined work, and to convey the resulting work. The terms of this
|
||||||
apply to the part which is the covered work, but the work with which it is
|
License will continue to apply to the part which is the covered work,
|
||||||
combined will remain governed by version 3 of the GNU General Public
|
but the work with which it is combined will remain governed by version
|
||||||
License.
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
the GNU Affero General Public License from time to time. Such new
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
versions will be similar in spirit to the present version, but may differ
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
in detail to address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
Each version is given a distinguishing version number. If the
|
||||||
Program specifies that a certain numbered version of the GNU Affero
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
General Public License "or any later version" applies to it, you have
|
Public License "or any later version" applies to it, you have the
|
||||||
the option of following the terms and conditions either of that
|
option of following the terms and conditions either of that numbered
|
||||||
numbered version or of any later version published by the Free
|
version or of any later version published by the Free Software
|
||||||
Software Foundation. If the Program does not specify a version number
|
Foundation. If the Program does not specify a version number of the
|
||||||
of the GNU Affero General Public License, you may choose any version
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
ever published by the Free Software Foundation.
|
by the Free Software Foundation.
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
If the Program specifies that a proxy can decide which future
|
||||||
versions of the GNU Affero General Public License can be used, that
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
proxy's public statement of acceptance of a version permanently
|
public statement of acceptance of a version permanently authorizes you
|
||||||
authorizes you to choose that version for the Program.
|
to choose that version for the Program.
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
Later license versions may give you additional or different
|
||||||
permissions. However, no additional obligations are imposed on any
|
permissions. However, no additional obligations are imposed on any
|
||||||
@@ -634,9 +633,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
Copyright (C) <year> <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
published by the Free Software Foundation, either version 3 of the
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
License, or (at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@@ -644,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@@ -659,4 +658,4 @@ specific requirements.
|
|||||||
You should also get your employer (if you work as a programmer) or school,
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
<http://www.gnu.org/licenses/>.
|
<https://www.gnu.org/licenses/>.
|
1
audio.h
1
audio.h
@@ -60,6 +60,7 @@ extern void AudioExit(void); ///< cleanup and exit audio module
|
|||||||
// Variables
|
// Variables
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern char AudioAlsaNotest; ///< disable Alsa capability test
|
||||||
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
||||||
extern char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
extern char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
||||||
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
||||||
|
315
codec.c
315
codec.c
@@ -36,10 +36,6 @@
|
|||||||
#define USE_AUDIO_DRIFT_CORRECTION
|
#define USE_AUDIO_DRIFT_CORRECTION
|
||||||
/// compile AC-3 audio drift correction support (very experimental)
|
/// compile AC-3 audio drift correction support (very experimental)
|
||||||
#define USE_AC3_DRIFT_CORRECTION
|
#define USE_AC3_DRIFT_CORRECTION
|
||||||
/// use ffmpeg libswresample API (autodected, Makefile)
|
|
||||||
#define noUSE_SWRESAMPLE
|
|
||||||
/// use libav libavresample API (autodected, Makefile)
|
|
||||||
#define noUSE_AVRESAMPLE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -51,35 +47,28 @@
|
|||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#define _(str) gettext(str) ///< gettext shortcut
|
#define _(str) gettext(str) ///< gettext shortcut
|
||||||
#define _N(str) str ///< gettext_noop shortcut
|
#define _N(str) str ///< gettext_noop shortcut
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <libavutil/mem.h>
|
#include <libavutil/mem.h>
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
#include <libswresample/swresample.h>
|
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
#include <libavresample/avresample.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __USE_GNU
|
#include <libswresample/swresample.h>
|
||||||
#define __USE_GNU
|
|
||||||
#endif
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "iatomic.h"
|
#include "iatomic.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Global
|
// Global
|
||||||
@@ -134,8 +123,7 @@ struct _video_decoder_
|
|||||||
** valid format, the formats are ordered by
|
** valid format, the formats are ordered by
|
||||||
** quality.
|
** quality.
|
||||||
*/
|
*/
|
||||||
static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
static enum AVPixelFormat Codec_get_format(AVCodecContext *video_ctx, const enum AVPixelFormat *fmt) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
enum AVPixelFormat fmt1;
|
enum AVPixelFormat fmt1;
|
||||||
|
|
||||||
@@ -147,7 +135,6 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu
|
|||||||
|
|
||||||
// decoder->GetFormatDone = 1;
|
// decoder->GetFormatDone = 1;
|
||||||
return Video_get_format(decoder->HwDecoder, video_ctx, fmt);
|
return Video_get_format(decoder->HwDecoder, video_ctx, fmt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static void Codec_free_buffer(void *opaque, uint8_t *data);
|
// static void Codec_free_buffer(void *opaque, uint8_t *data);
|
||||||
@@ -160,8 +147,7 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu
|
|||||||
** @param video_ctx Codec context
|
** @param video_ctx Codec context
|
||||||
** @param frame Get buffer for this frame
|
** @param frame Get buffer for this frame
|
||||||
*/
|
*/
|
||||||
static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int flags)
|
static int Codec_get_buffer2(AVCodecContext *video_ctx, AVFrame *frame, int flags) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
|
|
||||||
decoder = video_ctx->opaque;
|
decoder = video_ctx->opaque;
|
||||||
@@ -197,8 +183,7 @@ static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int fl
|
|||||||
**
|
**
|
||||||
** @returns private decoder pointer for video decoder.
|
** @returns private decoder pointer for video decoder.
|
||||||
*/
|
*/
|
||||||
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *hw_decoder) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
|
|
||||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||||
@@ -214,10 +199,7 @@ VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
|||||||
**
|
**
|
||||||
** @param decoder private video decoder
|
** @param decoder private video decoder
|
||||||
*/
|
*/
|
||||||
void CodecVideoDelDecoder(VideoDecoder * decoder)
|
void CodecVideoDelDecoder(VideoDecoder *decoder) { free(decoder); }
|
||||||
{
|
|
||||||
free(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Open video decoder.
|
** Open video decoder.
|
||||||
@@ -225,8 +207,7 @@ void CodecVideoDelDecoder(VideoDecoder * decoder)
|
|||||||
** @param decoder private video decoder
|
** @param decoder private video decoder
|
||||||
** @param codec_id video codec id
|
** @param codec_id video codec id
|
||||||
*/
|
*/
|
||||||
void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
|
||||||
{
|
|
||||||
AVCodec *video_codec;
|
AVCodec *video_codec;
|
||||||
const char *name;
|
const char *name;
|
||||||
int ret, deint = 2;
|
int ret, deint = 2;
|
||||||
@@ -253,20 +234,6 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef RASPI
|
|
||||||
switch (codec_id) {
|
|
||||||
case AV_CODEC_ID_MPEG2VIDEO:
|
|
||||||
name = "mpeg2_v4l2m2m";
|
|
||||||
break;
|
|
||||||
case AV_CODEC_ID_H264:
|
|
||||||
name = "h264_v4l2m2m";
|
|
||||||
// name = "h264_mmal";
|
|
||||||
break;
|
|
||||||
case AV_CODEC_ID_HEVC:
|
|
||||||
name = "hevc_v4l2m2m";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
||||||
Debug(3, "codec: decoder found\n");
|
Debug(3, "codec: decoder found\n");
|
||||||
@@ -283,30 +250,27 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
Fatal(_("codec: can't allocate video codec context\n"));
|
Fatal(_("codec: can't allocate video codec context\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef RASPI
|
|
||||||
if (!HwDeviceContext) {
|
if (!HwDeviceContext) {
|
||||||
Fatal("codec: no hw device context to be used");
|
Fatal("codec: no hw device context to be used");
|
||||||
}
|
}
|
||||||
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
||||||
#else
|
|
||||||
decoder->VideoCtx->pix_fmt = AV_PIX_FMT_DRM_PRIME; /* request a DRM frame */
|
|
||||||
// decoder->VideoCtx->pix_fmt = AV_PIX_FMT_MMAL; /* request a DRM frame */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// FIXME: for software decoder use all cpus, otherwise 1
|
// FIXME: for software decoder use all cpus, otherwise 1
|
||||||
decoder->VideoCtx->thread_count = 1;
|
decoder->VideoCtx->thread_count = 1;
|
||||||
|
|
||||||
decoder->VideoCtx->pkt_timebase.num = 1;
|
decoder->VideoCtx->pkt_timebase.num = 1;
|
||||||
decoder->VideoCtx->pkt_timebase.den = 90000;
|
decoder->VideoCtx->pkt_timebase.den = 90000;
|
||||||
decoder->VideoCtx->framerate.num = 50;
|
//decoder->VideoCtx->framerate.num = 50;
|
||||||
decoder->VideoCtx->framerate.den = 1;
|
//decoder->VideoCtx->framerate.den = 1;
|
||||||
|
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
// open codec
|
// open codec
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
deint = 2;
|
deint = 2;
|
||||||
#endif
|
#endif
|
||||||
#if defined VAAPI && !defined RASPI
|
|
||||||
|
#if defined VAAPI
|
||||||
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100)
|
||||||
// decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
// decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
||||||
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
||||||
Debug(3, "codec: auto threads enabled");
|
Debug(3, "codec: auto threads enabled");
|
||||||
@@ -317,6 +281,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
Debug(3, "codec: supports truncated packets");
|
Debug(3, "codec: supports truncated packets");
|
||||||
// decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED;
|
// decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// FIXME: own memory management for video frames.
|
// FIXME: own memory management for video frames.
|
||||||
if (video_codec->capabilities & AV_CODEC_CAP_DR1) {
|
if (video_codec->capabilities & AV_CODEC_CAP_DR1) {
|
||||||
Debug(3, "codec: can use own buffer management");
|
Debug(3, "codec: can use own buffer management");
|
||||||
@@ -333,36 +298,25 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
}
|
}
|
||||||
// if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0)
|
// if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0)
|
||||||
// Fatal(_("VAAPI Refcounts invalid\n"));
|
// Fatal(_("VAAPI Refcounts invalid\n"));
|
||||||
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100)
|
||||||
decoder->VideoCtx->thread_safe_callbacks = 0;
|
decoder->VideoCtx->thread_safe_callbacks = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RASPI
|
|
||||||
decoder->VideoCtx->codec_id = codec_id;
|
|
||||||
decoder->VideoCtx->flags |= AV_CODEC_FLAG_BITEXACT;
|
|
||||||
if (video_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS || AV_CODEC_CAP_SLICE_THREADS) {
|
|
||||||
Debug(3, "codec: supports frame threads");
|
|
||||||
decoder->VideoCtx->thread_count = 4;
|
|
||||||
// decoder->VideoCtx->thread_type |= FF_THREAD_FRAME;
|
|
||||||
}
|
|
||||||
if (video_codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
|
||||||
Debug(3, "codec: supports slice threads");
|
|
||||||
decoder->VideoCtx->thread_type |= FF_THREAD_SLICE;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
if (strcmp(decoder->VideoCodec->long_name, "Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
if (strcmp(decoder->VideoCodec->long_name,
|
||||||
|
"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint, 0) < 0) { // adaptive
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint, 0) < 0) { // adaptive
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option deint to video codec!\n"));
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 9, 0) < 0) {
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 10, 0) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option surfces to video codec!\n"));
|
Fatal(_("codec: can't set option surfces to video codec!\n"));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false", 0) < 0) {
|
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false", 0) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
||||||
@@ -372,12 +326,10 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option deint to video codec!\n"));
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 13, 0) < 0) {
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 13, 0) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option surfces to video codec!\n"));
|
Fatal(_("codec: can't set option surfces to video codec!\n"));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false", 0) < 0) {
|
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false", 0) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
||||||
@@ -418,7 +370,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
|
|
||||||
// reset buggy ffmpeg/libav flag
|
// reset buggy ffmpeg/libav flag
|
||||||
decoder->GetFormatDone = 0;
|
decoder->GetFormatDone = 0;
|
||||||
#if defined (YADIF) || defined (RASPI)
|
#if defined(YADIF)
|
||||||
decoder->filter = 0;
|
decoder->filter = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -428,8 +380,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
**
|
**
|
||||||
** @param video_decoder private video decoder
|
** @param video_decoder private video decoder
|
||||||
*/
|
*/
|
||||||
void CodecVideoClose(VideoDecoder * video_decoder)
|
void CodecVideoClose(VideoDecoder *video_decoder) {
|
||||||
{
|
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
|
||||||
// FIXME: play buffered data
|
// FIXME: play buffered data
|
||||||
@@ -441,14 +392,14 @@ void CodecVideoClose(VideoDecoder * video_decoder)
|
|||||||
#if 1
|
#if 1
|
||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
avcodec_send_packet(video_decoder->VideoCtx, NULL);
|
avcodec_send_packet(video_decoder->VideoCtx, NULL);
|
||||||
while (avcodec_receive_frame(video_decoder->VideoCtx, frame) >= 0) ;
|
while (avcodec_receive_frame(video_decoder->VideoCtx, frame) >= 0)
|
||||||
|
;
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
#endif
|
#endif
|
||||||
avcodec_close(video_decoder->VideoCtx);
|
avcodec_close(video_decoder->VideoCtx);
|
||||||
av_freep(&video_decoder->VideoCtx);
|
av_freep(&video_decoder->VideoCtx);
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -501,8 +452,7 @@ extern int push_filters(AVCodecContext * dec_ctx, void *decoder, AVFrame * frame
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *video_ctx = decoder->VideoCtx;
|
AVCodecContext *video_ctx = decoder->VideoCtx;
|
||||||
|
|
||||||
if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO && CuvidTestSurfaces()) {
|
if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO && CuvidTestSurfaces()) {
|
||||||
@@ -540,7 +490,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
decoder->filter = 2;
|
decoder->filter = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
if (decoder->filter == 2) {
|
||||||
push_filters(video_ctx, decoder->HwDecoder, frame);
|
push_filters(video_ctx, decoder->HwDecoder, frame);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -557,8 +507,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
|
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
|
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *video_ctx;
|
AVCodecContext *video_ctx;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
int ret, ret1;
|
int ret, ret1;
|
||||||
@@ -573,7 +522,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
pkt = avpkt; // use copy
|
pkt = avpkt; // use copy
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
|
|
||||||
// printf("decode packet %d\n",(GetusTicks()-first_time)/1000000);
|
|
||||||
ret1 = avcodec_send_packet(video_ctx, pkt);
|
ret1 = avcodec_send_packet(video_ctx, pkt);
|
||||||
|
|
||||||
// first_time = GetusTicks();
|
// first_time = GetusTicks();
|
||||||
@@ -593,25 +541,27 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
ret = avcodec_receive_frame(video_ctx, frame); // get new frame
|
ret = avcodec_receive_frame(video_ctx, frame); // get new frame
|
||||||
if (ret >= 0) { // one is avail.
|
if (ret >= 0) { // one is avail.
|
||||||
|
first_time = frame->pts;
|
||||||
got_frame = 1;
|
got_frame = 1;
|
||||||
} else {
|
} else {
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
}
|
}
|
||||||
//printf("got %s packet from decoder\n",got_frame?"1":"no");
|
//printf("got %s packet from decoder\n",got_frame?"1":"no");
|
||||||
if (got_frame) { // frame completed
|
if (got_frame) { // frame completed
|
||||||
// printf("video frame pts %#012" PRIx64 " %dms\n",frame->pts,(int)(apts - frame->pts) / 90);
|
// printf("video frame pts %#012" PRIx64 "
|
||||||
|
//%dms\n",frame->pts,(int)(apts - frame->pts) / 90);
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
if (decoder->filter) {
|
if (decoder->filter) {
|
||||||
if (decoder->filter == 1) {
|
if (decoder->filter == 1) {
|
||||||
if (init_filters(video_ctx, decoder->HwDecoder, frame) < 0) {
|
if (init_filters(video_ctx, decoder->HwDecoder, frame) < 0) {
|
||||||
Fatal(_("video: Init of YADIF Filter failed\n"));
|
Debug(3,"video: Init of YADIF Filter failed\n");
|
||||||
decoder->filter = 0;
|
decoder->filter = 0;
|
||||||
} else {
|
} else {
|
||||||
Debug(3, "Init YADIF ok\n");
|
Debug(3, "Init YADIF ok\n");
|
||||||
decoder->filter = 2;
|
decoder->filter = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
if (decoder->filter == 2) {
|
||||||
ret = push_filters(video_ctx, decoder->HwDecoder, frame);
|
ret = push_filters(video_ctx, decoder->HwDecoder, frame);
|
||||||
// av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
continue;
|
continue;
|
||||||
@@ -636,7 +586,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
if (!consumed) {
|
if (!consumed) {
|
||||||
goto next_part; // try again to stuff decoder
|
goto next_part; // try again to stuff decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -645,8 +594,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
**
|
**
|
||||||
** @param decoder video decoder data
|
** @param decoder video decoder data
|
||||||
*/
|
*/
|
||||||
void CodecVideoFlushBuffers(VideoDecoder * decoder)
|
void CodecVideoFlushBuffers(VideoDecoder *decoder) {
|
||||||
{
|
|
||||||
if (decoder->VideoCtx) {
|
if (decoder->VideoCtx) {
|
||||||
avcodec_flush_buffers(decoder->VideoCtx);
|
avcodec_flush_buffers(decoder->VideoCtx);
|
||||||
}
|
}
|
||||||
@@ -666,8 +614,7 @@ typedef struct _audio_decoder_ AudioDecoder;
|
|||||||
///
|
///
|
||||||
/// Audio decoder structure.
|
/// Audio decoder structure.
|
||||||
///
|
///
|
||||||
struct _audio_decoder_
|
struct _audio_decoder_ {
|
||||||
{
|
|
||||||
AVCodec *AudioCodec; ///< audio codec
|
AVCodec *AudioCodec; ///< audio codec
|
||||||
AVCodecContext *AudioCtx; ///< audio codec context
|
AVCodecContext *AudioCtx; ///< audio codec context
|
||||||
|
|
||||||
@@ -679,17 +626,7 @@ struct _audio_decoder_
|
|||||||
int HwChannels; ///< hw channels
|
int HwChannels; ///< hw channels
|
||||||
|
|
||||||
AVFrame *Frame; ///< decoded audio frame buffer
|
AVFrame *Frame; ///< decoded audio frame buffer
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
#if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(0, 15, 100)
|
|
||||||
struct SwrContext *Resample; ///< ffmpeg software resample context
|
|
||||||
#else
|
|
||||||
SwrContext *Resample; ///< ffmpeg software resample context
|
SwrContext *Resample; ///< ffmpeg software resample context
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
AVAudioResampleContext *Resample; ///< libav software resample context
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer
|
uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer
|
||||||
int SpdifIndex; ///< index into SPDIF output buffer
|
int SpdifIndex; ///< index into SPDIF output buffer
|
||||||
@@ -707,8 +644,7 @@ struct _audio_decoder_
|
|||||||
///
|
///
|
||||||
/// IEC Data type enumeration.
|
/// IEC Data type enumeration.
|
||||||
///
|
///
|
||||||
enum IEC61937
|
enum IEC61937 {
|
||||||
{
|
|
||||||
IEC61937_AC3 = 0x01, ///< AC-3 data
|
IEC61937_AC3 = 0x01, ///< AC-3 data
|
||||||
// FIXME: more data types
|
// FIXME: more data types
|
||||||
IEC61937_EAC3 = 0x15, ///< E-AC-3 data
|
IEC61937_EAC3 = 0x15, ///< E-AC-3 data
|
||||||
@@ -736,8 +672,7 @@ static char CodecDownmix; ///< enable AC-3 decoder downmix
|
|||||||
**
|
**
|
||||||
** @returns private decoder pointer for audio decoder.
|
** @returns private decoder pointer for audio decoder.
|
||||||
*/
|
*/
|
||||||
AudioDecoder *CodecAudioNewDecoder(void)
|
AudioDecoder *CodecAudioNewDecoder(void) {
|
||||||
{
|
|
||||||
AudioDecoder *audio_decoder;
|
AudioDecoder *audio_decoder;
|
||||||
|
|
||||||
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
||||||
@@ -755,8 +690,7 @@ AudioDecoder *CodecAudioNewDecoder(void)
|
|||||||
**
|
**
|
||||||
** @param decoder private audio decoder
|
** @param decoder private audio decoder
|
||||||
*/
|
*/
|
||||||
void CodecAudioDelDecoder(AudioDecoder * decoder)
|
void CodecAudioDelDecoder(AudioDecoder *decoder) {
|
||||||
{
|
|
||||||
av_frame_free(&decoder->Frame); // callee does checks
|
av_frame_free(&decoder->Frame); // callee does checks
|
||||||
free(decoder);
|
free(decoder);
|
||||||
}
|
}
|
||||||
@@ -767,8 +701,7 @@ void CodecAudioDelDecoder(AudioDecoder * decoder)
|
|||||||
** @param audio_decoder private audio decoder
|
** @param audio_decoder private audio decoder
|
||||||
** @param codec_id audio codec id
|
** @param codec_id audio codec id
|
||||||
*/
|
*/
|
||||||
void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
void CodecAudioOpen(AudioDecoder *audio_decoder, int codec_id) {
|
||||||
{
|
|
||||||
AVCodec *audio_codec;
|
AVCodec *audio_codec;
|
||||||
|
|
||||||
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, avcodec_get_name(codec_id));
|
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, avcodec_get_name(codec_id));
|
||||||
@@ -783,9 +716,6 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
|||||||
Fatal(_("codec: can't allocate audio codec context\n"));
|
Fatal(_("codec: can't allocate audio codec context\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodecDownmix) {
|
|
||||||
audio_decoder->AudioCtx->request_channel_layout = AV_CH_LAYOUT_STEREO;
|
|
||||||
}
|
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
// open codec
|
// open codec
|
||||||
if (1) {
|
if (1) {
|
||||||
@@ -817,20 +747,12 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
|||||||
**
|
**
|
||||||
** @param audio_decoder private audio decoder
|
** @param audio_decoder private audio decoder
|
||||||
*/
|
*/
|
||||||
void CodecAudioClose(AudioDecoder * audio_decoder)
|
void CodecAudioClose(AudioDecoder *audio_decoder) {
|
||||||
{
|
|
||||||
// FIXME: output any buffered data
|
// FIXME: output any buffered data
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
if (audio_decoder->Resample) {
|
if (audio_decoder->Resample) {
|
||||||
swr_free(&audio_decoder->Resample);
|
swr_free(&audio_decoder->Resample);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (audio_decoder->Resample) {
|
|
||||||
avresample_free(&audio_decoder->Resample);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (audio_decoder->AudioCtx) {
|
if (audio_decoder->AudioCtx) {
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
avcodec_close(audio_decoder->AudioCtx);
|
avcodec_close(audio_decoder->AudioCtx);
|
||||||
@@ -844,8 +766,7 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
|
|||||||
**
|
**
|
||||||
** @param mask enable mask (PCM, AC-3)
|
** @param mask enable mask (PCM, AC-3)
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioDrift(int mask)
|
void CodecSetAudioDrift(int mask) {
|
||||||
{
|
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
CodecAudioDrift = mask & (CORRECT_PCM | CORRECT_AC3);
|
CodecAudioDrift = mask & (CORRECT_PCM | CORRECT_AC3);
|
||||||
#endif
|
#endif
|
||||||
@@ -857,8 +778,7 @@ void CodecSetAudioDrift(int mask)
|
|||||||
**
|
**
|
||||||
** @param mask enable mask (PCM, AC-3, E-AC-3)
|
** @param mask enable mask (PCM, AC-3, E-AC-3)
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioPassthrough(int mask)
|
void CodecSetAudioPassthrough(int mask) {
|
||||||
{
|
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
CodecPassthrough = mask & (CodecPCM | CodecAC3 | CodecEAC3);
|
CodecPassthrough = mask & (CodecPCM | CodecAC3 | CodecEAC3);
|
||||||
#endif
|
#endif
|
||||||
@@ -870,8 +790,7 @@ void CodecSetAudioPassthrough(int mask)
|
|||||||
**
|
**
|
||||||
** @param onoff enable/disable downmix.
|
** @param onoff enable/disable downmix.
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioDownmix(int onoff)
|
void CodecSetAudioDownmix(int onoff) {
|
||||||
{
|
|
||||||
if (onoff == -1) {
|
if (onoff == -1) {
|
||||||
CodecDownmix ^= 1;
|
CodecDownmix ^= 1;
|
||||||
return;
|
return;
|
||||||
@@ -890,8 +809,7 @@ void CodecSetAudioDownmix(int onoff)
|
|||||||
** @param size size of sample buffer in bytes
|
** @param size size of sample buffer in bytes
|
||||||
** @param channels number of channels interleaved in sample buffer
|
** @param channels number of channels interleaved in sample buffer
|
||||||
*/
|
*/
|
||||||
static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
static void CodecReorderAudioFrame(int16_t *buf, int size, int channels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
int c;
|
int c;
|
||||||
int ls;
|
int ls;
|
||||||
@@ -945,13 +863,12 @@ static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
|||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param[out] passthrough pass-through output
|
** @param[out] passthrough pass-through output
|
||||||
*/
|
*/
|
||||||
static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough)
|
static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough) {
|
||||||
{
|
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
audio_ctx = audio_decoder->AudioCtx;
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
Debug(3, "codec/audio: format change %s %dHz *%d channels%s%s%s%s%s\n",
|
Debug(3, "codec/audio: Chanlayout %lx format change %s %dHz *%d channels%s%s%s%s%s\n",audio_ctx->channel_layout,
|
||||||
av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, audio_ctx->channels,
|
av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, audio_ctx->channels,
|
||||||
CodecPassthrough & CodecPCM ? " PCM" : "", CodecPassthrough & CodecMPA ? " MPA" : "",
|
CodecPassthrough & CodecPCM ? " PCM" : "", CodecPassthrough & CodecMPA ? " MPA" : "",
|
||||||
CodecPassthrough & CodecAC3 ? " AC-3" : "", CodecPassthrough & CodecEAC3 ? " E-AC-3" : "",
|
CodecPassthrough & CodecAC3 ? " AC-3" : "", CodecPassthrough & CodecEAC3 ? " E-AC-3" : "",
|
||||||
@@ -961,15 +878,15 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
||||||
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
||||||
audio_decoder->Channels = audio_ctx->channels;
|
audio_decoder->Channels = audio_ctx->channels;
|
||||||
audio_decoder->HwChannels = audio_ctx->channels;
|
audio_decoder->HwChannels = CodecDownmix ? 2 : audio_ctx->channels;
|
||||||
audio_decoder->Passthrough = CodecPassthrough;
|
audio_decoder->Passthrough = CodecPassthrough;
|
||||||
|
|
||||||
// SPDIF/HDMI pass-through
|
// SPDIF/HDMI pass-through
|
||||||
if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3)
|
if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) ||
|
||||||
|| (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
|
(CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
|
||||||
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
|
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
|
||||||
// E-AC-3 over HDMI some receivers need HBR
|
// E-AC-3 over HDMI some receivers need HBR
|
||||||
audio_decoder->HwSampleRate *= 4;
|
//audio_decoder->HwSampleRate *= 4;
|
||||||
}
|
}
|
||||||
audio_decoder->HwChannels = 2;
|
audio_decoder->HwChannels = 2;
|
||||||
audio_decoder->SpdifIndex = 0; // reset buffer
|
audio_decoder->SpdifIndex = 0; // reset buffer
|
||||||
@@ -981,8 +898,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
|
|
||||||
// try E-AC-3 none HBR
|
// try E-AC-3 none HBR
|
||||||
audio_decoder->HwSampleRate /= 4;
|
audio_decoder->HwSampleRate /= 4;
|
||||||
if (audio_ctx->codec_id != AV_CODEC_ID_EAC3
|
if (audio_ctx->codec_id != AV_CODEC_ID_EAC3 ||
|
||||||
|| (err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) {
|
(err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) {
|
||||||
|
|
||||||
Debug(3, "codec/audio: audio setup error\n");
|
Debug(3, "codec/audio: audio setup error\n");
|
||||||
// FIXME: handle errors
|
// FIXME: handle errors
|
||||||
@@ -1005,8 +922,7 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param avpkt undecoded audio packet
|
** @param avpkt undecoded audio packet
|
||||||
*/
|
*/
|
||||||
static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
static int CodecAudioPassthroughHelper(AudioDecoder *audio_decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
|
|
||||||
@@ -1025,11 +941,10 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac
|
|||||||
if (CodecAudioDrift & CORRECT_AC3) {
|
if (CodecAudioDrift & CORRECT_AC3) {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
x = (audio_decoder->DriftFrac +
|
x = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) /
|
||||||
(audio_decoder->DriftCorr * spdif_sz)) / (10 * audio_decoder->HwSampleRate * 100);
|
(10 * audio_decoder->HwSampleRate * 100);
|
||||||
audio_decoder->DriftFrac =
|
audio_decoder->DriftFrac = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) %
|
||||||
(audio_decoder->DriftFrac +
|
(10 * audio_decoder->HwSampleRate * 100);
|
||||||
(audio_decoder->DriftCorr * spdif_sz)) % (10 * audio_decoder->HwSampleRate * 100);
|
|
||||||
// round to word border
|
// round to word border
|
||||||
x *= audio_decoder->HwChannels * 4;
|
x *= audio_decoder->HwChannels * 4;
|
||||||
if (x < -64) { // limit correction
|
if (x < -64) { // limit correction
|
||||||
@@ -1112,16 +1027,13 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_SWRESAMPLE) || defined(USE_AVRESAMPLE)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Set/update audio pts clock.
|
** Set/update audio pts clock.
|
||||||
**
|
**
|
||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param pts presentation timestamp
|
** @param pts presentation timestamp
|
||||||
*/
|
*/
|
||||||
static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
static void CodecAudioSetClock(AudioDecoder *audio_decoder, int64_t pts) {
|
||||||
{
|
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
struct timespec nowtime;
|
struct timespec nowtime;
|
||||||
int64_t delay;
|
int64_t delay;
|
||||||
@@ -1152,8 +1064,8 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec)
|
tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec) * 1000 * 1000 * 1000 +
|
||||||
* 1000 * 1000 * 1000 + (nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec);
|
(nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec);
|
||||||
|
|
||||||
drift = (tim_diff * 90) / (1000 * 1000) - pts_diff + delay - audio_decoder->LastDelay;
|
drift = (tim_diff * 90) / (1000 * 1000) - pts_diff + delay - audio_decoder->LastDelay;
|
||||||
|
|
||||||
@@ -1181,10 +1093,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
audio_decoder->Drift = drift;
|
audio_decoder->Drift = drift;
|
||||||
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
||||||
// SPDIF/HDMI passthrough
|
// SPDIF/HDMI passthrough
|
||||||
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
|
if ((CodecAudioDrift & CORRECT_AC3) &&
|
||||||
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3)
|
(!(CodecPassthrough & CodecAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) &&
|
||||||
&& (!(CodecPassthrough & CodecEAC3)
|
(!(CodecPassthrough & CodecEAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
|
||||||
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
|
|
||||||
audio_decoder->DriftCorr = -corr;
|
audio_decoder->DriftCorr = -corr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1195,7 +1106,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
||||||
int distance;
|
int distance;
|
||||||
|
|
||||||
@@ -1209,17 +1119,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
|
||||||
int distance;
|
|
||||||
|
|
||||||
distance = (pts_diff * audio_decoder->HwSampleRate) / (900 * 1000);
|
|
||||||
if (avresample_set_compensation(audio_decoder->Resample, audio_decoder->DriftCorr / 10, distance)) {
|
|
||||||
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (1) {
|
if (1) {
|
||||||
static int c;
|
static int c;
|
||||||
|
|
||||||
@@ -1237,8 +1136,7 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
**
|
**
|
||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
*/
|
*/
|
||||||
static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
static void CodecAudioUpdateFormat(AudioDecoder *audio_decoder) {
|
||||||
{
|
|
||||||
int passthrough;
|
int passthrough;
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
|
|
||||||
@@ -1253,44 +1151,36 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
audio_ctx = audio_decoder->AudioCtx;
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate
|
if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate &&
|
||||||
&& !CodecAudioDrift) {
|
!CodecAudioDrift) {
|
||||||
// FIXME: use Resample only, when it is needed!
|
// FIXME: use Resample only, when it is needed!
|
||||||
fprintf(stderr, "no resample needed\n");
|
fprintf(stderr, "no resample needed\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
#if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(4,5,100)
|
||||||
audio_decoder->Resample =
|
audio_decoder->Resample = swr_alloc_set_opts(audio_decoder->Resample,
|
||||||
swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, AV_SAMPLE_FMT_S16,
|
CodecDownmix ? AV_CH_LAYOUT_STEREO : audio_ctx->channel_layout,
|
||||||
audio_decoder->HwSampleRate, audio_ctx->channel_layout, audio_ctx->sample_fmt, audio_ctx->sample_rate, 0,
|
AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate,
|
||||||
NULL);
|
audio_ctx->channel_layout, audio_ctx->sample_fmt,audio_ctx->sample_rate,
|
||||||
|
0, NULL);
|
||||||
|
#else
|
||||||
|
//printf("last ressort downmix Layout in %lx Lyout out: %llx \n",audio_ctx->channel_layout,AV_CH_LAYOUT_STEREO);
|
||||||
|
audio_decoder->Resample = swr_alloc();
|
||||||
|
av_opt_set_channel_layout(audio_decoder->Resample, "in_channel_layout",audio_ctx->channel_layout, 0);
|
||||||
|
av_opt_set_channel_layout(audio_decoder->Resample, "out_channel_layout", CodecDownmix ? AV_CH_LAYOUT_STEREO : audio_ctx->channel_layout , 0);
|
||||||
|
av_opt_set_int(audio_decoder->Resample, "in_sample_rate", audio_ctx->sample_rate, 0);
|
||||||
|
av_opt_set_int(audio_decoder->Resample, "out_sample_rate", audio_ctx->sample_rate, 0);
|
||||||
|
av_opt_set_sample_fmt(audio_decoder->Resample, "in_sample_fmt", audio_ctx->sample_fmt, 0);
|
||||||
|
av_opt_set_sample_fmt(audio_decoder->Resample, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||||
|
#endif
|
||||||
if (audio_decoder->Resample) {
|
if (audio_decoder->Resample) {
|
||||||
swr_init(audio_decoder->Resample);
|
swr_init(audio_decoder->Resample);
|
||||||
} else {
|
} else {
|
||||||
Error(_("codec/audio: can't setup resample\n"));
|
Error(_("codec/audio: can't setup resample\n"));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (!(audio_decoder->Resample = avresample_alloc_context())) {
|
|
||||||
Error(_("codec/audio: can't setup resample\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_channel_layout", audio_ctx->channel_layout, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_sample_fmt", audio_ctx->sample_fmt, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_sample_rate", audio_ctx->sample_rate, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_channel_layout", audio_ctx->channel_layout, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_sample_rate", audio_decoder->HwSampleRate, 0);
|
|
||||||
|
|
||||||
if (avresample_open(audio_decoder->Resample)) {
|
|
||||||
avresample_free(&audio_decoder->Resample);
|
|
||||||
audio_decoder->Resample = NULL;
|
|
||||||
Error(_("codec/audio: can't open resample\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1304,8 +1194,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
** @param avpkt audio packet
|
** @param avpkt audio packet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
void CodecAudioDecode(AudioDecoder *audio_decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *audio_ctx = audio_decoder->AudioCtx;
|
AVCodecContext *audio_ctx = audio_decoder->AudioCtx;
|
||||||
|
|
||||||
if (audio_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
if (audio_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
@@ -1332,8 +1221,9 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
CodecAudioSetClock(audio_decoder, avpkt->pts);
|
CodecAudioSetClock(audio_decoder, avpkt->pts);
|
||||||
}
|
}
|
||||||
// format change
|
// format change
|
||||||
if (audio_decoder->Passthrough != CodecPassthrough || audio_decoder->SampleRate != audio_ctx->sample_rate
|
if (audio_decoder->Passthrough != CodecPassthrough ||
|
||||||
|| audio_decoder->Channels != audio_ctx->channels) {
|
audio_decoder->SampleRate != audio_ctx->sample_rate ||
|
||||||
|
audio_decoder->Channels != audio_ctx->channels) {
|
||||||
CodecAudioUpdateFormat(audio_decoder);
|
CodecAudioUpdateFormat(audio_decoder);
|
||||||
}
|
}
|
||||||
if (!audio_decoder->HwSampleRate || !audio_decoder->HwChannels) {
|
if (!audio_decoder->HwSampleRate || !audio_decoder->HwChannels) {
|
||||||
@@ -1342,14 +1232,15 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
if (CodecAudioPassthroughHelper(audio_decoder, avpkt)) {
|
if (CodecAudioPassthroughHelper(audio_decoder, avpkt)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_decoder->Resample) {
|
if (audio_decoder->Resample) {
|
||||||
uint8_t outbuf[8192 * 2 * 8];
|
uint8_t outbuf[8192 * 2 * 8];
|
||||||
uint8_t *out[1];
|
uint8_t *out[1];
|
||||||
|
|
||||||
out[0] = outbuf;
|
out[0] = outbuf;
|
||||||
ret =
|
ret = swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels),
|
||||||
swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels),
|
|
||||||
(const uint8_t **)frame->extended_data, frame->nb_samples);
|
(const uint8_t **)frame->extended_data, frame->nb_samples);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (!(audio_decoder->Passthrough & CodecPCM)) {
|
if (!(audio_decoder->Passthrough & CodecPCM)) {
|
||||||
CodecReorderAudioFrame((int16_t *)outbuf, ret * 2 * audio_decoder->HwChannels,
|
CodecReorderAudioFrame((int16_t *)outbuf, ret * 2 * audio_decoder->HwChannels,
|
||||||
@@ -1363,18 +1254,12 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Flush the audio decoder.
|
** Flush the audio decoder.
|
||||||
**
|
**
|
||||||
** @param decoder audio decoder data
|
** @param decoder audio decoder data
|
||||||
*/
|
*/
|
||||||
void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
void CodecAudioFlushBuffers(AudioDecoder *decoder) { avcodec_flush_buffers(decoder->AudioCtx); }
|
||||||
{
|
|
||||||
|
|
||||||
avcodec_flush_buffers(decoder->AudioCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Codec
|
// Codec
|
||||||
@@ -1383,18 +1268,13 @@ void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
|||||||
/**
|
/**
|
||||||
** Empty log callback
|
** Empty log callback
|
||||||
*/
|
*/
|
||||||
static void CodecNoopCallback( __attribute__((unused))
|
static void CodecNoopCallback(__attribute__((unused)) void *ptr, __attribute__((unused)) int level,
|
||||||
void *ptr, __attribute__((unused))
|
__attribute__((unused)) const char *fmt, __attribute__((unused)) va_list vl) {}
|
||||||
int level, __attribute__((unused))
|
|
||||||
const char *fmt, __attribute__((unused)) va_list vl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Codec init
|
** Codec init
|
||||||
*/
|
*/
|
||||||
void CodecInit(void)
|
void CodecInit(void) {
|
||||||
{
|
|
||||||
pthread_mutex_init(&CodecLockMutex, NULL);
|
pthread_mutex_init(&CodecLockMutex, NULL);
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
// disable display ffmpeg error messages
|
// disable display ffmpeg error messages
|
||||||
@@ -1407,7 +1287,4 @@ void CodecInit(void)
|
|||||||
/**
|
/**
|
||||||
** Codec exit.
|
** Codec exit.
|
||||||
*/
|
*/
|
||||||
void CodecExit(void)
|
void CodecExit(void) { pthread_mutex_destroy(&CodecLockMutex); }
|
||||||
{
|
|
||||||
pthread_mutex_destroy(&CodecLockMutex);
|
|
||||||
}
|
|
||||||
|
7
codec.h
7
codec.h
@@ -35,8 +35,7 @@
|
|||||||
|
|
||||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
|
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
|
||||||
|
|
||||||
enum HWAccelID
|
enum HWAccelID {
|
||||||
{
|
|
||||||
HWACCEL_NONE = 0,
|
HWACCEL_NONE = 0,
|
||||||
HWACCEL_AUTO,
|
HWACCEL_AUTO,
|
||||||
HWACCEL_VDPAU,
|
HWACCEL_VDPAU,
|
||||||
@@ -53,8 +52,7 @@ extern AVBufferRef *hw_device_ctx;
|
|||||||
///
|
///
|
||||||
/// Video decoder structure.
|
/// Video decoder structure.
|
||||||
///
|
///
|
||||||
struct _video_decoder_
|
struct _video_decoder_ {
|
||||||
{
|
|
||||||
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
||||||
|
|
||||||
int GetFormatDone; ///< flag get format called!
|
int GetFormatDone; ///< flag get format called!
|
||||||
@@ -87,7 +85,6 @@ struct _video_decoder_
|
|||||||
double cached_hdr_peak;
|
double cached_hdr_peak;
|
||||||
// From VO
|
// From VO
|
||||||
struct mp_hwdec_devices *hwdec_devs;
|
struct mp_hwdec_devices *hwdec_devs;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
32
common.h
32
common.h
@@ -19,17 +19,17 @@
|
|||||||
#ifndef MPLAYER_GL_COMMON_H
|
#ifndef MPLAYER_GL_COMMON_H
|
||||||
#define MPLAYER_GL_COMMON_H
|
#define MPLAYER_GL_COMMON_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#if 0
|
#if 0
|
||||||
#include "config.h"
|
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
|
#include "config.h"
|
||||||
#include "misc/bstr.h"
|
#include "misc/bstr.h"
|
||||||
|
|
||||||
#include "video/out/vo.h"
|
|
||||||
#include "video/csputils.h"
|
#include "video/csputils.h"
|
||||||
#include "video/mp_image.h"
|
#include "video/mp_image.h"
|
||||||
|
#include "video/out/vo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_GL_COCOA
|
#if HAVE_GL_COCOA
|
||||||
@@ -53,8 +53,7 @@
|
|||||||
struct GL;
|
struct GL;
|
||||||
typedef struct GL GL;
|
typedef struct GL GL;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH
|
MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH
|
||||||
MPGL_CAP_FB = (1 << 5),
|
MPGL_CAP_FB = (1 << 5),
|
||||||
MPGL_CAP_VAO = (1 << 6),
|
MPGL_CAP_VAO = (1 << 6),
|
||||||
@@ -87,8 +86,7 @@ void mpgl_load_functions2(GL * gl, void *(*get_fn)(void *ctx, const char *n), vo
|
|||||||
typedef void(GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *);
|
typedef void(GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *);
|
||||||
|
|
||||||
// function pointers loaded from the OpenGL library
|
// function pointers loaded from the OpenGL library
|
||||||
struct GL
|
struct GL {
|
||||||
{
|
|
||||||
int version; // MPGL_VER() mangled (e.g. 210 for 2.1)
|
int version; // MPGL_VER() mangled (e.g. 210 for 2.1)
|
||||||
int es; // es version (e.g. 300), 0 for desktop GL
|
int es; // es version (e.g. 300), 0 for desktop GL
|
||||||
int glsl_version; // e.g. 130 for GLSL 1.30
|
int glsl_version; // e.g. 130 for GLSL 1.30
|
||||||
@@ -192,10 +190,8 @@ struct GL
|
|||||||
|
|
||||||
void(GLAPIENTRY *VDPAUInitNV)(const GLvoid *, const GLvoid *);
|
void(GLAPIENTRY *VDPAUInitNV)(const GLvoid *, const GLvoid *);
|
||||||
void(GLAPIENTRY *VDPAUFiniNV)(void);
|
void(GLAPIENTRY *VDPAUFiniNV)(void);
|
||||||
GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterOutputSurfaceNV)
|
GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterOutputSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *);
|
||||||
(GLvoid *, GLenum, GLsizei, const GLuint *);
|
GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterVideoSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *);
|
||||||
GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterVideoSurfaceNV)
|
|
||||||
(GLvoid *, GLenum, GLsizei, const GLuint *);
|
|
||||||
void(GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV);
|
void(GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV);
|
||||||
void(GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum);
|
void(GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum);
|
||||||
void(GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *);
|
void(GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *);
|
||||||
@@ -203,13 +199,17 @@ struct GL
|
|||||||
|
|
||||||
#if HAVE_GL_WIN32
|
#if HAVE_GL_WIN32
|
||||||
// The HANDLE type might not be present on non-Win32
|
// The HANDLE type might not be present on non-Win32
|
||||||
BOOL(GLAPIENTRY * DXSetResourceShareHandleNV) (void *dxObject, HANDLE shareHandle);
|
BOOL(GLAPIENTRY *DXSetResourceShareHandleNV)
|
||||||
|
(void *dxObject, HANDLE shareHandle);
|
||||||
HANDLE(GLAPIENTRY *DXOpenDeviceNV)(void *dxDevice);
|
HANDLE(GLAPIENTRY *DXOpenDeviceNV)(void *dxDevice);
|
||||||
BOOL(GLAPIENTRY *DXCloseDeviceNV)(HANDLE hDevice);
|
BOOL(GLAPIENTRY *DXCloseDeviceNV)(HANDLE hDevice);
|
||||||
HANDLE(GLAPIENTRY * DXRegisterObjectNV) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
HANDLE(GLAPIENTRY *DXRegisterObjectNV)
|
||||||
|
(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
||||||
BOOL(GLAPIENTRY *DXUnregisterObjectNV)(HANDLE hDevice, HANDLE hObject);
|
BOOL(GLAPIENTRY *DXUnregisterObjectNV)(HANDLE hDevice, HANDLE hObject);
|
||||||
BOOL(GLAPIENTRY * DXLockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects);
|
BOOL(GLAPIENTRY *DXLockObjectsNV)
|
||||||
BOOL(GLAPIENTRY * DXUnlockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects);
|
(HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||||
|
BOOL(GLAPIENTRY *DXUnlockObjectsNV)
|
||||||
|
(HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GLint(GLAPIENTRY *GetVideoSync)(GLuint *);
|
GLint(GLAPIENTRY *GetVideoSync)(GLuint *);
|
||||||
|
272
drm.c
272
drm.c
@@ -1,9 +1,7 @@
|
|||||||
#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>
|
||||||
|
|
||||||
@@ -13,8 +11,7 @@
|
|||||||
// DRM
|
// DRM
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct _Drm_Render_
|
struct _Drm_Render_ {
|
||||||
{
|
|
||||||
int fd_drm;
|
int fd_drm;
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
drmModeCrtc *saved_crtc;
|
drmModeCrtc *saved_crtc;
|
||||||
@@ -24,7 +21,6 @@ struct _Drm_Render_
|
|||||||
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++)
|
||||||
@@ -80,21 +73,16 @@ static const struct type_name connector_type_names[] = {
|
|||||||
{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)
|
||||||
@@ -151,15 +135,12 @@ static uint32_t GetPropertyID(int fd_drm, uint32_t objectID,
|
|||||||
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)
|
||||||
@@ -177,29 +158,25 @@ 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;
|
||||||
|
printf("Set video mode %d &%d\n",width,height);
|
||||||
if (height != 1080 && height != 2160)
|
if (height != 1080 && height != 2160)
|
||||||
return;
|
return;
|
||||||
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 &&
|
|
||||||
render->mode.hdisplay != width &&
|
|
||||||
render->mode.vdisplay != height &&
|
|
||||||
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
VideoWindowWidth = mode->hdisplay;
|
VideoWindowWidth = mode->hdisplay;
|
||||||
@@ -215,8 +192,7 @@ void set_video_mode(int width, int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FindDevice(VideoRender * render)
|
static int FindDevice(VideoRender *render) {
|
||||||
{
|
|
||||||
drmVersion *version;
|
drmVersion *version;
|
||||||
drmModeRes *resources;
|
drmModeRes *resources;
|
||||||
drmModeConnector *connector;
|
drmModeConnector *connector;
|
||||||
@@ -231,32 +207,28 @@ static int FindDevice(VideoRender * render)
|
|||||||
int i, ii = 0;
|
int i, ii = 0;
|
||||||
char connectorstr[10];
|
char connectorstr[10];
|
||||||
int found = 0;
|
int found = 0;
|
||||||
#ifdef RASPI
|
|
||||||
render->fd_drm = open("/dev/dri/card1", O_RDWR);
|
|
||||||
#else
|
|
||||||
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
render->fd_drm = open("/dev/dri/card0", O_RDWR);
|
||||||
#endif
|
|
||||||
if (render->fd_drm < 0) {
|
if (render->fd_drm < 0) {
|
||||||
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
|
render->fd_drm = open("/dev/dri/card1", O_RDWR);
|
||||||
|
if (render->fd_drm < 0) {
|
||||||
|
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0 or card1: %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;
|
||||||
}
|
}
|
||||||
@@ -290,9 +262,8 @@ static int FindDevice(VideoRender * render)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#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,12 +274,16 @@ 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);
|
||||||
|
printf("Connector >%s< is %sconnected\n", connectorstr,
|
||||||
|
connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
|
||||||
|
Debug(3,"Connector >%s< is %sconnected\n", connectorstr,
|
||||||
|
connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
|
||||||
if (DRMConnector && strcmp(DRMConnector, connectorstr))
|
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;
|
||||||
@@ -325,9 +300,10 @@ static int FindDevice(VideoRender * render)
|
|||||||
}
|
}
|
||||||
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
|
||||||
@@ -335,17 +311,14 @@ static int FindDevice(VideoRender * render)
|
|||||||
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);
|
||||||
|
Debug(3,"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;
|
||||||
@@ -357,10 +330,16 @@ static int FindDevice(VideoRender * render)
|
|||||||
found = 1;
|
found = 1;
|
||||||
i = resources->count_connectors; // uuuuhh
|
i = resources->count_connectors; // uuuuhh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
VideoWindowWidth = render->mode.hdisplay;
|
VideoWindowWidth = render->mode.hdisplay;
|
||||||
VideoWindowHeight = render->mode.vdisplay;
|
VideoWindowHeight = render->mode.vdisplay;
|
||||||
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);
|
||||||
|
Debug(3,"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) {
|
||||||
@@ -384,27 +363,23 @@ 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
|
||||||
for (k = 0; k < plane->count_formats; k++) {
|
for (k = 0; k < plane->count_formats; k++) {
|
||||||
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
if (encoder->possible_crtcs & plane->possible_crtcs) {
|
||||||
switch (plane->formats[k]) {
|
switch (plane->formats[k]) {
|
||||||
#ifdef RASPI
|
|
||||||
case DRM_FORMAT_ARGB8888:
|
|
||||||
#else
|
|
||||||
case DRM_FORMAT_XRGB2101010:
|
case DRM_FORMAT_XRGB2101010:
|
||||||
#endif
|
|
||||||
if (!render->video_plane) {
|
if (!render->video_plane) {
|
||||||
render->video_plane = plane->plane_id;
|
render->video_plane = plane->plane_id;
|
||||||
}
|
}
|
||||||
@@ -423,8 +398,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,11 +410,9 @@ 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)))) {
|
||||||
Fatal(_("video/DRM: out of memory\n"));
|
Fatal(_("video/DRM: out of memory\n"));
|
||||||
return;
|
return;
|
||||||
@@ -454,12 +426,14 @@ void VideoInitDrm()
|
|||||||
assert(gbm.dev != NULL);
|
assert(gbm.dev != NULL);
|
||||||
|
|
||||||
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
|
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
|
||||||
get_platform_display =
|
|
||||||
(void *) eglGetProcAddress("eglGetPlatformDisplay");
|
get_platform_display = (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();
|
||||||
|
|
||||||
assert(eglDisplay != NULL);
|
assert(eglDisplay != NULL);
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
@@ -476,12 +450,10 @@ void VideoInitDrm()
|
|||||||
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);
|
||||||
@@ -490,11 +462,9 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -506,6 +476,7 @@ 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;
|
render->bpp = bpp;
|
||||||
gbm.surface = gbm_surface_create(gbm.dev, VideoWindowWidth, VideoWindowHeight,
|
gbm.surface = gbm_surface_create(gbm.dev, VideoWindowWidth, VideoWindowHeight,
|
||||||
bpp == 10 ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_ARGB8888,
|
bpp == 10 ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_ARGB8888,
|
||||||
@@ -513,17 +484,18 @@ void InitBo(int bpp) {
|
|||||||
assert(gbm.surface != NULL);
|
assert(gbm.surface != NULL);
|
||||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL);
|
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL);
|
||||||
assert(eglSurface != 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 void drm_swap_buffers() {
|
static void drm_swap_buffers() {
|
||||||
|
|
||||||
uint32_t fb;
|
uint32_t fb;
|
||||||
|
|
||||||
eglSwapBuffers(eglDisplay, eglSurface);
|
eglSwapBuffers(eglDisplay, eglSurface);
|
||||||
|
usleep(1000);
|
||||||
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)
|
||||||
@@ -533,8 +505,8 @@ static void drm_swap_buffers () {
|
|||||||
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) {
|
||||||
@@ -552,30 +524,31 @@ 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);
|
||||||
sleep(2);
|
|
||||||
|
|
||||||
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->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",
|
||||||
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
old_color == AVCOL_PRI_BT2020 ? 2 : 1);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 0);
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
|
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, "ACTIVE", 1);
|
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 modeset 2 (%d): %m\n", errno);
|
||||||
|
|
||||||
if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0)
|
if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0)
|
||||||
fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno);
|
fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno);
|
||||||
|
|
||||||
drmModeAtomicFree(ModeReq);
|
drmModeAtomicFree(ModeReq);
|
||||||
m_need_modeset = 0;
|
m_need_modeset = 0;
|
||||||
|
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) {
|
||||||
@@ -584,7 +557,6 @@ static void drm_swap_buffers () {
|
|||||||
}
|
}
|
||||||
previous_bo = bo;
|
previous_bo = bo;
|
||||||
previous_fb = fb;
|
previous_fb = fb;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_clean_up() {
|
static void drm_clean_up() {
|
||||||
@@ -594,35 +566,81 @@ static void drm_clean_up () {
|
|||||||
return;
|
return;
|
||||||
Debug(3, "drm clean up\n");
|
Debug(3, "drm clean up\n");
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
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,
|
if (has_modeset) {
|
||||||
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
|
drmModeAtomicReqPtr ModeReq;
|
||||||
drmModeFreeCrtc (render->saved_crtc);
|
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);
|
||||||
|
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR,
|
||||||
|
"HDR_OUTPUT_METADATA", 0);
|
||||||
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, 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, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 1);
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
#if 0
|
||||||
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
eglDestroySurface(eglDisplay, eglSurface);
|
eglDestroySurface(eglDisplay, eglSurface);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
gbm_surface_destroy (gbm.surface);
|
|
||||||
eglDestroyContext (eglDisplay, eglContext);
|
|
||||||
EglCheck();
|
|
||||||
eglDestroyContext(eglDisplay, eglSharedContext);
|
eglDestroyContext(eglDisplay, eglSharedContext);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
|
eglDestroyContext(eglDisplay, eglContext);
|
||||||
|
EglCheck();
|
||||||
eglSharedContext = NULL;
|
eglSharedContext = NULL;
|
||||||
|
eglContext = NULL;
|
||||||
eglTerminate(eglDisplay);
|
eglTerminate(eglDisplay);
|
||||||
EglCheck();
|
EglCheck();
|
||||||
|
eglDisplay = NULL;
|
||||||
|
#endif
|
||||||
|
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
eglDestroySurface(eglDisplay, eglSurface);
|
||||||
|
EglCheck();
|
||||||
|
eglSurface = NULL;
|
||||||
|
gbm_surface_destroy(gbm.surface);
|
||||||
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;
|
|
||||||
free(render);
|
free(render);
|
||||||
|
render = NULL;
|
||||||
|
Debug(3, "nach drm clean up\n");
|
||||||
}
|
}
|
@@ -14,12 +14,11 @@
|
|||||||
#define _DRVAPI_ERROR_STRING_H_
|
#define _DRVAPI_ERROR_STRING_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// Error Code string definitions here
|
// Error Code string definitions here
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
char const *error_string;
|
char const *error_string;
|
||||||
unsigned int error_id;
|
unsigned int error_id;
|
||||||
} s_CudaErrorStr;
|
} s_CudaErrorStr;
|
||||||
@@ -84,8 +83,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8},
|
{"CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This indicates that no CUDA-capable devices were detected by the installed
|
* This indicates that no CUDA-capable devices were detected by the
|
||||||
* CUDA driver.
|
* installed CUDA driver.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100},
|
{"CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100},
|
||||||
|
|
||||||
@@ -256,18 +255,19 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This indicates that asynchronous operations issued previously have not
|
* This indicates that asynchronous operations issued previously have not
|
||||||
* completed yet. This result is not actually an error, but must be indicated
|
* completed yet. This result is not actually an error, but must be
|
||||||
* differently than ::CUDA_SUCCESS (which indicates completion). Calls that
|
* indicated differently than ::CUDA_SUCCESS (which indicates completion).
|
||||||
* may return this value include ::cuEventQuery() and ::cuStreamQuery().
|
* Calls that may return this value include ::cuEventQuery() and
|
||||||
|
* ::cuStreamQuery().
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_NOT_READY", 600},
|
{"CUDA_ERROR_NOT_READY", 600},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a
|
* While executing a kernel, the device encountered a
|
||||||
* load or store instruction on an invalid memory address.
|
* load or store instruction on an invalid memory address.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_ILLEGAL_ADDRESS", 700},
|
{"CUDA_ERROR_ILLEGAL_ADDRESS", 700},
|
||||||
|
|
||||||
@@ -342,8 +342,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_TOO_MANY_PEERS", 711},
|
{"CUDA_ERROR_TOO_MANY_PEERS", 711},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This error indicates that the memory range passed to ::cuMemHostRegister()
|
* This error indicates that the memory range passed to
|
||||||
* has already been registered.
|
* ::cuMemHostRegister() has already been registered.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712},
|
{"CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712},
|
||||||
|
|
||||||
@@ -356,25 +356,25 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a stack error.
|
* While executing a kernel, the device encountered a stack error.
|
||||||
* This can be due to stack corruption or exceeding the stack size limit.
|
* This can be due to stack corruption or exceeding the stack size limit.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_HARDWARE_STACK_ERROR", 714},
|
{"CUDA_ERROR_HARDWARE_STACK_ERROR", 714},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered an illegal instruction.
|
* While executing a kernel, the device encountered an illegal instruction.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_ILLEGAL_INSTRUCTION", 715},
|
{"CUDA_ERROR_ILLEGAL_INSTRUCTION", 715},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a load or store instruction
|
* While executing a kernel, the device encountered a load or store
|
||||||
* on a memory address which is not aligned.
|
* instruction on a memory address which is not aligned. This leaves the
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* process in an inconsistent state and any further CUDA work will return
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* the same error. To continue using CUDA, the process must be terminated
|
||||||
* and relaunched.
|
* and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_MISALIGNED_ADDRESS", 716},
|
{"CUDA_ERROR_MISALIGNED_ADDRESS", 716},
|
||||||
@@ -384,17 +384,17 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
* which can only operate on memory locations in certain address spaces
|
* which can only operate on memory locations in certain address spaces
|
||||||
* (global, shared, or local), but was supplied a memory address not
|
* (global, shared, or local), but was supplied a memory address not
|
||||||
* belonging to an allowed address space.
|
* belonging to an allowed address space.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_INVALID_ADDRESS_SPACE", 717},
|
{"CUDA_ERROR_INVALID_ADDRESS_SPACE", 717},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device program counter wrapped its address space.
|
* While executing a kernel, the device program counter wrapped its address
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* space. This leaves the process in an inconsistent state and any further
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* CUDA work will return the same error. To continue using CUDA, the process
|
||||||
* and relaunched.
|
* must be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_INVALID_PC", 718},
|
{"CUDA_ERROR_INVALID_PC", 718},
|
||||||
|
|
||||||
@@ -409,11 +409,13 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_LAUNCH_FAILED", 719},
|
{"CUDA_ERROR_LAUNCH_FAILED", 719},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This error indicates that the number of blocks launched per grid for a kernel that was
|
* This error indicates that the number of blocks launched per grid for a
|
||||||
* launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice
|
* kernel that was launched via either ::cuLaunchCooperativeKernel or
|
||||||
* exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor
|
* ::cuLaunchCooperativeKernelMultiDevice exceeds the maximum number of
|
||||||
* or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors
|
* blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor or
|
||||||
* as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
|
* ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number
|
||||||
|
* of multiprocessors as specified by the device attribute
|
||||||
|
* ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720},
|
{"CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720},
|
||||||
|
|
||||||
@@ -432,13 +434,11 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
* This indicates that an unknown internal error has occurred.
|
* This indicates that an unknown internal error has occurred.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_UNKNOWN", 999},
|
{"CUDA_ERROR_UNKNOWN", 999},
|
||||||
{NULL, -1}
|
{NULL, -1}};
|
||||||
};
|
|
||||||
|
|
||||||
// This is just a linear search through the array, since the error_id's are not
|
// This is just a linear search through the array, since the error_id's are not
|
||||||
// always ocurring consecutively
|
// always ocurring consecutively
|
||||||
static inline const char *getCudaDrvErrorString(CUresult error_id)
|
static inline const char *getCudaDrvErrorString(CUresult error_id) {
|
||||||
{
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
while (sCudaDrvErrorString[index].error_id != error_id && (int)sCudaDrvErrorString[index].error_id != -1) {
|
while (sCudaDrvErrorString[index].error_id != error_id && (int)sCudaDrvErrorString[index].error_id != -1) {
|
||||||
|
384
hdr.c
384
hdr.c
@@ -1,5 +1,5 @@
|
|||||||
#include <libavutil/mastering_display_metadata.h>
|
#include <libavutil/mastering_display_metadata.h>
|
||||||
|
#ifndef _DRM_MODE_H
|
||||||
/**
|
/**
|
||||||
* struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
|
* struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
|
||||||
*
|
*
|
||||||
@@ -85,8 +85,7 @@ struct hdr_output_metadata {
|
|||||||
struct hdr_metadata_infoframe hdmi_metadata_type1;
|
struct hdr_metadata_infoframe hdmi_metadata_type1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum hdr_metadata_eotf {
|
enum hdr_metadata_eotf {
|
||||||
EOTF_TRADITIONAL_GAMMA_SDR,
|
EOTF_TRADITIONAL_GAMMA_SDR,
|
||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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,
|
||||||
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.1596f,
|
||||||
|
0.8404f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.0366f,
|
||||||
|
0.0001f,
|
||||||
|
}},
|
||||||
.whitepoint = {{.3457, .3585}},
|
.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)
|
||||||
@@ -317,15 +455,10 @@ weston_colorspace_lookup(const char *name)
|
|||||||
|
|
||||||
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;
|
||||||
@@ -335,17 +468,9 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
struct AVMasteringDisplayMetadata *md = NULL;
|
struct AVMasteringDisplayMetadata *md = NULL;
|
||||||
struct AVContentLightMetadata *ld = NULL;
|
struct AVContentLightMetadata *ld = NULL;
|
||||||
|
|
||||||
if (render->hdr_metadata == -1) { // Metadata not supported
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 (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)
|
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
@@ -359,8 +484,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
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;
|
return;
|
||||||
}
|
} else if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
|
||||||
else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,12 +495,14 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
|
|
||||||
Debug(3, "Update HDR to TRC %d color %d\n", trc, color);
|
Debug(3, "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_color = color;
|
||||||
old_trc = trc;
|
old_trc = trc;
|
||||||
|
|
||||||
|
if (VulkanTargetColorSpace != 3) { // no HDR TV
|
||||||
|
m_need_modeset = 1; // change in colorsettings
|
||||||
|
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);
|
||||||
|
|
||||||
@@ -416,17 +542,14 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
|
|
||||||
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,
|
||||||
|
"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"
|
"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",
|
"min_luminance=%f, max_luminance=%f\n",
|
||||||
md->has_primaries, md->has_luminance,
|
md->has_primaries, md->has_luminance, av_q2d(md->display_primaries[0][0]),
|
||||||
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[0][1]),
|
av_q2d(md->display_primaries[1][1]), av_q2d(md->display_primaries[2][0]),
|
||||||
av_q2d(md->display_primaries[1][0]),
|
av_q2d(md->display_primaries[2][1]), av_q2d(md->white_point[0]), av_q2d(md->white_point[1]),
|
||||||
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));
|
av_q2d(md->min_luminance), av_q2d(md->max_luminance));
|
||||||
|
|
||||||
cs = &hdr10;
|
cs = &hdr10;
|
||||||
@@ -451,23 +574,15 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
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]),
|
|
||||||
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
|
max_lum, // max_display_mastering_luminance
|
||||||
min_lum, // min_display_mastering_luminance
|
min_lum, // min_display_mastering_luminance
|
||||||
MaxCLL, // Maximum Content Light Level (MaxCLL)
|
MaxCLL, // Maximum Content Light Level (MaxCLL)
|
||||||
MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
|
MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
|
||||||
eotf);
|
eotf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &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 blob create \n");
|
printf("DRM: HDR metadata: failed blob create \n");
|
||||||
@@ -475,8 +590,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
|
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, render->hdr_metadata, render->hdr_blob_id);
|
||||||
render->hdr_metadata, render->hdr_blob_id);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("DRM: HDR metadata: failed property set %d\n", ret);
|
printf("DRM: HDR metadata: failed property set %d\n", ret);
|
||||||
|
|
||||||
@@ -485,8 +599,8 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
render->hdr_blob_id = 0;
|
render->hdr_blob_id = 0;
|
||||||
return;
|
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");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
iatomic.h
22
iatomic.h
@@ -23,9 +23,7 @@
|
|||||||
/// @addtogroup iatomic
|
/// @addtogroup iatomic
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||||
+ __GNUC_MINOR__ * 100 \
|
|
||||||
+ __GNUC_PATCHLEVEL__)
|
|
||||||
|
|
||||||
// gcc before 4.7 didn't support atomic builtins,
|
// gcc before 4.7 didn't support atomic builtins,
|
||||||
// use alsa atomic functions.
|
// use alsa atomic functions.
|
||||||
@@ -59,38 +57,32 @@ typedef volatile int atomic_t;
|
|||||||
///
|
///
|
||||||
/// Set atomic value.
|
/// Set atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_set(ptr, val) \
|
#define atomic_set(ptr, val) __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_store_n(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Read atomic value.
|
/// Read atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_read(ptr) \
|
#define atomic_read(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST)
|
||||||
__atomic_load_n(ptr, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Increment atomic value.
|
/// Increment atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_inc(ptr) \
|
#define atomic_inc(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
||||||
__atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Decrement atomic value.
|
/// Decrement atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_dec(ptr) \
|
#define atomic_dec(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
||||||
__atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Add to atomic value.
|
/// Add to atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_add(val, ptr) \
|
#define atomic_add(val, ptr) __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Subtract from atomic value.
|
/// Subtract from atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_sub(val, ptr) \
|
#define atomic_sub(val, ptr) __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
23
misc.h
23
misc.h
@@ -24,8 +24,8 @@
|
|||||||
/// @addtogroup misc
|
/// @addtogroup misc
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <time.h> // clock_gettime
|
#include <time.h> // clock_gettime
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -46,8 +46,7 @@ extern int SysLogLevel; ///< how much information wanted
|
|||||||
// Prototypes
|
// Prototypes
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static inline void Syslog(const int, const char *format, ...)
|
static inline void Syslog(const int, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||||
__attribute__((format(printf, 2, 3)));
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Inlines
|
// Inlines
|
||||||
@@ -67,8 +66,7 @@ static inline void Syslog(const int, const char *format, ...)
|
|||||||
** - 2 info
|
** - 2 info
|
||||||
** - 3 important debug and fixme's
|
** - 3 important debug and fixme's
|
||||||
*/
|
*/
|
||||||
static inline void Syslog(const int level, const char *format, ...)
|
static inline void Syslog(const int level, const char *format, ...) {
|
||||||
{
|
|
||||||
if (SysLogLevel > level || DebugLevel > level) {
|
if (SysLogLevel > level || DebugLevel > level) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -86,7 +84,11 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
/**
|
/**
|
||||||
** Show fatal error.
|
** Show fatal error.
|
||||||
*/
|
*/
|
||||||
#define Fatal(fmt...) do { Error(fmt); abort(); } while (0)
|
#define Fatal(fmt...) \
|
||||||
|
do { \
|
||||||
|
Error(fmt); \
|
||||||
|
abort(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Show warning.
|
** Show warning.
|
||||||
@@ -116,8 +118,7 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
**
|
**
|
||||||
** @param ts dvb time stamp
|
** @param ts dvb time stamp
|
||||||
*/
|
*/
|
||||||
static inline const char *Timestamp2String(int64_t ts)
|
static inline const char *Timestamp2String(int64_t ts) {
|
||||||
{
|
|
||||||
static char buf[4][16];
|
static char buf[4][16];
|
||||||
static int idx;
|
static int idx;
|
||||||
|
|
||||||
@@ -136,8 +137,7 @@ static inline const char *Timestamp2String(int64_t ts)
|
|||||||
**
|
**
|
||||||
** @returns ticks in ms,
|
** @returns ticks in ms,
|
||||||
*/
|
*/
|
||||||
static inline uint32_t GetMsTicks(void)
|
static inline uint32_t GetMsTicks(void) {
|
||||||
{
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
#ifdef CLOCK_MONOTONIC
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
|
||||||
@@ -153,8 +153,7 @@ static inline uint32_t GetMsTicks(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t GetusTicks(void)
|
static inline uint64_t GetusTicks(void) {
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
#ifdef CLOCK_MONOTONIC
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
599
openglosd.cpp
599
openglosd.cpp
File diff suppressed because it is too large
Load Diff
392
openglosd.h
392
openglosd.h
@@ -1,6 +1,7 @@
|
|||||||
#ifndef __SOFTHDDEVICE_OPENGLOSD_H
|
#ifndef __SOFTHDDEVICE_OPENGLOSD_H
|
||||||
#define __SOFTHDDEVICE_OPENGLOSD_H
|
#define __SOFTHDDEVICE_OPENGLOSD_H
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/freeglut.h>
|
#include <GL/freeglut.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
@@ -36,17 +37,15 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
extern "C" pthread_mutex_t OSDMutex;
|
extern "C" pthread_mutex_t OSDMutex;
|
||||||
|
|
||||||
struct sOglImage
|
struct sOglImage {
|
||||||
{
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLint width;
|
GLint width;
|
||||||
GLint height;
|
GLint height;
|
||||||
@@ -62,28 +61,18 @@ void ConvertColor(const GLint & colARGB, glm::vec4 & col);
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cShader
|
* cShader
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
enum eShaderType
|
enum eShaderType { stRect, stTexture, stText, stCount };
|
||||||
{
|
|
||||||
stRect,
|
|
||||||
stTexture,
|
|
||||||
stText,
|
|
||||||
stCount
|
|
||||||
};
|
|
||||||
|
|
||||||
class cShader
|
class cShader {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
eShaderType type;
|
eShaderType type;
|
||||||
GLuint id;
|
GLuint id;
|
||||||
bool Compile(const char *vertexCode, const char *fragmentCode);
|
bool Compile(const char *vertexCode, const char *fragmentCode);
|
||||||
bool CheckCompileErrors(GLuint object, bool program = false);
|
bool CheckCompileErrors(GLuint object, bool program = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cShader(void)
|
cShader(void){};
|
||||||
{
|
virtual ~cShader(void){};
|
||||||
};
|
|
||||||
virtual ~ cShader(void)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
bool Load(eShaderType type);
|
bool Load(eShaderType type);
|
||||||
void Use(void);
|
void Use(void);
|
||||||
void SetFloat(const GLchar *name, GLfloat value);
|
void SetFloat(const GLchar *name, GLfloat value);
|
||||||
@@ -97,11 +86,9 @@ class cShader
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglGlyph
|
* cOglGlyph
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglGlyph:public cListObject
|
class cOglGlyph : public cListObject {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
struct tKerning
|
struct tKerning {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) {
|
tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) {
|
||||||
this->prevSym = prevSym;
|
this->prevSym = prevSym;
|
||||||
@@ -124,30 +111,12 @@ class cOglGlyph:public cListObject
|
|||||||
public:
|
public:
|
||||||
cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph);
|
cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph);
|
||||||
virtual ~cOglGlyph();
|
virtual ~cOglGlyph();
|
||||||
FT_ULong CharCode(void)
|
FT_ULong CharCode(void) { return charCode; }
|
||||||
{
|
int AdvanceX(void) { return advanceX; }
|
||||||
return charCode;
|
int BearingLeft(void) const { return bearingLeft; }
|
||||||
}
|
int BearingTop(void) const { return bearingTop; }
|
||||||
int AdvanceX(void)
|
int Width(void) const { return width; }
|
||||||
{
|
int Height(void) const { return height; }
|
||||||
return advanceX;
|
|
||||||
}
|
|
||||||
int BearingLeft(void) const
|
|
||||||
{
|
|
||||||
return bearingLeft;
|
|
||||||
}
|
|
||||||
int BearingTop(void) const
|
|
||||||
{
|
|
||||||
return bearingTop;
|
|
||||||
}
|
|
||||||
int Width(void) const
|
|
||||||
{
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
int Height(void) const
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
int GetKerningCache(FT_ULong prevSym);
|
int GetKerningCache(FT_ULong prevSym);
|
||||||
void SetKerningCache(FT_ULong prevSym, int kerning);
|
void SetKerningCache(FT_ULong prevSym, int kerning);
|
||||||
void BindTexture(void);
|
void BindTexture(void);
|
||||||
@@ -156,8 +125,7 @@ class cOglGlyph:public cListObject
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglFont
|
* cOglFont
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglFont:public cListObject
|
class cOglFont : public cListObject {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
static bool initiated;
|
static bool initiated;
|
||||||
cString name;
|
cString name;
|
||||||
@@ -170,26 +138,15 @@ class cOglFont:public cListObject
|
|||||||
mutable cList<cOglGlyph> glyphCache;
|
mutable cList<cOglGlyph> glyphCache;
|
||||||
cOglFont(const char *fontName, int charHeight);
|
cOglFont(const char *fontName, int charHeight);
|
||||||
static void Init(void);
|
static void Init(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~cOglFont(void);
|
virtual ~cOglFont(void);
|
||||||
static cOglFont *Get(const char *name, int charHeight);
|
static cOglFont *Get(const char *name, int charHeight);
|
||||||
static void Cleanup(void);
|
static void Cleanup(void);
|
||||||
const char *Name(void)
|
const char *Name(void) { return *name; };
|
||||||
{
|
int Size(void) { return size; };
|
||||||
return *name;
|
int Bottom(void) { return bottom; };
|
||||||
};
|
int Height(void) { return height; };
|
||||||
int Size(void)
|
|
||||||
{
|
|
||||||
return size;
|
|
||||||
};
|
|
||||||
int Bottom(void)
|
|
||||||
{
|
|
||||||
return bottom;
|
|
||||||
};
|
|
||||||
int Height(void)
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
};
|
|
||||||
cOglGlyph *Glyph(FT_ULong charCode) const;
|
cOglGlyph *Glyph(FT_ULong charCode) const;
|
||||||
int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const;
|
int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const;
|
||||||
};
|
};
|
||||||
@@ -198,8 +155,7 @@ class cOglFont:public cListObject
|
|||||||
* cOglFb
|
* cOglFb
|
||||||
* Framebuffer Object - OpenGL part of a Pixmap
|
* Framebuffer Object - OpenGL part of a Pixmap
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglFb
|
class cOglFb {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
bool initiated;
|
bool initiated;
|
||||||
// GLuint fb;
|
// GLuint fb;
|
||||||
@@ -207,16 +163,14 @@ class cOglFb
|
|||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint viewPortWidth, viewPortHeight;
|
GLint viewPortWidth, viewPortHeight;
|
||||||
bool scrollable;
|
bool scrollable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint fb;
|
GLuint fb;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
|
||||||
cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight);
|
cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight);
|
||||||
virtual ~cOglFb(void);
|
virtual ~cOglFb(void);
|
||||||
bool Initiated(void)
|
bool Initiated(void) { return initiated; }
|
||||||
{
|
|
||||||
return initiated;
|
|
||||||
}
|
|
||||||
virtual bool Init(void);
|
virtual bool Init(void);
|
||||||
void Bind(void);
|
void Bind(void);
|
||||||
void BindRead(void);
|
void BindRead(void);
|
||||||
@@ -224,38 +178,25 @@ class cOglFb
|
|||||||
virtual void Unbind(void);
|
virtual void Unbind(void);
|
||||||
bool BindTexture(void);
|
bool BindTexture(void);
|
||||||
void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2);
|
void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2);
|
||||||
GLint Width(void)
|
GLint Width(void) { return width; };
|
||||||
{
|
GLint Height(void) { return height; };
|
||||||
return width;
|
bool Scrollable(void) { return scrollable; };
|
||||||
};
|
GLint ViewportWidth(void) { return viewPortWidth; };
|
||||||
GLint Height(void)
|
GLint ViewportHeight(void) { return viewPortHeight; };
|
||||||
{
|
|
||||||
return height;
|
|
||||||
};
|
|
||||||
bool Scrollable(void)
|
|
||||||
{
|
|
||||||
return scrollable;
|
|
||||||
};
|
|
||||||
GLint ViewportWidth(void)
|
|
||||||
{
|
|
||||||
return viewPortWidth;
|
|
||||||
};
|
|
||||||
GLint ViewportHeight(void)
|
|
||||||
{
|
|
||||||
return viewPortHeight;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglOutputFb
|
* cOglOutputFb
|
||||||
* Output Framebuffer Object - holds Vdpau Output Surface which is our "output framebuffer"
|
* Output Framebuffer Object - holds Vdpau Output Surface which is our "output
|
||||||
|
*framebuffer"
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglOutputFb:public cOglFb
|
class cOglOutputFb : public cOglFb {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
bool initiated;
|
bool initiated;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLvdpauSurfaceNV surface;
|
GLvdpauSurfaceNV surface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint fb;
|
GLuint fb;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
@@ -270,18 +211,9 @@ class cOglOutputFb:public cOglFb
|
|||||||
* cOglVb
|
* cOglVb
|
||||||
* Vertex Buffer - OpenGl Vertices for the different drawing commands
|
* Vertex Buffer - OpenGl Vertices for the different drawing commands
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
enum eVertexBufferType
|
enum eVertexBufferType { vbRect, vbEllipse, vbSlope, vbTexture, vbText, vbCount };
|
||||||
{
|
|
||||||
vbRect,
|
|
||||||
vbEllipse,
|
|
||||||
vbSlope,
|
|
||||||
vbTexture,
|
|
||||||
vbText,
|
|
||||||
vbCount
|
|
||||||
};
|
|
||||||
|
|
||||||
class cOglVb
|
class cOglVb {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
eVertexBufferType type;
|
eVertexBufferType type;
|
||||||
eShaderType shader;
|
eShaderType shader;
|
||||||
@@ -291,6 +223,7 @@ class cOglVb
|
|||||||
int sizeVertex2;
|
int sizeVertex2;
|
||||||
int numVertices;
|
int numVertices;
|
||||||
GLuint drawMode;
|
GLuint drawMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglVb(int type);
|
cOglVb(int type);
|
||||||
virtual ~cOglVb(void);
|
virtual ~cOglVb(void);
|
||||||
@@ -310,141 +243,100 @@ class cOglVb
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOpenGLCmd
|
* cOpenGLCmd
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglCmd
|
class cOglCmd {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
cOglFb *fb;
|
cOglFb *fb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmd(cOglFb * fb)
|
cOglCmd(cOglFb *fb) { this->fb = fb; };
|
||||||
{
|
virtual ~cOglCmd(void){};
|
||||||
this->fb = fb;
|
|
||||||
};
|
|
||||||
virtual ~ cOglCmd(void)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
virtual const char *Description(void) = 0;
|
virtual const char *Description(void) = 0;
|
||||||
virtual bool Execute(void) = 0;
|
virtual bool Execute(void) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdInitOutputFb:public cOglCmd
|
class cOglCmdInitOutputFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglOutputFb *oFb;
|
cOglOutputFb *oFb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdInitOutputFb(cOglOutputFb *oFb);
|
cOglCmdInitOutputFb(cOglOutputFb *oFb);
|
||||||
virtual ~ cOglCmdInitOutputFb(void)
|
virtual ~cOglCmdInitOutputFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "InitOutputFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "InitOutputFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdInitFb:public cOglCmd
|
class cOglCmdInitFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL);
|
cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL);
|
||||||
virtual ~ cOglCmdInitFb(void)
|
virtual ~cOglCmdInitFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "InitFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "InitFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDeleteFb:public cOglCmd
|
class cOglCmdDeleteFb : public cOglCmd {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDeleteFb(cOglFb *fb);
|
cOglCmdDeleteFb(cOglFb *fb);
|
||||||
virtual ~ cOglCmdDeleteFb(void)
|
virtual ~cOglCmdDeleteFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DeleteFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DeleteFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdRenderFbToBufferFb:public cOglCmd
|
class cOglCmdRenderFbToBufferFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *buffer;
|
cOglFb *buffer;
|
||||||
GLfloat x, y;
|
GLfloat x, y;
|
||||||
GLfloat drawPortX, drawPortY;
|
GLfloat drawPortX, drawPortY;
|
||||||
GLint transparency;
|
GLint transparency;
|
||||||
|
GLint alphablending;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX,
|
cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX,
|
||||||
GLint drawPortY);
|
GLint drawPortY, bool alphablending);
|
||||||
virtual ~ cOglCmdRenderFbToBufferFb(void)
|
virtual ~cOglCmdRenderFbToBufferFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Render Framebuffer to Buffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Render Framebuffer to Buffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdCopyBufferToOutputFb:public cOglCmd
|
class cOglCmdCopyBufferToOutputFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglOutputFb *oFb;
|
cOglOutputFb *oFb;
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y);
|
cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y);
|
||||||
virtual ~ cOglCmdCopyBufferToOutputFb(void)
|
virtual ~cOglCmdCopyBufferToOutputFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Copy buffer to OutputFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Copy buffer to OutputFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdFill:public cOglCmd
|
class cOglCmdFill : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint color;
|
GLint color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdFill(cOglFb *fb, GLint color);
|
cOglCmdFill(cOglFb *fb, GLint color);
|
||||||
virtual ~ cOglCmdFill(void)
|
virtual ~cOglCmdFill(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Fill"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Fill";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawRectangle:public cOglCmd
|
class cOglCmdDrawRectangle : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint color;
|
GLint color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color);
|
cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color);
|
||||||
virtual ~ cOglCmdDrawRectangle(void)
|
virtual ~cOglCmdDrawRectangle(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawRectangle"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawRectangle";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawEllipse:public cOglCmd
|
class cOglCmdDrawEllipse : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
@@ -453,39 +345,29 @@ class cOglCmdDrawEllipse:public cOglCmd
|
|||||||
GLfloat *CreateVerticesFull(int &numVertices);
|
GLfloat *CreateVerticesFull(int &numVertices);
|
||||||
GLfloat *CreateVerticesQuadrant(int &numVertices);
|
GLfloat *CreateVerticesQuadrant(int &numVertices);
|
||||||
GLfloat *CreateVerticesHalf(int &numVertices);
|
GLfloat *CreateVerticesHalf(int &numVertices);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants);
|
cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants);
|
||||||
virtual ~ cOglCmdDrawEllipse(void)
|
virtual ~cOglCmdDrawEllipse(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawEllipse"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawEllipse";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawSlope:public cOglCmd
|
class cOglCmdDrawSlope : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint color;
|
GLint color;
|
||||||
GLint type;
|
GLint type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type);
|
cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type);
|
||||||
virtual ~ cOglCmdDrawSlope(void)
|
virtual ~cOglCmdDrawSlope(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawSlope"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawSlope";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawText:public cOglCmd
|
class cOglCmdDrawText : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint limitX;
|
GLint limitX;
|
||||||
@@ -493,81 +375,64 @@ class cOglCmdDrawText:public cOglCmd
|
|||||||
cString fontName;
|
cString fontName;
|
||||||
int fontSize;
|
int fontSize;
|
||||||
unsigned int *symbols;
|
unsigned int *symbols;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawText(cOglFb * fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name,
|
cOglCmdDrawText(cOglFb *fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, int fontSize,
|
||||||
int fontSize, tColor colorText);
|
tColor colorText);
|
||||||
virtual ~cOglCmdDrawText(void);
|
virtual ~cOglCmdDrawText(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "DrawText"; }
|
||||||
{
|
|
||||||
return "DrawText";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawImage:public cOglCmd
|
class cOglCmdDrawImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
tColor *argb;
|
tColor *argb;
|
||||||
GLint x, y, width, height;
|
GLint x, y, width, height;
|
||||||
bool overlay;
|
bool overlay;
|
||||||
GLfloat scaleX, scaleY;
|
GLfloat scaleX, scaleY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawImage(cOglFb * fb, tColor * argb, GLint width, GLint height, GLint x, GLint y, bool overlay =
|
cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint height, GLint x, GLint y, bool overlay = true,
|
||||||
true, double scaleX = 1.0f, double scaleY = 1.0f);
|
double scaleX = 1.0f, double scaleY = 1.0f);
|
||||||
virtual ~cOglCmdDrawImage(void);
|
virtual ~cOglCmdDrawImage(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "Draw Image"; }
|
||||||
{
|
|
||||||
return "Draw Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawTexture:public cOglCmd
|
class cOglCmdDrawTexture : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
|
GLfloat scaleX, scaleY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawTexture(cOglFb * fb, sOglImage * imageRef, GLint x, GLint y);
|
cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y, double scaleX = 1.0f, double scaleY = 1.0f);
|
||||||
virtual ~ cOglCmdDrawTexture(void)
|
virtual ~cOglCmdDrawTexture(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Draw Texture"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Draw Texture";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdStoreImage:public cOglCmd
|
class cOglCmdStoreImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
tColor *data;
|
tColor *data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdStoreImage(sOglImage *imageRef, tColor *argb);
|
cOglCmdStoreImage(sOglImage *imageRef, tColor *argb);
|
||||||
virtual ~cOglCmdStoreImage(void);
|
virtual ~cOglCmdStoreImage(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "Store Image"; }
|
||||||
{
|
|
||||||
return "Store Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDropImage:public cOglCmd
|
class cOglCmdDropImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait);
|
cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait);
|
||||||
virtual ~ cOglCmdDropImage(void)
|
virtual ~cOglCmdDropImage(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Drop Image"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Drop Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -577,8 +442,7 @@ class cOglCmdDropImage:public cOglCmd
|
|||||||
#define OGL_MAX_OSDIMAGES 256
|
#define OGL_MAX_OSDIMAGES 256
|
||||||
#define OGL_CMDQUEUE_SIZE 100
|
#define OGL_CMDQUEUE_SIZE 100
|
||||||
|
|
||||||
class cOglThread:public cThread
|
class cOglThread : public cThread {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cCondWait *startWait;
|
cCondWait *startWait;
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
@@ -597,8 +461,10 @@ class cOglThread:public cThread
|
|||||||
void Cleanup(void);
|
void Cleanup(void);
|
||||||
int GetFreeSlot(void);
|
int GetFreeSlot(void);
|
||||||
void ClearSlot(int slot);
|
void ClearSlot(int slot);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglThread(cCondWait *startWait, int maxCacheSize);
|
cOglThread(cCondWait *startWait, int maxCacheSize);
|
||||||
virtual ~cOglThread();
|
virtual ~cOglThread();
|
||||||
@@ -607,44 +473,27 @@ class cOglThread:public cThread
|
|||||||
int StoreImage(const cImage &image);
|
int StoreImage(const cImage &image);
|
||||||
void DropImageData(int imageHandle);
|
void DropImageData(int imageHandle);
|
||||||
sOglImage *GetImageRef(int slot);
|
sOglImage *GetImageRef(int slot);
|
||||||
int MaxTextureSize(void)
|
int MaxTextureSize(void) { return maxTextureSize; };
|
||||||
{
|
|
||||||
return maxTextureSize;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglPixmap
|
* cOglPixmap
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglPixmap:public cPixmap
|
class cOglPixmap : public cPixmap {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *fb;
|
cOglFb *fb;
|
||||||
std::shared_ptr<cOglThread> oglThread;
|
std::shared_ptr<cOglThread> oglThread;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglPixmap(std::shared_ptr < cOglThread > oglThread, int Layer, const cRect & ViewPort, const cRect & DrawPort =
|
cOglPixmap(std::shared_ptr<cOglThread> oglThread, int Layer, const cRect &ViewPort,
|
||||||
cRect::Null);
|
const cRect &DrawPort = cRect::Null);
|
||||||
virtual ~cOglPixmap(void);
|
virtual ~cOglPixmap(void);
|
||||||
cOglFb *Fb(void)
|
cOglFb *Fb(void) { return fb; };
|
||||||
{
|
int X(void) { return ViewPort().X(); };
|
||||||
return fb;
|
int Y(void) { return ViewPort().Y(); };
|
||||||
};
|
virtual bool IsDirty(void) { return dirty; }
|
||||||
int X(void)
|
virtual void SetDirty(bool dirty = true) { this->dirty = dirty; }
|
||||||
{
|
|
||||||
return ViewPort().X();
|
|
||||||
};
|
|
||||||
int Y(void)
|
|
||||||
{
|
|
||||||
return ViewPort().Y();
|
|
||||||
};
|
|
||||||
virtual bool IsDirty(void)
|
|
||||||
{
|
|
||||||
return dirty;
|
|
||||||
}
|
|
||||||
virtual void SetDirty(bool dirty = true) {
|
|
||||||
this->dirty = dirty;
|
|
||||||
}
|
|
||||||
virtual void SetAlpha(int Alpha);
|
virtual void SetAlpha(int Alpha);
|
||||||
virtual void SetTile(bool Tile);
|
virtual void SetTile(bool Tile);
|
||||||
virtual void SetViewPort(const cRect &Rect);
|
virtual void SetViewPort(const cRect &Rect);
|
||||||
@@ -653,9 +502,11 @@ class cOglPixmap:public cPixmap
|
|||||||
virtual void Fill(tColor Color);
|
virtual void Fill(tColor Color);
|
||||||
virtual void DrawImage(const cPoint &Point, const cImage &Image);
|
virtual void DrawImage(const cPoint &Point, const cImage &Image);
|
||||||
virtual void DrawImage(const cPoint &Point, int ImageHandle);
|
virtual void DrawImage(const cPoint &Point, int ImageHandle);
|
||||||
|
virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX = 1.0f, double FactorY = 1.0f, bool AntiAlias = false);
|
||||||
|
virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX = 1.0f, double FactorY = 1.0f, bool AntiAlias = false);
|
||||||
virtual void DrawPixel(const cPoint &Point, tColor Color);
|
virtual void DrawPixel(const cPoint &Point, tColor Color);
|
||||||
virtual void DrawBitmap(const cPoint & Point, const cBitmap & Bitmap, tColor ColorFg = 0, tColor ColorBg =
|
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0,
|
||||||
0, bool Overlay = false);
|
bool Overlay = false);
|
||||||
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
|
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
|
||||||
int Width = 0, int Height = 0, int Alignment = taDefault);
|
int Width = 0, int Height = 0, int Alignment = taDefault);
|
||||||
virtual void DrawRectangle(const cRect &Rect, tColor Color);
|
virtual void DrawRectangle(const cRect &Rect, tColor Color);
|
||||||
@@ -670,17 +521,18 @@ class cOglPixmap:public cPixmap
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* cOglOsd
|
* cOglOsd
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
class cOglOsd:public cOsd
|
class cOglOsd : public cOsd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *bFb;
|
cOglFb *bFb;
|
||||||
std::shared_ptr<cOglThread> oglThread;
|
std::shared_ptr<cOglThread> oglThread;
|
||||||
cVector<cOglPixmap *> oglPixmaps;
|
cVector<cOglPixmap *> oglPixmaps;
|
||||||
bool isSubtitleOsd;
|
bool isSubtitleOsd;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread);
|
cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread);
|
||||||
virtual ~cOglOsd();
|
virtual ~cOglOsd();
|
||||||
|
static void SetOsdPosition(int Left, int Top, int Width, int Height);
|
||||||
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
|
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
|
||||||
virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
|
virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
|
||||||
virtual void DestroyPixmap(cPixmap *Pixmap);
|
virtual void DestroyPixmap(cPixmap *Pixmap);
|
||||||
|
111
po/de_DE.po
111
po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: VDR \n"
|
"Project-Id-Version: VDR \n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2020-04-15 18:57+0200\n"
|
"POT-Creation-Date: 2021-12-30 10:23+0100\n"
|
||||||
"PO-Revision-Date: blabla\n"
|
"PO-Revision-Date: blabla\n"
|
||||||
"Last-Translator: blabla\n"
|
"Last-Translator: blabla\n"
|
||||||
"Language-Team: blabla\n"
|
"Language-Team: blabla\n"
|
||||||
@@ -140,91 +140,6 @@ msgstr ""
|
|||||||
msgid "snd_pcm_drop(): %s\n"
|
msgid "snd_pcm_drop(): %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_GETOSPACE): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: write error: %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: error not all bytes written\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: error poll %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: using %sdevice '%s'\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: can't open dsp device '%s': %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(MIXER_WRITE): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: can't open mixer device '%s': %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SOUND_MIXER_READ_DEVMASK): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: channel '%s' not supported\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: channel '%s' not found\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: should not happen\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_GETODELAY): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_SETFMT): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: device doesn't support 16 bit sample format.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_CHANNELS): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: device doesn't support %d channels.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_SPEED): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: device doesn't support %dHz sample rate.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_POLICY): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: delay %ums\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "audio: can't set channels %d sample-rate %dHz\n"
|
msgid "audio: can't set channels %d sample-rate %dHz\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -306,9 +221,6 @@ msgstr ""
|
|||||||
msgid "codec/audio: can't setup resample\n"
|
msgid "codec/audio: can't setup resample\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "codec/audio: can't open resample\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "A software and GPU emulated UHD device"
|
msgid "A software and GPU emulated UHD device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -408,7 +320,7 @@ msgstr ""
|
|||||||
msgid "Hue (-314..314) "
|
msgid "Hue (-314..314) "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Monitor Colorspace"
|
msgid "Temperature 6500K + x * 100K"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Color Blindness"
|
msgid "Color Blindness"
|
||||||
@@ -417,6 +329,9 @@ msgstr ""
|
|||||||
msgid "Color Correction (-100..100) "
|
msgid "Color Correction (-100..100) "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Monitor Type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Scaling"
|
msgid "Scaling"
|
||||||
msgstr "Skalierung"
|
msgstr "Skalierung"
|
||||||
|
|
||||||
@@ -574,15 +489,15 @@ msgstr ""
|
|||||||
msgid "Suspend SoftHdDevice"
|
msgid "Suspend SoftHdDevice"
|
||||||
msgstr "Unterbreche SoftHdDevice"
|
msgstr "Unterbreche SoftHdDevice"
|
||||||
|
|
||||||
|
msgid "Toggle LUT on/off"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "PIP toggle on/off: off"
|
msgid "PIP toggle on/off: off"
|
||||||
msgstr "PIP deaktivieren"
|
msgstr "PIP deaktivieren"
|
||||||
|
|
||||||
msgid "PIP toggle on/off: on"
|
msgid "PIP toggle on/off: on"
|
||||||
msgstr "PIP aktivieren"
|
msgstr "PIP aktivieren"
|
||||||
|
|
||||||
msgid "PIP zapmode (not working)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "PIP channel +"
|
msgid "PIP channel +"
|
||||||
msgstr "PIP Kanal +"
|
msgstr "PIP Kanal +"
|
||||||
|
|
||||||
@@ -715,6 +630,10 @@ msgstr ""
|
|||||||
msgid "[softhddev] no codec known for still picture\n"
|
msgid "[softhddev] no codec known for still picture\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, c-format
|
||||||
|
msgid "Too much shaders definded\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"
|
msgid "Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -884,6 +803,9 @@ msgstr ""
|
|||||||
msgid "Failed initializing libplacebo\n"
|
msgid "Failed initializing libplacebo\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Failed to create placebo opengl \n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Failed to create XCB Surface\n"
|
msgid "Failed to create XCB Surface\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -893,6 +815,9 @@ msgstr ""
|
|||||||
msgid "Failed creating vulkan swapchain!"
|
msgid "Failed creating vulkan swapchain!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "libplacebo: failed initializing swapchain\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Failed initializing libplacebo renderer\n"
|
msgid "Failed initializing libplacebo renderer\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
40
ringbuffer.c
40
ringbuffer.c
@@ -34,8 +34,7 @@
|
|||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
/// ring buffer structure
|
/// ring buffer structure
|
||||||
struct _ring_buffer_
|
struct _ring_buffer_ {
|
||||||
{
|
|
||||||
char *Buffer; ///< ring buffer data
|
char *Buffer; ///< ring buffer data
|
||||||
const char *BufferEnd; ///< end of buffer
|
const char *BufferEnd; ///< end of buffer
|
||||||
size_t Size; ///< bytes in buffer (for faster calc)
|
size_t Size; ///< bytes in buffer (for faster calc)
|
||||||
@@ -52,8 +51,7 @@ struct _ring_buffer_
|
|||||||
**
|
**
|
||||||
** @param rb Ring buffer to reset read/write pointers.
|
** @param rb Ring buffer to reset read/write pointers.
|
||||||
*/
|
*/
|
||||||
void RingBufferReset(RingBuffer * rb)
|
void RingBufferReset(RingBuffer *rb) {
|
||||||
{
|
|
||||||
rb->ReadPointer = rb->Buffer;
|
rb->ReadPointer = rb->Buffer;
|
||||||
rb->WritePointer = rb->Buffer;
|
rb->WritePointer = rb->Buffer;
|
||||||
atomic_set(&rb->Filled, 0);
|
atomic_set(&rb->Filled, 0);
|
||||||
@@ -67,8 +65,7 @@ void RingBufferReset(RingBuffer * rb)
|
|||||||
** @returns Allocated ring buffer, must be freed with
|
** @returns Allocated ring buffer, must be freed with
|
||||||
** RingBufferDel(), NULL for out of memory.
|
** RingBufferDel(), NULL for out of memory.
|
||||||
*/
|
*/
|
||||||
RingBuffer *RingBufferNew(size_t size)
|
RingBuffer *RingBufferNew(size_t size) {
|
||||||
{
|
|
||||||
RingBuffer *rb;
|
RingBuffer *rb;
|
||||||
|
|
||||||
if (!(rb = malloc(sizeof(*rb)))) { // allocate structure
|
if (!(rb = malloc(sizeof(*rb)))) { // allocate structure
|
||||||
@@ -89,8 +86,7 @@ RingBuffer *RingBufferNew(size_t size)
|
|||||||
/**
|
/**
|
||||||
** Free an allocated ring buffer.
|
** Free an allocated ring buffer.
|
||||||
*/
|
*/
|
||||||
void RingBufferDel(RingBuffer * rb)
|
void RingBufferDel(RingBuffer *rb) {
|
||||||
{
|
|
||||||
free(rb->Buffer);
|
free(rb->Buffer);
|
||||||
free(rb);
|
free(rb);
|
||||||
}
|
}
|
||||||
@@ -103,8 +99,7 @@ void RingBufferDel(RingBuffer * rb)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferWriteAdvance(RingBuffer * rb, size_t cnt)
|
size_t RingBufferWriteAdvance(RingBuffer *rb, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = rb->Size - atomic_read(&rb->Filled);
|
n = rb->Size - atomic_read(&rb->Filled);
|
||||||
@@ -142,8 +137,7 @@ size_t RingBufferWriteAdvance(RingBuffer * rb, size_t cnt)
|
|||||||
** @returns The number of bytes that could be placed in the ring
|
** @returns The number of bytes that could be placed in the ring
|
||||||
** buffer.
|
** buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferWrite(RingBuffer * rb, const void *buf, size_t cnt)
|
size_t RingBufferWrite(RingBuffer *rb, const void *buf, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = rb->Size - atomic_read(&rb->Filled);
|
n = rb->Size - atomic_read(&rb->Filled);
|
||||||
@@ -184,8 +178,7 @@ size_t RingBufferWrite(RingBuffer * rb, const void *buf, size_t cnt)
|
|||||||
** @returns The number of bytes that could be placed in the ring
|
** @returns The number of bytes that could be placed in the ring
|
||||||
** buffer at the write pointer.
|
** buffer at the write pointer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp)
|
size_t RingBufferGetWritePointer(RingBuffer *rb, void **wp) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
|
||||||
@@ -212,8 +205,7 @@ size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferReadAdvance(RingBuffer * rb, size_t cnt)
|
size_t RingBufferReadAdvance(RingBuffer *rb, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = atomic_read(&rb->Filled);
|
n = atomic_read(&rb->Filled);
|
||||||
@@ -250,8 +242,7 @@ size_t RingBufferReadAdvance(RingBuffer * rb, size_t cnt)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be read from ring buffer.
|
** @returns Number of bytes that could be read from ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferRead(RingBuffer * rb, void *buf, size_t cnt)
|
size_t RingBufferRead(RingBuffer *rb, void *buf, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = atomic_read(&rb->Filled);
|
n = atomic_read(&rb->Filled);
|
||||||
@@ -292,8 +283,7 @@ size_t RingBufferRead(RingBuffer * rb, void *buf, size_t cnt)
|
|||||||
** @returns The number of bytes that could be read from the ring
|
** @returns The number of bytes that could be read from the ring
|
||||||
** buffer at the read pointer.
|
** buffer at the read pointer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferGetReadPointer(RingBuffer * rb, const void **rp)
|
size_t RingBufferGetReadPointer(RingBuffer *rb, const void **rp) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
|
||||||
@@ -319,10 +309,7 @@ size_t RingBufferGetReadPointer(RingBuffer * rb, const void **rp)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes free in buffer.
|
** @returns Number of bytes free in buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferFreeBytes(RingBuffer * rb)
|
size_t RingBufferFreeBytes(RingBuffer *rb) { return rb->Size - atomic_read(&rb->Filled); }
|
||||||
{
|
|
||||||
return rb->Size - atomic_read(&rb->Filled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Get used bytes in ring buffer.
|
** Get used bytes in ring buffer.
|
||||||
@@ -331,7 +318,4 @@ size_t RingBufferFreeBytes(RingBuffer * rb)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes used in buffer.
|
** @returns Number of bytes used in buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferUsedBytes(RingBuffer * rb)
|
size_t RingBufferUsedBytes(RingBuffer *rb) { return atomic_read(&rb->Filled); }
|
||||||
{
|
|
||||||
return atomic_read(&rb->Filled);
|
|
||||||
}
|
|
||||||
|
130
shaders.h
130
shaders.h
@@ -4,11 +4,7 @@
|
|||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
const char *gl_version = "#version 330";
|
const char *gl_version = "#version 330";
|
||||||
#else
|
#else
|
||||||
#ifdef RASPI
|
|
||||||
const char *gl_version = "#version 300 es ";
|
const char *gl_version = "#version 300 es ";
|
||||||
#else
|
|
||||||
const char *gl_version = "#version 300 es ";
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Color conversion matrix: RGB = m * YUV + c
|
/* Color conversion matrix: RGB = m * YUV + c
|
||||||
@@ -24,65 +20,47 @@ const char *gl_version = "#version 300 es ";
|
|||||||
* is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector.
|
* is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector.
|
||||||
* The matrix might also be used for other conversions and colorspaces.
|
* The matrix might also be used for other conversions and colorspaces.
|
||||||
*/
|
*/
|
||||||
struct mp_cmat
|
struct mp_cmat {
|
||||||
{
|
|
||||||
GLfloat m[3][3]; // colormatrix
|
GLfloat m[3][3]; // colormatrix
|
||||||
GLfloat c[3]; // colormatrix_c
|
GLfloat c[3]; // colormatrix_c
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mp_mat
|
struct mp_mat {
|
||||||
{
|
|
||||||
GLfloat m[3][3];
|
GLfloat m[3][3];
|
||||||
};
|
};
|
||||||
|
|
||||||
// YUV input limited range (16-235 for luma, 16-240 for chroma)
|
// YUV input limited range (16-235 for luma, 16-240 for chroma)
|
||||||
// ITU-R BT.601 (SD)
|
// ITU-R BT.601 (SD)
|
||||||
struct mp_cmat yuv_bt601 = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt601 = {
|
||||||
{0.00000, -0.391762, 2.017232},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.391762, 2.017232}, {1.596027, -0.812968, 0.000000}},
|
||||||
{1.596027, -0.812968, 0.000000}},
|
{-0.874202, 0.531668, -1.085631}};
|
||||||
{-0.874202, 0.531668, -1.085631}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.709 (HD)
|
// ITU-R BT.709 (HD)
|
||||||
struct mp_cmat yuv_bt709 = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt709 = {
|
||||||
{0.00000, -0.213249, 2.112402},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.213249, 2.112402}, {1.792741, -0.532909, 0.000000}},
|
||||||
{1.792741, -0.532909, 0.000000}},
|
{-0.972945, 0.301483, -1.133402}};
|
||||||
{-0.972945, 0.301483, -1.133402}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.2020 non-constant luminance system
|
// ITU-R BT.2020 non-constant luminance system
|
||||||
struct mp_cmat yuv_bt2020ncl = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt2020ncl = {
|
||||||
{0.00000, -0.187326, 2.141772},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.187326, 2.141772}, {1.678674, -0.650424, 0.000000}},
|
||||||
{1.678674, -0.650424, 0.000000}},
|
{-0.915688, 0.347459, -1.148145}};
|
||||||
{-0.915688, 0.347459, -1.148145}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.2020 constant luminance system
|
// ITU-R BT.2020 constant luminance system
|
||||||
struct mp_cmat yuv_bt2020cl = { {{0.0000, 1.164384, 0.000000},
|
struct mp_cmat yuv_bt2020cl = {
|
||||||
{0.00000, 0.000000, 1.138393},
|
{{0.0000, 1.164384, 0.000000}, {0.00000, 0.000000, 1.138393}, {1.138393, 0.000000, 0.000000}},
|
||||||
{1.138393, 0.000000, 0.000000}},
|
{-0.571429, -0.073059, -0.571429}};
|
||||||
{-0.571429, -0.073059, -0.571429}
|
|
||||||
};
|
|
||||||
|
|
||||||
float cms_matrix[3][3] = { {1.660497, -0.124547, -0.018154},
|
float cms_matrix[3][3] = {
|
||||||
{-0.587657, 1.132895, -0.100597},
|
{1.660497, -0.124547, -0.018154}, {-0.587657, 1.132895, -0.100597}, {-0.072840, -0.008348, 1.118751}};
|
||||||
{-0.072840, -0.008348, 1.118751}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Common constants for SMPTE ST.2084 (PQ)
|
// Common constants for SMPTE ST.2084 (PQ)
|
||||||
static const float PQ_M1 = 2610. / 4096 * 1. / 4,
|
static const float PQ_M1 = 2610. / 4096 * 1. / 4, PQ_M2 = 2523. / 4096 * 128, PQ_C1 = 3424. / 4096,
|
||||||
PQ_M2 = 2523. / 4096 * 128,
|
PQ_C2 = 2413. / 4096 * 32, PQ_C3 = 2392. / 4096 * 32;
|
||||||
PQ_C1 = 3424. / 4096,
|
|
||||||
PQ_C2 = 2413. / 4096 * 32,
|
|
||||||
PQ_C3 = 2392. / 4096 * 32;
|
|
||||||
|
|
||||||
// Common constants for ARIB STD-B67 (HLG)
|
// Common constants for ARIB STD-B67 (HLG)
|
||||||
static const float HLG_A = 0.17883277,
|
static const float HLG_A = 0.17883277, HLG_B = 0.28466892, HLG_C = 0.55991073;
|
||||||
HLG_B = 0.28466892,
|
|
||||||
HLG_C = 0.55991073;
|
|
||||||
|
|
||||||
struct gl_vao_entry
|
struct gl_vao_entry {
|
||||||
{
|
|
||||||
// used for shader / glBindAttribLocation
|
// used for shader / glBindAttribLocation
|
||||||
const char *name;
|
const char *name;
|
||||||
// glVertexAttribPointer() arguments
|
// glVertexAttribPointer() arguments
|
||||||
@@ -92,20 +70,17 @@ struct gl_vao_entry
|
|||||||
int offset;
|
int offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex_pt
|
struct vertex_pt {
|
||||||
{
|
|
||||||
float x, y;
|
float x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex_pi
|
struct vertex_pi {
|
||||||
{
|
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXUNIT_VIDEO_NUM 6
|
#define TEXUNIT_VIDEO_NUM 6
|
||||||
|
|
||||||
struct vertex
|
struct vertex {
|
||||||
{
|
|
||||||
struct vertex_pt position;
|
struct vertex_pt position;
|
||||||
struct vertex_pt texcoord[TEXUNIT_VIDEO_NUM];
|
struct vertex_pt texcoord[TEXUNIT_VIDEO_NUM];
|
||||||
};
|
};
|
||||||
@@ -114,8 +89,7 @@ static const struct gl_vao_entry vertex_vao[] = {
|
|||||||
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
|
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
|
||||||
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
|
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
|
||||||
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
|
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
|
||||||
{0}
|
{0}};
|
||||||
};
|
|
||||||
|
|
||||||
#define GLSL(...) pl_shader_append(__VA_ARGS__)
|
#define GLSL(...) pl_shader_append(__VA_ARGS__)
|
||||||
#define GLSLV(...) pl_shader_append_v(__VA_ARGS__)
|
#define GLSLV(...) pl_shader_append_v(__VA_ARGS__)
|
||||||
@@ -123,18 +97,11 @@ static const struct gl_vao_entry vertex_vao[] = {
|
|||||||
char sh[SHADER_LENGTH];
|
char sh[SHADER_LENGTH];
|
||||||
char shv[SHADER_LENGTH];
|
char shv[SHADER_LENGTH];
|
||||||
|
|
||||||
GL_init()
|
void GL_init() { sh[0] = 0; }
|
||||||
{
|
|
||||||
sh[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLV_init()
|
void GLV_init() { shv[0] = 0; }
|
||||||
{
|
|
||||||
shv[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pl_shader_append(const char *fmt, ...)
|
void pl_shader_append(const char *fmt, ...) {
|
||||||
{
|
|
||||||
char temp[1000];
|
char temp[1000];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -145,11 +112,9 @@ pl_shader_append(const char *fmt, ...)
|
|||||||
if (strlen(sh) + strlen(temp) > SHADER_LENGTH)
|
if (strlen(sh) + strlen(temp) > SHADER_LENGTH)
|
||||||
Fatal(_("Shaderlenght fault\n"));
|
Fatal(_("Shaderlenght fault\n"));
|
||||||
strcat(sh, temp);
|
strcat(sh, temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pl_shader_append_v(const char *fmt, ...)
|
void pl_shader_append_v(const char *fmt, ...) {
|
||||||
{
|
|
||||||
char temp[1000];
|
char temp[1000];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -160,11 +125,9 @@ pl_shader_append_v(const char *fmt, ...)
|
|||||||
if (strlen(shv) + strlen(temp) > SHADER_LENGTH)
|
if (strlen(shv) + strlen(temp) > SHADER_LENGTH)
|
||||||
Fatal(_("Shaderlenght fault\n"));
|
Fatal(_("Shaderlenght fault\n"));
|
||||||
strcat(shv, temp);
|
strcat(shv, temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_attach_shader(GLuint program, GLenum type, const char *source)
|
static void compile_attach_shader(GLuint program, GLenum type, const char *source) {
|
||||||
{
|
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
GLint status = 1234, log_length;
|
GLint status = 1234, log_length;
|
||||||
char log[4000];
|
char log[4000];
|
||||||
@@ -183,11 +146,9 @@ static void compile_attach_shader(GLuint program, GLenum type, const char *sourc
|
|||||||
|
|
||||||
glAttachShader(program, shader);
|
glAttachShader(program, shader);
|
||||||
glDeleteShader(shader);
|
glDeleteShader(shader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void link_shader(GLuint program)
|
static void link_shader(GLuint program) {
|
||||||
{
|
|
||||||
GLint status, log_length;
|
GLint status, log_length;
|
||||||
|
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
@@ -198,8 +159,7 @@ static void link_shader(GLuint program)
|
|||||||
Debug(3, "Link Status %d loglen %d\n", status, log_length);
|
Debug(3, "Link Status %d loglen %d\n", status, log_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint sc_generate_osd(GLuint gl_prog)
|
static GLuint sc_generate_osd(GLuint gl_prog) {
|
||||||
{
|
|
||||||
|
|
||||||
Debug(3, "vor create osd\n");
|
Debug(3, "vor create osd\n");
|
||||||
gl_prog = glCreateProgram();
|
gl_prog = glCreateProgram();
|
||||||
@@ -243,8 +203,7 @@ static GLuint sc_generate_osd(GLuint gl_prog)
|
|||||||
return gl_prog;
|
return gl_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) {
|
||||||
{
|
|
||||||
|
|
||||||
char vname[80];
|
char vname[80];
|
||||||
int n;
|
int n;
|
||||||
@@ -280,6 +239,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
|
|
||||||
switch (colorspace) {
|
switch (colorspace) {
|
||||||
case AVCOL_SPC_RGB:
|
case AVCOL_SPC_RGB:
|
||||||
|
case AVCOL_SPC_BT470BG:
|
||||||
m = &yuv_bt601.m[0][0];
|
m = &yuv_bt601.m[0][0];
|
||||||
c = &yuv_bt601.c[0];
|
c = &yuv_bt601.c[0];
|
||||||
Debug(3, "BT601 Colorspace used\n");
|
Debug(3, "BT601 Colorspace used\n");
|
||||||
@@ -332,15 +292,21 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n");
|
GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n");
|
||||||
}
|
}
|
||||||
GLSL("// color conversion\n");
|
GLSL("// color conversion\n");
|
||||||
GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n");
|
GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; "
|
||||||
|
"\n");
|
||||||
GLSL("color.a = 1.0; \n");
|
GLSL("color.a = 1.0; \n");
|
||||||
|
|
||||||
GLSL("// pl_shader_linearize \n");
|
GLSL("// pl_shader_linearize \n");
|
||||||
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
||||||
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
||||||
// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n");
|
// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n");
|
||||||
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
|
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb -
|
||||||
GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\n");
|
// vec3(%f)) * vec3(1.0/%f)) + vec3(%f) ,
|
||||||
|
// bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
|
||||||
|
GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - "
|
||||||
|
"vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), "
|
||||||
|
"bvec3(lessThan(vec3(0.5), color.rgb)));\n");
|
||||||
|
GLSL("color.rgb *= vec3(1.0/3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
|
||||||
GLSL("// color mapping \n");
|
GLSL("// color mapping \n");
|
||||||
GLSL("color.rgb = cms_matrix * color.rgb; \n");
|
GLSL("color.rgb = cms_matrix * color.rgb; \n");
|
||||||
#ifndef GAMMA
|
#ifndef GAMMA
|
||||||
@@ -348,7 +314,10 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
||||||
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
||||||
// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n");
|
// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n");
|
||||||
GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), bvec3(lessThan(vec3(1.0), color.rgb))); \n");
|
GLSL("color.rgb *= vec3(3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
|
||||||
|
GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * "
|
||||||
|
"log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), "
|
||||||
|
"bvec3(lessThan(vec3(1.0), color.rgb))); \n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
GLSL("out_color = color; \n");
|
GLSL("out_color = color; \n");
|
||||||
@@ -372,7 +341,9 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
#ifndef GAMMA
|
#ifndef GAMMA
|
||||||
GLSL("// delinearize gamma to sRGB \n");
|
GLSL("// delinearize gamma to sRGB \n");
|
||||||
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
||||||
GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n");
|
GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * "
|
||||||
|
"pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), "
|
||||||
|
"bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n");
|
||||||
#endif
|
#endif
|
||||||
GLSL("// color mapping \n");
|
GLSL("// color mapping \n");
|
||||||
GLSL("out_color = color; \n");
|
GLSL("out_color = color; \n");
|
||||||
@@ -413,8 +384,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
return gl_prog;
|
return gl_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_pass_quad(int flip, float xcrop, float ycrop)
|
static void render_pass_quad(int flip, float xcrop, float ycrop) {
|
||||||
{
|
|
||||||
struct vertex va[4];
|
struct vertex va[4];
|
||||||
int n;
|
int n;
|
||||||
const struct gl_vao_entry *e;
|
const struct gl_vao_entry *e;
|
||||||
|
801
softhdcuvid.cpp
801
softhdcuvid.cpp
File diff suppressed because it is too large
Load Diff
387
softhddev.c
387
softhddev.c
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
/// C callback feed key press
|
/// C callback feed key press
|
||||||
extern void FeedKeyPress(const char *, const char *, int, int, const char *);
|
extern void FeedKeyPress(const char *, const char *, int, int, const char *);
|
||||||
|
@@ -26,11 +26,9 @@
|
|||||||
#define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1"
|
#define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1"
|
||||||
#define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0"
|
#define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0"
|
||||||
|
|
||||||
enum
|
enum { GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
|
||||||
{ GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int structSize;
|
int structSize;
|
||||||
|
|
||||||
// request data
|
// request data
|
||||||
@@ -45,13 +43,11 @@ typedef struct
|
|||||||
void *img;
|
void *img;
|
||||||
} SoftHDDevice_AtmoGrabService_v1_0_t;
|
} SoftHDDevice_AtmoGrabService_v1_0_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int Mode;
|
int Mode;
|
||||||
} SoftHDDevice_Osd3DModeService_v1_0_t;
|
} SoftHDDevice_Osd3DModeService_v1_0_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
// request/reply data
|
// request/reply data
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
|
4
video.h
4
video.h
@@ -45,6 +45,7 @@ extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
|||||||
extern int VideoAudioDelay; ///< audio/video delay
|
extern int VideoAudioDelay; ///< audio/video delay
|
||||||
extern char ConfigStartX11Server; ///< flag start the x11 server
|
extern char ConfigStartX11Server; ///< flag start the x11 server
|
||||||
extern char MyConfigDir[];
|
extern char MyConfigDir[];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Prototypes
|
// Prototypes
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -116,6 +117,9 @@ extern void VideoSetSaturation(int);
|
|||||||
/// Set Gamma.
|
/// Set Gamma.
|
||||||
extern void VideoSetGamma(int);
|
extern void VideoSetGamma(int);
|
||||||
|
|
||||||
|
/// Set Color Temp.
|
||||||
|
extern void VideoSetTemperature(int);
|
||||||
|
|
||||||
/// Set ColorSpace.
|
/// Set ColorSpace.
|
||||||
extern void VideoSetTargetColor(int);
|
extern void VideoSetTargetColor(int);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user