mirror of
				https://github.com/jojo61/vdr-plugin-softhdcuvid.git
				synced 2025-03-01 10:39:28 +00:00 
			
		
		
		
	Compare commits
	
		
			107 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2c8e75e3ff | ||
|  | e3fe68d7e6 | ||
|  | 41da5ca526 | ||
|  | 68fc7e4511 | ||
|  | 46df18afe0 | ||
|  | 0ff83f0e31 | ||
|  | 230bb5ca11 | ||
|  | f026e8e86d | ||
|  | 9dd936df86 | ||
|  | 4e5529efcf | ||
|  | 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 | ||||
							
								
								
									
										123
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								Makefile
									
									
									
									
									
								
							| @@ -22,26 +22,18 @@ CUVID ?= 0 | ||||
| # only valid for VAAPI | ||||
| DRM ?= 0 | ||||
|  | ||||
|  | ||||
| # use libplacebo - | ||||
| # available for all decoders but for DRM you need LIBPLACEBO_GL | ||||
| LIBPLACEBO ?= 1 | ||||
| LIBPLACEBO ?= 0 | ||||
| LIBPLACEBO_GL ?= 0 | ||||
|  | ||||
| # use YADIF deint - only available with cuvid | ||||
| #YADIF=1 | ||||
| YADIF = 1 | ||||
|  | ||||
| # use gamma correction | ||||
| #GAMMA ?= 0 | ||||
|  | ||||
|  | ||||
|  | ||||
| CONFIG :=  #-DDEBUG 		# remove # to enable debug output | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| CONFIG := -DDEBUG 		# remove '#' to enable debug output | ||||
|  | ||||
| #--------------------- no more config needed past this point-------------------------------- | ||||
|  | ||||
| @@ -61,7 +53,7 @@ endif | ||||
|  | ||||
| ifeq ($(CUVID),1) | ||||
| ifeq ($(DRM),1) | ||||
| $(error Missmatch in Plugin selection) | ||||
| $(error Mismatch in Plugin selection) | ||||
| exit 1; | ||||
| endif | ||||
| endif | ||||
| @@ -69,42 +61,27 @@ endif | ||||
|  | ||||
| ifeq ($(CUVID),1) | ||||
| ifeq ($(VAAPI),1) | ||||
| $(error Missmatch in Plugin selection) | ||||
| $(error Mismatch in Plugin selection) | ||||
| exit 1; | ||||
| endif | ||||
| endif | ||||
|  | ||||
| endif # MAKECMDGOALS!=indent | ||||
| endif # MAKECMDGOALS!=clean | ||||
|  | ||||
|  | ||||
| #-------------------------- | ||||
|  | ||||
|  | ||||
|  | ||||
| PLUGIN = softhdcuvid | ||||
|  | ||||
| # support OPENGLOSD always needed | ||||
| OPENGLOSD=1 | ||||
|  | ||||
| # support alsa audio output module | ||||
| ALSA ?= $(shell pkg-config --exists alsa && echo 1) | ||||
|     # support OSS audio output module | ||||
| OSS ?= 1 | ||||
|  | ||||
| # use DMPS | ||||
| SCREENSAVER=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 += -DSTILL_DEBUG=2		# still picture debug verbose level | ||||
| CONFIG += -DAV_INFO -DAV_INFO_TIME=3000	# info/debug a/v sync | ||||
| @@ -136,8 +113,8 @@ TMPDIR ?= /tmp | ||||
|  | ||||
| ### The compiler options: | ||||
|  | ||||
| export CFLAGS	= $(call PKGCFG,cflags)  | ||||
| export CXXFLAGS = $(call PKGCFG,cxxflags) | ||||
| export CFLAGS	= $(call PKGCFG,cflags) -fpermissive | ||||
| export CXXFLAGS = $(call PKGCFG,cxxflags) -fpermissive | ||||
|  | ||||
| ifeq ($(CFLAGS),) | ||||
| $(warning CFLAGS not set) | ||||
| @@ -154,20 +131,8 @@ APIVERSION = $(call PKGCFG,apiversion) | ||||
|  | ||||
| -include $(PLGCFG) | ||||
|  | ||||
|  | ||||
|  | ||||
| ### 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) | ||||
| #_CFLAGS += $(shell pkg-config --cflags libva-glx) | ||||
| #LIBS += $(shell pkg-config --libs libva-glx) | ||||
| @@ -193,30 +158,29 @@ endif | ||||
|  | ||||
| ifeq ($(LIBPLACEBO_GL),1) | ||||
| CONFIG += -DPLACEBO_GL -DPLACEBO | ||||
| LIBS += -lepoxy   | ||||
| LIBS += -lplacebo  | ||||
| _CFLAGS += $(shell pkg-config --cflags libplacebo) | ||||
| LIBS += $(shell pkg-config --libs epoxy libplacebo) | ||||
| else | ||||
| LIBS += -lEGL   | ||||
| LIBS += $(shell pkg-config --libs egl) | ||||
| endif | ||||
|  | ||||
| ifeq ($(LIBPLACEBO),1) | ||||
| CONFIG += -DPLACEBO | ||||
| LIBS += -lEGL   | ||||
| LIBS += -lplacebo  | ||||
| _CFLAGS += $(shell pkg-config --cflags libplacebo) | ||||
| LIBS += $(shell pkg-config --libs egl libplacebo) | ||||
| endif | ||||
|  | ||||
| ifeq ($(DRM),1) | ||||
| PLUGIN = softhddrm | ||||
| CONFIG += -DUSE_DRM -DVAAPI | ||||
| _CFLAGS += $(shell pkg-config --cflags libdrm) | ||||
| LIBS += -lgbm -ldrm -lEGL | ||||
| LIBS += $(shell pkg-config --libs egl gbm libdrm) | ||||
| endif | ||||
|  | ||||
|  | ||||
| ifeq ($(CUVID),1) | ||||
| CONFIG += -DUSE_PIP			# PIP support | ||||
| #CONFIG += -DUSE_PIP			# PIP support | ||||
| CONFIG += -DCUVID			# enable CUVID decoder | ||||
| LIBS += -lEGL -lGL  | ||||
| LIBS += $(shell pkg-config --libs egl gl) | ||||
| ifeq ($(YADIF),1) | ||||
| CONFIG += -DYADIF			# Yadif only with CUVID | ||||
| endif | ||||
| @@ -226,7 +190,6 @@ ifeq ($(GAMMA),1) | ||||
| CONFIG += -DGAMMA | ||||
| endif | ||||
|  | ||||
|  | ||||
| ARCHIVE = $(PLUGIN)-$(VERSION) | ||||
| PACKAGE = vdr-$(ARCHIVE) | ||||
|  | ||||
| @@ -234,15 +197,16 @@ PACKAGE = vdr-$(ARCHIVE) | ||||
|  | ||||
| SOFILE = libvdr-$(PLUGIN).so | ||||
|  | ||||
|  | ||||
| # | ||||
| # Test that libswresample is available | ||||
| # | ||||
| #ifneq (exists, $(shell pkg-config libswresample && echo exists)) | ||||
| #  $(warning ******************************************************************) | ||||
| #  $(warning 'libswresample' not found!) | ||||
| #  $(error ******************************************************************) | ||||
| #endif | ||||
| ifneq (exists, $(shell pkg-config libswresample && echo exists)) | ||||
|   $(warning ******************************************************************) | ||||
|   $(warning 'libswresample' not found!) | ||||
|   $(error ******************************************************************) | ||||
| endif | ||||
| _CFLAGS += $(shell pkg-config --cflags libswresample) | ||||
| LIBS += $(shell pkg-config --libs libswresample) | ||||
|  | ||||
| # | ||||
| # Test and set config for libavutil | ||||
| @@ -277,22 +241,22 @@ endif | ||||
| _CFLAGS += $(shell pkg-config --cflags libavcodec) | ||||
| 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) | ||||
| CONFIG += -DUSE_SCREENSAVER | ||||
| _CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms) | ||||
| LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms) | ||||
| 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) | ||||
| #LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm) | ||||
| @@ -309,6 +273,8 @@ LIBS +=  -lcuda  -lnvcuvid | ||||
| endif | ||||
|  | ||||
| LIBS += -lGLEW -lGLU  -ldl -lglut | ||||
| #LIBS += -ldl $(shell pkg-config --libs glew glu glut) | ||||
|  | ||||
| ### Includes and Defines (add further entries here): | ||||
|  | ||||
| INCLUDES += | ||||
| @@ -319,10 +285,9 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \ | ||||
| ### Make it standard | ||||
|  | ||||
| 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) \ | ||||
|     -g -W  -Wextra -Winit-self -Wdeclaration-after-statement | ||||
|  | ||||
|     -g -W -Wextra | ||||
|  | ||||
| ### The object files (add further files here): | ||||
|  | ||||
| @@ -383,7 +348,6 @@ install-i18n: $(I18Nmsgs) | ||||
|  | ||||
| $(OBJS): Makefile | ||||
|  | ||||
|  | ||||
| $(SOFILE): $(OBJS) shaders.h | ||||
| 	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared  $(OBJS) $(LIBS) -o $@ | ||||
|  | ||||
| @@ -404,17 +368,14 @@ clean: | ||||
| 	@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot | ||||
| 	@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ | ||||
|  | ||||
| ## Private Targets: | ||||
|  | ||||
| HDRS = $(wildcard *.h) | ||||
|  | ||||
| indent: | ||||
| 	for i in $(SRCS) $(HDRS); do \ | ||||
| 		indent $$i; \ | ||||
| 		unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \ | ||||
| 		mv $$i.up $$i; \ | ||||
| 	for i in $(SRCS) drm.c hdr.c $(HDRS); do \ | ||||
| 	  clang-format -i $$i; \ | ||||
| 	done | ||||
|  | ||||
| ## Private Targets: | ||||
|  | ||||
| video_test: video.c Makefile | ||||
| 	$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \ | ||||
| 	$(LIBS) -o $@ | ||||
|   | ||||
							
								
								
									
										75
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								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 output opengl or DRM | ||||
|     o Audio FFMpeg / Alsa / Analog | ||||
|     o Audio FFMpeg / Alsa / Digital | ||||
|     o Audio FFMpeg / OSS / Analog | ||||
|     o Audio FFMpeg / ALSA / Analog | ||||
|     o Audio FFMpeg / ALSA / Digital | ||||
|     o HDMI/SPDIF pass-through | ||||
|     o Software volume, compression, normalize and channel resample | ||||
|     o VDR ScaleVideo API | ||||
|     o CUDA deinterlacer | ||||
|     o Suspend / Dettach | ||||
|     o Suspend / Detach | ||||
|     o Support for ambilight | ||||
|     o Support for Screencopy | ||||
|     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. | ||||
| @@ -71,15 +69,20 @@ Quickstart: | ||||
|  | ||||
| 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. | ||||
|     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. | ||||
|     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 | ||||
|     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: | ||||
| -------- | ||||
| @@ -90,9 +93,6 @@ Install: | ||||
| 	make | ||||
| 	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>.. ' | ||||
|  | ||||
| Beginners Guide for libplacebo: | ||||
| @@ -100,27 +100,43 @@ Beginners Guide for libplacebo: | ||||
|     When using libplacebo you will find several config options. | ||||
|  | ||||
|     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. | ||||
|     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 | ||||
|     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 | ||||
|     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. | ||||
|     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 | ||||
|     in rare cases. | ||||
|  | ||||
|     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. | ||||
|     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 | ||||
|     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: | ||||
|  | ||||
| 	DISPLAY=:0.0 | ||||
| 		x11 display name | ||||
| 		X11 display name | ||||
|  | ||||
|     only if alsa is configured | ||||
|     ALSA configuration: | ||||
| 	ALSA_DEVICE=default | ||||
| 		alsa PCM device name | ||||
| 		ALSA PCM device name | ||||
| 	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 control device name | ||||
| 		ALSA control device name | ||||
| 	ALSA_MIXER_CHANNEL=PCM | ||||
| 		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 | ||||
| 		ALSA control channel name | ||||
|  | ||||
| Setup: /etc/vdr/setup.conf | ||||
| ------ | ||||
| @@ -178,7 +184,7 @@ Setup: /etc/vdr/setup.conf | ||||
| 	(only 0, 1, 4 supported with VA-API) | ||||
|  | ||||
| 	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 | ||||
| 	0 = disabled, 1 = enabled | ||||
| @@ -245,8 +251,8 @@ Setup: /etc/vdr/setup.conf | ||||
| 	(Red * 65536 +  Green * 256 + Blue) | ||||
|  | ||||
| 	softhddevice.StudioLevels = 0 | ||||
| 		0 use PC levels (0-255) with vdpau. | ||||
| 		1 use studio levels (16-235) with vdpau. | ||||
| 	0 use limited RGB (16-235) with vdpau. | ||||
| 	1 use full RGB (0-255) with vdpau. | ||||
|  | ||||
| 	softhddevice.Suspend.Close = 0 | ||||
| 	1 suspend closes x11 window, connection and audio device. | ||||
| @@ -317,10 +323,7 @@ Commandline: | ||||
|  | ||||
| 	Selects audio output module and device. | ||||
| 	""		to disable audio output | ||||
| 	/...		to use oss audio module (if compiled with oss | ||||
| 			support) | ||||
| 	other		to use alsa audio module (if compiled with alsa | ||||
| 			support) | ||||
| 	other		to use ALSA audio module | ||||
|  | ||||
| SVDRP: | ||||
| ------ | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
|                     GNU AFFERO GENERAL PUBLIC LICENSE | ||||
|                        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 | ||||
|  of this license document, but changing it is not allowed. | ||||
| 
 | ||||
|                             Preamble | ||||
| 
 | ||||
|   The GNU Affero General Public License is a free, copyleft license | ||||
| for software and other kinds of works, specifically designed to ensure | ||||
|   The GNU Affero General Public License is a free, copyleft license for | ||||
| software and other kinds of works, specifically designed to ensure | ||||
| cooperation with the community in the case of network server software. | ||||
| 
 | ||||
|   The licenses for most software and other practical works are | ||||
| designed to take away your freedom to share and change the works.  By | ||||
| contrast, our General Public Licenses are intended to guarantee your | ||||
| freedom to share and change all versions of a program--to make sure it | ||||
| remains free software for all its users. | ||||
|   The licenses for most software and other practical works are designed | ||||
| to take away your freedom to share and change the works.  By contrast, | ||||
| our General Public Licenses are intended to guarantee your freedom to | ||||
| share and change all versions of a program--to make sure it remains free | ||||
| software for all its users. | ||||
| 
 | ||||
|   When we speak of free software, we are referring to freedom, not | ||||
| price.  Our General Public Licenses are designed to make sure that you | ||||
| @@ -60,11 +60,10 @@ modification follow. | ||||
| 
 | ||||
|   0. Definitions. | ||||
| 
 | ||||
|   "This License" refers to version 3 of the GNU Affero General Public | ||||
| License. | ||||
|   "This License" refers to version 3 of the GNU Affero General Public License. | ||||
| 
 | ||||
|   "Copyright" also means copyright-like laws that apply to other kinds | ||||
| of works, such as semiconductor masks. | ||||
|   "Copyright" also means copyright-like laws that apply to other kinds of | ||||
| works, such as semiconductor masks. | ||||
| 
 | ||||
|   "The Program" refers to any copyrightable work licensed under this | ||||
| 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 | ||||
| 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 | ||||
| governed by this License along with a term that is a further restriction, | ||||
| you may remove that term.  If a license document contains a further | ||||
| restriction but permits relicensing or conveying under this License, you | ||||
| may add to a covered work material governed by the terms of that license | ||||
| document, provided that the further restriction does not survive such | ||||
| relicensing or conveying. | ||||
| governed by this License along with a term that is a further | ||||
| restriction, you may remove that term.  If a license document contains | ||||
| a further restriction but permits relicensing or conveying under this | ||||
| License, you may add to a covered work material governed by the terms | ||||
| of that license document, provided that the further restriction does | ||||
| not survive such relicensing or conveying. | ||||
| 
 | ||||
|   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 | ||||
| @@ -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 | ||||
| following paragraph. | ||||
| 
 | ||||
|   Notwithstanding any other provision of this License, you have permission | ||||
| to link or combine any covered work with a work licensed under version 3 | ||||
| of the GNU General Public License into a single combined work, and to | ||||
| convey the resulting work.  The terms of this License will continue to | ||||
| apply to the part which is the covered work, but the work with which it is | ||||
| combined will remain governed by version 3 of the GNU General Public | ||||
| License. | ||||
|   Notwithstanding any other provision of this License, you have | ||||
| permission to link or combine any covered work with a work licensed | ||||
| under version 3 of the GNU General Public License into a single | ||||
| combined work, and to convey the resulting work.  The terms of this | ||||
| License will continue to apply to the part which is the covered work, | ||||
| but the work with which it is combined will remain governed by version | ||||
| 3 of the GNU General Public License. | ||||
| 
 | ||||
|   14. Revised Versions of this License. | ||||
| 
 | ||||
|   The Free Software Foundation may publish revised and/or new versions of | ||||
| the GNU Affero General Public License from time to time.  Such new | ||||
| versions will be similar in spirit to the present version, but may differ | ||||
| in detail to address new problems or concerns. | ||||
| the GNU Affero General Public License from time to time.  Such new versions | ||||
| will be similar in spirit to the present version, but may differ in detail to | ||||
| address new problems or concerns. | ||||
| 
 | ||||
|   Each version is given a distinguishing version number.  If the | ||||
| Program specifies that a certain numbered version of the GNU Affero | ||||
| General Public License "or any later version" applies to it, you have | ||||
| the option of following the terms and conditions either of that | ||||
| numbered version or of any later version published by the Free | ||||
| Software Foundation.  If the Program does not specify a version number | ||||
| of the GNU Affero General Public License, you may choose any version | ||||
| ever published by the Free Software Foundation. | ||||
| Program specifies that a certain numbered version of the GNU Affero General | ||||
| Public License "or any later version" applies to it, you have the | ||||
| option of following the terms and conditions either of that numbered | ||||
| version or of any later version published by the Free Software | ||||
| Foundation.  If the Program does not specify a version number of the | ||||
| GNU Affero General Public License, you may choose any version ever published | ||||
| by the Free Software Foundation. | ||||
| 
 | ||||
|   If the Program specifies that a proxy can decide which future | ||||
| versions of the GNU Affero General Public License can be used, that | ||||
| proxy's public statement of acceptance of a version permanently | ||||
| authorizes you to choose that version for the Program. | ||||
| versions of the GNU Affero General Public License can be used, that proxy's | ||||
| public statement of acceptance of a version permanently authorizes you | ||||
| to choose that version for the Program. | ||||
| 
 | ||||
|   Later license versions may give you additional or different | ||||
| 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> | ||||
| 
 | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU Affero General Public License as | ||||
|     published by the Free Software Foundation, either version 3 of the | ||||
|     License, or (at your option) any later version. | ||||
|     it under the terms of the GNU Affero General Public License as published by | ||||
|     the Free Software Foundation, either version 3 of the License, or | ||||
|     (at your option) any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     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. | ||||
| 
 | ||||
|     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. | ||||
| 
 | ||||
| @@ -659,4 +658,4 @@ specific requirements. | ||||
|   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. | ||||
| 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 | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| extern char AudioAlsaNotest;         ///< disable Alsa capability test | ||||
| extern char AudioAlsaDriverBroken;   ///< disable broken driver message | ||||
| extern char AudioAlsaNoCloseOpen;    ///< disable alsa close/open fix | ||||
| extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix | ||||
|   | ||||
							
								
								
									
										393
									
								
								codec.c
									
									
									
									
									
								
							
							
						
						
									
										393
									
								
								codec.c
									
									
									
									
									
								
							| @@ -36,10 +36,6 @@ | ||||
| #define USE_AUDIO_DRIFT_CORRECTION | ||||
| /// compile AC-3 audio drift correction support (very experimental) | ||||
| #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 <stdlib.h> | ||||
| @@ -51,35 +47,28 @@ | ||||
| #include <endian.h> | ||||
| #endif | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <libintl.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
| #define _(str) gettext(str) ///< gettext shortcut | ||||
| #define _N(str) str         ///< gettext_noop shortcut | ||||
|  | ||||
| #include <libavcodec/avcodec.h> | ||||
| #include <libavutil/opt.h> | ||||
| #include <libavutil/mem.h> | ||||
|  | ||||
| #ifdef USE_SWRESAMPLE | ||||
| #include <libswresample/swresample.h> | ||||
| #endif | ||||
| #ifdef USE_AVRESAMPLE | ||||
| #include <libavresample/avresample.h> | ||||
| #include <libavutil/opt.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef __USE_GNU | ||||
| #define __USE_GNU | ||||
| #endif | ||||
| #include <libswresample/swresample.h> | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| // clang-format off | ||||
| #include "iatomic.h" | ||||
| #include "misc.h" | ||||
| #include "video.h" | ||||
| #include "audio.h" | ||||
| #include "codec.h" | ||||
| // clang-format on | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //  Global | ||||
| @@ -134,10 +123,9 @@ struct _video_decoder_ | ||||
| **			valid format, the formats are ordered by | ||||
| **			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; | ||||
|     enum AVPixelFormat fmt1; | ||||
|  | ||||
|  | ||||
|     decoder = video_ctx->opaque; | ||||
|     // bug in ffmpeg 1.1.1, called with zero width or height | ||||
| @@ -147,7 +135,6 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu | ||||
|  | ||||
|     //	decoder->GetFormatDone = 1; | ||||
|     return Video_get_format(decoder->HwDecoder, video_ctx, fmt); | ||||
|  | ||||
| } | ||||
|  | ||||
| // 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 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; | ||||
|  | ||||
|     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. | ||||
| */ | ||||
| VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder) | ||||
| { | ||||
| VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *hw_decoder) { | ||||
|     VideoDecoder *decoder; | ||||
|  | ||||
|     if (!(decoder = calloc(1, sizeof(*decoder)))) { | ||||
| @@ -214,10 +199,7 @@ VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder) | ||||
| ** | ||||
| **  @param decoder  private video decoder | ||||
| */ | ||||
| void CodecVideoDelDecoder(VideoDecoder * decoder) | ||||
| { | ||||
|     free(decoder); | ||||
| } | ||||
| void CodecVideoDelDecoder(VideoDecoder *decoder) { free(decoder); } | ||||
|  | ||||
| /** | ||||
| **  Open video decoder. | ||||
| @@ -225,11 +207,14 @@ void CodecVideoDelDecoder(VideoDecoder * decoder) | ||||
| **  @param decoder  private video decoder | ||||
| **  @param codec_id video codec id | ||||
| */ | ||||
| void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
| { | ||||
| void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100) | ||||
|     AVCodec *video_codec; | ||||
| #else | ||||
|     const AVCodec *video_codec; | ||||
| #endif | ||||
|     const char *name; | ||||
|     int ret, deint = 2; | ||||
|     int ret; | ||||
|  | ||||
|     Debug(3, "***************codec: Video Open using video codec ID %#06x (%s)\n", codec_id, | ||||
|           avcodec_get_name(codec_id)); | ||||
| @@ -253,20 +238,6 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|                 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 | ||||
|     if (name && (video_codec = avcodec_find_decoder_by_name(name))) { | ||||
|         Debug(3, "codec: decoder found\n"); | ||||
| @@ -283,30 +254,25 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|         Fatal(_("codec: can't allocate video codec context\n")); | ||||
|     } | ||||
|  | ||||
| #ifndef RASPI | ||||
|     if (!HwDeviceContext) { | ||||
|         Fatal("codec: no hw device context to be used"); | ||||
|     } | ||||
|     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 | ||||
|     decoder->VideoCtx->thread_count = 1; | ||||
|  | ||||
|     decoder->VideoCtx->pkt_timebase.num = 1; | ||||
|     decoder->VideoCtx->pkt_timebase.den = 90000; | ||||
|     decoder->VideoCtx->framerate.num = 50; | ||||
|     decoder->VideoCtx->framerate.den = 1; | ||||
|     //decoder->VideoCtx->framerate.num = 50; | ||||
|     //decoder->VideoCtx->framerate.den = 1; | ||||
|  | ||||
|     pthread_mutex_lock(&CodecLockMutex); | ||||
|     // open codec | ||||
| #ifdef YADIF | ||||
|     deint = 2; | ||||
| #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 | ||||
|     if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) { | ||||
|         Debug(3, "codec: auto threads enabled"); | ||||
| @@ -317,6 +283,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|         Debug(3, "codec: supports truncated packets"); | ||||
|         // decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED; | ||||
|     } | ||||
| #endif | ||||
|     // FIXME: own memory management for video frames. | ||||
|     if (video_codec->capabilities & AV_CODEC_CAP_DR1) { | ||||
|         Debug(3, "codec: can use own buffer management"); | ||||
| @@ -333,36 +300,26 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|     } | ||||
|     //    if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0) | ||||
|     //	  Fatal(_("VAAPI Refcounts invalid\n")); | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100) | ||||
|     decoder->VideoCtx->thread_safe_callbacks = 0; | ||||
|  | ||||
| #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 | ||||
|  | ||||
| #ifdef CUVID | ||||
|     if (strcmp(decoder->VideoCodec->long_name, "Nvidia CUVID MPEG2VIDEO decoder") == 0) {   // deinterlace for mpeg2 is somehow broken | ||||
|     int deint = 2; | ||||
|     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 | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             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); | ||||
|             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) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             Fatal(_("codec: can't set option drop 2.field to video codec!\n")); | ||||
| @@ -372,12 +329,10 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             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) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             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) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             Fatal(_("codec: can't set option drop 2.field  to video codec!\n")); | ||||
| @@ -418,7 +373,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
|  | ||||
|     // reset buggy ffmpeg/libav flag | ||||
|     decoder->GetFormatDone = 0; | ||||
| #if defined (YADIF) || defined (RASPI) | ||||
| #if defined(YADIF) | ||||
|     decoder->filter = 0; | ||||
| #endif | ||||
| } | ||||
| @@ -428,8 +383,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) | ||||
| ** | ||||
| **  @param video_decoder    private video decoder | ||||
| */ | ||||
| void CodecVideoClose(VideoDecoder * video_decoder) | ||||
| { | ||||
| void CodecVideoClose(VideoDecoder *video_decoder) { | ||||
|     AVFrame *frame; | ||||
|  | ||||
|     // FIXME: play buffered data | ||||
| @@ -438,17 +392,21 @@ void CodecVideoClose(VideoDecoder * video_decoder) | ||||
|     Debug(3, "CodecVideoClose\n"); | ||||
|     if (video_decoder->VideoCtx) { | ||||
|         pthread_mutex_lock(&CodecLockMutex); | ||||
| #if 1 | ||||
|  | ||||
|         frame = av_frame_alloc(); | ||||
|         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); | ||||
| #endif | ||||
|  | ||||
| #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(55,63,100) | ||||
| 	    avcodec_close(video_decoder->VideoCtx); | ||||
| 	    av_freep(&video_decoder->VideoCtx); | ||||
| #else | ||||
| 	    avcodec_free_context(&video_decoder->VideoCtx); | ||||
| #endif | ||||
|         pthread_mutex_unlock(&CodecLockMutex); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| @@ -501,8 +459,7 @@ extern int push_filters(AVCodecContext * dec_ctx, void *decoder, AVFrame * frame | ||||
| #endif | ||||
|  | ||||
| #ifdef VAAPI | ||||
| void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
| { | ||||
| void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) { | ||||
|     AVCodecContext *video_ctx = decoder->VideoCtx; | ||||
|  | ||||
|     if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO && CuvidTestSurfaces()) { | ||||
| @@ -540,7 +497,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|                             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); | ||||
|                         continue; | ||||
|                     } | ||||
| @@ -557,14 +514,13 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|  | ||||
| #ifdef CUVID | ||||
|  | ||||
| void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
| { | ||||
| void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) { | ||||
|     AVCodecContext *video_ctx; | ||||
|     AVFrame *frame; | ||||
|     int ret, ret1; | ||||
|     int got_frame; | ||||
|     int consumed = 0; | ||||
|     static uint64_t first_time = 0; | ||||
|     //static uint64_t first_time = 0; | ||||
|     const AVPacket *pkt; | ||||
|  | ||||
| next_part: | ||||
| @@ -573,7 +529,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|     pkt = avpkt; // use copy | ||||
|     got_frame = 0; | ||||
|  | ||||
|     // printf("decode packet  %d\n",(GetusTicks()-first_time)/1000000); | ||||
|     ret1 = avcodec_send_packet(video_ctx, pkt); | ||||
|  | ||||
|     // first_time = GetusTicks(); | ||||
| @@ -593,25 +548,27 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|             frame = av_frame_alloc(); | ||||
|             ret = avcodec_receive_frame(video_ctx, frame); // get new frame | ||||
|             if (ret >= 0) {                                // one is avail. | ||||
|                 //first_time = frame->pts; | ||||
|                 got_frame = 1; | ||||
|             } else { | ||||
|                 got_frame = 0; | ||||
|             } | ||||
|             //printf("got %s packet from decoder\n",got_frame?"1":"no"); | ||||
|             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 | ||||
|                 if (decoder->filter) { | ||||
|                     if (decoder->filter == 1) { | ||||
|                         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; | ||||
|                         } else { | ||||
|                             Debug(3, "Init YADIF ok\n"); | ||||
|                             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); | ||||
|                         // av_frame_unref(frame); | ||||
|                         continue; | ||||
| @@ -636,7 +593,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|     if (!consumed) { | ||||
|         goto next_part; // try again to stuff decoder | ||||
|     } | ||||
|  | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @@ -645,8 +601,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
| ** | ||||
| **  @param decoder  video decoder data | ||||
| */ | ||||
| void CodecVideoFlushBuffers(VideoDecoder * decoder) | ||||
| { | ||||
| void CodecVideoFlushBuffers(VideoDecoder *decoder) { | ||||
|     if (decoder->VideoCtx) { | ||||
|         avcodec_flush_buffers(decoder->VideoCtx); | ||||
|     } | ||||
| @@ -666,9 +621,12 @@ typedef struct _audio_decoder_ AudioDecoder; | ||||
| /// | ||||
| /// Audio decoder structure. | ||||
| /// | ||||
| struct _audio_decoder_ | ||||
| { | ||||
| struct _audio_decoder_ { | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100) | ||||
|     AVCodec *AudioCodec;		///< audio codec | ||||
| #else | ||||
|     const AVCodec *AudioCodec;		///< audio codec | ||||
| #endif | ||||
|     AVCodecContext *AudioCtx; ///< audio codec context | ||||
|  | ||||
|     char Passthrough; ///< current pass-through flags | ||||
| @@ -679,17 +637,7 @@ struct _audio_decoder_ | ||||
|     int HwChannels;   ///< hw channels | ||||
|  | ||||
|     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 | ||||
| #endif | ||||
| #endif | ||||
| #ifdef USE_AVRESAMPLE | ||||
|     AVAudioResampleContext *Resample;   ///< libav software resample context | ||||
| #endif | ||||
|  | ||||
|     uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer | ||||
|     int SpdifIndex;            ///< index into SPDIF output buffer | ||||
| @@ -707,8 +655,7 @@ struct _audio_decoder_ | ||||
| /// | ||||
| /// IEC Data type enumeration. | ||||
| /// | ||||
| enum IEC61937 | ||||
| { | ||||
| enum IEC61937 { | ||||
|     IEC61937_AC3 = 0x01, ///< AC-3 data | ||||
|     // FIXME: more data types | ||||
|     IEC61937_EAC3 = 0x15, ///< E-AC-3 data | ||||
| @@ -736,8 +683,7 @@ static char CodecDownmix;               ///< enable AC-3 decoder downmix | ||||
| ** | ||||
| **  @returns private decoder pointer for audio decoder. | ||||
| */ | ||||
| AudioDecoder *CodecAudioNewDecoder(void) | ||||
| { | ||||
| AudioDecoder *CodecAudioNewDecoder(void) { | ||||
|     AudioDecoder *audio_decoder; | ||||
|  | ||||
|     if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) { | ||||
| @@ -755,8 +701,7 @@ AudioDecoder *CodecAudioNewDecoder(void) | ||||
| ** | ||||
| **  @param decoder  private audio decoder | ||||
| */ | ||||
| void CodecAudioDelDecoder(AudioDecoder * decoder) | ||||
| { | ||||
| void CodecAudioDelDecoder(AudioDecoder *decoder) { | ||||
|     av_frame_free(&decoder->Frame); // callee does checks | ||||
|     free(decoder); | ||||
| } | ||||
| @@ -767,10 +712,12 @@ void CodecAudioDelDecoder(AudioDecoder * decoder) | ||||
| **  @param audio_decoder    private audio decoder | ||||
| **  @param codec_id audio   codec id | ||||
| */ | ||||
| void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id) | ||||
| { | ||||
| void CodecAudioOpen(AudioDecoder *audio_decoder, int codec_id) { | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100) | ||||
|     AVCodec *audio_codec; | ||||
|  | ||||
| #else | ||||
|     const AVCodec *audio_codec; | ||||
| #endif | ||||
|     Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, avcodec_get_name(codec_id)); | ||||
|     if (!(audio_codec = avcodec_find_decoder(codec_id))) { | ||||
|         // if (!(audio_codec = avcodec_find_decoder(codec_id))) { | ||||
| @@ -783,9 +730,6 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id) | ||||
|         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); | ||||
|     // open codec | ||||
|     if (1) { | ||||
| @@ -817,24 +761,20 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id) | ||||
| ** | ||||
| **  @param audio_decoder    private audio decoder | ||||
| */ | ||||
| void CodecAudioClose(AudioDecoder * audio_decoder) | ||||
| { | ||||
| void CodecAudioClose(AudioDecoder *audio_decoder) { | ||||
|     // FIXME: output any buffered data | ||||
|  | ||||
| #ifdef USE_SWRESAMPLE | ||||
|     if (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) { | ||||
|         pthread_mutex_lock(&CodecLockMutex); | ||||
| #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(55,63,100) | ||||
| 	    avcodec_close(audio_decoder->AudioCtx); | ||||
| 	    av_freep(&audio_decoder->AudioCtx); | ||||
| #else | ||||
| 	    avcodec_free_context(&audio_decoder->AudioCtx); | ||||
| #endif | ||||
|         pthread_mutex_unlock(&CodecLockMutex); | ||||
|     } | ||||
| } | ||||
| @@ -844,8 +784,7 @@ void CodecAudioClose(AudioDecoder * audio_decoder) | ||||
| ** | ||||
| **  @param mask enable mask (PCM, AC-3) | ||||
| */ | ||||
| void CodecSetAudioDrift(int mask) | ||||
| { | ||||
| void CodecSetAudioDrift(int mask) { | ||||
| #ifdef USE_AUDIO_DRIFT_CORRECTION | ||||
|     CodecAudioDrift = mask & (CORRECT_PCM | CORRECT_AC3); | ||||
| #endif | ||||
| @@ -857,8 +796,7 @@ void CodecSetAudioDrift(int mask) | ||||
| ** | ||||
| **  @param mask enable mask (PCM, AC-3, E-AC-3) | ||||
| */ | ||||
| void CodecSetAudioPassthrough(int mask) | ||||
| { | ||||
| void CodecSetAudioPassthrough(int mask) { | ||||
| #ifdef USE_PASSTHROUGH | ||||
|     CodecPassthrough = mask & (CodecPCM | CodecAC3 | CodecEAC3); | ||||
| #endif | ||||
| @@ -870,8 +808,7 @@ void CodecSetAudioPassthrough(int mask) | ||||
| ** | ||||
| **  @param onoff    enable/disable downmix. | ||||
| */ | ||||
| void CodecSetAudioDownmix(int onoff) | ||||
| { | ||||
| void CodecSetAudioDownmix(int onoff) { | ||||
|     if (onoff == -1) { | ||||
|         CodecDownmix ^= 1; | ||||
|         return; | ||||
| @@ -890,8 +827,7 @@ void CodecSetAudioDownmix(int onoff) | ||||
| **  @param size		size of sample buffer in bytes | ||||
| **  @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 c; | ||||
|     int ls; | ||||
| @@ -945,31 +881,46 @@ static void CodecReorderAudioFrame(int16_t * buf, int size, int channels) | ||||
| **  @param audio_decoder    audio decoder data | ||||
| **  @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; | ||||
|     int err; | ||||
|  | ||||
|     audio_ctx = audio_decoder->AudioCtx; | ||||
|     Debug(3, "codec/audio: format change %s %dHz *%d channels%s%s%s%s%s\n", | ||||
|         av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, audio_ctx->channels, | ||||
|         CodecPassthrough & CodecPCM ? " PCM" : "", CodecPassthrough & CodecMPA ? " MPA" : "", | ||||
|         CodecPassthrough & CodecAC3 ? " AC-3" : "", CodecPassthrough & CodecEAC3 ? " E-AC-3" : "", | ||||
|      | ||||
|   | ||||
|     Debug(3, "codec/audio: format change %s %dHz *%d channels%s%s%s%s%s%s\n", | ||||
| 	av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
| 	audio_ctx->channels, CodecPassthrough & CodecPCM ? " PCM" : "", | ||||
| #else | ||||
| 	audio_ctx->ch_layout.nb_channels, CodecPassthrough & CodecPCM ? " PCM" : "", | ||||
| #endif | ||||
| 	CodecPassthrough & CodecMPA ? " MPA" : "", | ||||
| 	CodecPassthrough & CodecAC3 ? " AC-3" : "", | ||||
| 	CodecPassthrough & CodecEAC3 ? " E-AC-3" : "", | ||||
| 	CodecPassthrough & CodecDTS ? " DTS" : "", | ||||
| 	CodecPassthrough ? " pass-through" : ""); | ||||
|  | ||||
|  | ||||
|     *passthrough = 0; | ||||
|     audio_decoder->SampleRate = audio_ctx->sample_rate; | ||||
|     audio_decoder->HwSampleRate = audio_ctx->sample_rate; | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
|     audio_decoder->Channels = audio_ctx->channels; | ||||
|     audio_decoder->HwChannels = audio_ctx->channels; | ||||
|     audio_decoder->Passthrough = CodecPassthrough; | ||||
| #else | ||||
|     audio_decoder->Channels = audio_ctx->ch_layout.nb_channels; | ||||
|     audio_decoder->HwChannels = audio_ctx->ch_layout.nb_channels; | ||||
| #endif | ||||
|     if (CodecDownmix && !CodecPassthrough) audio_decoder->HwChannels = 2; | ||||
|  | ||||
|     audio_decoder->Passthrough = CodecPassthrough; | ||||
|     // SPDIF/HDMI pass-through | ||||
|     if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) | ||||
|         || (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) { | ||||
|     if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) || | ||||
|         (CodecPassthrough & CodecEAC3 && 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 | ||||
|             audio_decoder->HwSampleRate *= 4; | ||||
|             //audio_decoder->HwSampleRate *= 4; | ||||
|         } | ||||
|         audio_decoder->HwChannels = 2; | ||||
|         audio_decoder->SpdifIndex = 0; // reset buffer | ||||
| @@ -981,8 +932,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough | ||||
|  | ||||
|         // try E-AC-3 none HBR | ||||
|         audio_decoder->HwSampleRate /= 4; | ||||
|         if (audio_ctx->codec_id != AV_CODEC_ID_EAC3 | ||||
|             || (err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) { | ||||
|         if (audio_ctx->codec_id != AV_CODEC_ID_EAC3 || | ||||
|             (err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) { | ||||
|  | ||||
|             Debug(3, "codec/audio: audio setup error\n"); | ||||
|             // FIXME: handle errors | ||||
| @@ -992,10 +943,16 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Debug(3, "codec/audio: resample %s %dHz *%d -> %s %dHz *%d\n", av_get_sample_fmt_name(audio_ctx->sample_fmt), | ||||
|         audio_ctx->sample_rate, audio_ctx->channels, av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), | ||||
|     Debug(3, "codec/audio: resample %s %dHz *%d -> %s %dHz *%d\n", | ||||
| 	    av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
| 	    audio_ctx->channels, av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), | ||||
| #else | ||||
| 	    audio_ctx->ch_layout.nb_channels, av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), | ||||
| #endif | ||||
| 	    audio_decoder->HwSampleRate, audio_decoder->HwChannels); | ||||
|  | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -1005,8 +962,7 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough | ||||
| **  @param audio_decoder    audio decoder data | ||||
| **  @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 | ||||
|     const AVCodecContext *audio_ctx; | ||||
|  | ||||
| @@ -1025,11 +981,10 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac | ||||
|         if (CodecAudioDrift & CORRECT_AC3) { | ||||
|             int x; | ||||
|  | ||||
|             x = (audio_decoder->DriftFrac + | ||||
|                 (audio_decoder->DriftCorr * spdif_sz)) / (10 * audio_decoder->HwSampleRate * 100); | ||||
|             audio_decoder->DriftFrac = | ||||
|                 (audio_decoder->DriftFrac + | ||||
|                 (audio_decoder->DriftCorr * spdif_sz)) % (10 * audio_decoder->HwSampleRate * 100); | ||||
|             x = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) / | ||||
|                 (10 * audio_decoder->HwSampleRate * 100); | ||||
|             audio_decoder->DriftFrac = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) % | ||||
|                                        (10 * audio_decoder->HwSampleRate * 100); | ||||
|             // round to word border | ||||
|             x *= audio_decoder->HwChannels * 4; | ||||
|             if (x < -64) { // limit correction | ||||
| @@ -1112,16 +1067,13 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #if defined(USE_SWRESAMPLE) || defined(USE_AVRESAMPLE) | ||||
|  | ||||
| /** | ||||
| **  Set/update audio pts clock. | ||||
| ** | ||||
| **  @param audio_decoder    audio decoder data | ||||
| **  @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 | ||||
|     struct timespec nowtime; | ||||
|     int64_t delay; | ||||
| @@ -1152,8 +1104,8 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec) | ||||
|         * 1000 * 1000 * 1000 + (nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec); | ||||
|     tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec) * 1000 * 1000 * 1000 + | ||||
|                (nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec); | ||||
|  | ||||
|     drift = (tim_diff * 90) / (1000 * 1000) - pts_diff + delay - audio_decoder->LastDelay; | ||||
|  | ||||
| @@ -1181,10 +1133,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) | ||||
|         audio_decoder->Drift = drift; | ||||
|         corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000); | ||||
|         // SPDIF/HDMI passthrough | ||||
|         if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3) | ||||
|                 || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) | ||||
|             && (!(CodecPassthrough & CodecEAC3) | ||||
|                 || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) { | ||||
|         if ((CodecAudioDrift & CORRECT_AC3) && | ||||
|             (!(CodecPassthrough & CodecAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) && | ||||
|             (!(CodecPassthrough & CodecEAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) { | ||||
|             audio_decoder->DriftCorr = -corr; | ||||
|         } | ||||
|  | ||||
| @@ -1195,7 +1146,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| #ifdef USE_SWRESAMPLE | ||||
|     if (audio_decoder->Resample && audio_decoder->DriftCorr) { | ||||
|         int distance; | ||||
|  | ||||
| @@ -1209,17 +1159,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) | ||||
|             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) { | ||||
|         static int c; | ||||
|  | ||||
| @@ -1237,11 +1176,16 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) | ||||
| ** | ||||
| **  @param audio_decoder    audio decoder data | ||||
| */ | ||||
| static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) | ||||
| { | ||||
| static void CodecAudioUpdateFormat(AudioDecoder *audio_decoder) { | ||||
|     int passthrough; | ||||
|     const AVCodecContext *audio_ctx; | ||||
|  | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
|     int64_t dmlayout = AV_CH_LAYOUT_STEREO; | ||||
| #else | ||||
|     AVChannelLayout dmlayout = AV_CHANNEL_LAYOUT_STEREO; | ||||
| #endif | ||||
|  | ||||
|     if (CodecAudioUpdateHelper(audio_decoder, &passthrough)) { | ||||
|         // FIXME: handle swresample format conversions. | ||||
|         return; | ||||
| @@ -1252,45 +1196,39 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) | ||||
|  | ||||
|     audio_ctx = audio_decoder->AudioCtx; | ||||
|  | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
|     if (!CodecDownmix || CodecPassthrough) dmlayout = audio_ctx->channel_layout; | ||||
| #else | ||||
|     if (!CodecDownmix || CodecPassthrough) dmlayout = audio_ctx->ch_layout; | ||||
| #endif | ||||
|  | ||||
| #ifdef DEBUG | ||||
|     if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate | ||||
|         && !CodecAudioDrift) { | ||||
|     if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate && | ||||
|         !CodecAudioDrift) { | ||||
|         // FIXME: use Resample only, when it is needed! | ||||
|         fprintf(stderr, "no resample needed\n"); | ||||
|     } | ||||
| #endif | ||||
|      | ||||
| #ifdef USE_SWRESAMPLE | ||||
| #if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(4,5,100) | ||||
|     audio_decoder->Resample = | ||||
|         swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, AV_SAMPLE_FMT_S16, | ||||
|         audio_decoder->HwSampleRate, audio_ctx->channel_layout, audio_ctx->sample_fmt, audio_ctx->sample_rate, 0, | ||||
|         NULL); | ||||
|         swr_alloc_set_opts(audio_decoder->Resample, dmlayout, | ||||
|         AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate, | ||||
|         audio_ctx->channel_layout, audio_ctx->sample_fmt, | ||||
| #else | ||||
|         swr_alloc_set_opts2(&audio_decoder->Resample, &dmlayout, | ||||
|         AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate, | ||||
|         &audio_ctx->ch_layout, audio_ctx->sample_fmt, | ||||
| #endif | ||||
| 	   audio_ctx->sample_rate, 0, NULL);  | ||||
|  | ||||
|     if (audio_decoder->Resample) { | ||||
| 	swr_init(audio_decoder->Resample); | ||||
|     } else { | ||||
| 	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 +1242,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) | ||||
| **  @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; | ||||
|  | ||||
|     if (audio_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { | ||||
| @@ -1332,8 +1269,13 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) | ||||
|                 CodecAudioSetClock(audio_decoder, avpkt->pts); | ||||
|             } | ||||
|             // format change | ||||
|             if (audio_decoder->Passthrough != CodecPassthrough || audio_decoder->SampleRate != audio_ctx->sample_rate | ||||
|                 || audio_decoder->Channels != audio_ctx->channels) { | ||||
|             if (audio_decoder->Passthrough != CodecPassthrough || | ||||
|                 audio_decoder->SampleRate != audio_ctx->sample_rate || | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,24,100) | ||||
|                 audio_decoder->Channels != audio_ctx->channels) { | ||||
| #else | ||||
|                 audio_decoder->Channels != audio_ctx->ch_layout.nb_channels) { | ||||
| #endif | ||||
|                 CodecAudioUpdateFormat(audio_decoder); | ||||
|             } | ||||
|             if (!audio_decoder->HwSampleRate || !audio_decoder->HwChannels) { | ||||
| @@ -1342,14 +1284,15 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) | ||||
|             if (CodecAudioPassthroughHelper(audio_decoder, avpkt)) { | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if (audio_decoder->Resample) { | ||||
|                 uint8_t outbuf[8192  * 2 * 8]; | ||||
|                 uint8_t *out[1]; | ||||
|  | ||||
|                 out[0] = outbuf; | ||||
|                 ret = | ||||
|                     swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels), | ||||
|                 ret = swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels), | ||||
|                                   (const uint8_t **)frame->extended_data, frame->nb_samples); | ||||
|                                    | ||||
|                 if (ret > 0) { | ||||
|                     if (!(audio_decoder->Passthrough & CodecPCM)) { | ||||
|                         CodecReorderAudioFrame((int16_t *)outbuf, ret * 2 * audio_decoder->HwChannels, | ||||
| @@ -1363,18 +1306,12 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /** | ||||
| **  Flush the audio decoder. | ||||
| ** | ||||
| **  @param decoder  audio decoder data | ||||
| */ | ||||
| void CodecAudioFlushBuffers(AudioDecoder * decoder) | ||||
| { | ||||
|  | ||||
|     avcodec_flush_buffers(decoder->AudioCtx); | ||||
| } | ||||
| void CodecAudioFlushBuffers(AudioDecoder *decoder) { avcodec_flush_buffers(decoder->AudioCtx); } | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //  Codec | ||||
| @@ -1383,18 +1320,13 @@ void CodecAudioFlushBuffers(AudioDecoder * decoder) | ||||
| /** | ||||
| **  Empty log callback | ||||
| */ | ||||
| static void CodecNoopCallback( __attribute__((unused)) | ||||
|     void *ptr, __attribute__((unused)) | ||||
|     int level, __attribute__((unused)) | ||||
|     const char *fmt, __attribute__((unused)) va_list vl) | ||||
| { | ||||
| } | ||||
| static void CodecNoopCallback(__attribute__((unused)) void *ptr, __attribute__((unused)) int level, | ||||
|                               __attribute__((unused)) const char *fmt, __attribute__((unused)) va_list vl) {} | ||||
|  | ||||
| /** | ||||
| **  Codec init | ||||
| */ | ||||
| void CodecInit(void) | ||||
| { | ||||
| void CodecInit(void) { | ||||
|     pthread_mutex_init(&CodecLockMutex, NULL); | ||||
| #ifndef DEBUG | ||||
|     // disable display ffmpeg error messages | ||||
| @@ -1407,7 +1339,4 @@ void CodecInit(void) | ||||
| /** | ||||
| **  Codec exit. | ||||
| */ | ||||
| void CodecExit(void) | ||||
| { | ||||
|     pthread_mutex_destroy(&CodecLockMutex); | ||||
| } | ||||
| void CodecExit(void) { pthread_mutex_destroy(&CodecLockMutex); } | ||||
|   | ||||
							
								
								
									
										11
									
								
								codec.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								codec.h
									
									
									
									
									
								
							| @@ -35,8 +35,7 @@ | ||||
|  | ||||
| #define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 | ||||
|  | ||||
| enum HWAccelID | ||||
| { | ||||
| enum HWAccelID { | ||||
|     HWACCEL_NONE = 0, | ||||
|     HWACCEL_AUTO, | ||||
|     HWACCEL_VDPAU, | ||||
| @@ -53,12 +52,15 @@ extern AVBufferRef *hw_device_ctx; | ||||
| /// | ||||
| /// Video decoder structure. | ||||
| /// | ||||
| struct _video_decoder_ | ||||
| { | ||||
| struct _video_decoder_ { | ||||
|     VideoHwDecoder *HwDecoder; ///< video hardware decoder | ||||
|  | ||||
|     int GetFormatDone;        ///< flag get format called! | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100) | ||||
|      AVCodec *VideoCodec;                ///< video codec | ||||
| #else | ||||
|      const AVCodec *VideoCodec;          ///< video codec | ||||
| #endif | ||||
|     AVCodecContext *VideoCtx; ///< video codec context | ||||
|     // #ifdef FFMPEG_WORKAROUND_ARTIFACTS | ||||
|     int FirstKeyFrame; ///< flag first frame | ||||
| @@ -87,7 +89,6 @@ struct _video_decoder_ | ||||
|     double cached_hdr_peak; | ||||
|     // From VO | ||||
|     struct mp_hwdec_devices *hwdec_devs; | ||||
|  | ||||
| }; | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
|   | ||||
							
								
								
									
										32
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								common.h
									
									
									
									
									
								
							| @@ -19,17 +19,17 @@ | ||||
| #ifndef MPLAYER_GL_COMMON_H | ||||
| #define MPLAYER_GL_COMMON_H | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #if 0 | ||||
| #include "config.h" | ||||
| #include "common/msg.h" | ||||
| #include "config.h" | ||||
| #include "misc/bstr.h" | ||||
|  | ||||
| #include "video/out/vo.h" | ||||
| #include "video/csputils.h" | ||||
| #include "video/mp_image.h" | ||||
| #include "video/out/vo.h" | ||||
| #endif | ||||
|  | ||||
| #if HAVE_GL_COCOA | ||||
| @@ -53,8 +53,7 @@ | ||||
| struct GL; | ||||
| typedef struct GL GL; | ||||
|  | ||||
| enum | ||||
| { | ||||
| enum { | ||||
|     MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH | ||||
|     MPGL_CAP_FB = (1 << 5), | ||||
|     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 *); | ||||
|  | ||||
| // function pointers loaded from the OpenGL library | ||||
| struct GL | ||||
| { | ||||
| struct GL { | ||||
|     int version;        // MPGL_VER() mangled (e.g. 210 for 2.1) | ||||
|     int es;             // es version (e.g. 300), 0 for desktop GL | ||||
|     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 *VDPAUFiniNV)(void); | ||||
|      GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterOutputSurfaceNV) | ||||
|      (GLvoid *, GLenum, GLsizei, const GLuint *); | ||||
|      GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterVideoSurfaceNV) | ||||
|      (GLvoid *, GLenum, GLsizei, const GLuint *); | ||||
|     GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterOutputSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *); | ||||
|     GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterVideoSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *); | ||||
|     void(GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV); | ||||
|     void(GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum); | ||||
|     void(GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *); | ||||
| @@ -203,13 +199,17 @@ struct GL | ||||
|  | ||||
| #if HAVE_GL_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); | ||||
|     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 * DXLockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects); | ||||
|      BOOL(GLAPIENTRY * DXUnlockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects); | ||||
|     BOOL(GLAPIENTRY *DXLockObjectsNV) | ||||
|     (HANDLE hDevice, GLint count, HANDLE *hObjects); | ||||
|     BOOL(GLAPIENTRY *DXUnlockObjectsNV) | ||||
|     (HANDLE hDevice, GLint count, HANDLE *hObjects); | ||||
| #endif | ||||
|  | ||||
|     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 <sys/mman.h> | ||||
| #include <xf86drm.h> | ||||
| #include <xf86drmMode.h> | ||||
| #include <drm_fourcc.h> | ||||
| #include <unistd.h> | ||||
| #include <xf86drm.h> | ||||
| #include <xf86drmMode.h> | ||||
|  | ||||
| @@ -13,8 +11,7 @@ | ||||
| //  DRM | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| struct _Drm_Render_ | ||||
| { | ||||
| struct _Drm_Render_ { | ||||
|     int fd_drm; | ||||
|     drmModeModeInfo mode; | ||||
|     drmModeCrtc *saved_crtc; | ||||
| @@ -24,7 +21,6 @@ struct _Drm_Render_ | ||||
|     uint32_t hdr_metadata; | ||||
|     uint32_t mmWidth, mmHeight; // Size in mm | ||||
|     uint32_t hdr_blob_id; | ||||
|  | ||||
| }; | ||||
| typedef struct _Drm_Render_ VideoRender; | ||||
|  | ||||
| @@ -46,10 +42,7 @@ struct type_name { | ||||
|     const char *name; | ||||
| }; | ||||
|  | ||||
| static const char *util_lookup_type_name(unsigned int type, | ||||
|                      const struct type_name *table, | ||||
|                      unsigned int count) | ||||
| { | ||||
| static const char *util_lookup_type_name(unsigned int type, const struct type_name *table, unsigned int count) { | ||||
|     unsigned int i; | ||||
|  | ||||
|     for (i = 0; i < count; i++) | ||||
| @@ -80,21 +73,16 @@ static const struct type_name connector_type_names[] = { | ||||
|     {DRM_MODE_CONNECTOR_DPI, "DPI"}, | ||||
| }; | ||||
|  | ||||
| const char *util_lookup_connector_type_name(unsigned int type) | ||||
| { | ||||
|     return util_lookup_type_name(type, connector_type_names, | ||||
|                      ARRAY_SIZE(connector_type_names)); | ||||
| const char *util_lookup_connector_type_name(unsigned int type) { | ||||
|     return util_lookup_type_name(type, connector_type_names, ARRAY_SIZE(connector_type_names)); | ||||
| } | ||||
|  | ||||
| static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID, | ||||
|                         uint32_t objectType, const char *propName) | ||||
| { | ||||
| static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) { | ||||
|     uint32_t i; | ||||
|     int found = 0; | ||||
|     uint64_t value = 0; | ||||
|     drmModePropertyPtr Prop; | ||||
|     drmModeObjectPropertiesPtr objectProps = | ||||
|         drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|     drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|  | ||||
|     for (i = 0; i < objectProps->count_props; i++) { | ||||
|         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 | ||||
|     if (!found) | ||||
|         fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n", | ||||
|             propName); | ||||
|         fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n", propName); | ||||
| #endif | ||||
|     return value; | ||||
| } | ||||
| static uint32_t GetPropertyID(int fd_drm, uint32_t objectID, | ||||
|                         uint32_t objectType, const char *propName) | ||||
| { | ||||
| static uint32_t GetPropertyID(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) { | ||||
|     uint32_t i; | ||||
|     int found = 0; | ||||
|     uint32_t value = -1; | ||||
|     drmModePropertyPtr Prop; | ||||
|     drmModeObjectPropertiesPtr objectProps = | ||||
|         drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|     drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|  | ||||
|     for (i = 0; i < objectProps->count_props; i++) { | ||||
|         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; | ||||
| } | ||||
|  | ||||
| static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, | ||||
|                     uint32_t objectID, uint32_t objectType, | ||||
|                     const char *propName, uint64_t value) | ||||
| { | ||||
| static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, uint32_t objectID, uint32_t objectType, | ||||
|                               const char *propName, uint64_t value) { | ||||
|     uint32_t i; | ||||
|     uint64_t id = 0; | ||||
|     drmModePropertyPtr Prop; | ||||
|     drmModeObjectPropertiesPtr objectProps = | ||||
|         drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|     drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType); | ||||
|  | ||||
|     for (i = 0; i < objectProps->count_props; i++) { | ||||
|         if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL) | ||||
| @@ -177,29 +158,25 @@ static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, | ||||
|     drmModeFreeObjectProperties(objectProps); | ||||
|  | ||||
|     if (id == 0) | ||||
|         printf( "SetPropertyRequest: Unable to find value for property \'%s\'.\n", | ||||
|             propName); | ||||
|         printf("SetPropertyRequest: Unable to find value for property \'%s\'.\n", propName); | ||||
|  | ||||
|     return drmModeAtomicAddProperty(ModeReq, objectID, id, value); | ||||
| } | ||||
|  | ||||
| static void CuvidSetVideoMode(void); | ||||
| void set_video_mode(int width, int height) | ||||
| { | ||||
| void set_video_mode(int width, int height) { | ||||
|     drmModeConnector *connector; | ||||
|     drmModeModeInfo *mode; | ||||
|     int ii; | ||||
|     printf("Set video mode %d &%d\n",width,height); | ||||
|     if (height != 1080 && height != 2160) | ||||
|         return; | ||||
|     connector = drmModeGetConnector(render->fd_drm, render->connector_id); | ||||
|     for (ii = 0; ii < connector->count_modes; ii++) { | ||||
|         mode = &connector->modes[ii]; | ||||
|         printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh); | ||||
| 		if (width == mode->hdisplay && | ||||
| 				height == mode->vdisplay && | ||||
| 				mode->vrefresh == DRMRefresh && | ||||
| 				render->mode.hdisplay != width && | ||||
| 		        render->mode.vdisplay != height && | ||||
|         if (width == mode->hdisplay && height == mode->vdisplay && mode->vrefresh == DRMRefresh && | ||||
|             render->mode.hdisplay != width && render->mode.vdisplay != height && | ||||
|             !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { | ||||
|             memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); | ||||
|             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; | ||||
|     drmModeRes *resources; | ||||
|     drmModeConnector *connector; | ||||
| @@ -231,32 +207,28 @@ static int FindDevice(VideoRender * render) | ||||
|     int i, ii = 0; | ||||
|     char connectorstr[10]; | ||||
|     int found = 0; | ||||
| #ifdef RASPI | ||||
|     render->fd_drm = open("/dev/dri/card1", O_RDWR); | ||||
| #else | ||||
|     render->fd_drm = open("/dev/dri/card0", O_RDWR); | ||||
| #endif | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     int ret = drmSetMaster(render->fd_drm); | ||||
|  | ||||
| 	if (ret < 0) | ||||
| 	{ | ||||
|     if (ret < 0) { | ||||
|         drm_magic_t 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)); | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         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)); | ||||
|             return -1; | ||||
|         } | ||||
| @@ -290,9 +262,8 @@ static int FindDevice(VideoRender * render) | ||||
|     } | ||||
|  | ||||
| #ifdef DEBUG | ||||
|     Debug(3,"[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n", | ||||
|         resources->count_connectors, resources->count_crtcs, | ||||
|         resources->count_encoders); | ||||
|     Debug(3, "[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n", resources->count_connectors, | ||||
|           resources->count_crtcs, resources->count_encoders); | ||||
| #endif | ||||
|  | ||||
|     // find all available connectors | ||||
| @@ -303,12 +274,16 @@ static int FindDevice(VideoRender * render) | ||||
|             return -errno; | ||||
|         } | ||||
|  | ||||
|         sprintf(connectorstr,"%s-%u",util_lookup_connector_type_name(connector->connector_type),connector->connector_type_id); | ||||
|         printf("Connector >%s< is %sconnected\n",connectorstr,connector->connection == DRM_MODE_CONNECTED?"":"not "); | ||||
|         sprintf(connectorstr, "%s-%u", util_lookup_connector_type_name(connector->connector_type), | ||||
|                 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)) | ||||
|             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; | ||||
|             if ((aspect > 1.70) && (aspect < 1.85)) { | ||||
|                 render->mmHeight = 90; | ||||
| @@ -325,9 +300,10 @@ static int FindDevice(VideoRender * render) | ||||
|             } | ||||
|             render->crtc_id = encoder->crtc_id; | ||||
|  | ||||
|             render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, | ||||
|                             DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA"); | ||||
|             printf("ID %d of METADATA in Connector %d connected %d\n",render->hdr_metadata,connector->connector_id,connector->connection); | ||||
|             render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, DRM_MODE_OBJECT_CONNECTOR, | ||||
|                                                  "HDR_OUTPUT_METADATA"); | ||||
|             printf("ID %d of METADATA in Connector %d connected %d\n", render->hdr_metadata, connector->connector_id, | ||||
|                    connector->connection); | ||||
|  | ||||
|             memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback | ||||
|             // search Modes for Connector | ||||
| @@ -335,17 +311,14 @@ static int FindDevice(VideoRender * render) | ||||
|                 mode = &connector->modes[ii]; | ||||
|  | ||||
|                 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 == mode->hdisplay && | ||||
|                             VideoWindowHeight == mode->vdisplay && | ||||
|                             mode->vrefresh == DRMRefresh && | ||||
|                             !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { | ||||
|                     if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay && | ||||
|                         mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { | ||||
|                         memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 else { | ||||
|                 } else { | ||||
|                     if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) { | ||||
|                         memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); | ||||
|                         VideoWindowWidth = mode->hdisplay; | ||||
| @@ -357,10 +330,16 @@ static int FindDevice(VideoRender * render) | ||||
|             found = 1; | ||||
|             i = resources->count_connectors; // uuuuhh | ||||
|         } | ||||
|  | ||||
|         if (found) { | ||||
|             VideoWindowWidth = render->mode.hdisplay; | ||||
|             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); | ||||
|     } | ||||
|     if (!found) { | ||||
| @@ -384,27 +363,23 @@ static int FindDevice(VideoRender * render) | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], | ||||
|                             DRM_MODE_OBJECT_PLANE, "type"); | ||||
|         uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], DRM_MODE_OBJECT_PLANE, "type"); | ||||
|         uint64_t zpos = 0; | ||||
|  | ||||
| #ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!! | ||||
|         printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", | ||||
|             plane->plane_id, plane->crtc_id, plane->possible_crtcs, resources->crtcs[i], | ||||
|             (type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane" : | ||||
|             (type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane" : | ||||
|             (type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane" : "No plane type"); | ||||
|         printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", plane->plane_id, | ||||
|                plane->crtc_id, plane->possible_crtcs, resources->crtcs[i], | ||||
|                (type == DRM_PLANE_TYPE_PRIMARY)   ? "primary plane" | ||||
|                : (type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane" | ||||
|                : (type == DRM_PLANE_TYPE_CURSOR)  ? "cursor plane" | ||||
|                                                   : "No plane type"); | ||||
| #endif | ||||
|  | ||||
|         // test pixel format and plane caps | ||||
|         for (k = 0; k < plane->count_formats; k++) { | ||||
|             if (encoder->possible_crtcs & plane->possible_crtcs) { | ||||
|                 switch (plane->formats[k]) { | ||||
| #ifdef RASPI | ||||
|                     case DRM_FORMAT_ARGB8888: | ||||
| #else | ||||
|                     case DRM_FORMAT_XRGB2101010: | ||||
| #endif | ||||
|                         if (!render->video_plane) { | ||||
|                             render->video_plane = plane->plane_id; | ||||
|                         } | ||||
| @@ -423,8 +398,7 @@ static int FindDevice(VideoRender * render) | ||||
|     drmModeFreeResources(resources); | ||||
|  | ||||
| #ifdef DRM_DEBUG | ||||
|     printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n", | ||||
|         render->crtc_id, render->video_plane); | ||||
|     printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n", render->crtc_id, render->video_plane); | ||||
| #endif | ||||
|  | ||||
|     // save actual modesetting | ||||
| @@ -436,11 +410,9 @@ static int FindDevice(VideoRender * render) | ||||
| /// | ||||
| /// Initialize video output module. | ||||
| /// | ||||
| void VideoInitDrm() | ||||
| { | ||||
| void VideoInitDrm() { | ||||
|     int i; | ||||
|  | ||||
|  | ||||
|     if (!(render = calloc(1, sizeof(*render)))) { | ||||
|         Fatal(_("video/DRM: out of memory\n")); | ||||
|         return; | ||||
| @@ -454,12 +426,14 @@ void VideoInitDrm() | ||||
|     assert(gbm.dev != NULL); | ||||
|  | ||||
|     PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL; | ||||
|     get_platform_display = | ||||
|         (void *) eglGetProcAddress("eglGetPlatformDisplay"); | ||||
|  | ||||
|     get_platform_display = (void *)eglGetProcAddress("eglGetPlatformDisplayEXT"); | ||||
|     assert(get_platform_display != NULL); | ||||
|  | ||||
|     eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL); | ||||
|  | ||||
|     EglCheck(); | ||||
|  | ||||
|     assert(eglDisplay != NULL); | ||||
|     //    return; | ||||
|  | ||||
| @@ -476,12 +450,10 @@ void VideoInitDrm() | ||||
|         return; | ||||
|     } | ||||
|     printf("set CRTC %d of Connector %d aktiv\n", render->crtc_id, render->connector_id); | ||||
|     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); | ||||
|     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); | ||||
| @@ -490,11 +462,9 @@ void VideoInitDrm() | ||||
|         fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno); | ||||
|  | ||||
|     drmModeAtomicFree(ModeReq); | ||||
|  | ||||
| } | ||||
|  | ||||
| void get_drm_aspect(int *num,int *den) | ||||
| { | ||||
| void get_drm_aspect(int *num, int *den) { | ||||
|     *num = VideoWindowWidth; | ||||
|     *den = VideoWindowHeight; | ||||
| } | ||||
| @@ -506,6 +476,7 @@ static int old_color=-1,old_trc=-1; | ||||
|  | ||||
| void InitBo(int bpp) { | ||||
|     // create the GBM and EGL surface | ||||
|  | ||||
|     render->bpp = bpp; | ||||
|     gbm.surface = gbm_surface_create(gbm.dev, VideoWindowWidth, VideoWindowHeight, | ||||
|                                      bpp == 10 ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_ARGB8888, | ||||
| @@ -513,17 +484,18 @@ void InitBo(int bpp) { | ||||
|     assert(gbm.surface != NULL); | ||||
|     eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL); | ||||
|     assert(eglSurface != NULL); | ||||
|  | ||||
| } | ||||
|  | ||||
| static struct gbm_bo *previous_bo = NULL; | ||||
| static uint32_t previous_fb; | ||||
| static int has_modeset = 0; | ||||
|  | ||||
| static void drm_swap_buffers() { | ||||
|  | ||||
|     uint32_t fb; | ||||
|  | ||||
|     eglSwapBuffers(eglDisplay, eglSurface); | ||||
|     usleep(1000); | ||||
|     struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface); | ||||
| #if 1 | ||||
|     if (bo == NULL) | ||||
| @@ -533,8 +505,8 @@ static void drm_swap_buffers () { | ||||
|     uint32_t handle = gbm_bo_get_handle(bo).u32; | ||||
|     uint32_t pitch = gbm_bo_get_stride(bo); | ||||
|  | ||||
|  | ||||
|     drmModeAddFB (render->fd_drm, VideoWindowWidth,VideoWindowHeight,render->bpp==10? 30:24, 32, pitch, handle, &fb); | ||||
|     drmModeAddFB(render->fd_drm, VideoWindowWidth, VideoWindowHeight, render->bpp == 10 ? 30 : 24, 32, pitch, handle, | ||||
|                  &fb); | ||||
|     //  drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); | ||||
|  | ||||
|     if (m_need_modeset) { | ||||
| @@ -552,30 +524,31 @@ static void drm_swap_buffers () { | ||||
|         } | ||||
|  | ||||
|         // 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); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0); | ||||
|         if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) | ||||
|             fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); | ||||
|         sleep(2); | ||||
|  | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, | ||||
|                             DRM_MODE_OBJECT_CONNECTOR, "Colorspace",old_color==AVCOL_PRI_BT2020?9:2 ); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, | ||||
|                             DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, | ||||
|                             DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, | ||||
|                             DRM_MODE_OBJECT_CRTC, "ACTIVE", 1); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace", | ||||
|                            old_color == AVCOL_PRI_BT2020 ? 9 : 2); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING", | ||||
|                            old_color == AVCOL_PRI_BT2020 ? 2 : 1); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 0); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID); | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->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); | ||||
|             fprintf(stderr, "cannot set atomic mode modeset 2 (%d): %m\n", errno); | ||||
|  | ||||
|         if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0) | ||||
|             fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno); | ||||
|  | ||||
|         drmModeAtomicFree(ModeReq); | ||||
|         m_need_modeset = 0; | ||||
|         has_modeset = 1; | ||||
|     } | ||||
|      | ||||
|     drmModeSetCrtc(render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); | ||||
|  | ||||
|     if (previous_bo) { | ||||
| @@ -584,7 +557,6 @@ static void drm_swap_buffers () { | ||||
|     } | ||||
|     previous_bo = bo; | ||||
|     previous_fb = fb; | ||||
|  | ||||
| } | ||||
|  | ||||
| static void drm_clean_up() { | ||||
| @@ -594,35 +566,81 @@ static void drm_clean_up () { | ||||
|         return; | ||||
|     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) { | ||||
|         drmModeRmFB(render->fd_drm, previous_fb); | ||||
|         gbm_surface_release_buffer(gbm.surface, previous_bo); | ||||
|     } | ||||
|  | ||||
|     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 (has_modeset) { | ||||
|         drmModeAtomicReqPtr ModeReq; | ||||
|         const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; | ||||
|         uint32_t modeID = 0; | ||||
|  | ||||
|         if (drmModeCreatePropertyBlob(render->fd_drm, &render->mode, sizeof(render->mode), &modeID) != 0) { | ||||
|             fprintf(stderr, "Failed to create mode property.\n"); | ||||
|             return; | ||||
|         } | ||||
|         if (!(ModeReq = drmModeAtomicAlloc())) { | ||||
|             fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Need to disable the CRTC in order to submit the HDR data.... | ||||
|         SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0); | ||||
|         if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) | ||||
|             fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); | ||||
|  | ||||
|         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) | ||||
|         drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); | ||||
|     render->hdr_blob_id = 0; | ||||
|  | ||||
| #if 0 | ||||
|     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||||
|     eglDestroySurface(eglDisplay, eglSurface); | ||||
|     EglCheck(); | ||||
|     gbm_surface_destroy (gbm.surface); | ||||
|     eglDestroyContext (eglDisplay, eglContext); | ||||
| 	EglCheck(); | ||||
|     eglDestroyContext(eglDisplay, eglSharedContext); | ||||
|     EglCheck(); | ||||
|     eglDestroyContext(eglDisplay, eglContext); | ||||
|     EglCheck(); | ||||
|     eglSharedContext = NULL; | ||||
|  | ||||
|     eglContext = NULL; | ||||
|     eglTerminate(eglDisplay); | ||||
|     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); | ||||
|     drmDropMaster(render->fd_drm); | ||||
|     close(render->fd_drm); | ||||
| 	eglDisplay = NULL; | ||||
|     free(render); | ||||
|  | ||||
|     render = NULL; | ||||
|     Debug(3, "nach drm clean up\n"); | ||||
| } | ||||
| @@ -14,12 +14,11 @@ | ||||
| #define _DRVAPI_ERROR_STRING_H_ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| // Error Code string definitions here | ||||
| typedef struct | ||||
| { | ||||
| typedef struct { | ||||
|     char const *error_string; | ||||
|     unsigned int error_id; | ||||
| } s_CudaErrorStr; | ||||
| @@ -84,8 +83,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|     {"CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8}, | ||||
|  | ||||
|     /** | ||||
|      * This indicates that no CUDA-capable devices were detected by the installed | ||||
|      * CUDA driver. | ||||
|      * This indicates that no CUDA-capable devices were detected by the | ||||
|      * installed CUDA driver. | ||||
|      */ | ||||
|     {"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 | ||||
|      * completed yet. This result is not actually an error, but must be indicated | ||||
|      * differently than ::CUDA_SUCCESS (which indicates completion). Calls that | ||||
|      * may return this value include ::cuEventQuery() and ::cuStreamQuery(). | ||||
|      * completed yet. This result is not actually an error, but must be | ||||
|      * indicated differently than ::CUDA_SUCCESS (which indicates completion). | ||||
|      * Calls that may return this value include ::cuEventQuery() and | ||||
|      * ::cuStreamQuery(). | ||||
|      */ | ||||
|     {"CUDA_ERROR_NOT_READY", 600}, | ||||
|  | ||||
|     /** | ||||
|      * While executing a kernel, the device encountered a | ||||
|      * load or store instruction on an invalid memory address. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA work | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA | ||||
|      * work will return the same error. To continue using CUDA, the process must | ||||
|      * be terminated and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_ILLEGAL_ADDRESS", 700}, | ||||
|  | ||||
| @@ -342,8 +342,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|     {"CUDA_ERROR_TOO_MANY_PEERS", 711}, | ||||
|  | ||||
|     /** | ||||
|      * This error indicates that the memory range passed to ::cuMemHostRegister() | ||||
|      * has already been registered. | ||||
|      * This error indicates that the memory range passed to | ||||
|      * ::cuMemHostRegister() has already been registered. | ||||
|      */ | ||||
|     {"CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712}, | ||||
|  | ||||
| @@ -356,25 +356,25 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|     /** | ||||
|      * While executing a kernel, the device encountered a stack error. | ||||
|      * 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 | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA | ||||
|      * work will return the same error. To continue using CUDA, the process must | ||||
|      * be terminated and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_HARDWARE_STACK_ERROR", 714}, | ||||
|  | ||||
|     /** | ||||
|      * While executing a kernel, the device encountered an illegal instruction. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA work | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA | ||||
|      * work will return the same error. To continue using CUDA, the process must | ||||
|      * be terminated and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_ILLEGAL_INSTRUCTION", 715}, | ||||
|  | ||||
|     /** | ||||
|      * While executing a kernel, the device encountered a load or store instruction | ||||
|      * on a memory address which is not aligned. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA work | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * While executing a kernel, the device encountered a load or store | ||||
|      * instruction on a memory address which is not aligned. This leaves the | ||||
|      * process in an inconsistent state and any further CUDA work will return | ||||
|      * the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_MISALIGNED_ADDRESS", 716}, | ||||
| @@ -384,17 +384,17 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|      * which can only operate on memory locations in certain address spaces | ||||
|      * (global, shared, or local), but was supplied a memory address not | ||||
|      * belonging to an allowed address space. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA work | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA | ||||
|      * work will return the same error. To continue using CUDA, the process must | ||||
|      * be terminated and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_INVALID_ADDRESS_SPACE", 717}, | ||||
|  | ||||
|     /** | ||||
|      * While executing a kernel, the device program counter wrapped its address space. | ||||
|      * This leaves the process in an inconsistent state and any further CUDA work | ||||
|      * will return the same error. To continue using CUDA, the process must be terminated | ||||
|      * and relaunched. | ||||
|      * While executing a kernel, the device program counter wrapped its address | ||||
|      * space. This leaves the process in an inconsistent state and any further | ||||
|      * CUDA work will return the same error. To continue using CUDA, the process | ||||
|      * must be terminated and relaunched. | ||||
|      */ | ||||
|     {"CUDA_ERROR_INVALID_PC", 718}, | ||||
|  | ||||
| @@ -409,11 +409,13 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|     {"CUDA_ERROR_LAUNCH_FAILED", 719}, | ||||
|  | ||||
|     /** | ||||
|      * This error indicates that the number of blocks launched per grid for a kernel that was | ||||
|      * launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice | ||||
|      * exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor | ||||
|      * or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors | ||||
|      * as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT. | ||||
|      * This error indicates that the number of blocks launched per grid for a | ||||
|      * kernel that was launched via either ::cuLaunchCooperativeKernel or | ||||
|      * ::cuLaunchCooperativeKernelMultiDevice exceeds the maximum number of | ||||
|      * blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor or | ||||
|      * ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number | ||||
|      * of multiprocessors as specified by the device attribute | ||||
|      * ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT. | ||||
|      */ | ||||
|     {"CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720}, | ||||
|  | ||||
| @@ -432,13 +434,11 @@ s_CudaErrorStr sCudaDrvErrorString[] = { | ||||
|      * This indicates that an unknown internal error has occurred. | ||||
|      */ | ||||
|     {"CUDA_ERROR_UNKNOWN", 999}, | ||||
|     {NULL, -1} | ||||
| }; | ||||
|     {NULL, -1}}; | ||||
|  | ||||
| // This is just a linear search through the array, since the error_id's are not | ||||
| // always ocurring consecutively | ||||
| static inline const char *getCudaDrvErrorString(CUresult error_id) | ||||
| { | ||||
| static inline const char *getCudaDrvErrorString(CUresult error_id) { | ||||
|     int index = 0; | ||||
|  | ||||
|     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> | ||||
|  | ||||
| #ifndef _DRM_MODE_H | ||||
| /** | ||||
|  * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data. | ||||
|  * | ||||
| @@ -85,8 +85,7 @@ struct hdr_output_metadata { | ||||
|         struct hdr_metadata_infoframe hdmi_metadata_type1; | ||||
|     }; | ||||
| }; | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
| enum hdr_metadata_eotf { | ||||
|     EOTF_TRADITIONAL_GAMMA_SDR, | ||||
| @@ -95,27 +94,15 @@ enum hdr_metadata_eotf { | ||||
|     EOTF_HLG, | ||||
| }; | ||||
|  | ||||
|  | ||||
| enum metadata_id { | ||||
|     METADATA_TYPE1, | ||||
| }; | ||||
|  | ||||
| void | ||||
| weston_hdr_metadata(void *data, | ||||
|             uint16_t display_primary_r_x, | ||||
|             uint16_t display_primary_r_y, | ||||
|             uint16_t display_primary_g_x, | ||||
|             uint16_t display_primary_g_y, | ||||
|             uint16_t display_primary_b_x, | ||||
|             uint16_t display_primary_b_y, | ||||
|             uint16_t white_point_x, | ||||
|             uint16_t white_point_y, | ||||
|             uint16_t min_luminance, | ||||
|             uint16_t max_luminance, | ||||
|             uint16_t max_cll, | ||||
|             uint16_t max_fall, | ||||
|             enum hdr_metadata_eotf eotf) | ||||
| { | ||||
| void weston_hdr_metadata(void *data, uint16_t display_primary_r_x, uint16_t display_primary_r_y, | ||||
|                          uint16_t display_primary_g_x, uint16_t display_primary_g_y, uint16_t display_primary_b_x, | ||||
|                          uint16_t display_primary_b_y, uint16_t white_point_x, uint16_t white_point_y, | ||||
|                          uint16_t min_luminance, uint16_t max_luminance, uint16_t max_cll, uint16_t max_fall, | ||||
|                          enum hdr_metadata_eotf eotf) { | ||||
|     uint8_t *data8; | ||||
|     uint16_t *data16; | ||||
|  | ||||
| @@ -155,151 +142,302 @@ struct weston_colorspace { | ||||
| struct weston_colorspace hdr10; | ||||
|  | ||||
| static const struct weston_colorspace bt470m = { | ||||
|     .r = {{ 0.670f, 0.330f, }}, | ||||
|     .g = {{ 0.210f, 0.710f, }}, | ||||
|     .b = {{ 0.140f, 0.080f, }}, | ||||
|     .whitepoint = {{ 0.3101f, 0.3162f, }}, | ||||
|     .r = {{ | ||||
|         0.670f, | ||||
|         0.330f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.210f, | ||||
|         0.710f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.140f, | ||||
|         0.080f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3101f, | ||||
|         0.3162f, | ||||
|     }}, | ||||
|     .name = "BT.470 M", | ||||
|     .whitepoint_name = "C", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace bt470bg = { | ||||
|     .r = {{ 0.640f, 0.330f, }}, | ||||
|     .g = {{ 0.290f, 0.600f, }}, | ||||
|     .b = {{ 0.150f, 0.060f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.640f, | ||||
|         0.330f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.290f, | ||||
|         0.600f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.150f, | ||||
|         0.060f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "BT.470 B/G", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace smpte170m = { | ||||
|     .r = {{ 0.630f, 0.340f, }}, | ||||
|     .g = {{ 0.310f, 0.595f, }}, | ||||
|     .b = {{ 0.155f, 0.070f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.630f, | ||||
|         0.340f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.310f, | ||||
|         0.595f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.155f, | ||||
|         0.070f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "SMPTE 170M", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace smpte240m = { | ||||
|     .r = {{ 0.630f, 0.340f, }}, | ||||
|     .g = {{ 0.310f, 0.595f, }}, | ||||
|     .b = {{ 0.155f, 0.070f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.630f, | ||||
|         0.340f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.310f, | ||||
|         0.595f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.155f, | ||||
|         0.070f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "SMPTE 240M", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace bt709 = { | ||||
|     .r = {{ 0.640f, 0.330f, }}, | ||||
|     .g = {{ 0.300f, 0.600f, }}, | ||||
|     .b = {{ 0.150f, 0.060f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.640f, | ||||
|         0.330f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.300f, | ||||
|         0.600f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.150f, | ||||
|         0.060f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "BT.709", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace bt2020 = { | ||||
|     .r = {{ 0.708f, 0.292f, }}, | ||||
|     .g = {{ 0.170f, 0.797f, }}, | ||||
|     .b = {{ 0.131f, 0.046f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.708f, | ||||
|         0.292f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.170f, | ||||
|         0.797f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.131f, | ||||
|         0.046f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "BT.2020", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace srgb = { | ||||
|     .r = {{ 0.640f, 0.330f, }}, | ||||
|     .g = {{ 0.300f, 0.600f, }}, | ||||
|     .b = {{ 0.150f, 0.060f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.640f, | ||||
|         0.330f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.300f, | ||||
|         0.600f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.150f, | ||||
|         0.060f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "sRGB", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace adobergb = { | ||||
|     .r = {{ 0.640f, 0.330f, }}, | ||||
|     .g = {{ 0.210f, 0.710f, }}, | ||||
|     .b = {{ 0.150f, 0.060f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.640f, | ||||
|         0.330f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.210f, | ||||
|         0.710f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.150f, | ||||
|         0.060f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "AdobeRGB", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace dci_p3 = { | ||||
|     .r = {{ 0.680f, 0.320f, }}, | ||||
|     .g = {{ 0.265f, 0.690f, }}, | ||||
|     .b = {{ 0.150f, 0.060f, }}, | ||||
|     .whitepoint = {{ 0.3127f, 0.3290f, }}, | ||||
|     .r = {{ | ||||
|         0.680f, | ||||
|         0.320f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.265f, | ||||
|         0.690f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.150f, | ||||
|         0.060f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.3127f, | ||||
|         0.3290f, | ||||
|     }}, | ||||
|     .name = "DCI-P3 D65", | ||||
|     .whitepoint_name = "D65", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace prophotorgb = { | ||||
|     .r = {{ 0.7347f, 0.2653f, }}, | ||||
|     .g = {{ 0.1596f, 0.8404f, }}, | ||||
|     .b = {{ 0.0366f, 0.0001f, }}, | ||||
|     .r = {{ | ||||
|         0.7347f, | ||||
|         0.2653f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.1596f, | ||||
|         0.8404f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.0366f, | ||||
|         0.0001f, | ||||
|     }}, | ||||
|     .whitepoint = {{.3457, .3585}}, | ||||
|     .name = "ProPhoto RGB", | ||||
|     .whitepoint_name = "D50", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace ciergb = { | ||||
|     .r = {{ 0.7347f, 0.2653f, }}, | ||||
|     .g = {{ 0.2738f, 0.7174f, }}, | ||||
|     .b = {{ 0.1666f, 0.0089f, }}, | ||||
|     .whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }}, | ||||
|     .r = {{ | ||||
|         0.7347f, | ||||
|         0.2653f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.2738f, | ||||
|         0.7174f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.1666f, | ||||
|         0.0089f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         1.0f / 3.0f, | ||||
|         1.0f / 3.0f, | ||||
|     }}, | ||||
|     .name = "CIE RGB", | ||||
|     .whitepoint_name = "E", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace ciexyz = { | ||||
|     .r = {{ 1.0f, 0.0f, }}, | ||||
|     .g = {{ 0.0f, 1.0f, }}, | ||||
|     .b = {{ 0.0f, 0.0f, }}, | ||||
|     .whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }}, | ||||
|     .r = {{ | ||||
|         1.0f, | ||||
|         0.0f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.0f, | ||||
|         1.0f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.0f, | ||||
|         0.0f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         1.0f / 3.0f, | ||||
|         1.0f / 3.0f, | ||||
|     }}, | ||||
|     .name = "CIE XYZ", | ||||
|     .whitepoint_name = "E", | ||||
| }; | ||||
|  | ||||
| const struct weston_colorspace ap0 = { | ||||
|     .r = {{ 0.7347f,  0.2653f, }}, | ||||
|     .g = {{ 0.0000f,  1.0000f, }}, | ||||
|     .b = {{ 0.0001f, -0.0770f, }}, | ||||
|     .whitepoint = {{ .32168f, .33767f, }}, | ||||
|     .r = {{ | ||||
|         0.7347f, | ||||
|         0.2653f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.0000f, | ||||
|         1.0000f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.0001f, | ||||
|         -0.0770f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         .32168f, | ||||
|         .33767f, | ||||
|     }}, | ||||
|     .name = "ACES primaries #0", | ||||
|     .whitepoint_name = "D60", | ||||
| }; | ||||
|  | ||||
| const struct weston_colorspace ap1 = { | ||||
|     .r = {{ 0.713f, 0.393f, }}, | ||||
|     .g = {{ 0.165f, 0.830f, }}, | ||||
|     .b = {{ 0.128f, 0.044f, }}, | ||||
|     .whitepoint = {{ 0.32168f, 0.33767f, }}, | ||||
|     .r = {{ | ||||
|         0.713f, | ||||
|         0.393f, | ||||
|     }}, | ||||
|     .g = {{ | ||||
|         0.165f, | ||||
|         0.830f, | ||||
|     }}, | ||||
|     .b = {{ | ||||
|         0.128f, | ||||
|         0.044f, | ||||
|     }}, | ||||
|     .whitepoint = {{ | ||||
|         0.32168f, | ||||
|         0.33767f, | ||||
|     }}, | ||||
|     .name = "ACES primaries #1", | ||||
|     .whitepoint_name = "D60", | ||||
| }; | ||||
|  | ||||
| static const struct weston_colorspace *const colorspaces[] = { | ||||
|     &bt470m, | ||||
|     &bt470bg, | ||||
|     &smpte170m, | ||||
|     &smpte240m, | ||||
|     &bt709, | ||||
|     &bt2020, | ||||
|     &srgb, | ||||
|     &adobergb, | ||||
|     &dci_p3, | ||||
|     &prophotorgb, | ||||
|     &ciergb, | ||||
|     &ciexyz, | ||||
|     &ap0, | ||||
|     &ap1, | ||||
|     &bt470m,   &bt470bg, &smpte170m,   &smpte240m, &bt709,  &bt2020, &srgb, | ||||
|     &adobergb, &dci_p3,  &prophotorgb, &ciergb,    &ciexyz, &ap0,    &ap1, | ||||
| }; | ||||
| #define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0]) | ||||
| const struct weston_colorspace * | ||||
| weston_colorspace_lookup(const char *name) | ||||
| { | ||||
| const struct weston_colorspace *weston_colorspace_lookup(const char *name) { | ||||
|     unsigned i; | ||||
|  | ||||
|     if (!name) | ||||
| @@ -317,15 +455,10 @@ weston_colorspace_lookup(const char *name) | ||||
|  | ||||
| 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 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; | ||||
|     struct weston_colorspace *cs; | ||||
|     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 AVContentLightMetadata *ld = NULL; | ||||
|  | ||||
|     if (render->hdr_metadata == -1) { // Metadata not supported | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|     // clean up FFMEPG stuff | ||||
|     if (trc == AVCOL_TRC_BT2020_10) | ||||
|         trc = AVCOL_TRC_ARIB_STD_B67; | ||||
|     if (trc == AVCOL_TRC_UNSPECIFIED) | ||||
|         trc = AVCOL_TRC_BT709; | ||||
|     if (color == AVCOL_PRI_UNSPECIFIED) | ||||
|         color = AVCOL_PRI_BT709; | ||||
|  | ||||
|     if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata) | ||||
|         return; // nothing to do | ||||
| @@ -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 (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) { | ||||
|             return; | ||||
|         } | ||||
|     else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) { | ||||
|         } else if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) { | ||||
|             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); | ||||
|  | ||||
|     if (trc == AVCOL_TRC_BT2020_10) | ||||
|         trc = AVCOL_TRC_ARIB_STD_B67; | ||||
|  | ||||
|     old_color = color; | ||||
|     old_trc = trc; | ||||
|  | ||||
|     if (VulkanTargetColorSpace != 3) { // no HDR TV | ||||
|         m_need_modeset = 1;            // change in colorsettings | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (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->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" | ||||
|                   "min_luminance=%f, max_luminance=%f\n", | ||||
|               md->has_primaries, md->has_luminance, | ||||
|               av_q2d(md->display_primaries[0][0]), | ||||
|               av_q2d(md->display_primaries[0][1]), | ||||
|               av_q2d(md->display_primaries[1][0]), | ||||
|               av_q2d(md->display_primaries[1][1]), | ||||
|               av_q2d(md->display_primaries[2][0]), | ||||
|               av_q2d(md->display_primaries[2][1]), | ||||
|               av_q2d(md->white_point[0]), av_q2d(md->white_point[1]), | ||||
|                   md->has_primaries, md->has_luminance, av_q2d(md->display_primaries[0][0]), | ||||
|                   av_q2d(md->display_primaries[0][1]), av_q2d(md->display_primaries[1][0]), | ||||
|                   av_q2d(md->display_primaries[1][1]), av_q2d(md->display_primaries[2][0]), | ||||
|                   av_q2d(md->display_primaries[2][1]), av_q2d(md->white_point[0]), av_q2d(md->white_point[1]), | ||||
|                   av_q2d(md->min_luminance), av_q2d(md->max_luminance)); | ||||
|  | ||||
|             cs = &hdr10; | ||||
| @@ -451,23 +574,15 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid | ||||
|         MaxFALL = ld->MaxFALL; | ||||
|     } | ||||
|     data.metadata_type = 7; // ???????????????????????? | ||||
|     weston_hdr_metadata(&data.hdmi_metadata_type1, | ||||
|                 encode_xyy(cs->r.f[0]), | ||||
|                 encode_xyy(cs->r.f[1]), | ||||
|                 encode_xyy(cs->g.f[0]), | ||||
|                 encode_xyy(cs->g.f[1]), | ||||
|                 encode_xyy(cs->b.f[0]), | ||||
|                 encode_xyy(cs->b.f[1]), | ||||
|                 encode_xyy(cs->whitepoint.f[0]), | ||||
|                 encode_xyy(cs->whitepoint.f[1]), | ||||
|     weston_hdr_metadata(&data.hdmi_metadata_type1, encode_xyy(cs->r.f[0]), encode_xyy(cs->r.f[1]), | ||||
|                         encode_xyy(cs->g.f[0]), encode_xyy(cs->g.f[1]), encode_xyy(cs->b.f[0]), encode_xyy(cs->b.f[1]), | ||||
|                         encode_xyy(cs->whitepoint.f[0]), encode_xyy(cs->whitepoint.f[1]), | ||||
|                         max_lum, // max_display_mastering_luminance | ||||
|                         min_lum, // min_display_mastering_luminance | ||||
|                         MaxCLL,  // Maximum Content Light Level (MaxCLL) | ||||
|                         MaxFALL, // Maximum Frame-Average Light Level (MaxFALL) | ||||
|                         eotf); | ||||
|  | ||||
|  | ||||
|  | ||||
|     ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id); | ||||
|     if (ret) { | ||||
|         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; | ||||
|     } | ||||
|  | ||||
|     ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, | ||||
|                       render->hdr_metadata, render->hdr_blob_id); | ||||
|     ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, render->hdr_metadata, render->hdr_blob_id); | ||||
|     if (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; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     m_need_modeset = 1; | ||||
|  | ||||
|     Debug(3, "DRM: HDR metadata: prop set\n"); | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										22
									
								
								iatomic.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								iatomic.h
									
									
									
									
									
								
							| @@ -23,9 +23,7 @@ | ||||
| /// @addtogroup iatomic | ||||
| /// @{ | ||||
|  | ||||
| #define GCC_VERSION (__GNUC__ * 10000 \ | ||||
| 	+ __GNUC_MINOR__ * 100 \ | ||||
| 	+ __GNUC_PATCHLEVEL__) | ||||
| #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) | ||||
|  | ||||
| //  gcc before 4.7 didn't support atomic builtins, | ||||
| //  use alsa atomic functions. | ||||
| @@ -59,38 +57,32 @@ typedef volatile int atomic_t; | ||||
| /// | ||||
| /// Set atomic value. | ||||
| /// | ||||
| #define atomic_set(ptr, val) \ | ||||
|     __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST) | ||||
| #define atomic_set(ptr, val) __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| /// | ||||
| /// Read atomic value. | ||||
| /// | ||||
| #define atomic_read(ptr) \ | ||||
|     __atomic_load_n(ptr, __ATOMIC_SEQ_CST) | ||||
| #define atomic_read(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| /// | ||||
| /// Increment atomic value. | ||||
| /// | ||||
| #define atomic_inc(ptr) \ | ||||
|     __atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST) | ||||
| #define atomic_inc(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| /// | ||||
| /// Decrement atomic value. | ||||
| /// | ||||
| #define atomic_dec(ptr) \ | ||||
|     __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST) | ||||
| #define atomic_dec(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| /// | ||||
| /// Add to atomic value. | ||||
| /// | ||||
| #define atomic_add(val, ptr) \ | ||||
|     __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST) | ||||
| #define atomic_add(val, ptr) __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| /// | ||||
| /// Subtract from atomic value. | ||||
| /// | ||||
| #define atomic_sub(val, ptr) \ | ||||
|     __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST) | ||||
| #define atomic_sub(val, ptr) __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST) | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										23
									
								
								misc.h
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								misc.h
									
									
									
									
									
								
							| @@ -24,8 +24,8 @@ | ||||
| /// @addtogroup misc | ||||
| /// @{ | ||||
|  | ||||
| #include <syslog.h> | ||||
| #include <stdarg.h> | ||||
| #include <syslog.h> | ||||
| #include <time.h> // clock_gettime | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -46,8 +46,7 @@ extern int SysLogLevel;                 ///< how much information wanted | ||||
| //  Prototypes | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| static inline void Syslog(const int, const char *format, ...) | ||||
|     __attribute__((format(printf, 2, 3))); | ||||
| static inline void Syslog(const int, const char *format, ...) __attribute__((format(printf, 2, 3))); | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| //  Inlines | ||||
| @@ -67,8 +66,7 @@ static inline void Syslog(const int, const char *format, ...) | ||||
| **	- 2	info | ||||
| **	- 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) { | ||||
|         va_list ap; | ||||
|  | ||||
| @@ -86,7 +84,11 @@ static inline void Syslog(const int level, const char *format, ...) | ||||
| /** | ||||
| **	Show fatal error. | ||||
| */ | ||||
| #define Fatal(fmt...)	do { Error(fmt); abort(); } while (0) | ||||
| #define Fatal(fmt...)                                                                                                 \ | ||||
|     do {                                                                                                              \ | ||||
|         Error(fmt);                                                                                                   \ | ||||
|         abort();                                                                                                      \ | ||||
|     } while (0) | ||||
|  | ||||
| /** | ||||
| **	Show warning. | ||||
| @@ -116,8 +118,7 @@ static inline void Syslog(const int level, const char *format, ...) | ||||
| ** | ||||
| **	@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 int idx; | ||||
|  | ||||
| @@ -136,8 +137,7 @@ static inline const char *Timestamp2String(int64_t ts) | ||||
| ** | ||||
| **	@returns ticks in ms, | ||||
| */ | ||||
| static inline uint32_t GetMsTicks(void) | ||||
| { | ||||
| static inline uint32_t GetMsTicks(void) { | ||||
| #ifdef CLOCK_MONOTONIC | ||||
|     struct timespec tspec; | ||||
|  | ||||
| @@ -153,8 +153,7 @@ static inline uint32_t GetMsTicks(void) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static inline uint64_t GetusTicks(void) | ||||
| { | ||||
| static inline uint64_t GetusTicks(void) { | ||||
|  | ||||
| #ifdef CLOCK_MONOTONIC | ||||
|     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 | ||||
| #define __SOFTHDDEVICE_OPENGLOSD_H | ||||
|  | ||||
| // clang-format off | ||||
| #include <GL/glew.h> | ||||
| #include <GL/freeglut.h> | ||||
| #include <GL/gl.h> | ||||
| @@ -36,17 +37,15 @@ extern "C" | ||||
| { | ||||
| #include <stdint.h> | ||||
| #include <libavcodec/avcodec.h> | ||||
|  | ||||
| #include "audio.h" | ||||
| #include "video.h" | ||||
| #include "codec.h" | ||||
|  | ||||
| } | ||||
| // clang-format on | ||||
|  | ||||
| extern "C" pthread_mutex_t OSDMutex; | ||||
|  | ||||
| struct sOglImage | ||||
| { | ||||
| struct sOglImage { | ||||
|     GLuint texture; | ||||
|     GLint width; | ||||
|     GLint height; | ||||
| @@ -62,28 +61,18 @@ void ConvertColor(const GLint & colARGB, glm::vec4 & col); | ||||
| /**************************************************************************************** | ||||
|  * cShader | ||||
|  ****************************************************************************************/ | ||||
| enum eShaderType | ||||
| { | ||||
|     stRect, | ||||
|     stTexture, | ||||
|     stText, | ||||
|     stCount | ||||
| }; | ||||
| enum eShaderType { stRect, stTexture, stText, stCount }; | ||||
|  | ||||
| class cShader | ||||
| { | ||||
| class cShader { | ||||
|   private: | ||||
|     eShaderType type; | ||||
|     GLuint id; | ||||
|     bool Compile(const char *vertexCode, const char *fragmentCode); | ||||
|     bool CheckCompileErrors(GLuint object, bool program = false); | ||||
|  | ||||
|   public: | ||||
|      cShader(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual ~ cShader(void) | ||||
|     { | ||||
|     }; | ||||
|     cShader(void){}; | ||||
|     virtual ~cShader(void){}; | ||||
|     bool Load(eShaderType type); | ||||
|     void Use(void); | ||||
|     void SetFloat(const GLchar *name, GLfloat value); | ||||
| @@ -97,11 +86,9 @@ class cShader | ||||
| /**************************************************************************************** | ||||
|  * cOglGlyph | ||||
|  ****************************************************************************************/ | ||||
| class cOglGlyph:public cListObject | ||||
| { | ||||
| class cOglGlyph : public cListObject { | ||||
|   private: | ||||
|     struct tKerning | ||||
|     { | ||||
|     struct tKerning { | ||||
|       public: | ||||
|         tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) { | ||||
|             this->prevSym = prevSym; | ||||
| @@ -124,30 +111,12 @@ class cOglGlyph:public cListObject | ||||
|   public: | ||||
|     cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph); | ||||
|     virtual ~cOglGlyph(); | ||||
|     FT_ULong CharCode(void) | ||||
|     { | ||||
|         return charCode; | ||||
|     } | ||||
|     int AdvanceX(void) | ||||
|     { | ||||
|         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; | ||||
|     } | ||||
|     FT_ULong CharCode(void) { return charCode; } | ||||
|     int AdvanceX(void) { 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); | ||||
|     void SetKerningCache(FT_ULong prevSym, int kerning); | ||||
|     void BindTexture(void); | ||||
| @@ -156,8 +125,7 @@ class cOglGlyph:public cListObject | ||||
| /**************************************************************************************** | ||||
|  * cOglFont | ||||
|  ****************************************************************************************/ | ||||
| class cOglFont:public cListObject | ||||
| { | ||||
| class cOglFont : public cListObject { | ||||
|   private: | ||||
|     static bool initiated; | ||||
|     cString name; | ||||
| @@ -170,26 +138,15 @@ class cOglFont:public cListObject | ||||
|     mutable cList<cOglGlyph> glyphCache; | ||||
|     cOglFont(const char *fontName, int charHeight); | ||||
|     static void Init(void); | ||||
|  | ||||
|   public: | ||||
|     virtual ~cOglFont(void); | ||||
|     static cOglFont *Get(const char *name, int charHeight); | ||||
|     static void Cleanup(void); | ||||
|     const char *Name(void) | ||||
|     { | ||||
|         return *name; | ||||
|     }; | ||||
|     int Size(void) | ||||
|     { | ||||
|         return size; | ||||
|     }; | ||||
|     int Bottom(void) | ||||
|     { | ||||
|         return bottom; | ||||
|     }; | ||||
|     int Height(void) | ||||
|     { | ||||
|         return height; | ||||
|     }; | ||||
|     const char *Name(void) { return *name; }; | ||||
|     int Size(void) { return size; }; | ||||
|     int Bottom(void) { return bottom; }; | ||||
|     int Height(void) { return height; }; | ||||
|     cOglGlyph *Glyph(FT_ULong charCode) const; | ||||
|     int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const; | ||||
| }; | ||||
| @@ -198,8 +155,7 @@ class cOglFont:public cListObject | ||||
|  * cOglFb | ||||
|  * Framebuffer Object - OpenGL part of a Pixmap | ||||
|  ****************************************************************************************/ | ||||
| class cOglFb | ||||
| { | ||||
| class cOglFb { | ||||
|   protected: | ||||
|     bool initiated; | ||||
|     // GLuint fb; | ||||
| @@ -207,16 +163,14 @@ class cOglFb | ||||
|     GLint width, height; | ||||
|     GLint viewPortWidth, viewPortHeight; | ||||
|     bool scrollable; | ||||
|  | ||||
|   public: | ||||
|     GLuint fb; | ||||
|     GLuint texture; | ||||
|  | ||||
|     cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight); | ||||
|     virtual ~cOglFb(void); | ||||
|     bool Initiated(void) | ||||
|     { | ||||
|         return initiated; | ||||
|     } | ||||
|     bool Initiated(void) { return initiated; } | ||||
|     virtual bool Init(void); | ||||
|     void Bind(void); | ||||
|     void BindRead(void); | ||||
| @@ -224,38 +178,25 @@ class cOglFb | ||||
|     virtual void Unbind(void); | ||||
|     bool BindTexture(void); | ||||
|     void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2); | ||||
|     GLint Width(void) | ||||
|     { | ||||
|         return width; | ||||
|     }; | ||||
|     GLint Height(void) | ||||
|     { | ||||
|         return height; | ||||
|     }; | ||||
|     bool Scrollable(void) | ||||
|     { | ||||
|         return scrollable; | ||||
|     }; | ||||
|     GLint ViewportWidth(void) | ||||
|     { | ||||
|         return viewPortWidth; | ||||
|     }; | ||||
|     GLint ViewportHeight(void) | ||||
|     { | ||||
|         return viewPortHeight; | ||||
|     }; | ||||
|     GLint Width(void) { return width; }; | ||||
|     GLint Height(void) { return height; }; | ||||
|     bool Scrollable(void) { return scrollable; }; | ||||
|     GLint ViewportWidth(void) { return viewPortWidth; }; | ||||
|     GLint ViewportHeight(void) { return viewPortHeight; }; | ||||
| }; | ||||
|  | ||||
| /**************************************************************************************** | ||||
|  * 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: | ||||
|     bool initiated; | ||||
|  | ||||
|   private: | ||||
|     GLvdpauSurfaceNV surface; | ||||
|  | ||||
|   public: | ||||
|     GLuint fb; | ||||
|     GLuint texture; | ||||
| @@ -270,18 +211,9 @@ class cOglOutputFb:public cOglFb | ||||
|  * cOglVb | ||||
|  * Vertex Buffer - OpenGl Vertices for the different drawing commands | ||||
|  ****************************************************************************************/ | ||||
| enum eVertexBufferType | ||||
| { | ||||
|     vbRect, | ||||
|     vbEllipse, | ||||
|     vbSlope, | ||||
|     vbTexture, | ||||
|     vbText, | ||||
|     vbCount | ||||
| }; | ||||
| enum eVertexBufferType { vbRect, vbEllipse, vbSlope, vbTexture, vbText, vbCount }; | ||||
|  | ||||
| class cOglVb | ||||
| { | ||||
| class cOglVb { | ||||
|   private: | ||||
|     eVertexBufferType type; | ||||
|     eShaderType shader; | ||||
| @@ -291,6 +223,7 @@ class cOglVb | ||||
|     int sizeVertex2; | ||||
|     int numVertices; | ||||
|     GLuint drawMode; | ||||
|  | ||||
|   public: | ||||
|     cOglVb(int type); | ||||
|     virtual ~cOglVb(void); | ||||
| @@ -310,141 +243,100 @@ class cOglVb | ||||
| /**************************************************************************************** | ||||
|  * cOpenGLCmd | ||||
|  ****************************************************************************************/ | ||||
| class cOglCmd | ||||
| { | ||||
| class cOglCmd { | ||||
|   protected: | ||||
|     cOglFb *fb; | ||||
|  | ||||
|   public: | ||||
|     cOglCmd(cOglFb * fb) | ||||
|     { | ||||
|         this->fb = fb; | ||||
|     }; | ||||
|     virtual ~ cOglCmd(void) | ||||
|     { | ||||
|     }; | ||||
|     cOglCmd(cOglFb *fb) { this->fb = fb; }; | ||||
|     virtual ~cOglCmd(void){}; | ||||
|     virtual const char *Description(void) = 0; | ||||
|     virtual bool Execute(void) = 0; | ||||
| }; | ||||
|  | ||||
| class cOglCmdInitOutputFb:public cOglCmd | ||||
| { | ||||
| class cOglCmdInitOutputFb : public cOglCmd { | ||||
|   private: | ||||
|     cOglOutputFb *oFb; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdInitOutputFb(cOglOutputFb *oFb); | ||||
|     virtual ~ cOglCmdInitOutputFb(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "InitOutputFramebuffer"; | ||||
|     } | ||||
|     virtual ~cOglCmdInitOutputFb(void){}; | ||||
|     virtual const char *Description(void) { return "InitOutputFramebuffer"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdInitFb:public cOglCmd | ||||
| { | ||||
| class cOglCmdInitFb : public cOglCmd { | ||||
|   private: | ||||
|     cCondWait *wait; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL); | ||||
|     virtual ~ cOglCmdInitFb(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "InitFramebuffer"; | ||||
|     } | ||||
|     virtual ~cOglCmdInitFb(void){}; | ||||
|     virtual const char *Description(void) { return "InitFramebuffer"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDeleteFb:public cOglCmd | ||||
| { | ||||
| class cOglCmdDeleteFb : public cOglCmd { | ||||
|   public: | ||||
|     cOglCmdDeleteFb(cOglFb *fb); | ||||
|     virtual ~ cOglCmdDeleteFb(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "DeleteFramebuffer"; | ||||
|     } | ||||
|     virtual ~cOglCmdDeleteFb(void){}; | ||||
|     virtual const char *Description(void) { return "DeleteFramebuffer"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdRenderFbToBufferFb:public cOglCmd | ||||
| { | ||||
| class cOglCmdRenderFbToBufferFb : public cOglCmd { | ||||
|   private: | ||||
|     cOglFb *buffer; | ||||
|     GLfloat x, y; | ||||
|     GLfloat drawPortX, drawPortY; | ||||
|     GLint transparency; | ||||
|     GLint alphablending; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX, | ||||
|         GLint drawPortY); | ||||
|      virtual ~ cOglCmdRenderFbToBufferFb(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Render Framebuffer to Buffer"; | ||||
|     } | ||||
|                               GLint drawPortY, bool alphablending); | ||||
|     virtual ~cOglCmdRenderFbToBufferFb(void){}; | ||||
|     virtual const char *Description(void) { return "Render Framebuffer to Buffer"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdCopyBufferToOutputFb:public cOglCmd | ||||
| { | ||||
| class cOglCmdCopyBufferToOutputFb : public cOglCmd { | ||||
|   private: | ||||
|     cOglOutputFb *oFb; | ||||
|     GLint x, y; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y); | ||||
|      virtual ~ cOglCmdCopyBufferToOutputFb(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Copy buffer to OutputFramebuffer"; | ||||
|     } | ||||
|     virtual ~cOglCmdCopyBufferToOutputFb(void){}; | ||||
|     virtual const char *Description(void) { return "Copy buffer to OutputFramebuffer"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdFill:public cOglCmd | ||||
| { | ||||
| class cOglCmdFill : public cOglCmd { | ||||
|   private: | ||||
|     GLint color; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdFill(cOglFb *fb, GLint color); | ||||
|     virtual ~ cOglCmdFill(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Fill"; | ||||
|     } | ||||
|     virtual ~cOglCmdFill(void){}; | ||||
|     virtual const char *Description(void) { return "Fill"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawRectangle:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawRectangle : public cOglCmd { | ||||
|   private: | ||||
|     GLint x, y; | ||||
|     GLint width, height; | ||||
|     GLint color; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color); | ||||
|      virtual ~ cOglCmdDrawRectangle(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "DrawRectangle"; | ||||
|     } | ||||
|     virtual ~cOglCmdDrawRectangle(void){}; | ||||
|     virtual const char *Description(void) { return "DrawRectangle"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawEllipse:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawEllipse : public cOglCmd { | ||||
|   private: | ||||
|     GLint x, y; | ||||
|     GLint width, height; | ||||
| @@ -453,39 +345,29 @@ class cOglCmdDrawEllipse:public cOglCmd | ||||
|     GLfloat *CreateVerticesFull(int &numVertices); | ||||
|     GLfloat *CreateVerticesQuadrant(int &numVertices); | ||||
|     GLfloat *CreateVerticesHalf(int &numVertices); | ||||
|  | ||||
|   public: | ||||
|     cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants); | ||||
|      virtual ~ cOglCmdDrawEllipse(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "DrawEllipse"; | ||||
|     } | ||||
|     virtual ~cOglCmdDrawEllipse(void){}; | ||||
|     virtual const char *Description(void) { return "DrawEllipse"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawSlope:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawSlope : public cOglCmd { | ||||
|   private: | ||||
|     GLint x, y; | ||||
|     GLint width, height; | ||||
|     GLint color; | ||||
|     GLint type; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type); | ||||
|      virtual ~ cOglCmdDrawSlope(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "DrawSlope"; | ||||
|     } | ||||
|     virtual ~cOglCmdDrawSlope(void){}; | ||||
|     virtual const char *Description(void) { return "DrawSlope"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawText:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawText : public cOglCmd { | ||||
|   private: | ||||
|     GLint x, y; | ||||
|     GLint limitX; | ||||
| @@ -493,81 +375,64 @@ class cOglCmdDrawText:public cOglCmd | ||||
|     cString fontName; | ||||
|     int fontSize; | ||||
|     unsigned int *symbols; | ||||
|  | ||||
|   public: | ||||
|      cOglCmdDrawText(cOglFb * fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, | ||||
|         int fontSize, tColor colorText); | ||||
|     cOglCmdDrawText(cOglFb *fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, int fontSize, | ||||
|                     tColor colorText); | ||||
|     virtual ~cOglCmdDrawText(void); | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "DrawText"; | ||||
|     } | ||||
|     virtual const char *Description(void) { return "DrawText"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawImage:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawImage : public cOglCmd { | ||||
|   private: | ||||
|     tColor *argb; | ||||
|     GLint x, y, width, height; | ||||
|     bool overlay; | ||||
|     GLfloat scaleX, scaleY; | ||||
|  | ||||
|   public: | ||||
|      cOglCmdDrawImage(cOglFb * fb, tColor * argb, GLint width, GLint height, GLint x, GLint y, bool overlay = | ||||
|         true, double scaleX = 1.0f, double scaleY = 1.0f); | ||||
|     cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint height, GLint x, GLint y, bool overlay = true, | ||||
|                      double scaleX = 1.0f, double scaleY = 1.0f); | ||||
|     virtual ~cOglCmdDrawImage(void); | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Draw Image"; | ||||
|     } | ||||
|     virtual const char *Description(void) { return "Draw Image"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDrawTexture:public cOglCmd | ||||
| { | ||||
| class cOglCmdDrawTexture : public cOglCmd { | ||||
|   private: | ||||
|     sOglImage *imageRef; | ||||
|     GLint x, y; | ||||
|     GLfloat scaleX, scaleY; | ||||
|  | ||||
|   public: | ||||
|      cOglCmdDrawTexture(cOglFb * fb, sOglImage * imageRef, GLint x, GLint y); | ||||
|      virtual ~ cOglCmdDrawTexture(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Draw Texture"; | ||||
|     } | ||||
|     cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y, double scaleX = 1.0f, double scaleY = 1.0f); | ||||
|     virtual ~cOglCmdDrawTexture(void){}; | ||||
|     virtual const char *Description(void) { return "Draw Texture"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdStoreImage:public cOglCmd | ||||
| { | ||||
| class cOglCmdStoreImage : public cOglCmd { | ||||
|   private: | ||||
|     sOglImage *imageRef; | ||||
|     tColor *data; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdStoreImage(sOglImage *imageRef, tColor *argb); | ||||
|     virtual ~cOglCmdStoreImage(void); | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Store Image"; | ||||
|     } | ||||
|     virtual const char *Description(void) { return "Store Image"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| class cOglCmdDropImage:public cOglCmd | ||||
| { | ||||
| class cOglCmdDropImage : public cOglCmd { | ||||
|   private: | ||||
|     sOglImage *imageRef; | ||||
|     cCondWait *wait; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait); | ||||
|      virtual ~ cOglCmdDropImage(void) | ||||
|     { | ||||
|     }; | ||||
|     virtual const char *Description(void) | ||||
|     { | ||||
|         return "Drop Image"; | ||||
|     } | ||||
|     virtual ~cOglCmdDropImage(void){}; | ||||
|     virtual const char *Description(void) { return "Drop Image"; } | ||||
|     virtual bool Execute(void); | ||||
| }; | ||||
|  | ||||
| @@ -577,8 +442,7 @@ class cOglCmdDropImage:public cOglCmd | ||||
| #define OGL_MAX_OSDIMAGES 256 | ||||
| #define OGL_CMDQUEUE_SIZE 100 | ||||
|  | ||||
| class cOglThread:public cThread | ||||
| { | ||||
| class cOglThread : public cThread { | ||||
|   private: | ||||
|     cCondWait *startWait; | ||||
|     cCondWait *wait; | ||||
| @@ -597,8 +461,10 @@ class cOglThread:public cThread | ||||
|     void Cleanup(void); | ||||
|     int GetFreeSlot(void); | ||||
|     void ClearSlot(int slot); | ||||
|  | ||||
|   protected: | ||||
|     virtual void Action(void); | ||||
|  | ||||
|   public: | ||||
|     cOglThread(cCondWait *startWait, int maxCacheSize); | ||||
|     virtual ~cOglThread(); | ||||
| @@ -607,44 +473,27 @@ class cOglThread:public cThread | ||||
|     int StoreImage(const cImage &image); | ||||
|     void DropImageData(int imageHandle); | ||||
|     sOglImage *GetImageRef(int slot); | ||||
|     int MaxTextureSize(void) | ||||
|     { | ||||
|         return maxTextureSize; | ||||
|     }; | ||||
|     int MaxTextureSize(void) { return maxTextureSize; }; | ||||
| }; | ||||
|  | ||||
| /**************************************************************************************** | ||||
|  * cOglPixmap | ||||
|  ****************************************************************************************/ | ||||
| class cOglPixmap:public cPixmap | ||||
| { | ||||
| class cOglPixmap : public cPixmap { | ||||
|   private: | ||||
|     cOglFb *fb; | ||||
|     std::shared_ptr<cOglThread> oglThread; | ||||
|     bool dirty; | ||||
|  | ||||
|   public: | ||||
|      cOglPixmap(std::shared_ptr < cOglThread > oglThread, int Layer, const cRect & ViewPort, const cRect & DrawPort = | ||||
|         cRect::Null); | ||||
|     cOglPixmap(std::shared_ptr<cOglThread> oglThread, int Layer, const cRect &ViewPort, | ||||
|                const cRect &DrawPort = cRect::Null); | ||||
|     virtual ~cOglPixmap(void); | ||||
|     cOglFb *Fb(void) | ||||
|     { | ||||
|         return fb; | ||||
|     }; | ||||
|     int X(void) | ||||
|     { | ||||
|         return ViewPort().X(); | ||||
|     }; | ||||
|     int Y(void) | ||||
|     { | ||||
|         return ViewPort().Y(); | ||||
|     }; | ||||
|     virtual bool IsDirty(void) | ||||
|     { | ||||
|         return dirty; | ||||
|     } | ||||
|     virtual void SetDirty(bool dirty = true) { | ||||
|         this->dirty = dirty; | ||||
|     } | ||||
|     cOglFb *Fb(void) { return fb; }; | ||||
|     int X(void) { 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 SetTile(bool Tile); | ||||
|     virtual void SetViewPort(const cRect &Rect); | ||||
| @@ -653,9 +502,11 @@ class cOglPixmap:public cPixmap | ||||
|     virtual void Fill(tColor Color); | ||||
|     virtual void DrawImage(const cPoint &Point, const cImage &Image); | ||||
|     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 DrawBitmap(const cPoint & Point, const cBitmap & Bitmap, tColor ColorFg = 0, tColor ColorBg = | ||||
|         0, bool Overlay = false); | ||||
|     virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, | ||||
|                             bool Overlay = false); | ||||
|     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); | ||||
|     virtual void DrawRectangle(const cRect &Rect, tColor Color); | ||||
| @@ -670,17 +521,18 @@ class cOglPixmap:public cPixmap | ||||
| /****************************************************************************** | ||||
|  * cOglOsd | ||||
|  ******************************************************************************/ | ||||
| class cOglOsd:public cOsd | ||||
| { | ||||
| class cOglOsd : public cOsd { | ||||
|   private: | ||||
|     cOglFb *bFb; | ||||
|     std::shared_ptr<cOglThread> oglThread; | ||||
|     cVector<cOglPixmap *> oglPixmaps; | ||||
|     bool isSubtitleOsd; | ||||
|  | ||||
|   protected: | ||||
|   public: | ||||
|     cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread); | ||||
|     virtual ~cOglOsd(); | ||||
|     static void SetOsdPosition(int Left, int Top, int Width, int Height); | ||||
|     virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); | ||||
|     virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null); | ||||
|     virtual void DestroyPixmap(cPixmap *Pixmap); | ||||
|   | ||||
							
								
								
									
										111
									
								
								po/de_DE.po
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								po/de_DE.po
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: VDR \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" | ||||
| "Last-Translator: blabla\n" | ||||
| "Language-Team: blabla\n" | ||||
| @@ -140,91 +140,6 @@ msgstr "" | ||||
| msgid "snd_pcm_drop(): %s\n" | ||||
| 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 | ||||
| msgid "audio: can't set channels %d sample-rate %dHz\n" | ||||
| msgstr "" | ||||
| @@ -306,9 +221,6 @@ msgstr "" | ||||
| msgid "codec/audio: can't setup resample\n" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "codec/audio: can't open resample\n" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "A software and GPU emulated UHD device" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -408,7 +320,7 @@ msgstr "" | ||||
| msgid "Hue (-314..314) " | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Monitor Colorspace" | ||||
| msgid "Temperature 6500K + x * 100K" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Color Blindness" | ||||
| @@ -417,6 +329,9 @@ msgstr "" | ||||
| msgid "Color Correction (-100..100) " | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Monitor Type" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Scaling" | ||||
| msgstr "Skalierung" | ||||
|  | ||||
| @@ -574,15 +489,15 @@ msgstr "" | ||||
| msgid "Suspend SoftHdDevice" | ||||
| msgstr "Unterbreche SoftHdDevice" | ||||
|  | ||||
| msgid "Toggle LUT on/off" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "PIP toggle on/off: off" | ||||
| msgstr "PIP deaktivieren" | ||||
|  | ||||
| msgid "PIP toggle on/off: on" | ||||
| msgstr "PIP aktivieren" | ||||
|  | ||||
| msgid "PIP zapmode (not working)" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "PIP channel +" | ||||
| msgstr "PIP Kanal +" | ||||
|  | ||||
| @@ -715,6 +630,10 @@ msgstr "" | ||||
| msgid "[softhddev] no codec known for still picture\n" | ||||
| msgstr "" | ||||
|  | ||||
| #, c-format | ||||
| msgid "Too much shaders definded\n" | ||||
| msgstr "" | ||||
|  | ||||
| #, c-format | ||||
| msgid "Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n" | ||||
| msgstr "" | ||||
| @@ -884,6 +803,9 @@ msgstr "" | ||||
| msgid "Failed initializing libplacebo\n" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Failed to create placebo opengl \n" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Failed to create XCB Surface\n" | ||||
| msgstr "" | ||||
|  | ||||
| @@ -893,6 +815,9 @@ msgstr "" | ||||
| msgid "Failed creating vulkan swapchain!" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "libplacebo: failed initializing swapchain\n" | ||||
| msgstr "" | ||||
|  | ||||
| msgid "Failed initializing libplacebo renderer\n" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
							
								
								
									
										40
									
								
								ringbuffer.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								ringbuffer.c
									
									
									
									
									
								
							| @@ -34,8 +34,7 @@ | ||||
| #include "ringbuffer.h" | ||||
|  | ||||
| /// ring buffer structure | ||||
| struct _ring_buffer_ | ||||
| { | ||||
| struct _ring_buffer_ { | ||||
|     char *Buffer;          ///< ring buffer data | ||||
|     const char *BufferEnd; ///< end of buffer | ||||
|     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. | ||||
| */ | ||||
| void RingBufferReset(RingBuffer * rb) | ||||
| { | ||||
| void RingBufferReset(RingBuffer *rb) { | ||||
|     rb->ReadPointer = rb->Buffer; | ||||
|     rb->WritePointer = rb->Buffer; | ||||
|     atomic_set(&rb->Filled, 0); | ||||
| @@ -67,8 +65,7 @@ void RingBufferReset(RingBuffer * rb) | ||||
| **	@returns	Allocated ring buffer, must be freed with | ||||
| **			RingBufferDel(), NULL for out of memory. | ||||
| */ | ||||
| RingBuffer *RingBufferNew(size_t size) | ||||
| { | ||||
| RingBuffer *RingBufferNew(size_t size) { | ||||
|     RingBuffer *rb; | ||||
|  | ||||
|     if (!(rb = malloc(sizeof(*rb)))) { // allocate structure | ||||
| @@ -89,8 +86,7 @@ RingBuffer *RingBufferNew(size_t size) | ||||
| /** | ||||
| **	Free an allocated ring buffer. | ||||
| */ | ||||
| void RingBufferDel(RingBuffer * rb) | ||||
| { | ||||
| void RingBufferDel(RingBuffer *rb) { | ||||
|     free(rb->Buffer); | ||||
|     free(rb); | ||||
| } | ||||
| @@ -103,8 +99,7 @@ void RingBufferDel(RingBuffer * rb) | ||||
| ** | ||||
| **	@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; | ||||
|  | ||||
|     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 | ||||
| **			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; | ||||
|  | ||||
|     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 | ||||
| **			buffer at the write pointer. | ||||
| */ | ||||
| size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp) | ||||
| { | ||||
| size_t RingBufferGetWritePointer(RingBuffer *rb, void **wp) { | ||||
|     size_t n; | ||||
|     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. | ||||
| */ | ||||
| size_t RingBufferReadAdvance(RingBuffer * rb, size_t cnt) | ||||
| { | ||||
| size_t RingBufferReadAdvance(RingBuffer *rb, size_t cnt) { | ||||
|     size_t n; | ||||
|  | ||||
|     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. | ||||
| */ | ||||
| size_t RingBufferRead(RingBuffer * rb, void *buf, size_t cnt) | ||||
| { | ||||
| size_t RingBufferRead(RingBuffer *rb, void *buf, size_t cnt) { | ||||
|     size_t n; | ||||
|  | ||||
|     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 | ||||
| **			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 cnt; | ||||
|  | ||||
| @@ -319,10 +309,7 @@ size_t RingBufferGetReadPointer(RingBuffer * rb, const void **rp) | ||||
| ** | ||||
| **	@returns	Number of bytes free in buffer. | ||||
| */ | ||||
| size_t RingBufferFreeBytes(RingBuffer * rb) | ||||
| { | ||||
|     return rb->Size - atomic_read(&rb->Filled); | ||||
| } | ||||
| size_t RingBufferFreeBytes(RingBuffer *rb) { return rb->Size - atomic_read(&rb->Filled); } | ||||
|  | ||||
| /** | ||||
| **	Get used bytes in ring buffer. | ||||
| @@ -331,7 +318,4 @@ size_t RingBufferFreeBytes(RingBuffer * rb) | ||||
| ** | ||||
| **	@returns	Number of bytes used in buffer. | ||||
| */ | ||||
| size_t RingBufferUsedBytes(RingBuffer * rb) | ||||
| { | ||||
|     return atomic_read(&rb->Filled); | ||||
| } | ||||
| size_t RingBufferUsedBytes(RingBuffer *rb) { return atomic_read(&rb->Filled); } | ||||
|   | ||||
							
								
								
									
										136
									
								
								shaders.h
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								shaders.h
									
									
									
									
									
								
							| @@ -4,11 +4,7 @@ | ||||
| #ifdef CUVID | ||||
| const char *gl_version = "#version 330"; | ||||
| #else | ||||
| #ifdef RASPI | ||||
| const char *gl_version = "#version 300 es "; | ||||
| #else | ||||
| const char *gl_version = "#version 300 es "; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* 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. | ||||
|  * The matrix might also be used for other conversions and colorspaces. | ||||
|  */ | ||||
| struct mp_cmat | ||||
| { | ||||
| struct mp_cmat { | ||||
|     GLfloat m[3][3]; // colormatrix | ||||
|     GLfloat c[3];    // colormatrix_c | ||||
| }; | ||||
|  | ||||
| struct mp_mat | ||||
| { | ||||
| struct mp_mat { | ||||
|     GLfloat m[3][3]; | ||||
| }; | ||||
|  | ||||
| // YUV input limited range (16-235 for luma, 16-240 for chroma) | ||||
| // ITU-R BT.601 (SD) | ||||
| struct mp_cmat yuv_bt601 = { {{1.164384, 1.164384, 1.164384}, | ||||
|     						  {0.00000, -0.391762, 2.017232}, | ||||
|     						  {1.596027, -0.812968, 0.000000}}, | ||||
| 							  {-0.874202, 0.531668, -1.085631} | ||||
| }; | ||||
| struct mp_cmat yuv_bt601 = { | ||||
|     {{1.164384, 1.164384, 1.164384}, {0.00000, -0.391762, 2.017232}, {1.596027, -0.812968, 0.000000}}, | ||||
|     {-0.874202, 0.531668, -1.085631}}; | ||||
|  | ||||
| // ITU-R BT.709 (HD) | ||||
| struct mp_cmat yuv_bt709 = { {{1.164384, 1.164384, 1.164384}, | ||||
|     						  {0.00000, -0.213249, 2.112402}, | ||||
|     						  {1.792741, -0.532909, 0.000000}}, | ||||
| 							  {-0.972945, 0.301483, -1.133402} | ||||
| }; | ||||
| struct mp_cmat yuv_bt709 = { | ||||
|     {{1.164384, 1.164384, 1.164384}, {0.00000, -0.213249, 2.112402}, {1.792741, -0.532909, 0.000000}}, | ||||
|     {-0.972945, 0.301483, -1.133402}}; | ||||
|  | ||||
| // ITU-R BT.2020 non-constant luminance system | ||||
| struct mp_cmat yuv_bt2020ncl = { {{1.164384, 1.164384, 1.164384}, | ||||
|     							  {0.00000, -0.187326, 2.141772}, | ||||
|     							  {1.678674, -0.650424, 0.000000}}, | ||||
| 								  {-0.915688, 0.347459, -1.148145} | ||||
| }; | ||||
| struct mp_cmat yuv_bt2020ncl = { | ||||
|     {{1.164384, 1.164384, 1.164384}, {0.00000, -0.187326, 2.141772}, {1.678674, -0.650424, 0.000000}}, | ||||
|     {-0.915688, 0.347459, -1.148145}}; | ||||
|  | ||||
| // ITU-R BT.2020 constant luminance system | ||||
| struct mp_cmat yuv_bt2020cl = { {{0.0000, 1.164384, 0.000000}, | ||||
|     							 {0.00000, 0.000000, 1.138393}, | ||||
|     							 {1.138393, 0.000000, 0.000000}}, | ||||
| 							  	 {-0.571429, -0.073059, -0.571429} | ||||
| }; | ||||
| struct mp_cmat yuv_bt2020cl = { | ||||
|     {{0.0000, 1.164384, 0.000000}, {0.00000, 0.000000, 1.138393}, {1.138393, 0.000000, 0.000000}}, | ||||
|     {-0.571429, -0.073059, -0.571429}}; | ||||
|  | ||||
| float cms_matrix[3][3] = { {1.660497, -0.124547, -0.018154}, | ||||
| 						 {-0.587657, 1.132895, -0.100597}, | ||||
| 						 {-0.072840, -0.008348, 1.118751} | ||||
| }; | ||||
| float cms_matrix[3][3] = { | ||||
|     {1.660497, -0.124547, -0.018154}, {-0.587657, 1.132895, -0.100597}, {-0.072840, -0.008348, 1.118751}}; | ||||
|  | ||||
| // Common constants for SMPTE ST.2084 (PQ) | ||||
| static const float PQ_M1 = 2610. / 4096 * 1. / 4, | ||||
| 				   PQ_M2 = 2523. / 4096 * 128, | ||||
| 				   PQ_C1 = 3424. / 4096,  | ||||
| 				   PQ_C2 =    2413. / 4096 * 32,  | ||||
| 				   PQ_C3 = 2392. / 4096 * 32; | ||||
| static const float PQ_M1 = 2610. / 4096 * 1. / 4, PQ_M2 = 2523. / 4096 * 128, PQ_C1 = 3424. / 4096, | ||||
|                    PQ_C2 = 2413. / 4096 * 32, PQ_C3 = 2392. / 4096 * 32; | ||||
|  | ||||
| // Common constants for ARIB STD-B67 (HLG) | ||||
| static const float HLG_A = 0.17883277, | ||||
| 				   HLG_B = 0.28466892,  | ||||
| 				   HLG_C = 0.55991073; | ||||
| static const float HLG_A = 0.17883277, HLG_B = 0.28466892, HLG_C = 0.55991073; | ||||
|  | ||||
| struct gl_vao_entry | ||||
| { | ||||
| struct gl_vao_entry { | ||||
|     // used for shader / glBindAttribLocation | ||||
|     const char *name; | ||||
|     // glVertexAttribPointer() arguments | ||||
| @@ -92,20 +70,17 @@ struct gl_vao_entry | ||||
|     int offset; | ||||
| }; | ||||
|  | ||||
| struct vertex_pt | ||||
| { | ||||
| struct vertex_pt { | ||||
|     float x, y; | ||||
| }; | ||||
|  | ||||
| struct vertex_pi | ||||
| { | ||||
| struct vertex_pi { | ||||
|     GLint x, y; | ||||
| }; | ||||
|  | ||||
| #define TEXUNIT_VIDEO_NUM 6 | ||||
|  | ||||
| struct vertex | ||||
| { | ||||
| struct vertex { | ||||
|     struct vertex_pt position; | ||||
|     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)}, | ||||
|     {"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])}, | ||||
|     {"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])}, | ||||
|     {0} | ||||
| }; | ||||
|     {0}}; | ||||
|  | ||||
| #define GLSL(...) pl_shader_append(__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 shv[SHADER_LENGTH]; | ||||
|  | ||||
| GL_init() | ||||
| { | ||||
|     sh[0] = 0; | ||||
| } | ||||
| void GL_init() { sh[0] = 0; } | ||||
|  | ||||
| GLV_init() | ||||
| { | ||||
|     shv[0] = 0; | ||||
| } | ||||
| void GLV_init() { shv[0] = 0; } | ||||
|  | ||||
| pl_shader_append(const char *fmt, ...) | ||||
| { | ||||
| void pl_shader_append(const char *fmt, ...) { | ||||
|     char temp[1000]; | ||||
|     va_list ap; | ||||
|  | ||||
| @@ -145,11 +112,9 @@ pl_shader_append(const char *fmt, ...) | ||||
|     if (strlen(sh) + strlen(temp) > SHADER_LENGTH) | ||||
|         Fatal(_("Shaderlenght fault\n")); | ||||
|     strcat(sh, temp); | ||||
|  | ||||
| } | ||||
|  | ||||
| pl_shader_append_v(const char *fmt, ...) | ||||
| { | ||||
| void pl_shader_append_v(const char *fmt, ...) { | ||||
|     char temp[1000]; | ||||
|     va_list ap; | ||||
|  | ||||
| @@ -160,11 +125,9 @@ pl_shader_append_v(const char *fmt, ...) | ||||
|     if (strlen(shv) + strlen(temp) > SHADER_LENGTH) | ||||
|         Fatal(_("Shaderlenght fault\n")); | ||||
|     strcat(shv, temp); | ||||
|  | ||||
| } | ||||
|  | ||||
| static void compile_attach_shader(GLuint program, GLenum type, const char *source) | ||||
| { | ||||
| #ifndef PLACEBO | ||||
| static void compile_attach_shader(GLuint program, GLenum type, const char *source) { | ||||
|     GLuint shader; | ||||
|     GLint status = 1234, log_length; | ||||
|     char log[4000]; | ||||
| @@ -183,11 +146,9 @@ static void compile_attach_shader(GLuint program, GLenum type, const char *sourc | ||||
|  | ||||
|     glAttachShader(program, shader); | ||||
|     glDeleteShader(shader); | ||||
|  | ||||
| } | ||||
|  | ||||
| static void link_shader(GLuint program) | ||||
| { | ||||
| static void link_shader(GLuint program) { | ||||
|     GLint status, log_length; | ||||
|  | ||||
|     glLinkProgram(program); | ||||
| @@ -198,8 +159,8 @@ static void link_shader(GLuint program) | ||||
|     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"); | ||||
|     gl_prog = glCreateProgram(); | ||||
| @@ -243,14 +204,13 @@ static GLuint sc_generate_osd(GLuint 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]; | ||||
|     int n; | ||||
|     GLint cmsLoc; | ||||
|     float *m, *c, *cms; | ||||
|     char *frag; | ||||
|     //char *frag; | ||||
|  | ||||
|     GL_init(); | ||||
|     GLSL("%s\n", gl_version); | ||||
| @@ -280,6 +240,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) | ||||
|  | ||||
|     switch (colorspace) { | ||||
|         case AVCOL_SPC_RGB: | ||||
|         case AVCOL_SPC_BT470BG: | ||||
|             m = &yuv_bt601.m[0][0]; | ||||
|             c = &yuv_bt601.c[0]; | ||||
|             Debug(3, "BT601 Colorspace used\n"); | ||||
| @@ -332,15 +293,21 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) | ||||
|             GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\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("// pl_shader_linearize			 \n"); | ||||
|         GLSL("color.rgb = max(color.rgb, 0.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 = 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 - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\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 - " | ||||
|              "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.rgb = cms_matrix * color.rgb;	 \n"); | ||||
| #ifndef GAMMA | ||||
| @@ -348,7 +315,10 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) | ||||
|         GLSL("color.rgb = max(color.rgb, 0.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 = 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 | ||||
|         GLSL("out_color = color;			 \n"); | ||||
| @@ -372,7 +342,9 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) | ||||
| #ifndef GAMMA | ||||
|         GLSL("// delinearize gamma to sRGB		 \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 | ||||
|         GLSL("// color mapping		  \n"); | ||||
|         GLSL("out_color = color;	  \n"); | ||||
| @@ -413,8 +385,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) | ||||
|     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]; | ||||
|     int n; | ||||
|     const struct gl_vao_entry *e; | ||||
| @@ -476,3 +447,4 @@ static void render_pass_quad(int flip, float xcrop, float ycrop) | ||||
|     for (n = 0; vertex_vao[n].name; n++) | ||||
|         glDisableVertexAttribArray(n); | ||||
| } | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										803
									
								
								softhdcuvid.cpp
									
									
									
									
									
								
							
							
						
						
									
										803
									
								
								softhdcuvid.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										414
									
								
								softhddev.c
									
									
									
									
									
								
							
							
						
						
									
										414
									
								
								softhddev.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,8 +21,7 @@ | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| extern "C" { | ||||
| #endif | ||||
| /// C callback feed key press | ||||
| extern void FeedKeyPress(const char *, const char *, int, int, const char *); | ||||
|   | ||||
| @@ -26,11 +26,9 @@ | ||||
| #define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1" | ||||
| #define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0" | ||||
|  | ||||
| enum | ||||
| { GRAB_IMG_RGBA_FORMAT_B8G8R8A8 }; | ||||
| enum { GRAB_IMG_RGBA_FORMAT_B8G8R8A8 }; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| typedef struct { | ||||
|     int structSize; | ||||
|  | ||||
|     // request data | ||||
| @@ -45,13 +43,11 @@ typedef struct | ||||
|     void *img; | ||||
| } SoftHDDevice_AtmoGrabService_v1_0_t; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| typedef struct { | ||||
|     int Mode; | ||||
| } SoftHDDevice_Osd3DModeService_v1_0_t; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| typedef struct { | ||||
|     // request/reply data | ||||
|  | ||||
|     int width; | ||||
|   | ||||
							
								
								
									
										8
									
								
								video.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								video.h
									
									
									
									
									
								
							| @@ -45,6 +45,7 @@ extern char VideoIgnoreRepeatPict;      ///< disable repeat pict warning | ||||
| extern int VideoAudioDelay;              ///< audio/video delay | ||||
| extern char ConfigStartX11Server;        ///< flag start the x11 server | ||||
| extern char MyConfigDir[]; | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //  Prototypes | ||||
| //---------------------------------------------------------------------------- | ||||
| @@ -116,6 +117,9 @@ extern void VideoSetSaturation(int); | ||||
| /// Set Gamma. | ||||
| extern void VideoSetGamma(int); | ||||
|  | ||||
| /// Set Color Temp. | ||||
| extern void VideoSetTemperature(int); | ||||
|  | ||||
| /// Set ColorSpace. | ||||
| extern void VideoSetTargetColor(int); | ||||
|  | ||||
| @@ -245,6 +249,10 @@ extern int VideoRaiseWindow(void); | ||||
| /// Set Shaders | ||||
| extern int VideoSetShader(char *); | ||||
|  | ||||
| extern void VideoSetRefresh(char *); | ||||
|  | ||||
| extern void VideoSetConnector(char *); | ||||
|  | ||||
| #ifdef USE_OPENGLOSD | ||||
| extern void ActivateOsd(GLuint, int, int, int, int); | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user