mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
commit
ce71019f44
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
|
|
97
Makefile
97
Makefile
@ -22,7 +22,6 @@ CUVID ?= 0
|
|||||||
# only valid for VAAPI
|
# only valid for VAAPI
|
||||||
DRM ?= 0
|
DRM ?= 0
|
||||||
|
|
||||||
|
|
||||||
# use libplacebo -
|
# use libplacebo -
|
||||||
# available for all decoders but for DRM you need LIBPLACEBO_GL
|
# available for all decoders but for DRM you need LIBPLACEBO_GL
|
||||||
LIBPLACEBO ?= 1
|
LIBPLACEBO ?= 1
|
||||||
@ -34,13 +33,7 @@ LIBPLACEBO_GL ?= 0
|
|||||||
# use gamma correction
|
# use gamma correction
|
||||||
#GAMMA ?= 0
|
#GAMMA ?= 0
|
||||||
|
|
||||||
|
CONFIG := -DDEBUG # remove '#' to enable debug output
|
||||||
|
|
||||||
CONFIG := -DDEBUG # remove # to enable debug output
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------- no more config needed past this point--------------------------------
|
#--------------------- no more config needed past this point--------------------------------
|
||||||
@ -61,7 +54,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
ifeq ($(DRM),1)
|
ifeq ($(DRM),1)
|
||||||
$(error Missmatch in Plugin selection)
|
$(error Mismatch in Plugin selection)
|
||||||
exit 1;
|
exit 1;
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -69,42 +62,27 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
ifeq ($(VAAPI),1)
|
ifeq ($(VAAPI),1)
|
||||||
$(error Missmatch in Plugin selection)
|
$(error Mismatch in Plugin selection)
|
||||||
exit 1;
|
exit 1;
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif # MAKECMDGOALS!=indent
|
endif # MAKECMDGOALS!=indent
|
||||||
endif # MAKECMDGOALS!=clean
|
endif # MAKECMDGOALS!=clean
|
||||||
|
|
||||||
|
|
||||||
#--------------------------
|
#--------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PLUGIN = softhdcuvid
|
PLUGIN = softhdcuvid
|
||||||
|
|
||||||
# support OPENGLOSD always needed
|
# support OPENGLOSD always needed
|
||||||
OPENGLOSD=1
|
OPENGLOSD=1
|
||||||
|
|
||||||
# support alsa audio output module
|
|
||||||
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
|
|
||||||
# support OSS audio output module
|
|
||||||
OSS ?= 1
|
|
||||||
|
|
||||||
# use DMPS
|
# use DMPS
|
||||||
SCREENSAVER=1
|
SCREENSAVER=1
|
||||||
|
|
||||||
OPENGL=1
|
OPENGL=1
|
||||||
|
|
||||||
# use ffmpeg libswresample
|
|
||||||
SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1)
|
|
||||||
SWRESAMPLE = 1
|
|
||||||
|
|
||||||
# use libav libavresample
|
|
||||||
#ifneq ($(SWRESAMPLE),1)
|
|
||||||
#AVRESAMPLE ?= $(shell pkg-config --exists libavresample && echo 1#)
|
|
||||||
#AVRESAMPLE = 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CONFIG += -DHAVE_GL # needed for mpv libs
|
CONFIG += -DHAVE_GL # needed for mpv libs
|
||||||
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
||||||
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
||||||
@ -154,20 +132,8 @@ APIVERSION = $(call PKGCFG,apiversion)
|
|||||||
|
|
||||||
-include $(PLGCFG)
|
-include $(PLGCFG)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Parse softhddevice config
|
### Parse softhddevice config
|
||||||
|
|
||||||
ifeq ($(ALSA),1)
|
|
||||||
CONFIG += -DUSE_ALSA
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags alsa)
|
|
||||||
LIBS += $(shell pkg-config --libs alsa)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OSS),1)
|
|
||||||
CONFIG += -DUSE_OSS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OPENGL),1)
|
ifeq ($(OPENGL),1)
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
#_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||||
#LIBS += $(shell pkg-config --libs libva-glx)
|
#LIBS += $(shell pkg-config --libs libva-glx)
|
||||||
@ -212,7 +178,6 @@ _CFLAGS += $(shell pkg-config --cflags libdrm)
|
|||||||
LIBS += -lgbm -ldrm -lEGL
|
LIBS += -lgbm -ldrm -lEGL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(CUVID),1)
|
ifeq ($(CUVID),1)
|
||||||
#CONFIG += -DUSE_PIP # PIP support
|
#CONFIG += -DUSE_PIP # PIP support
|
||||||
CONFIG += -DCUVID # enable CUVID decoder
|
CONFIG += -DCUVID # enable CUVID decoder
|
||||||
@ -226,7 +191,6 @@ ifeq ($(GAMMA),1)
|
|||||||
CONFIG += -DGAMMA
|
CONFIG += -DGAMMA
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||||
PACKAGE = vdr-$(ARCHIVE)
|
PACKAGE = vdr-$(ARCHIVE)
|
||||||
|
|
||||||
@ -234,15 +198,16 @@ PACKAGE = vdr-$(ARCHIVE)
|
|||||||
|
|
||||||
SOFILE = libvdr-$(PLUGIN).so
|
SOFILE = libvdr-$(PLUGIN).so
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that libswresample is available
|
# Test that libswresample is available
|
||||||
#
|
#
|
||||||
#ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
||||||
# $(warning ******************************************************************)
|
$(warning ******************************************************************)
|
||||||
# $(warning 'libswresample' not found!)
|
$(warning 'libswresample' not found!)
|
||||||
# $(error ******************************************************************)
|
$(error ******************************************************************)
|
||||||
#endif
|
endif
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
||||||
|
LIBS += $(shell pkg-config --libs libswresample)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test and set config for libavutil
|
# Test and set config for libavutil
|
||||||
@ -277,22 +242,22 @@ endif
|
|||||||
_CFLAGS += $(shell pkg-config --cflags libavcodec)
|
_CFLAGS += $(shell pkg-config --cflags libavcodec)
|
||||||
LIBS += $(shell pkg-config --libs libavcodec libavfilter)
|
LIBS += $(shell pkg-config --libs libavcodec libavfilter)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test and set config for alsa
|
||||||
|
#
|
||||||
|
ifneq (exists, $(shell pkg-config alsa && echo exists))
|
||||||
|
$(warning ******************************************************************)
|
||||||
|
$(warning 'alsa' not found!)
|
||||||
|
$(error ******************************************************************)
|
||||||
|
endif
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags alsa)
|
||||||
|
LIBS += $(shell pkg-config --libs alsa)
|
||||||
|
|
||||||
ifeq ($(SCREENSAVER),1)
|
ifeq ($(SCREENSAVER),1)
|
||||||
CONFIG += -DUSE_SCREENSAVER
|
CONFIG += -DUSE_SCREENSAVER
|
||||||
_CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms)
|
_CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms)
|
||||||
LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms)
|
LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms)
|
||||||
endif
|
endif
|
||||||
ifeq ($(SWRESAMPLE),1)
|
|
||||||
CONFIG += -DUSE_SWRESAMPLE
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
|
||||||
LIBS += $(shell pkg-config --libs libswresample)
|
|
||||||
endif
|
|
||||||
ifeq ($(AVRESAMPLE),1)
|
|
||||||
CONFIG += -DUSE_AVRESAMPLE
|
|
||||||
_CFLAGS += $(shell pkg-config --cflags libavresample)
|
|
||||||
LIBS += $(shell pkg-config --libs libavresample)
|
|
||||||
endif
|
|
||||||
|
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
@ -309,6 +274,7 @@ LIBS += -lcuda -lnvcuvid
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS += -lGLEW -lGLU -ldl -lglut
|
LIBS += -lGLEW -lGLU -ldl -lglut
|
||||||
|
|
||||||
### Includes and Defines (add further entries here):
|
### Includes and Defines (add further entries here):
|
||||||
|
|
||||||
INCLUDES +=
|
INCLUDES +=
|
||||||
@ -319,10 +285,9 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \
|
|||||||
### Make it standard
|
### Make it standard
|
||||||
|
|
||||||
override CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
override CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
||||||
-g -W -Wextra -Winit-self -Werror=overloaded-virtual -Wno-unused-parameter
|
-g -W -Wextra -Werror=overloaded-virtual -Wno-unused-parameter
|
||||||
override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
||||||
-g -W -Wextra -Winit-self -std=gnu99
|
-g -W -Wextra
|
||||||
|
|
||||||
|
|
||||||
### The object files (add further files here):
|
### The object files (add further files here):
|
||||||
|
|
||||||
@ -383,7 +348,6 @@ install-i18n: $(I18Nmsgs)
|
|||||||
|
|
||||||
$(OBJS): Makefile
|
$(OBJS): Makefile
|
||||||
|
|
||||||
|
|
||||||
$(SOFILE): $(OBJS) shaders.h
|
$(SOFILE): $(OBJS) shaders.h
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
|
|
||||||
@ -404,17 +368,14 @@ clean:
|
|||||||
@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot
|
@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot
|
||||||
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
|
||||||
|
|
||||||
## Private Targets:
|
|
||||||
|
|
||||||
HDRS = $(wildcard *.h)
|
HDRS = $(wildcard *.h)
|
||||||
|
|
||||||
indent:
|
indent:
|
||||||
for i in $(SRCS) $(HDRS); do \
|
for i in $(SRCS) drm.c hdr.c $(HDRS); do \
|
||||||
indent $$i; \
|
clang-format -i $$i; \
|
||||||
unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \
|
|
||||||
mv $$i.up $$i; \
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
## Private Targets:
|
||||||
|
|
||||||
video_test: video.c Makefile
|
video_test: video.c Makefile
|
||||||
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \
|
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \
|
||||||
$(LIBS) -o $@
|
$(LIBS) -o $@
|
||||||
|
39
README.md
39
README.md
@ -25,14 +25,13 @@ A software and GPU emulated UHD output device plugin for VDR.
|
|||||||
|
|
||||||
o Video decoder CUVID or VAAPI
|
o Video decoder CUVID or VAAPI
|
||||||
o Video output opengl or DRM
|
o Video output opengl or DRM
|
||||||
o Audio FFMpeg / Alsa / Analog
|
o Audio FFMpeg / ALSA / Analog
|
||||||
o Audio FFMpeg / Alsa / Digital
|
o Audio FFMpeg / ALSA / Digital
|
||||||
o Audio FFMpeg / OSS / Analog
|
|
||||||
o HDMI/SPDIF pass-through
|
o HDMI/SPDIF pass-through
|
||||||
o Software volume, compression, normalize and channel resample
|
o Software volume, compression, normalize and channel resample
|
||||||
o VDR ScaleVideo API
|
o VDR ScaleVideo API
|
||||||
o CUDA deinterlacer
|
o CUDA deinterlacer
|
||||||
o Suspend / Dettach
|
o Suspend / Detach
|
||||||
o Support for ambilight
|
o Support for ambilight
|
||||||
o Support for Screencopy
|
o Support for Screencopy
|
||||||
o PIP (Picture-in-Picture) (only for CUVID)
|
o PIP (Picture-in-Picture) (only for CUVID)
|
||||||
@ -96,9 +95,6 @@ Install:
|
|||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|
||||||
You can edit Makefile to enable/disable Alsa / OSS
|
|
||||||
support. The default is to autodetect as much as possible.
|
|
||||||
|
|
||||||
You have to start vdr with -P 'softhdcuvid -d :0.0 ..<more option>.. '
|
You have to start vdr with -P 'softhdcuvid -d :0.0 ..<more option>.. '
|
||||||
|
|
||||||
Beginners Guide for libplacebo:
|
Beginners Guide for libplacebo:
|
||||||
@ -148,27 +144,17 @@ Setup: environment
|
|||||||
Following is supported:
|
Following is supported:
|
||||||
|
|
||||||
DISPLAY=:0.0
|
DISPLAY=:0.0
|
||||||
x11 display name
|
X11 display name
|
||||||
|
|
||||||
only if alsa is configured
|
ALSA configuration:
|
||||||
ALSA_DEVICE=default
|
ALSA_DEVICE=default
|
||||||
alsa PCM device name
|
ALSA PCM device name
|
||||||
ALSA_PASSTHROUGH_DEVICE=
|
ALSA_PASSTHROUGH_DEVICE=
|
||||||
alsa pass-though (AC-3,E-AC-3,DTS,...) device name
|
ALSA pass-though (AC-3,E-AC-3,DTS,...) device name
|
||||||
ALSA_MIXER=default
|
ALSA_MIXER=default
|
||||||
alsa control device name
|
ALSA control device name
|
||||||
ALSA_MIXER_CHANNEL=PCM
|
ALSA_MIXER_CHANNEL=PCM
|
||||||
alsa control channel name
|
ALSA control channel name
|
||||||
|
|
||||||
only if oss is configured
|
|
||||||
OSS_AUDIODEV=/dev/dsp
|
|
||||||
oss dsp device name
|
|
||||||
OSS_PASSTHROUGHDEV=
|
|
||||||
oss pass-though (AC-3,E-AC-3,DTS,...) device name
|
|
||||||
OSS_MIXERDEV=/dev/mixer
|
|
||||||
oss mixer device name
|
|
||||||
OSS_MIXER_CHANNEL=pcm
|
|
||||||
oss mixer channel name
|
|
||||||
|
|
||||||
Setup: /etc/vdr/setup.conf
|
Setup: /etc/vdr/setup.conf
|
||||||
------
|
------
|
||||||
@ -197,7 +183,7 @@ Setup: /etc/vdr/setup.conf
|
|||||||
(only 0, 1, 4 supported with VA-API)
|
(only 0, 1, 4 supported with VA-API)
|
||||||
|
|
||||||
softhddevice.<res>.SkipChromaDeinterlace = 0
|
softhddevice.<res>.SkipChromaDeinterlace = 0
|
||||||
0 = disabled, 1 = enabled (for slower cards, poor qualität)
|
0 = disabled, 1 = enabled (for slower cards, poor qualit<EFBFBD>t)
|
||||||
|
|
||||||
softhddevice.<res>.InverseTelecine = 0
|
softhddevice.<res>.InverseTelecine = 0
|
||||||
0 = disabled, 1 = enabled
|
0 = disabled, 1 = enabled
|
||||||
@ -336,10 +322,7 @@ Commandline:
|
|||||||
|
|
||||||
Selects audio output module and device.
|
Selects audio output module and device.
|
||||||
"" to disable audio output
|
"" to disable audio output
|
||||||
/... to use oss audio module (if compiled with oss
|
other to use ALSA audio module
|
||||||
support)
|
|
||||||
other to use alsa audio module (if compiled with alsa
|
|
||||||
support)
|
|
||||||
|
|
||||||
SVDRP:
|
SVDRP:
|
||||||
------
|
------
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
Version 3, 19 November 2007
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The GNU Affero General Public License is a free, copyleft license
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
for software and other kinds of works, specifically designed to ensure
|
software and other kinds of works, specifically designed to ensure
|
||||||
cooperation with the community in the case of network server software.
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
The licenses for most software and other practical works are
|
The licenses for most software and other practical works are designed
|
||||||
designed to take away your freedom to share and change the works. By
|
to take away your freedom to share and change the works. By contrast,
|
||||||
contrast, our General Public Licenses are intended to guarantee your
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
freedom to share and change all versions of a program--to make sure it
|
share and change all versions of a program--to make sure it remains free
|
||||||
remains free software for all its users.
|
software for all its users.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
@ -60,11 +60,10 @@ modification follow.
|
|||||||
|
|
||||||
0. Definitions.
|
0. Definitions.
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU Affero General Public
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
of works, such as semiconductor masks.
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
@ -377,12 +376,12 @@ that material) supplement the terms of this License with terms:
|
|||||||
All other non-permissive additional terms are considered "further
|
All other non-permissive additional terms are considered "further
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
received it, or any part of it, contains a notice stating that it is
|
received it, or any part of it, contains a notice stating that it is
|
||||||
governed by this License along with a term that is a further restriction,
|
governed by this License along with a term that is a further
|
||||||
you may remove that term. If a license document contains a further
|
restriction, you may remove that term. If a license document contains
|
||||||
restriction but permits relicensing or conveying under this License, you
|
a further restriction but permits relicensing or conveying under this
|
||||||
may add to a covered work material governed by the terms of that license
|
License, you may add to a covered work material governed by the terms
|
||||||
document, provided that the further restriction does not survive such
|
of that license document, provided that the further restriction does
|
||||||
relicensing or conveying.
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
If you add terms to a covered work in accord with this section, you
|
||||||
must place, in the relevant source files, a statement of the
|
must place, in the relevant source files, a statement of the
|
||||||
@ -551,34 +550,34 @@ shall include the Corresponding Source for any work covered by version 3
|
|||||||
of the GNU General Public License that is incorporated pursuant to the
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
following paragraph.
|
following paragraph.
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have permission
|
Notwithstanding any other provision of this License, you have
|
||||||
to link or combine any covered work with a work licensed under version 3
|
permission to link or combine any covered work with a work licensed
|
||||||
of the GNU General Public License into a single combined work, and to
|
under version 3 of the GNU General Public License into a single
|
||||||
convey the resulting work. The terms of this License will continue to
|
combined work, and to convey the resulting work. The terms of this
|
||||||
apply to the part which is the covered work, but the work with which it is
|
License will continue to apply to the part which is the covered work,
|
||||||
combined will remain governed by version 3 of the GNU General Public
|
but the work with which it is combined will remain governed by version
|
||||||
License.
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
the GNU Affero General Public License from time to time. Such new
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
versions will be similar in spirit to the present version, but may differ
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
in detail to address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
Each version is given a distinguishing version number. If the
|
||||||
Program specifies that a certain numbered version of the GNU Affero
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
General Public License "or any later version" applies to it, you have
|
Public License "or any later version" applies to it, you have the
|
||||||
the option of following the terms and conditions either of that
|
option of following the terms and conditions either of that numbered
|
||||||
numbered version or of any later version published by the Free
|
version or of any later version published by the Free Software
|
||||||
Software Foundation. If the Program does not specify a version number
|
Foundation. If the Program does not specify a version number of the
|
||||||
of the GNU Affero General Public License, you may choose any version
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
ever published by the Free Software Foundation.
|
by the Free Software Foundation.
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
If the Program specifies that a proxy can decide which future
|
||||||
versions of the GNU Affero General Public License can be used, that
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
proxy's public statement of acceptance of a version permanently
|
public statement of acceptance of a version permanently authorizes you
|
||||||
authorizes you to choose that version for the Program.
|
to choose that version for the Program.
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
Later license versions may give you additional or different
|
||||||
permissions. However, no additional obligations are imposed on any
|
permissions. However, no additional obligations are imposed on any
|
||||||
@ -634,9 +633,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
Copyright (C) <year> <name of author>
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
published by the Free Software Foundation, either version 3 of the
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
License, or (at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@ -644,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@ -659,4 +658,4 @@ specific requirements.
|
|||||||
You should also get your employer (if you work as a programmer) or school,
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
<http://www.gnu.org/licenses/>.
|
<https://www.gnu.org/licenses/>.
|
245
codec.c
245
codec.c
@ -36,10 +36,6 @@
|
|||||||
#define USE_AUDIO_DRIFT_CORRECTION
|
#define USE_AUDIO_DRIFT_CORRECTION
|
||||||
/// compile AC-3 audio drift correction support (very experimental)
|
/// compile AC-3 audio drift correction support (very experimental)
|
||||||
#define USE_AC3_DRIFT_CORRECTION
|
#define USE_AC3_DRIFT_CORRECTION
|
||||||
/// use ffmpeg libswresample API (autodected, Makefile)
|
|
||||||
#define noUSE_SWRESAMPLE
|
|
||||||
/// use libav libavresample API (autodected, Makefile)
|
|
||||||
#define noUSE_AVRESAMPLE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -51,35 +47,28 @@
|
|||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#define _(str) gettext(str) ///< gettext shortcut
|
#define _(str) gettext(str) ///< gettext shortcut
|
||||||
#define _N(str) str ///< gettext_noop shortcut
|
#define _N(str) str ///< gettext_noop shortcut
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavutil/opt.h>
|
|
||||||
#include <libavutil/mem.h>
|
#include <libavutil/mem.h>
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
#include <libswresample/swresample.h>
|
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
#include <libavresample/avresample.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __USE_GNU
|
#include <libswresample/swresample.h>
|
||||||
#define __USE_GNU
|
|
||||||
#endif
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "iatomic.h"
|
#include "iatomic.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Global
|
// Global
|
||||||
@ -134,8 +123,7 @@ struct _video_decoder_
|
|||||||
** valid format, the formats are ordered by
|
** valid format, the formats are ordered by
|
||||||
** quality.
|
** quality.
|
||||||
*/
|
*/
|
||||||
static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
static enum AVPixelFormat Codec_get_format(AVCodecContext *video_ctx, const enum AVPixelFormat *fmt) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
enum AVPixelFormat fmt1;
|
enum AVPixelFormat fmt1;
|
||||||
|
|
||||||
@ -147,7 +135,6 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu
|
|||||||
|
|
||||||
// decoder->GetFormatDone = 1;
|
// decoder->GetFormatDone = 1;
|
||||||
return Video_get_format(decoder->HwDecoder, video_ctx, fmt);
|
return Video_get_format(decoder->HwDecoder, video_ctx, fmt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static void Codec_free_buffer(void *opaque, uint8_t *data);
|
// static void Codec_free_buffer(void *opaque, uint8_t *data);
|
||||||
@ -160,8 +147,7 @@ static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx, const enu
|
|||||||
** @param video_ctx Codec context
|
** @param video_ctx Codec context
|
||||||
** @param frame Get buffer for this frame
|
** @param frame Get buffer for this frame
|
||||||
*/
|
*/
|
||||||
static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int flags)
|
static int Codec_get_buffer2(AVCodecContext *video_ctx, AVFrame *frame, int flags) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
|
|
||||||
decoder = video_ctx->opaque;
|
decoder = video_ctx->opaque;
|
||||||
@ -197,8 +183,7 @@ static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int fl
|
|||||||
**
|
**
|
||||||
** @returns private decoder pointer for video decoder.
|
** @returns private decoder pointer for video decoder.
|
||||||
*/
|
*/
|
||||||
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *hw_decoder) {
|
||||||
{
|
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
|
|
||||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||||
@ -214,10 +199,7 @@ VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
|||||||
**
|
**
|
||||||
** @param decoder private video decoder
|
** @param decoder private video decoder
|
||||||
*/
|
*/
|
||||||
void CodecVideoDelDecoder(VideoDecoder * decoder)
|
void CodecVideoDelDecoder(VideoDecoder *decoder) { free(decoder); }
|
||||||
{
|
|
||||||
free(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Open video decoder.
|
** Open video decoder.
|
||||||
@ -225,8 +207,7 @@ void CodecVideoDelDecoder(VideoDecoder * decoder)
|
|||||||
** @param decoder private video decoder
|
** @param decoder private video decoder
|
||||||
** @param codec_id video codec id
|
** @param codec_id video codec id
|
||||||
*/
|
*/
|
||||||
void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
|
||||||
{
|
|
||||||
AVCodec *video_codec;
|
AVCodec *video_codec;
|
||||||
const char *name;
|
const char *name;
|
||||||
int ret, deint = 2;
|
int ret, deint = 2;
|
||||||
@ -290,7 +271,8 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
|
||||||
#else
|
#else
|
||||||
decoder->VideoCtx->pix_fmt = AV_PIX_FMT_DRM_PRIME; /* request a DRM frame */
|
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 */
|
// decoder->VideoCtx->pix_fmt = AV_PIX_FMT_MMAL; /* request a DRM frame
|
||||||
|
//*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: for software decoder use all cpus, otherwise 1
|
// FIXME: for software decoder use all cpus, otherwise 1
|
||||||
@ -352,7 +334,8 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
if (strcmp(decoder->VideoCodec->long_name, "Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
if (strcmp(decoder->VideoCodec->long_name,
|
||||||
|
"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint, 0) < 0) { // adaptive
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint, 0) < 0) { // adaptive
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option deint to video codec!\n"));
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
@ -428,8 +411,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
**
|
**
|
||||||
** @param video_decoder private video decoder
|
** @param video_decoder private video decoder
|
||||||
*/
|
*/
|
||||||
void CodecVideoClose(VideoDecoder * video_decoder)
|
void CodecVideoClose(VideoDecoder *video_decoder) {
|
||||||
{
|
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
|
||||||
// FIXME: play buffered data
|
// FIXME: play buffered data
|
||||||
@ -441,14 +423,14 @@ void CodecVideoClose(VideoDecoder * video_decoder)
|
|||||||
#if 1
|
#if 1
|
||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
avcodec_send_packet(video_decoder->VideoCtx, NULL);
|
avcodec_send_packet(video_decoder->VideoCtx, NULL);
|
||||||
while (avcodec_receive_frame(video_decoder->VideoCtx, frame) >= 0) ;
|
while (avcodec_receive_frame(video_decoder->VideoCtx, frame) >= 0)
|
||||||
|
;
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
#endif
|
#endif
|
||||||
avcodec_close(video_decoder->VideoCtx);
|
avcodec_close(video_decoder->VideoCtx);
|
||||||
av_freep(&video_decoder->VideoCtx);
|
av_freep(&video_decoder->VideoCtx);
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -501,8 +483,7 @@ extern int push_filters(AVCodecContext * dec_ctx, void *decoder, AVFrame * frame
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VAAPI
|
#ifdef VAAPI
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *video_ctx = decoder->VideoCtx;
|
AVCodecContext *video_ctx = decoder->VideoCtx;
|
||||||
|
|
||||||
if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO && CuvidTestSurfaces()) {
|
if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO && CuvidTestSurfaces()) {
|
||||||
@ -540,7 +521,8 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
decoder->filter = 2;
|
decoder->filter = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
if (frame->interlaced_frame && decoder->filter == 2 &&
|
||||||
|
(frame->height != 720)) { // broken ZDF sends Interlaced flag
|
||||||
push_filters(video_ctx, decoder->HwDecoder, frame);
|
push_filters(video_ctx, decoder->HwDecoder, frame);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -557,8 +539,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
|
|
||||||
#ifdef CUVID
|
#ifdef CUVID
|
||||||
|
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *video_ctx;
|
AVCodecContext *video_ctx;
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
int ret, ret1;
|
int ret, ret1;
|
||||||
@ -597,9 +578,11 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
} else {
|
} else {
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
}
|
}
|
||||||
// printf("got %s packet from decoder\n",got_frame?"1":"no");
|
// printf("got %s packet from
|
||||||
|
// decoder\n",got_frame?"1":"no");
|
||||||
if (got_frame) { // frame completed
|
if (got_frame) { // frame completed
|
||||||
// printf("video frame pts %#012" PRIx64 " %dms\n",frame->pts,(int)(apts - frame->pts) / 90);
|
// printf("video frame pts %#012" PRIx64 "
|
||||||
|
//%dms\n",frame->pts,(int)(apts - frame->pts) / 90);
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
if (decoder->filter) {
|
if (decoder->filter) {
|
||||||
if (decoder->filter == 1) {
|
if (decoder->filter == 1) {
|
||||||
@ -611,7 +594,8 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
decoder->filter = 2;
|
decoder->filter = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
if (frame->interlaced_frame && decoder->filter == 2 &&
|
||||||
|
(frame->height != 720)) { // broken ZDF sends Interlaced flag
|
||||||
ret = push_filters(video_ctx, decoder->HwDecoder, frame);
|
ret = push_filters(video_ctx, decoder->HwDecoder, frame);
|
||||||
// av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
continue;
|
continue;
|
||||||
@ -636,7 +620,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
if (!consumed) {
|
if (!consumed) {
|
||||||
goto next_part; // try again to stuff decoder
|
goto next_part; // try again to stuff decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -645,8 +628,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
**
|
**
|
||||||
** @param decoder video decoder data
|
** @param decoder video decoder data
|
||||||
*/
|
*/
|
||||||
void CodecVideoFlushBuffers(VideoDecoder * decoder)
|
void CodecVideoFlushBuffers(VideoDecoder *decoder) {
|
||||||
{
|
|
||||||
if (decoder->VideoCtx) {
|
if (decoder->VideoCtx) {
|
||||||
avcodec_flush_buffers(decoder->VideoCtx);
|
avcodec_flush_buffers(decoder->VideoCtx);
|
||||||
}
|
}
|
||||||
@ -666,8 +648,7 @@ typedef struct _audio_decoder_ AudioDecoder;
|
|||||||
///
|
///
|
||||||
/// Audio decoder structure.
|
/// Audio decoder structure.
|
||||||
///
|
///
|
||||||
struct _audio_decoder_
|
struct _audio_decoder_ {
|
||||||
{
|
|
||||||
AVCodec *AudioCodec; ///< audio codec
|
AVCodec *AudioCodec; ///< audio codec
|
||||||
AVCodecContext *AudioCtx; ///< audio codec context
|
AVCodecContext *AudioCtx; ///< audio codec context
|
||||||
|
|
||||||
@ -679,17 +660,7 @@ struct _audio_decoder_
|
|||||||
int HwChannels; ///< hw channels
|
int HwChannels; ///< hw channels
|
||||||
|
|
||||||
AVFrame *Frame; ///< decoded audio frame buffer
|
AVFrame *Frame; ///< decoded audio frame buffer
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
#if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(0, 15, 100)
|
|
||||||
struct SwrContext *Resample; ///< ffmpeg software resample context
|
|
||||||
#else
|
|
||||||
SwrContext *Resample; ///< ffmpeg software resample context
|
SwrContext *Resample; ///< ffmpeg software resample context
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
AVAudioResampleContext *Resample; ///< libav software resample context
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer
|
uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer
|
||||||
int SpdifIndex; ///< index into SPDIF output buffer
|
int SpdifIndex; ///< index into SPDIF output buffer
|
||||||
@ -707,8 +678,7 @@ struct _audio_decoder_
|
|||||||
///
|
///
|
||||||
/// IEC Data type enumeration.
|
/// IEC Data type enumeration.
|
||||||
///
|
///
|
||||||
enum IEC61937
|
enum IEC61937 {
|
||||||
{
|
|
||||||
IEC61937_AC3 = 0x01, ///< AC-3 data
|
IEC61937_AC3 = 0x01, ///< AC-3 data
|
||||||
// FIXME: more data types
|
// FIXME: more data types
|
||||||
IEC61937_EAC3 = 0x15, ///< E-AC-3 data
|
IEC61937_EAC3 = 0x15, ///< E-AC-3 data
|
||||||
@ -736,8 +706,7 @@ static char CodecDownmix; ///< enable AC-3 decoder downmix
|
|||||||
**
|
**
|
||||||
** @returns private decoder pointer for audio decoder.
|
** @returns private decoder pointer for audio decoder.
|
||||||
*/
|
*/
|
||||||
AudioDecoder *CodecAudioNewDecoder(void)
|
AudioDecoder *CodecAudioNewDecoder(void) {
|
||||||
{
|
|
||||||
AudioDecoder *audio_decoder;
|
AudioDecoder *audio_decoder;
|
||||||
|
|
||||||
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
||||||
@ -755,8 +724,7 @@ AudioDecoder *CodecAudioNewDecoder(void)
|
|||||||
**
|
**
|
||||||
** @param decoder private audio decoder
|
** @param decoder private audio decoder
|
||||||
*/
|
*/
|
||||||
void CodecAudioDelDecoder(AudioDecoder * decoder)
|
void CodecAudioDelDecoder(AudioDecoder *decoder) {
|
||||||
{
|
|
||||||
av_frame_free(&decoder->Frame); // callee does checks
|
av_frame_free(&decoder->Frame); // callee does checks
|
||||||
free(decoder);
|
free(decoder);
|
||||||
}
|
}
|
||||||
@ -767,8 +735,7 @@ void CodecAudioDelDecoder(AudioDecoder * decoder)
|
|||||||
** @param audio_decoder private audio decoder
|
** @param audio_decoder private audio decoder
|
||||||
** @param codec_id audio codec id
|
** @param codec_id audio codec id
|
||||||
*/
|
*/
|
||||||
void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
void CodecAudioOpen(AudioDecoder *audio_decoder, int codec_id) {
|
||||||
{
|
|
||||||
AVCodec *audio_codec;
|
AVCodec *audio_codec;
|
||||||
|
|
||||||
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, avcodec_get_name(codec_id));
|
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, avcodec_get_name(codec_id));
|
||||||
@ -817,20 +784,12 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
|||||||
**
|
**
|
||||||
** @param audio_decoder private audio decoder
|
** @param audio_decoder private audio decoder
|
||||||
*/
|
*/
|
||||||
void CodecAudioClose(AudioDecoder * audio_decoder)
|
void CodecAudioClose(AudioDecoder *audio_decoder) {
|
||||||
{
|
|
||||||
// FIXME: output any buffered data
|
// FIXME: output any buffered data
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
if (audio_decoder->Resample) {
|
if (audio_decoder->Resample) {
|
||||||
swr_free(&audio_decoder->Resample);
|
swr_free(&audio_decoder->Resample);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (audio_decoder->Resample) {
|
|
||||||
avresample_free(&audio_decoder->Resample);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (audio_decoder->AudioCtx) {
|
if (audio_decoder->AudioCtx) {
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
avcodec_close(audio_decoder->AudioCtx);
|
avcodec_close(audio_decoder->AudioCtx);
|
||||||
@ -844,8 +803,7 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
|
|||||||
**
|
**
|
||||||
** @param mask enable mask (PCM, AC-3)
|
** @param mask enable mask (PCM, AC-3)
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioDrift(int mask)
|
void CodecSetAudioDrift(int mask) {
|
||||||
{
|
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
CodecAudioDrift = mask & (CORRECT_PCM | CORRECT_AC3);
|
CodecAudioDrift = mask & (CORRECT_PCM | CORRECT_AC3);
|
||||||
#endif
|
#endif
|
||||||
@ -857,8 +815,7 @@ void CodecSetAudioDrift(int mask)
|
|||||||
**
|
**
|
||||||
** @param mask enable mask (PCM, AC-3, E-AC-3)
|
** @param mask enable mask (PCM, AC-3, E-AC-3)
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioPassthrough(int mask)
|
void CodecSetAudioPassthrough(int mask) {
|
||||||
{
|
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
CodecPassthrough = mask & (CodecPCM | CodecAC3 | CodecEAC3);
|
CodecPassthrough = mask & (CodecPCM | CodecAC3 | CodecEAC3);
|
||||||
#endif
|
#endif
|
||||||
@ -870,8 +827,7 @@ void CodecSetAudioPassthrough(int mask)
|
|||||||
**
|
**
|
||||||
** @param onoff enable/disable downmix.
|
** @param onoff enable/disable downmix.
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioDownmix(int onoff)
|
void CodecSetAudioDownmix(int onoff) {
|
||||||
{
|
|
||||||
if (onoff == -1) {
|
if (onoff == -1) {
|
||||||
CodecDownmix ^= 1;
|
CodecDownmix ^= 1;
|
||||||
return;
|
return;
|
||||||
@ -890,8 +846,7 @@ void CodecSetAudioDownmix(int onoff)
|
|||||||
** @param size size of sample buffer in bytes
|
** @param size size of sample buffer in bytes
|
||||||
** @param channels number of channels interleaved in sample buffer
|
** @param channels number of channels interleaved in sample buffer
|
||||||
*/
|
*/
|
||||||
static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
static void CodecReorderAudioFrame(int16_t *buf, int size, int channels) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
int c;
|
int c;
|
||||||
int ls;
|
int ls;
|
||||||
@ -945,8 +900,7 @@ static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
|||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param[out] passthrough pass-through output
|
** @param[out] passthrough pass-through output
|
||||||
*/
|
*/
|
||||||
static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough)
|
static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough) {
|
||||||
{
|
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -965,8 +919,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
audio_decoder->Passthrough = CodecPassthrough;
|
audio_decoder->Passthrough = CodecPassthrough;
|
||||||
|
|
||||||
// SPDIF/HDMI pass-through
|
// SPDIF/HDMI pass-through
|
||||||
if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3)
|
if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) ||
|
||||||
|| (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
|
(CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
|
||||||
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
|
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
|
||||||
// E-AC-3 over HDMI some receivers need HBR
|
// E-AC-3 over HDMI some receivers need HBR
|
||||||
audio_decoder->HwSampleRate *= 4;
|
audio_decoder->HwSampleRate *= 4;
|
||||||
@ -981,8 +935,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
|
|
||||||
// try E-AC-3 none HBR
|
// try E-AC-3 none HBR
|
||||||
audio_decoder->HwSampleRate /= 4;
|
audio_decoder->HwSampleRate /= 4;
|
||||||
if (audio_ctx->codec_id != AV_CODEC_ID_EAC3
|
if (audio_ctx->codec_id != AV_CODEC_ID_EAC3 ||
|
||||||
|| (err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) {
|
(err = AudioSetup(&audio_decoder->HwSampleRate, &audio_decoder->HwChannels, *passthrough))) {
|
||||||
|
|
||||||
Debug(3, "codec/audio: audio setup error\n");
|
Debug(3, "codec/audio: audio setup error\n");
|
||||||
// FIXME: handle errors
|
// FIXME: handle errors
|
||||||
@ -1005,8 +959,7 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder, int *passthrough
|
|||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param avpkt undecoded audio packet
|
** @param avpkt undecoded audio packet
|
||||||
*/
|
*/
|
||||||
static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
static int CodecAudioPassthroughHelper(AudioDecoder *audio_decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
|
|
||||||
@ -1025,11 +978,10 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac
|
|||||||
if (CodecAudioDrift & CORRECT_AC3) {
|
if (CodecAudioDrift & CORRECT_AC3) {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
x = (audio_decoder->DriftFrac +
|
x = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) /
|
||||||
(audio_decoder->DriftCorr * spdif_sz)) / (10 * audio_decoder->HwSampleRate * 100);
|
(10 * audio_decoder->HwSampleRate * 100);
|
||||||
audio_decoder->DriftFrac =
|
audio_decoder->DriftFrac = (audio_decoder->DriftFrac + (audio_decoder->DriftCorr * spdif_sz)) %
|
||||||
(audio_decoder->DriftFrac +
|
(10 * audio_decoder->HwSampleRate * 100);
|
||||||
(audio_decoder->DriftCorr * spdif_sz)) % (10 * audio_decoder->HwSampleRate * 100);
|
|
||||||
// round to word border
|
// round to word border
|
||||||
x *= audio_decoder->HwChannels * 4;
|
x *= audio_decoder->HwChannels * 4;
|
||||||
if (x < -64) { // limit correction
|
if (x < -64) { // limit correction
|
||||||
@ -1112,16 +1064,13 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_SWRESAMPLE) || defined(USE_AVRESAMPLE)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Set/update audio pts clock.
|
** Set/update audio pts clock.
|
||||||
**
|
**
|
||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
** @param pts presentation timestamp
|
** @param pts presentation timestamp
|
||||||
*/
|
*/
|
||||||
static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
static void CodecAudioSetClock(AudioDecoder *audio_decoder, int64_t pts) {
|
||||||
{
|
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
struct timespec nowtime;
|
struct timespec nowtime;
|
||||||
int64_t delay;
|
int64_t delay;
|
||||||
@ -1152,8 +1101,8 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec)
|
tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec) * 1000 * 1000 * 1000 +
|
||||||
* 1000 * 1000 * 1000 + (nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec);
|
(nowtime.tv_nsec - audio_decoder->LastTime.tv_nsec);
|
||||||
|
|
||||||
drift = (tim_diff * 90) / (1000 * 1000) - pts_diff + delay - audio_decoder->LastDelay;
|
drift = (tim_diff * 90) / (1000 * 1000) - pts_diff + delay - audio_decoder->LastDelay;
|
||||||
|
|
||||||
@ -1181,10 +1130,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
audio_decoder->Drift = drift;
|
audio_decoder->Drift = drift;
|
||||||
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
||||||
// SPDIF/HDMI passthrough
|
// SPDIF/HDMI passthrough
|
||||||
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
|
if ((CodecAudioDrift & CORRECT_AC3) &&
|
||||||
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3)
|
(!(CodecPassthrough & CodecAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) &&
|
||||||
&& (!(CodecPassthrough & CodecEAC3)
|
(!(CodecPassthrough & CodecEAC3) || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
|
||||||
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
|
|
||||||
audio_decoder->DriftCorr = -corr;
|
audio_decoder->DriftCorr = -corr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,7 +1143,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
|
||||||
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
||||||
int distance;
|
int distance;
|
||||||
|
|
||||||
@ -1209,17 +1156,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
|
|
||||||
int distance;
|
|
||||||
|
|
||||||
distance = (pts_diff * audio_decoder->HwSampleRate) / (900 * 1000);
|
|
||||||
if (avresample_set_compensation(audio_decoder->Resample, audio_decoder->DriftCorr / 10, distance)) {
|
|
||||||
Debug(3, "codec/audio: swr_set_compensation failed\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (1) {
|
if (1) {
|
||||||
static int c;
|
static int c;
|
||||||
|
|
||||||
@ -1237,8 +1173,7 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
**
|
**
|
||||||
** @param audio_decoder audio decoder data
|
** @param audio_decoder audio decoder data
|
||||||
*/
|
*/
|
||||||
static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
static void CodecAudioUpdateFormat(AudioDecoder *audio_decoder) {
|
||||||
{
|
|
||||||
int passthrough;
|
int passthrough;
|
||||||
const AVCodecContext *audio_ctx;
|
const AVCodecContext *audio_ctx;
|
||||||
|
|
||||||
@ -1253,44 +1188,21 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
audio_ctx = audio_decoder->AudioCtx;
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate
|
if (audio_ctx->sample_fmt == AV_SAMPLE_FMT_S16 && audio_ctx->sample_rate == audio_decoder->HwSampleRate &&
|
||||||
&& !CodecAudioDrift) {
|
!CodecAudioDrift) {
|
||||||
// FIXME: use Resample only, when it is needed!
|
// FIXME: use Resample only, when it is needed!
|
||||||
fprintf(stderr, "no resample needed\n");
|
fprintf(stderr, "no resample needed\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWRESAMPLE
|
audio_decoder->Resample = swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, AV_SAMPLE_FMT_S16,
|
||||||
audio_decoder->Resample =
|
audio_decoder->HwSampleRate, audio_ctx->channel_layout,
|
||||||
swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, AV_SAMPLE_FMT_S16,
|
audio_ctx->sample_fmt, audio_ctx->sample_rate, 0, NULL);
|
||||||
audio_decoder->HwSampleRate, audio_ctx->channel_layout, audio_ctx->sample_fmt, audio_ctx->sample_rate, 0,
|
|
||||||
NULL);
|
|
||||||
if (audio_decoder->Resample) {
|
if (audio_decoder->Resample) {
|
||||||
swr_init(audio_decoder->Resample);
|
swr_init(audio_decoder->Resample);
|
||||||
} else {
|
} else {
|
||||||
Error(_("codec/audio: can't setup resample\n"));
|
Error(_("codec/audio: can't setup resample\n"));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef USE_AVRESAMPLE
|
|
||||||
if (!(audio_decoder->Resample = avresample_alloc_context())) {
|
|
||||||
Error(_("codec/audio: can't setup resample\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_channel_layout", audio_ctx->channel_layout, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_sample_fmt", audio_ctx->sample_fmt, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "in_sample_rate", audio_ctx->sample_rate, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_channel_layout", audio_ctx->channel_layout, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
|
||||||
av_opt_set_int(audio_decoder->Resample, "out_sample_rate", audio_decoder->HwSampleRate, 0);
|
|
||||||
|
|
||||||
if (avresample_open(audio_decoder->Resample)) {
|
|
||||||
avresample_free(&audio_decoder->Resample);
|
|
||||||
audio_decoder->Resample = NULL;
|
|
||||||
Error(_("codec/audio: can't open resample\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1304,8 +1216,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
** @param avpkt audio packet
|
** @param avpkt audio packet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
void CodecAudioDecode(AudioDecoder *audio_decoder, const AVPacket *avpkt) {
|
||||||
{
|
|
||||||
AVCodecContext *audio_ctx = audio_decoder->AudioCtx;
|
AVCodecContext *audio_ctx = audio_decoder->AudioCtx;
|
||||||
|
|
||||||
if (audio_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
if (audio_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
@ -1332,8 +1243,9 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
CodecAudioSetClock(audio_decoder, avpkt->pts);
|
CodecAudioSetClock(audio_decoder, avpkt->pts);
|
||||||
}
|
}
|
||||||
// format change
|
// format change
|
||||||
if (audio_decoder->Passthrough != CodecPassthrough || audio_decoder->SampleRate != audio_ctx->sample_rate
|
if (audio_decoder->Passthrough != CodecPassthrough ||
|
||||||
|| audio_decoder->Channels != audio_ctx->channels) {
|
audio_decoder->SampleRate != audio_ctx->sample_rate ||
|
||||||
|
audio_decoder->Channels != audio_ctx->channels) {
|
||||||
CodecAudioUpdateFormat(audio_decoder);
|
CodecAudioUpdateFormat(audio_decoder);
|
||||||
}
|
}
|
||||||
if (!audio_decoder->HwSampleRate || !audio_decoder->HwChannels) {
|
if (!audio_decoder->HwSampleRate || !audio_decoder->HwChannels) {
|
||||||
@ -1347,8 +1259,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
uint8_t *out[1];
|
uint8_t *out[1];
|
||||||
|
|
||||||
out[0] = outbuf;
|
out[0] = outbuf;
|
||||||
ret =
|
ret = swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels),
|
||||||
swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels),
|
|
||||||
(const uint8_t **)frame->extended_data, frame->nb_samples);
|
(const uint8_t **)frame->extended_data, frame->nb_samples);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (!(audio_decoder->Passthrough & CodecPCM)) {
|
if (!(audio_decoder->Passthrough & CodecPCM)) {
|
||||||
@ -1363,18 +1274,12 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Flush the audio decoder.
|
** Flush the audio decoder.
|
||||||
**
|
**
|
||||||
** @param decoder audio decoder data
|
** @param decoder audio decoder data
|
||||||
*/
|
*/
|
||||||
void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
void CodecAudioFlushBuffers(AudioDecoder *decoder) { avcodec_flush_buffers(decoder->AudioCtx); }
|
||||||
{
|
|
||||||
|
|
||||||
avcodec_flush_buffers(decoder->AudioCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Codec
|
// Codec
|
||||||
@ -1383,18 +1288,13 @@ void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
|||||||
/**
|
/**
|
||||||
** Empty log callback
|
** Empty log callback
|
||||||
*/
|
*/
|
||||||
static void CodecNoopCallback( __attribute__((unused))
|
static void CodecNoopCallback(__attribute__((unused)) void *ptr, __attribute__((unused)) int level,
|
||||||
void *ptr, __attribute__((unused))
|
__attribute__((unused)) const char *fmt, __attribute__((unused)) va_list vl) {}
|
||||||
int level, __attribute__((unused))
|
|
||||||
const char *fmt, __attribute__((unused)) va_list vl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Codec init
|
** Codec init
|
||||||
*/
|
*/
|
||||||
void CodecInit(void)
|
void CodecInit(void) {
|
||||||
{
|
|
||||||
pthread_mutex_init(&CodecLockMutex, NULL);
|
pthread_mutex_init(&CodecLockMutex, NULL);
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
// disable display ffmpeg error messages
|
// disable display ffmpeg error messages
|
||||||
@ -1407,7 +1307,4 @@ void CodecInit(void)
|
|||||||
/**
|
/**
|
||||||
** Codec exit.
|
** Codec exit.
|
||||||
*/
|
*/
|
||||||
void CodecExit(void)
|
void CodecExit(void) { pthread_mutex_destroy(&CodecLockMutex); }
|
||||||
{
|
|
||||||
pthread_mutex_destroy(&CodecLockMutex);
|
|
||||||
}
|
|
||||||
|
7
codec.h
7
codec.h
@ -35,8 +35,7 @@
|
|||||||
|
|
||||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
|
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
|
||||||
|
|
||||||
enum HWAccelID
|
enum HWAccelID {
|
||||||
{
|
|
||||||
HWACCEL_NONE = 0,
|
HWACCEL_NONE = 0,
|
||||||
HWACCEL_AUTO,
|
HWACCEL_AUTO,
|
||||||
HWACCEL_VDPAU,
|
HWACCEL_VDPAU,
|
||||||
@ -53,8 +52,7 @@ extern AVBufferRef *hw_device_ctx;
|
|||||||
///
|
///
|
||||||
/// Video decoder structure.
|
/// Video decoder structure.
|
||||||
///
|
///
|
||||||
struct _video_decoder_
|
struct _video_decoder_ {
|
||||||
{
|
|
||||||
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
||||||
|
|
||||||
int GetFormatDone; ///< flag get format called!
|
int GetFormatDone; ///< flag get format called!
|
||||||
@ -87,7 +85,6 @@ struct _video_decoder_
|
|||||||
double cached_hdr_peak;
|
double cached_hdr_peak;
|
||||||
// From VO
|
// From VO
|
||||||
struct mp_hwdec_devices *hwdec_devs;
|
struct mp_hwdec_devices *hwdec_devs;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
32
common.h
32
common.h
@ -19,17 +19,17 @@
|
|||||||
#ifndef MPLAYER_GL_COMMON_H
|
#ifndef MPLAYER_GL_COMMON_H
|
||||||
#define MPLAYER_GL_COMMON_H
|
#define MPLAYER_GL_COMMON_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#if 0
|
#if 0
|
||||||
#include "config.h"
|
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
|
#include "config.h"
|
||||||
#include "misc/bstr.h"
|
#include "misc/bstr.h"
|
||||||
|
|
||||||
#include "video/out/vo.h"
|
|
||||||
#include "video/csputils.h"
|
#include "video/csputils.h"
|
||||||
#include "video/mp_image.h"
|
#include "video/mp_image.h"
|
||||||
|
#include "video/out/vo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_GL_COCOA
|
#if HAVE_GL_COCOA
|
||||||
@ -53,8 +53,7 @@
|
|||||||
struct GL;
|
struct GL;
|
||||||
typedef struct GL GL;
|
typedef struct GL GL;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH
|
MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH
|
||||||
MPGL_CAP_FB = (1 << 5),
|
MPGL_CAP_FB = (1 << 5),
|
||||||
MPGL_CAP_VAO = (1 << 6),
|
MPGL_CAP_VAO = (1 << 6),
|
||||||
@ -87,8 +86,7 @@ void mpgl_load_functions2(GL * gl, void *(*get_fn)(void *ctx, const char *n), vo
|
|||||||
typedef void(GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *);
|
typedef void(GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *);
|
||||||
|
|
||||||
// function pointers loaded from the OpenGL library
|
// function pointers loaded from the OpenGL library
|
||||||
struct GL
|
struct GL {
|
||||||
{
|
|
||||||
int version; // MPGL_VER() mangled (e.g. 210 for 2.1)
|
int version; // MPGL_VER() mangled (e.g. 210 for 2.1)
|
||||||
int es; // es version (e.g. 300), 0 for desktop GL
|
int es; // es version (e.g. 300), 0 for desktop GL
|
||||||
int glsl_version; // e.g. 130 for GLSL 1.30
|
int glsl_version; // e.g. 130 for GLSL 1.30
|
||||||
@ -192,10 +190,8 @@ struct GL
|
|||||||
|
|
||||||
void(GLAPIENTRY *VDPAUInitNV)(const GLvoid *, const GLvoid *);
|
void(GLAPIENTRY *VDPAUInitNV)(const GLvoid *, const GLvoid *);
|
||||||
void(GLAPIENTRY *VDPAUFiniNV)(void);
|
void(GLAPIENTRY *VDPAUFiniNV)(void);
|
||||||
GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterOutputSurfaceNV)
|
GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterOutputSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *);
|
||||||
(GLvoid *, GLenum, GLsizei, const GLuint *);
|
GLvdpauSurfaceNV(GLAPIENTRY *VDPAURegisterVideoSurfaceNV)(GLvoid *, GLenum, GLsizei, const GLuint *);
|
||||||
GLvdpauSurfaceNV(GLAPIENTRY * VDPAURegisterVideoSurfaceNV)
|
|
||||||
(GLvoid *, GLenum, GLsizei, const GLuint *);
|
|
||||||
void(GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV);
|
void(GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV);
|
||||||
void(GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum);
|
void(GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum);
|
||||||
void(GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *);
|
void(GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *);
|
||||||
@ -203,13 +199,17 @@ struct GL
|
|||||||
|
|
||||||
#if HAVE_GL_WIN32
|
#if HAVE_GL_WIN32
|
||||||
// The HANDLE type might not be present on non-Win32
|
// The HANDLE type might not be present on non-Win32
|
||||||
BOOL(GLAPIENTRY * DXSetResourceShareHandleNV) (void *dxObject, HANDLE shareHandle);
|
BOOL(GLAPIENTRY *DXSetResourceShareHandleNV)
|
||||||
|
(void *dxObject, HANDLE shareHandle);
|
||||||
HANDLE(GLAPIENTRY *DXOpenDeviceNV)(void *dxDevice);
|
HANDLE(GLAPIENTRY *DXOpenDeviceNV)(void *dxDevice);
|
||||||
BOOL(GLAPIENTRY *DXCloseDeviceNV)(HANDLE hDevice);
|
BOOL(GLAPIENTRY *DXCloseDeviceNV)(HANDLE hDevice);
|
||||||
HANDLE(GLAPIENTRY * DXRegisterObjectNV) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
HANDLE(GLAPIENTRY *DXRegisterObjectNV)
|
||||||
|
(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
||||||
BOOL(GLAPIENTRY *DXUnregisterObjectNV)(HANDLE hDevice, HANDLE hObject);
|
BOOL(GLAPIENTRY *DXUnregisterObjectNV)(HANDLE hDevice, HANDLE hObject);
|
||||||
BOOL(GLAPIENTRY * DXLockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects);
|
BOOL(GLAPIENTRY *DXLockObjectsNV)
|
||||||
BOOL(GLAPIENTRY * DXUnlockObjectsNV) (HANDLE hDevice, GLint count, HANDLE * hObjects);
|
(HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||||
|
BOOL(GLAPIENTRY *DXUnlockObjectsNV)
|
||||||
|
(HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GLint(GLAPIENTRY *GetVideoSync)(GLuint *);
|
GLint(GLAPIENTRY *GetVideoSync)(GLuint *);
|
||||||
|
200
drm.c
200
drm.c
@ -1,9 +1,7 @@
|
|||||||
#include <unistd.h>
|
#include <drm_fourcc.h>
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <xf86drm.h>
|
#include <unistd.h>
|
||||||
#include <xf86drmMode.h>
|
|
||||||
#include <drm_fourcc.h>
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
@ -13,8 +11,7 @@
|
|||||||
// DRM
|
// DRM
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct _Drm_Render_
|
struct _Drm_Render_ {
|
||||||
{
|
|
||||||
int fd_drm;
|
int fd_drm;
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
drmModeCrtc *saved_crtc;
|
drmModeCrtc *saved_crtc;
|
||||||
@ -24,7 +21,6 @@ struct _Drm_Render_
|
|||||||
uint32_t hdr_metadata;
|
uint32_t hdr_metadata;
|
||||||
uint32_t mmWidth, mmHeight; // Size in mm
|
uint32_t mmWidth, mmHeight; // Size in mm
|
||||||
uint32_t hdr_blob_id;
|
uint32_t hdr_blob_id;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct _Drm_Render_ VideoRender;
|
typedef struct _Drm_Render_ VideoRender;
|
||||||
|
|
||||||
@ -46,10 +42,7 @@ struct type_name {
|
|||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *util_lookup_type_name(unsigned int type,
|
static const char *util_lookup_type_name(unsigned int type, const struct type_name *table, unsigned int count) {
|
||||||
const struct type_name *table,
|
|
||||||
unsigned int count)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
@ -80,21 +73,16 @@ static const struct type_name connector_type_names[] = {
|
|||||||
{DRM_MODE_CONNECTOR_DPI, "DPI"},
|
{DRM_MODE_CONNECTOR_DPI, "DPI"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *util_lookup_connector_type_name(unsigned int type)
|
const char *util_lookup_connector_type_name(unsigned int type) {
|
||||||
{
|
return util_lookup_type_name(type, connector_type_names, ARRAY_SIZE(connector_type_names));
|
||||||
return util_lookup_type_name(type, connector_type_names,
|
|
||||||
ARRAY_SIZE(connector_type_names));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID,
|
static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) {
|
||||||
uint32_t objectType, const char *propName)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
drmModePropertyPtr Prop;
|
drmModePropertyPtr Prop;
|
||||||
drmModeObjectPropertiesPtr objectProps =
|
drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
|
||||||
|
|
||||||
for (i = 0; i < objectProps->count_props; i++) {
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
@ -115,20 +103,16 @@ static uint64_t GetPropertyValue(int fd_drm, uint32_t objectID,
|
|||||||
|
|
||||||
#ifdef DRM_DEBUG
|
#ifdef DRM_DEBUG
|
||||||
if (!found)
|
if (!found)
|
||||||
fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n",
|
fprintf(stderr, "GetPropertyValue: Unable to find value for property \'%s\'.\n", propName);
|
||||||
propName);
|
|
||||||
#endif
|
#endif
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
static uint32_t GetPropertyID(int fd_drm, uint32_t objectID,
|
static uint32_t GetPropertyID(int fd_drm, uint32_t objectID, uint32_t objectType, const char *propName) {
|
||||||
uint32_t objectType, const char *propName)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
uint32_t value = -1;
|
uint32_t value = -1;
|
||||||
drmModePropertyPtr Prop;
|
drmModePropertyPtr Prop;
|
||||||
drmModeObjectPropertiesPtr objectProps =
|
drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
|
||||||
|
|
||||||
for (i = 0; i < objectProps->count_props; i++) {
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
@ -151,15 +135,12 @@ static uint32_t GetPropertyID(int fd_drm, uint32_t objectID,
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm,
|
static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm, uint32_t objectID, uint32_t objectType,
|
||||||
uint32_t objectID, uint32_t objectType,
|
const char *propName, uint64_t value) {
|
||||||
const char *propName, uint64_t value)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint64_t id = 0;
|
uint64_t id = 0;
|
||||||
drmModePropertyPtr Prop;
|
drmModePropertyPtr Prop;
|
||||||
drmModeObjectPropertiesPtr objectProps =
|
drmModeObjectPropertiesPtr objectProps = drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
||||||
drmModeObjectGetProperties(fd_drm, objectID, objectType);
|
|
||||||
|
|
||||||
for (i = 0; i < objectProps->count_props; i++) {
|
for (i = 0; i < objectProps->count_props; i++) {
|
||||||
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
if ((Prop = drmModeGetProperty(fd_drm, objectProps->props[i])) == NULL)
|
||||||
@ -177,15 +158,13 @@ static int SetPropertyRequest(drmModeAtomicReqPtr ModeReq, int fd_drm,
|
|||||||
drmModeFreeObjectProperties(objectProps);
|
drmModeFreeObjectProperties(objectProps);
|
||||||
|
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
printf( "SetPropertyRequest: Unable to find value for property \'%s\'.\n",
|
printf("SetPropertyRequest: Unable to find value for property \'%s\'.\n", propName);
|
||||||
propName);
|
|
||||||
|
|
||||||
return drmModeAtomicAddProperty(ModeReq, objectID, id, value);
|
return drmModeAtomicAddProperty(ModeReq, objectID, id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CuvidSetVideoMode(void);
|
static void CuvidSetVideoMode(void);
|
||||||
void set_video_mode(int width, int height)
|
void set_video_mode(int width, int height) {
|
||||||
{
|
|
||||||
drmModeConnector *connector;
|
drmModeConnector *connector;
|
||||||
drmModeModeInfo *mode;
|
drmModeModeInfo *mode;
|
||||||
int ii;
|
int ii;
|
||||||
@ -195,11 +174,8 @@ void set_video_mode(int width, int height)
|
|||||||
for (ii = 0; ii < connector->count_modes; ii++) {
|
for (ii = 0; ii < connector->count_modes; ii++) {
|
||||||
mode = &connector->modes[ii];
|
mode = &connector->modes[ii];
|
||||||
printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
||||||
if (width == mode->hdisplay &&
|
if (width == mode->hdisplay && height == mode->vdisplay && mode->vrefresh == DRMRefresh &&
|
||||||
height == mode->vdisplay &&
|
render->mode.hdisplay != width && render->mode.vdisplay != height &&
|
||||||
mode->vrefresh == DRMRefresh &&
|
|
||||||
render->mode.hdisplay != width &&
|
|
||||||
render->mode.vdisplay != height &&
|
|
||||||
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
VideoWindowWidth = mode->hdisplay;
|
VideoWindowWidth = mode->hdisplay;
|
||||||
@ -215,8 +191,7 @@ void set_video_mode(int width, int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FindDevice(VideoRender * render)
|
static int FindDevice(VideoRender *render) {
|
||||||
{
|
|
||||||
drmVersion *version;
|
drmVersion *version;
|
||||||
drmModeRes *resources;
|
drmModeRes *resources;
|
||||||
drmModeConnector *connector;
|
drmModeConnector *connector;
|
||||||
@ -243,20 +218,17 @@ static int FindDevice(VideoRender * render)
|
|||||||
|
|
||||||
int ret = drmSetMaster(render->fd_drm);
|
int ret = drmSetMaster(render->fd_drm);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
{
|
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
|
|
||||||
ret = drmGetMagic(render->fd_drm, &magic);
|
ret = drmGetMagic(render->fd_drm, &magic);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
{
|
|
||||||
Debug(3, "drm:%s - failed to get drm magic: %s\n", __FUNCTION__, strerror(errno));
|
Debug(3, "drm:%s - failed to get drm magic: %s\n", __FUNCTION__, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmAuthMagic(render->fd_drm, magic);
|
ret = drmAuthMagic(render->fd_drm, magic);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
{
|
|
||||||
Debug(3, "drm:%s - failed to authorize drm magic: %s\n", __FUNCTION__, strerror(errno));
|
Debug(3, "drm:%s - failed to authorize drm magic: %s\n", __FUNCTION__, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -290,9 +262,8 @@ static int FindDevice(VideoRender * render)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Debug(3,"[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n",
|
Debug(3, "[FindDevice] DRM have %i connectors, %i crtcs, %i encoders\n", resources->count_connectors,
|
||||||
resources->count_connectors, resources->count_crtcs,
|
resources->count_crtcs, resources->count_encoders);
|
||||||
resources->count_encoders);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// find all available connectors
|
// find all available connectors
|
||||||
@ -303,8 +274,10 @@ static int FindDevice(VideoRender * render)
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(connectorstr,"%s-%u",util_lookup_connector_type_name(connector->connector_type),connector->connector_type_id);
|
sprintf(connectorstr, "%s-%u", util_lookup_connector_type_name(connector->connector_type),
|
||||||
printf("Connector >%s< is %sconnected\n",connectorstr,connector->connection == DRM_MODE_CONNECTED?"":"not ");
|
connector->connector_type_id);
|
||||||
|
printf("Connector >%s< is %sconnected\n", connectorstr,
|
||||||
|
connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
|
||||||
if (DRMConnector && strcmp(DRMConnector, connectorstr))
|
if (DRMConnector && strcmp(DRMConnector, connectorstr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -325,9 +298,10 @@ static int FindDevice(VideoRender * render)
|
|||||||
}
|
}
|
||||||
render->crtc_id = encoder->crtc_id;
|
render->crtc_id = encoder->crtc_id;
|
||||||
|
|
||||||
render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id,
|
render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, DRM_MODE_OBJECT_CONNECTOR,
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA");
|
"HDR_OUTPUT_METADATA");
|
||||||
printf("ID %d of METADATA in Connector %d connected %d\n",render->hdr_metadata,connector->connector_id,connector->connection);
|
printf("ID %d of METADATA in Connector %d connected %d\n", render->hdr_metadata, connector->connector_id,
|
||||||
|
connector->connection);
|
||||||
|
|
||||||
memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback
|
memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback
|
||||||
// search Modes for Connector
|
// search Modes for Connector
|
||||||
@ -337,15 +311,12 @@ static int FindDevice(VideoRender * render)
|
|||||||
printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
||||||
|
|
||||||
if (VideoWindowWidth && VideoWindowHeight) { // preset by command line
|
if (VideoWindowWidth && VideoWindowHeight) { // preset by command line
|
||||||
if (VideoWindowWidth == mode->hdisplay &&
|
if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay &&
|
||||||
VideoWindowHeight == mode->vdisplay &&
|
mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
mode->vrefresh == DRMRefresh &&
|
|
||||||
!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
|
||||||
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
|
||||||
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
memcpy(&render->mode, mode, sizeof(drmModeModeInfo));
|
||||||
VideoWindowWidth = mode->hdisplay;
|
VideoWindowWidth = mode->hdisplay;
|
||||||
@ -360,7 +331,8 @@ static int FindDevice(VideoRender * render)
|
|||||||
VideoWindowWidth = render->mode.hdisplay;
|
VideoWindowWidth = render->mode.hdisplay;
|
||||||
VideoWindowHeight = render->mode.vdisplay;
|
VideoWindowHeight = render->mode.vdisplay;
|
||||||
if (found)
|
if (found)
|
||||||
printf("Use Mode %d %dx%d Rate %d\n",ii,render->mode.hdisplay,render->mode.vdisplay,render->mode.vrefresh);
|
printf("Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay,
|
||||||
|
render->mode.vrefresh);
|
||||||
drmModeFreeConnector(connector);
|
drmModeFreeConnector(connector);
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
@ -384,16 +356,16 @@ static int FindDevice(VideoRender * render)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j],
|
uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], DRM_MODE_OBJECT_PLANE, "type");
|
||||||
DRM_MODE_OBJECT_PLANE, "type");
|
|
||||||
uint64_t zpos = 0;
|
uint64_t zpos = 0;
|
||||||
|
|
||||||
#ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!!
|
#ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!!
|
||||||
printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n",
|
printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", plane->plane_id,
|
||||||
plane->plane_id, plane->crtc_id, plane->possible_crtcs, resources->crtcs[i],
|
plane->crtc_id, plane->possible_crtcs, resources->crtcs[i],
|
||||||
(type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane" :
|
(type == DRM_PLANE_TYPE_PRIMARY) ? "primary plane"
|
||||||
(type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane" :
|
: (type == DRM_PLANE_TYPE_OVERLAY) ? "overlay plane"
|
||||||
(type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane" : "No plane type");
|
: (type == DRM_PLANE_TYPE_CURSOR) ? "cursor plane"
|
||||||
|
: "No plane type");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// test pixel format and plane caps
|
// test pixel format and plane caps
|
||||||
@ -423,8 +395,7 @@ static int FindDevice(VideoRender * render)
|
|||||||
drmModeFreeResources(resources);
|
drmModeFreeResources(resources);
|
||||||
|
|
||||||
#ifdef DRM_DEBUG
|
#ifdef DRM_DEBUG
|
||||||
printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n",
|
printf("[FindDevice] DRM setup CRTC: %i video_plane: %i \n", render->crtc_id, render->video_plane);
|
||||||
render->crtc_id, render->video_plane);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// save actual modesetting
|
// save actual modesetting
|
||||||
@ -436,8 +407,7 @@ static int FindDevice(VideoRender * render)
|
|||||||
///
|
///
|
||||||
/// Initialize video output module.
|
/// Initialize video output module.
|
||||||
///
|
///
|
||||||
void VideoInitDrm()
|
void VideoInitDrm() {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(render = calloc(1, sizeof(*render)))) {
|
if (!(render = calloc(1, sizeof(*render)))) {
|
||||||
@ -454,8 +424,7 @@ void VideoInitDrm()
|
|||||||
|
|
||||||
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
|
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
|
||||||
|
|
||||||
get_platform_display =
|
get_platform_display = (void *)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||||
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
|
|
||||||
assert(get_platform_display != NULL);
|
assert(get_platform_display != NULL);
|
||||||
|
|
||||||
eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL);
|
eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL);
|
||||||
@ -478,12 +447,10 @@ void VideoInitDrm()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("set CRTC %d of Connector %d aktiv\n", render->crtc_id, render->connector_id);
|
printf("set CRTC %d of Connector %d aktiv\n", render->crtc_id, render->connector_id);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
||||||
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
render->crtc_id);
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
|
||||||
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
|
||||||
|
|
||||||
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
@ -492,11 +459,9 @@ void VideoInitDrm()
|
|||||||
fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno);
|
fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno);
|
||||||
|
|
||||||
drmModeAtomicFree(ModeReq);
|
drmModeAtomicFree(ModeReq);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_drm_aspect(int *num,int *den)
|
void get_drm_aspect(int *num, int *den) {
|
||||||
{
|
|
||||||
*num = VideoWindowWidth;
|
*num = VideoWindowWidth;
|
||||||
*den = VideoWindowHeight;
|
*den = VideoWindowHeight;
|
||||||
}
|
}
|
||||||
@ -516,7 +481,6 @@ void InitBo(int bpp) {
|
|||||||
assert(gbm.surface != NULL);
|
assert(gbm.surface != NULL);
|
||||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL);
|
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, gbm.surface, NULL);
|
||||||
assert(eglSurface != NULL);
|
assert(eglSurface != NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gbm_bo *previous_bo = NULL;
|
static struct gbm_bo *previous_bo = NULL;
|
||||||
@ -537,8 +501,8 @@ static void drm_swap_buffers () {
|
|||||||
uint32_t handle = gbm_bo_get_handle(bo).u32;
|
uint32_t handle = gbm_bo_get_handle(bo).u32;
|
||||||
uint32_t pitch = gbm_bo_get_stride(bo);
|
uint32_t pitch = gbm_bo_get_stride(bo);
|
||||||
|
|
||||||
|
drmModeAddFB(render->fd_drm, VideoWindowWidth, VideoWindowHeight, render->bpp == 10 ? 30 : 24, 32, pitch, handle,
|
||||||
drmModeAddFB (render->fd_drm, VideoWindowWidth,VideoWindowHeight,render->bpp==10? 30:24, 32, pitch, handle, &fb);
|
&fb);
|
||||||
// drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
|
// drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode);
|
||||||
|
|
||||||
if (m_need_modeset) {
|
if (m_need_modeset) {
|
||||||
@ -556,23 +520,19 @@ static void drm_swap_buffers () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need to disable the CRTC in order to submit the HDR data....
|
// Need to disable the CRTC in order to submit the HDR data....
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
|
||||||
DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
|
|
||||||
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
|
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace",
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "Colorspace",old_color==AVCOL_PRI_BT2020?9:2 );
|
old_color == AVCOL_PRI_BT2020 ? 9 : 2);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",
|
||||||
DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",old_color==AVCOL_PRI_BT2020?2:1 );
|
old_color == AVCOL_PRI_BT2020 ? 2 : 1);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 0);
|
||||||
DRM_MODE_OBJECT_PLANE, "COLOR_RANGE",0 );
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
|
||||||
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
render->crtc_id);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
|
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
|
||||||
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
|
||||||
|
|
||||||
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
fprintf(stderr, "cannot set atomic mode modeset 2 (%d): %m\n", errno);
|
fprintf(stderr, "cannot set atomic mode modeset 2 (%d): %m\n", errno);
|
||||||
@ -592,7 +552,6 @@ static void drm_swap_buffers () {
|
|||||||
}
|
}
|
||||||
previous_bo = bo;
|
previous_bo = bo;
|
||||||
previous_fb = fb;
|
previous_fb = fb;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_clean_up() {
|
static void drm_clean_up() {
|
||||||
@ -607,8 +566,8 @@ static void drm_clean_up () {
|
|||||||
gbm_surface_release_buffer(gbm.surface, previous_bo);
|
gbm_surface_release_buffer(gbm.surface, previous_bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id,
|
drmModeSetCrtc(render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id, render->saved_crtc->x,
|
||||||
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
|
render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
|
||||||
drmModeFreeCrtc(render->saved_crtc);
|
drmModeFreeCrtc(render->saved_crtc);
|
||||||
|
|
||||||
if (has_modeset) {
|
if (has_modeset) {
|
||||||
@ -626,25 +585,19 @@ static void drm_clean_up () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need to disable the CRTC in order to submit the HDR data....
|
// Need to disable the CRTC in order to submit the HDR data....
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
|
||||||
DRM_MODE_OBJECT_CRTC, "ACTIVE", 0);
|
|
||||||
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
|
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR,
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA", 0);
|
"HDR_OUTPUT_METADATA", 0);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace", 2);
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "Colorspace",2 );
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING", 1);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane, DRM_MODE_OBJECT_PLANE, "COLOR_RANGE", 1);
|
||||||
DRM_MODE_OBJECT_PLANE, "COLOR_ENCODING",1 );
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->video_plane,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID",
|
||||||
DRM_MODE_OBJECT_PLANE, "COLOR_RANGE",1 );
|
render->crtc_id);
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
||||||
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
|
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
|
|
||||||
DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id);
|
|
||||||
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
|
|
||||||
DRM_MODE_OBJECT_CRTC, "ACTIVE", 1);
|
|
||||||
|
|
||||||
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0)
|
||||||
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
|
||||||
@ -677,5 +630,4 @@ static void drm_clean_up () {
|
|||||||
close(render->fd_drm);
|
close(render->fd_drm);
|
||||||
eglDisplay = NULL;
|
eglDisplay = NULL;
|
||||||
free(render);
|
free(render);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,11 @@
|
|||||||
#define _DRVAPI_ERROR_STRING_H_
|
#define _DRVAPI_ERROR_STRING_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// Error Code string definitions here
|
// Error Code string definitions here
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
char const *error_string;
|
char const *error_string;
|
||||||
unsigned int error_id;
|
unsigned int error_id;
|
||||||
} s_CudaErrorStr;
|
} s_CudaErrorStr;
|
||||||
@ -84,8 +83,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8},
|
{"CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This indicates that no CUDA-capable devices were detected by the installed
|
* This indicates that no CUDA-capable devices were detected by the
|
||||||
* CUDA driver.
|
* installed CUDA driver.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100},
|
{"CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100},
|
||||||
|
|
||||||
@ -256,18 +255,19 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This indicates that asynchronous operations issued previously have not
|
* This indicates that asynchronous operations issued previously have not
|
||||||
* completed yet. This result is not actually an error, but must be indicated
|
* completed yet. This result is not actually an error, but must be
|
||||||
* differently than ::CUDA_SUCCESS (which indicates completion). Calls that
|
* indicated differently than ::CUDA_SUCCESS (which indicates completion).
|
||||||
* may return this value include ::cuEventQuery() and ::cuStreamQuery().
|
* Calls that may return this value include ::cuEventQuery() and
|
||||||
|
* ::cuStreamQuery().
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_NOT_READY", 600},
|
{"CUDA_ERROR_NOT_READY", 600},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a
|
* While executing a kernel, the device encountered a
|
||||||
* load or store instruction on an invalid memory address.
|
* load or store instruction on an invalid memory address.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_ILLEGAL_ADDRESS", 700},
|
{"CUDA_ERROR_ILLEGAL_ADDRESS", 700},
|
||||||
|
|
||||||
@ -342,8 +342,8 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_TOO_MANY_PEERS", 711},
|
{"CUDA_ERROR_TOO_MANY_PEERS", 711},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This error indicates that the memory range passed to ::cuMemHostRegister()
|
* This error indicates that the memory range passed to
|
||||||
* has already been registered.
|
* ::cuMemHostRegister() has already been registered.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712},
|
{"CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712},
|
||||||
|
|
||||||
@ -356,25 +356,25 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a stack error.
|
* While executing a kernel, the device encountered a stack error.
|
||||||
* This can be due to stack corruption or exceeding the stack size limit.
|
* This can be due to stack corruption or exceeding the stack size limit.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_HARDWARE_STACK_ERROR", 714},
|
{"CUDA_ERROR_HARDWARE_STACK_ERROR", 714},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered an illegal instruction.
|
* While executing a kernel, the device encountered an illegal instruction.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_ILLEGAL_INSTRUCTION", 715},
|
{"CUDA_ERROR_ILLEGAL_INSTRUCTION", 715},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device encountered a load or store instruction
|
* While executing a kernel, the device encountered a load or store
|
||||||
* on a memory address which is not aligned.
|
* instruction on a memory address which is not aligned. This leaves the
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* process in an inconsistent state and any further CUDA work will return
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* the same error. To continue using CUDA, the process must be terminated
|
||||||
* and relaunched.
|
* and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_MISALIGNED_ADDRESS", 716},
|
{"CUDA_ERROR_MISALIGNED_ADDRESS", 716},
|
||||||
@ -384,17 +384,17 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
* which can only operate on memory locations in certain address spaces
|
* which can only operate on memory locations in certain address spaces
|
||||||
* (global, shared, or local), but was supplied a memory address not
|
* (global, shared, or local), but was supplied a memory address not
|
||||||
* belonging to an allowed address space.
|
* belonging to an allowed address space.
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* This leaves the process in an inconsistent state and any further CUDA
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* work will return the same error. To continue using CUDA, the process must
|
||||||
* and relaunched.
|
* be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_INVALID_ADDRESS_SPACE", 717},
|
{"CUDA_ERROR_INVALID_ADDRESS_SPACE", 717},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While executing a kernel, the device program counter wrapped its address space.
|
* While executing a kernel, the device program counter wrapped its address
|
||||||
* This leaves the process in an inconsistent state and any further CUDA work
|
* space. This leaves the process in an inconsistent state and any further
|
||||||
* will return the same error. To continue using CUDA, the process must be terminated
|
* CUDA work will return the same error. To continue using CUDA, the process
|
||||||
* and relaunched.
|
* must be terminated and relaunched.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_INVALID_PC", 718},
|
{"CUDA_ERROR_INVALID_PC", 718},
|
||||||
|
|
||||||
@ -409,11 +409,13 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
{"CUDA_ERROR_LAUNCH_FAILED", 719},
|
{"CUDA_ERROR_LAUNCH_FAILED", 719},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This error indicates that the number of blocks launched per grid for a kernel that was
|
* This error indicates that the number of blocks launched per grid for a
|
||||||
* launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice
|
* kernel that was launched via either ::cuLaunchCooperativeKernel or
|
||||||
* exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor
|
* ::cuLaunchCooperativeKernelMultiDevice exceeds the maximum number of
|
||||||
* or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors
|
* blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor or
|
||||||
* as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
|
* ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number
|
||||||
|
* of multiprocessors as specified by the device attribute
|
||||||
|
* ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720},
|
{"CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720},
|
||||||
|
|
||||||
@ -432,13 +434,11 @@ s_CudaErrorStr sCudaDrvErrorString[] = {
|
|||||||
* This indicates that an unknown internal error has occurred.
|
* This indicates that an unknown internal error has occurred.
|
||||||
*/
|
*/
|
||||||
{"CUDA_ERROR_UNKNOWN", 999},
|
{"CUDA_ERROR_UNKNOWN", 999},
|
||||||
{NULL, -1}
|
{NULL, -1}};
|
||||||
};
|
|
||||||
|
|
||||||
// This is just a linear search through the array, since the error_id's are not
|
// This is just a linear search through the array, since the error_id's are not
|
||||||
// always ocurring consecutively
|
// always ocurring consecutively
|
||||||
static inline const char *getCudaDrvErrorString(CUresult error_id)
|
static inline const char *getCudaDrvErrorString(CUresult error_id) {
|
||||||
{
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
while (sCudaDrvErrorString[index].error_id != error_id && (int)sCudaDrvErrorString[index].error_id != -1) {
|
while (sCudaDrvErrorString[index].error_id != error_id && (int)sCudaDrvErrorString[index].error_id != -1) {
|
||||||
|
367
hdr.c
367
hdr.c
@ -87,7 +87,6 @@ struct hdr_output_metadata {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum hdr_metadata_eotf {
|
enum hdr_metadata_eotf {
|
||||||
EOTF_TRADITIONAL_GAMMA_SDR,
|
EOTF_TRADITIONAL_GAMMA_SDR,
|
||||||
EOTF_TRADITIONAL_GAMMA_HDR,
|
EOTF_TRADITIONAL_GAMMA_HDR,
|
||||||
@ -95,27 +94,15 @@ enum hdr_metadata_eotf {
|
|||||||
EOTF_HLG,
|
EOTF_HLG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum metadata_id {
|
enum metadata_id {
|
||||||
METADATA_TYPE1,
|
METADATA_TYPE1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void weston_hdr_metadata(void *data, uint16_t display_primary_r_x, uint16_t display_primary_r_y,
|
||||||
weston_hdr_metadata(void *data,
|
uint16_t display_primary_g_x, uint16_t display_primary_g_y, uint16_t display_primary_b_x,
|
||||||
uint16_t display_primary_r_x,
|
uint16_t display_primary_b_y, uint16_t white_point_x, uint16_t white_point_y,
|
||||||
uint16_t display_primary_r_y,
|
uint16_t min_luminance, uint16_t max_luminance, uint16_t max_cll, uint16_t max_fall,
|
||||||
uint16_t display_primary_g_x,
|
enum hdr_metadata_eotf eotf) {
|
||||||
uint16_t display_primary_g_y,
|
|
||||||
uint16_t display_primary_b_x,
|
|
||||||
uint16_t display_primary_b_y,
|
|
||||||
uint16_t white_point_x,
|
|
||||||
uint16_t white_point_y,
|
|
||||||
uint16_t min_luminance,
|
|
||||||
uint16_t max_luminance,
|
|
||||||
uint16_t max_cll,
|
|
||||||
uint16_t max_fall,
|
|
||||||
enum hdr_metadata_eotf eotf)
|
|
||||||
{
|
|
||||||
uint8_t *data8;
|
uint8_t *data8;
|
||||||
uint16_t *data16;
|
uint16_t *data16;
|
||||||
|
|
||||||
@ -155,151 +142,302 @@ struct weston_colorspace {
|
|||||||
struct weston_colorspace hdr10;
|
struct weston_colorspace hdr10;
|
||||||
|
|
||||||
static const struct weston_colorspace bt470m = {
|
static const struct weston_colorspace bt470m = {
|
||||||
.r = {{ 0.670f, 0.330f, }},
|
.r = {{
|
||||||
.g = {{ 0.210f, 0.710f, }},
|
0.670f,
|
||||||
.b = {{ 0.140f, 0.080f, }},
|
0.330f,
|
||||||
.whitepoint = {{ 0.3101f, 0.3162f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.210f,
|
||||||
|
0.710f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.140f,
|
||||||
|
0.080f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3101f,
|
||||||
|
0.3162f,
|
||||||
|
}},
|
||||||
.name = "BT.470 M",
|
.name = "BT.470 M",
|
||||||
.whitepoint_name = "C",
|
.whitepoint_name = "C",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace bt470bg = {
|
static const struct weston_colorspace bt470bg = {
|
||||||
.r = {{ 0.640f, 0.330f, }},
|
.r = {{
|
||||||
.g = {{ 0.290f, 0.600f, }},
|
0.640f,
|
||||||
.b = {{ 0.150f, 0.060f, }},
|
0.330f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.290f,
|
||||||
|
0.600f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.150f,
|
||||||
|
0.060f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "BT.470 B/G",
|
.name = "BT.470 B/G",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace smpte170m = {
|
static const struct weston_colorspace smpte170m = {
|
||||||
.r = {{ 0.630f, 0.340f, }},
|
.r = {{
|
||||||
.g = {{ 0.310f, 0.595f, }},
|
0.630f,
|
||||||
.b = {{ 0.155f, 0.070f, }},
|
0.340f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.310f,
|
||||||
|
0.595f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.155f,
|
||||||
|
0.070f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "SMPTE 170M",
|
.name = "SMPTE 170M",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace smpte240m = {
|
static const struct weston_colorspace smpte240m = {
|
||||||
.r = {{ 0.630f, 0.340f, }},
|
.r = {{
|
||||||
.g = {{ 0.310f, 0.595f, }},
|
0.630f,
|
||||||
.b = {{ 0.155f, 0.070f, }},
|
0.340f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.310f,
|
||||||
|
0.595f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.155f,
|
||||||
|
0.070f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "SMPTE 240M",
|
.name = "SMPTE 240M",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace bt709 = {
|
static const struct weston_colorspace bt709 = {
|
||||||
.r = {{ 0.640f, 0.330f, }},
|
.r = {{
|
||||||
.g = {{ 0.300f, 0.600f, }},
|
0.640f,
|
||||||
.b = {{ 0.150f, 0.060f, }},
|
0.330f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.300f,
|
||||||
|
0.600f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.150f,
|
||||||
|
0.060f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "BT.709",
|
.name = "BT.709",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace bt2020 = {
|
static const struct weston_colorspace bt2020 = {
|
||||||
.r = {{ 0.708f, 0.292f, }},
|
.r = {{
|
||||||
.g = {{ 0.170f, 0.797f, }},
|
0.708f,
|
||||||
.b = {{ 0.131f, 0.046f, }},
|
0.292f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.170f,
|
||||||
|
0.797f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.131f,
|
||||||
|
0.046f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "BT.2020",
|
.name = "BT.2020",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace srgb = {
|
static const struct weston_colorspace srgb = {
|
||||||
.r = {{ 0.640f, 0.330f, }},
|
.r = {{
|
||||||
.g = {{ 0.300f, 0.600f, }},
|
0.640f,
|
||||||
.b = {{ 0.150f, 0.060f, }},
|
0.330f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.300f,
|
||||||
|
0.600f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.150f,
|
||||||
|
0.060f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "sRGB",
|
.name = "sRGB",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace adobergb = {
|
static const struct weston_colorspace adobergb = {
|
||||||
.r = {{ 0.640f, 0.330f, }},
|
.r = {{
|
||||||
.g = {{ 0.210f, 0.710f, }},
|
0.640f,
|
||||||
.b = {{ 0.150f, 0.060f, }},
|
0.330f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.210f,
|
||||||
|
0.710f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.150f,
|
||||||
|
0.060f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "AdobeRGB",
|
.name = "AdobeRGB",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace dci_p3 = {
|
static const struct weston_colorspace dci_p3 = {
|
||||||
.r = {{ 0.680f, 0.320f, }},
|
.r = {{
|
||||||
.g = {{ 0.265f, 0.690f, }},
|
0.680f,
|
||||||
.b = {{ 0.150f, 0.060f, }},
|
0.320f,
|
||||||
.whitepoint = {{ 0.3127f, 0.3290f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.265f,
|
||||||
|
0.690f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.150f,
|
||||||
|
0.060f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.3127f,
|
||||||
|
0.3290f,
|
||||||
|
}},
|
||||||
.name = "DCI-P3 D65",
|
.name = "DCI-P3 D65",
|
||||||
.whitepoint_name = "D65",
|
.whitepoint_name = "D65",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace prophotorgb = {
|
static const struct weston_colorspace prophotorgb = {
|
||||||
.r = {{ 0.7347f, 0.2653f, }},
|
.r = {{
|
||||||
.g = {{ 0.1596f, 0.8404f, }},
|
0.7347f,
|
||||||
.b = {{ 0.0366f, 0.0001f, }},
|
0.2653f,
|
||||||
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.1596f,
|
||||||
|
0.8404f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.0366f,
|
||||||
|
0.0001f,
|
||||||
|
}},
|
||||||
.whitepoint = {{.3457, .3585}},
|
.whitepoint = {{.3457, .3585}},
|
||||||
.name = "ProPhoto RGB",
|
.name = "ProPhoto RGB",
|
||||||
.whitepoint_name = "D50",
|
.whitepoint_name = "D50",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace ciergb = {
|
static const struct weston_colorspace ciergb = {
|
||||||
.r = {{ 0.7347f, 0.2653f, }},
|
.r = {{
|
||||||
.g = {{ 0.2738f, 0.7174f, }},
|
0.7347f,
|
||||||
.b = {{ 0.1666f, 0.0089f, }},
|
0.2653f,
|
||||||
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.2738f,
|
||||||
|
0.7174f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.1666f,
|
||||||
|
0.0089f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
1.0f / 3.0f,
|
||||||
|
1.0f / 3.0f,
|
||||||
|
}},
|
||||||
.name = "CIE RGB",
|
.name = "CIE RGB",
|
||||||
.whitepoint_name = "E",
|
.whitepoint_name = "E",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace ciexyz = {
|
static const struct weston_colorspace ciexyz = {
|
||||||
.r = {{ 1.0f, 0.0f, }},
|
.r = {{
|
||||||
.g = {{ 0.0f, 1.0f, }},
|
1.0f,
|
||||||
.b = {{ 0.0f, 0.0f, }},
|
0.0f,
|
||||||
.whitepoint = {{ 1.0f / 3.0f, 1.0f / 3.0f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.0f,
|
||||||
|
1.0f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
1.0f / 3.0f,
|
||||||
|
1.0f / 3.0f,
|
||||||
|
}},
|
||||||
.name = "CIE XYZ",
|
.name = "CIE XYZ",
|
||||||
.whitepoint_name = "E",
|
.whitepoint_name = "E",
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct weston_colorspace ap0 = {
|
const struct weston_colorspace ap0 = {
|
||||||
.r = {{ 0.7347f, 0.2653f, }},
|
.r = {{
|
||||||
.g = {{ 0.0000f, 1.0000f, }},
|
0.7347f,
|
||||||
.b = {{ 0.0001f, -0.0770f, }},
|
0.2653f,
|
||||||
.whitepoint = {{ .32168f, .33767f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.0000f,
|
||||||
|
1.0000f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.0001f,
|
||||||
|
-0.0770f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
.32168f,
|
||||||
|
.33767f,
|
||||||
|
}},
|
||||||
.name = "ACES primaries #0",
|
.name = "ACES primaries #0",
|
||||||
.whitepoint_name = "D60",
|
.whitepoint_name = "D60",
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct weston_colorspace ap1 = {
|
const struct weston_colorspace ap1 = {
|
||||||
.r = {{ 0.713f, 0.393f, }},
|
.r = {{
|
||||||
.g = {{ 0.165f, 0.830f, }},
|
0.713f,
|
||||||
.b = {{ 0.128f, 0.044f, }},
|
0.393f,
|
||||||
.whitepoint = {{ 0.32168f, 0.33767f, }},
|
}},
|
||||||
|
.g = {{
|
||||||
|
0.165f,
|
||||||
|
0.830f,
|
||||||
|
}},
|
||||||
|
.b = {{
|
||||||
|
0.128f,
|
||||||
|
0.044f,
|
||||||
|
}},
|
||||||
|
.whitepoint = {{
|
||||||
|
0.32168f,
|
||||||
|
0.33767f,
|
||||||
|
}},
|
||||||
.name = "ACES primaries #1",
|
.name = "ACES primaries #1",
|
||||||
.whitepoint_name = "D60",
|
.whitepoint_name = "D60",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct weston_colorspace *const colorspaces[] = {
|
static const struct weston_colorspace *const colorspaces[] = {
|
||||||
&bt470m,
|
&bt470m, &bt470bg, &smpte170m, &smpte240m, &bt709, &bt2020, &srgb,
|
||||||
&bt470bg,
|
&adobergb, &dci_p3, &prophotorgb, &ciergb, &ciexyz, &ap0, &ap1,
|
||||||
&smpte170m,
|
|
||||||
&smpte240m,
|
|
||||||
&bt709,
|
|
||||||
&bt2020,
|
|
||||||
&srgb,
|
|
||||||
&adobergb,
|
|
||||||
&dci_p3,
|
|
||||||
&prophotorgb,
|
|
||||||
&ciergb,
|
|
||||||
&ciexyz,
|
|
||||||
&ap0,
|
|
||||||
&ap1,
|
|
||||||
};
|
};
|
||||||
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
|
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
|
||||||
const struct weston_colorspace *
|
const struct weston_colorspace *weston_colorspace_lookup(const char *name) {
|
||||||
weston_colorspace_lookup(const char *name)
|
|
||||||
{
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
@ -317,15 +455,10 @@ weston_colorspace_lookup(const char *name)
|
|||||||
|
|
||||||
static int cleanup = 0;
|
static int cleanup = 0;
|
||||||
|
|
||||||
|
static uint16_t encode_xyy(float xyy) { return xyy * 50000; }
|
||||||
static uint16_t encode_xyy(float xyy)
|
|
||||||
{
|
|
||||||
return xyy * 50000;
|
|
||||||
}
|
|
||||||
static AVMasteringDisplayMetadata md_save = {0};
|
static AVMasteringDisplayMetadata md_save = {0};
|
||||||
static AVContentLightMetadata ld_save = {0};
|
static AVContentLightMetadata ld_save = {0};
|
||||||
static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSideData *sd2)
|
static void set_hdr_metadata(int color, int trc, AVFrameSideData *sd1, AVFrameSideData *sd2) {
|
||||||
{
|
|
||||||
drmModeAtomicReqPtr ModeReq;
|
drmModeAtomicReqPtr ModeReq;
|
||||||
struct weston_colorspace *cs;
|
struct weston_colorspace *cs;
|
||||||
enum hdr_metadata_eotf eotf;
|
enum hdr_metadata_eotf eotf;
|
||||||
@ -335,13 +468,10 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
struct AVMasteringDisplayMetadata *md = NULL;
|
struct AVMasteringDisplayMetadata *md = NULL;
|
||||||
struct AVContentLightMetadata *ld = NULL;
|
struct AVContentLightMetadata *ld = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// clean up FFMEPG stuff
|
// clean up FFMEPG stuff
|
||||||
if (trc == AVCOL_TRC_BT2020_10)
|
if (trc == AVCOL_TRC_BT2020_10)
|
||||||
trc = AVCOL_TRC_ARIB_STD_B67;
|
trc = AVCOL_TRC_ARIB_STD_B67;
|
||||||
|
|
||||||
|
|
||||||
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
|
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
|
||||||
return; // nothing to do
|
return; // nothing to do
|
||||||
|
|
||||||
@ -354,8 +484,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
if (md && !memcmp(md, &md_save, sizeof(md_save)))
|
if (md && !memcmp(md, &md_save, sizeof(md_save)))
|
||||||
if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
|
if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
|
||||||
return;
|
return;
|
||||||
}
|
} else if (ld && !memcmp(ld, &ld_save, sizeof(ld_save))) {
|
||||||
else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +498,6 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
old_color = color;
|
old_color = color;
|
||||||
old_trc = trc;
|
old_trc = trc;
|
||||||
|
|
||||||
|
|
||||||
if (VulkanTargetColorSpace != 3) { // no HDR TV
|
if (VulkanTargetColorSpace != 3) { // no HDR TV
|
||||||
m_need_modeset = 1; // change in colorsettings
|
m_need_modeset = 1; // change in colorsettings
|
||||||
return;
|
return;
|
||||||
@ -414,17 +542,14 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
|
|
||||||
if (md) { // we got Metadata
|
if (md) { // we got Metadata
|
||||||
if (md->has_primaries) {
|
if (md->has_primaries) {
|
||||||
Debug(3,"Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n"
|
Debug(3,
|
||||||
|
"Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n"
|
||||||
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) \n"
|
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) \n"
|
||||||
"min_luminance=%f, max_luminance=%f\n",
|
"min_luminance=%f, max_luminance=%f\n",
|
||||||
md->has_primaries, md->has_luminance,
|
md->has_primaries, md->has_luminance, av_q2d(md->display_primaries[0][0]),
|
||||||
av_q2d(md->display_primaries[0][0]),
|
av_q2d(md->display_primaries[0][1]), av_q2d(md->display_primaries[1][0]),
|
||||||
av_q2d(md->display_primaries[0][1]),
|
av_q2d(md->display_primaries[1][1]), av_q2d(md->display_primaries[2][0]),
|
||||||
av_q2d(md->display_primaries[1][0]),
|
av_q2d(md->display_primaries[2][1]), av_q2d(md->white_point[0]), av_q2d(md->white_point[1]),
|
||||||
av_q2d(md->display_primaries[1][1]),
|
|
||||||
av_q2d(md->display_primaries[2][0]),
|
|
||||||
av_q2d(md->display_primaries[2][1]),
|
|
||||||
av_q2d(md->white_point[0]), av_q2d(md->white_point[1]),
|
|
||||||
av_q2d(md->min_luminance), av_q2d(md->max_luminance));
|
av_q2d(md->min_luminance), av_q2d(md->max_luminance));
|
||||||
|
|
||||||
cs = &hdr10;
|
cs = &hdr10;
|
||||||
@ -449,23 +574,15 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
MaxFALL = ld->MaxFALL;
|
MaxFALL = ld->MaxFALL;
|
||||||
}
|
}
|
||||||
data.metadata_type = 7; // ????????????????????????
|
data.metadata_type = 7; // ????????????????????????
|
||||||
weston_hdr_metadata(&data.hdmi_metadata_type1,
|
weston_hdr_metadata(&data.hdmi_metadata_type1, encode_xyy(cs->r.f[0]), encode_xyy(cs->r.f[1]),
|
||||||
encode_xyy(cs->r.f[0]),
|
encode_xyy(cs->g.f[0]), encode_xyy(cs->g.f[1]), encode_xyy(cs->b.f[0]), encode_xyy(cs->b.f[1]),
|
||||||
encode_xyy(cs->r.f[1]),
|
encode_xyy(cs->whitepoint.f[0]), encode_xyy(cs->whitepoint.f[1]),
|
||||||
encode_xyy(cs->g.f[0]),
|
|
||||||
encode_xyy(cs->g.f[1]),
|
|
||||||
encode_xyy(cs->b.f[0]),
|
|
||||||
encode_xyy(cs->b.f[1]),
|
|
||||||
encode_xyy(cs->whitepoint.f[0]),
|
|
||||||
encode_xyy(cs->whitepoint.f[1]),
|
|
||||||
max_lum, // max_display_mastering_luminance
|
max_lum, // max_display_mastering_luminance
|
||||||
min_lum, // min_display_mastering_luminance
|
min_lum, // min_display_mastering_luminance
|
||||||
MaxCLL, // Maximum Content Light Level (MaxCLL)
|
MaxCLL, // Maximum Content Light Level (MaxCLL)
|
||||||
MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
|
MaxFALL, // Maximum Frame-Average Light Level (MaxFALL)
|
||||||
eotf);
|
eotf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
|
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("DRM: HDR metadata: failed blob create \n");
|
printf("DRM: HDR metadata: failed blob create \n");
|
||||||
@ -473,8 +590,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
|
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, render->hdr_metadata, render->hdr_blob_id);
|
||||||
render->hdr_metadata, render->hdr_blob_id);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("DRM: HDR metadata: failed property set %d\n", ret);
|
printf("DRM: HDR metadata: failed property set %d\n", ret);
|
||||||
|
|
||||||
@ -487,5 +603,4 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
|
|||||||
m_need_modeset = 1;
|
m_need_modeset = 1;
|
||||||
|
|
||||||
Debug(3, "DRM: HDR metadata: prop set\n");
|
Debug(3, "DRM: HDR metadata: prop set\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
iatomic.h
22
iatomic.h
@ -23,9 +23,7 @@
|
|||||||
/// @addtogroup iatomic
|
/// @addtogroup iatomic
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 \
|
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||||
+ __GNUC_MINOR__ * 100 \
|
|
||||||
+ __GNUC_PATCHLEVEL__)
|
|
||||||
|
|
||||||
// gcc before 4.7 didn't support atomic builtins,
|
// gcc before 4.7 didn't support atomic builtins,
|
||||||
// use alsa atomic functions.
|
// use alsa atomic functions.
|
||||||
@ -59,38 +57,32 @@ typedef volatile int atomic_t;
|
|||||||
///
|
///
|
||||||
/// Set atomic value.
|
/// Set atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_set(ptr, val) \
|
#define atomic_set(ptr, val) __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_store_n(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Read atomic value.
|
/// Read atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_read(ptr) \
|
#define atomic_read(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST)
|
||||||
__atomic_load_n(ptr, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Increment atomic value.
|
/// Increment atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_inc(ptr) \
|
#define atomic_inc(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
||||||
__atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Decrement atomic value.
|
/// Decrement atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_dec(ptr) \
|
#define atomic_dec(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
||||||
__atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Add to atomic value.
|
/// Add to atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_add(val, ptr) \
|
#define atomic_add(val, ptr) __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Subtract from atomic value.
|
/// Subtract from atomic value.
|
||||||
///
|
///
|
||||||
#define atomic_sub(val, ptr) \
|
#define atomic_sub(val, ptr) __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
||||||
__atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
23
misc.h
23
misc.h
@ -24,8 +24,8 @@
|
|||||||
/// @addtogroup misc
|
/// @addtogroup misc
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <time.h> // clock_gettime
|
#include <time.h> // clock_gettime
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -46,8 +46,7 @@ extern int SysLogLevel; ///< how much information wanted
|
|||||||
// Prototypes
|
// Prototypes
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static inline void Syslog(const int, const char *format, ...)
|
static inline void Syslog(const int, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||||
__attribute__((format(printf, 2, 3)));
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Inlines
|
// Inlines
|
||||||
@ -67,8 +66,7 @@ static inline void Syslog(const int, const char *format, ...)
|
|||||||
** - 2 info
|
** - 2 info
|
||||||
** - 3 important debug and fixme's
|
** - 3 important debug and fixme's
|
||||||
*/
|
*/
|
||||||
static inline void Syslog(const int level, const char *format, ...)
|
static inline void Syslog(const int level, const char *format, ...) {
|
||||||
{
|
|
||||||
if (SysLogLevel > level || DebugLevel > level) {
|
if (SysLogLevel > level || DebugLevel > level) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@ -86,7 +84,11 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
/**
|
/**
|
||||||
** Show fatal error.
|
** Show fatal error.
|
||||||
*/
|
*/
|
||||||
#define Fatal(fmt...) do { Error(fmt); abort(); } while (0)
|
#define Fatal(fmt...) \
|
||||||
|
do { \
|
||||||
|
Error(fmt); \
|
||||||
|
abort(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Show warning.
|
** Show warning.
|
||||||
@ -116,8 +118,7 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
**
|
**
|
||||||
** @param ts dvb time stamp
|
** @param ts dvb time stamp
|
||||||
*/
|
*/
|
||||||
static inline const char *Timestamp2String(int64_t ts)
|
static inline const char *Timestamp2String(int64_t ts) {
|
||||||
{
|
|
||||||
static char buf[4][16];
|
static char buf[4][16];
|
||||||
static int idx;
|
static int idx;
|
||||||
|
|
||||||
@ -136,8 +137,7 @@ static inline const char *Timestamp2String(int64_t ts)
|
|||||||
**
|
**
|
||||||
** @returns ticks in ms,
|
** @returns ticks in ms,
|
||||||
*/
|
*/
|
||||||
static inline uint32_t GetMsTicks(void)
|
static inline uint32_t GetMsTicks(void) {
|
||||||
{
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
#ifdef CLOCK_MONOTONIC
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
|
||||||
@ -153,8 +153,7 @@ static inline uint32_t GetMsTicks(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t GetusTicks(void)
|
static inline uint64_t GetusTicks(void) {
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
#ifdef CLOCK_MONOTONIC
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
513
openglosd.cpp
513
openglosd.cpp
File diff suppressed because it is too large
Load Diff
383
openglosd.h
383
openglosd.h
@ -1,6 +1,7 @@
|
|||||||
#ifndef __SOFTHDDEVICE_OPENGLOSD_H
|
#ifndef __SOFTHDDEVICE_OPENGLOSD_H
|
||||||
#define __SOFTHDDEVICE_OPENGLOSD_H
|
#define __SOFTHDDEVICE_OPENGLOSD_H
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/freeglut.h>
|
#include <GL/freeglut.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
@ -36,17 +37,15 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
extern "C" pthread_mutex_t OSDMutex;
|
extern "C" pthread_mutex_t OSDMutex;
|
||||||
|
|
||||||
struct sOglImage
|
struct sOglImage {
|
||||||
{
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLint width;
|
GLint width;
|
||||||
GLint height;
|
GLint height;
|
||||||
@ -62,28 +61,18 @@ void ConvertColor(const GLint & colARGB, glm::vec4 & col);
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cShader
|
* cShader
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
enum eShaderType
|
enum eShaderType { stRect, stTexture, stText, stCount };
|
||||||
{
|
|
||||||
stRect,
|
|
||||||
stTexture,
|
|
||||||
stText,
|
|
||||||
stCount
|
|
||||||
};
|
|
||||||
|
|
||||||
class cShader
|
class cShader {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
eShaderType type;
|
eShaderType type;
|
||||||
GLuint id;
|
GLuint id;
|
||||||
bool Compile(const char *vertexCode, const char *fragmentCode);
|
bool Compile(const char *vertexCode, const char *fragmentCode);
|
||||||
bool CheckCompileErrors(GLuint object, bool program = false);
|
bool CheckCompileErrors(GLuint object, bool program = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cShader(void)
|
cShader(void){};
|
||||||
{
|
virtual ~cShader(void){};
|
||||||
};
|
|
||||||
virtual ~ cShader(void)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
bool Load(eShaderType type);
|
bool Load(eShaderType type);
|
||||||
void Use(void);
|
void Use(void);
|
||||||
void SetFloat(const GLchar *name, GLfloat value);
|
void SetFloat(const GLchar *name, GLfloat value);
|
||||||
@ -97,11 +86,9 @@ class cShader
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglGlyph
|
* cOglGlyph
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglGlyph:public cListObject
|
class cOglGlyph : public cListObject {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
struct tKerning
|
struct tKerning {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) {
|
tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) {
|
||||||
this->prevSym = prevSym;
|
this->prevSym = prevSym;
|
||||||
@ -124,30 +111,12 @@ class cOglGlyph:public cListObject
|
|||||||
public:
|
public:
|
||||||
cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph);
|
cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph);
|
||||||
virtual ~cOglGlyph();
|
virtual ~cOglGlyph();
|
||||||
FT_ULong CharCode(void)
|
FT_ULong CharCode(void) { return charCode; }
|
||||||
{
|
int AdvanceX(void) { return advanceX; }
|
||||||
return charCode;
|
int BearingLeft(void) const { return bearingLeft; }
|
||||||
}
|
int BearingTop(void) const { return bearingTop; }
|
||||||
int AdvanceX(void)
|
int Width(void) const { return width; }
|
||||||
{
|
int Height(void) const { return height; }
|
||||||
return advanceX;
|
|
||||||
}
|
|
||||||
int BearingLeft(void) const
|
|
||||||
{
|
|
||||||
return bearingLeft;
|
|
||||||
}
|
|
||||||
int BearingTop(void) const
|
|
||||||
{
|
|
||||||
return bearingTop;
|
|
||||||
}
|
|
||||||
int Width(void) const
|
|
||||||
{
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
int Height(void) const
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
int GetKerningCache(FT_ULong prevSym);
|
int GetKerningCache(FT_ULong prevSym);
|
||||||
void SetKerningCache(FT_ULong prevSym, int kerning);
|
void SetKerningCache(FT_ULong prevSym, int kerning);
|
||||||
void BindTexture(void);
|
void BindTexture(void);
|
||||||
@ -156,8 +125,7 @@ class cOglGlyph:public cListObject
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglFont
|
* cOglFont
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglFont:public cListObject
|
class cOglFont : public cListObject {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
static bool initiated;
|
static bool initiated;
|
||||||
cString name;
|
cString name;
|
||||||
@ -170,26 +138,15 @@ class cOglFont:public cListObject
|
|||||||
mutable cList<cOglGlyph> glyphCache;
|
mutable cList<cOglGlyph> glyphCache;
|
||||||
cOglFont(const char *fontName, int charHeight);
|
cOglFont(const char *fontName, int charHeight);
|
||||||
static void Init(void);
|
static void Init(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~cOglFont(void);
|
virtual ~cOglFont(void);
|
||||||
static cOglFont *Get(const char *name, int charHeight);
|
static cOglFont *Get(const char *name, int charHeight);
|
||||||
static void Cleanup(void);
|
static void Cleanup(void);
|
||||||
const char *Name(void)
|
const char *Name(void) { return *name; };
|
||||||
{
|
int Size(void) { return size; };
|
||||||
return *name;
|
int Bottom(void) { return bottom; };
|
||||||
};
|
int Height(void) { return height; };
|
||||||
int Size(void)
|
|
||||||
{
|
|
||||||
return size;
|
|
||||||
};
|
|
||||||
int Bottom(void)
|
|
||||||
{
|
|
||||||
return bottom;
|
|
||||||
};
|
|
||||||
int Height(void)
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
};
|
|
||||||
cOglGlyph *Glyph(FT_ULong charCode) const;
|
cOglGlyph *Glyph(FT_ULong charCode) const;
|
||||||
int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const;
|
int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const;
|
||||||
};
|
};
|
||||||
@ -198,8 +155,7 @@ class cOglFont:public cListObject
|
|||||||
* cOglFb
|
* cOglFb
|
||||||
* Framebuffer Object - OpenGL part of a Pixmap
|
* Framebuffer Object - OpenGL part of a Pixmap
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglFb
|
class cOglFb {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
bool initiated;
|
bool initiated;
|
||||||
// GLuint fb;
|
// GLuint fb;
|
||||||
@ -207,16 +163,14 @@ class cOglFb
|
|||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint viewPortWidth, viewPortHeight;
|
GLint viewPortWidth, viewPortHeight;
|
||||||
bool scrollable;
|
bool scrollable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint fb;
|
GLuint fb;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
|
||||||
cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight);
|
cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight);
|
||||||
virtual ~cOglFb(void);
|
virtual ~cOglFb(void);
|
||||||
bool Initiated(void)
|
bool Initiated(void) { return initiated; }
|
||||||
{
|
|
||||||
return initiated;
|
|
||||||
}
|
|
||||||
virtual bool Init(void);
|
virtual bool Init(void);
|
||||||
void Bind(void);
|
void Bind(void);
|
||||||
void BindRead(void);
|
void BindRead(void);
|
||||||
@ -224,38 +178,25 @@ class cOglFb
|
|||||||
virtual void Unbind(void);
|
virtual void Unbind(void);
|
||||||
bool BindTexture(void);
|
bool BindTexture(void);
|
||||||
void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2);
|
void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2);
|
||||||
GLint Width(void)
|
GLint Width(void) { return width; };
|
||||||
{
|
GLint Height(void) { return height; };
|
||||||
return width;
|
bool Scrollable(void) { return scrollable; };
|
||||||
};
|
GLint ViewportWidth(void) { return viewPortWidth; };
|
||||||
GLint Height(void)
|
GLint ViewportHeight(void) { return viewPortHeight; };
|
||||||
{
|
|
||||||
return height;
|
|
||||||
};
|
|
||||||
bool Scrollable(void)
|
|
||||||
{
|
|
||||||
return scrollable;
|
|
||||||
};
|
|
||||||
GLint ViewportWidth(void)
|
|
||||||
{
|
|
||||||
return viewPortWidth;
|
|
||||||
};
|
|
||||||
GLint ViewportHeight(void)
|
|
||||||
{
|
|
||||||
return viewPortHeight;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglOutputFb
|
* cOglOutputFb
|
||||||
* Output Framebuffer Object - holds Vdpau Output Surface which is our "output framebuffer"
|
* Output Framebuffer Object - holds Vdpau Output Surface which is our "output
|
||||||
|
*framebuffer"
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglOutputFb:public cOglFb
|
class cOglOutputFb : public cOglFb {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
bool initiated;
|
bool initiated;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLvdpauSurfaceNV surface;
|
GLvdpauSurfaceNV surface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint fb;
|
GLuint fb;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
@ -270,18 +211,9 @@ class cOglOutputFb:public cOglFb
|
|||||||
* cOglVb
|
* cOglVb
|
||||||
* Vertex Buffer - OpenGl Vertices for the different drawing commands
|
* Vertex Buffer - OpenGl Vertices for the different drawing commands
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
enum eVertexBufferType
|
enum eVertexBufferType { vbRect, vbEllipse, vbSlope, vbTexture, vbText, vbCount };
|
||||||
{
|
|
||||||
vbRect,
|
|
||||||
vbEllipse,
|
|
||||||
vbSlope,
|
|
||||||
vbTexture,
|
|
||||||
vbText,
|
|
||||||
vbCount
|
|
||||||
};
|
|
||||||
|
|
||||||
class cOglVb
|
class cOglVb {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
eVertexBufferType type;
|
eVertexBufferType type;
|
||||||
eShaderType shader;
|
eShaderType shader;
|
||||||
@ -291,6 +223,7 @@ class cOglVb
|
|||||||
int sizeVertex2;
|
int sizeVertex2;
|
||||||
int numVertices;
|
int numVertices;
|
||||||
GLuint drawMode;
|
GLuint drawMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglVb(int type);
|
cOglVb(int type);
|
||||||
virtual ~cOglVb(void);
|
virtual ~cOglVb(void);
|
||||||
@ -310,141 +243,99 @@ class cOglVb
|
|||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOpenGLCmd
|
* cOpenGLCmd
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglCmd
|
class cOglCmd {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
cOglFb *fb;
|
cOglFb *fb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmd(cOglFb * fb)
|
cOglCmd(cOglFb *fb) { this->fb = fb; };
|
||||||
{
|
virtual ~cOglCmd(void){};
|
||||||
this->fb = fb;
|
|
||||||
};
|
|
||||||
virtual ~ cOglCmd(void)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
virtual const char *Description(void) = 0;
|
virtual const char *Description(void) = 0;
|
||||||
virtual bool Execute(void) = 0;
|
virtual bool Execute(void) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdInitOutputFb:public cOglCmd
|
class cOglCmdInitOutputFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglOutputFb *oFb;
|
cOglOutputFb *oFb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdInitOutputFb(cOglOutputFb *oFb);
|
cOglCmdInitOutputFb(cOglOutputFb *oFb);
|
||||||
virtual ~ cOglCmdInitOutputFb(void)
|
virtual ~cOglCmdInitOutputFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "InitOutputFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "InitOutputFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdInitFb:public cOglCmd
|
class cOglCmdInitFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL);
|
cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL);
|
||||||
virtual ~ cOglCmdInitFb(void)
|
virtual ~cOglCmdInitFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "InitFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "InitFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDeleteFb:public cOglCmd
|
class cOglCmdDeleteFb : public cOglCmd {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDeleteFb(cOglFb *fb);
|
cOglCmdDeleteFb(cOglFb *fb);
|
||||||
virtual ~ cOglCmdDeleteFb(void)
|
virtual ~cOglCmdDeleteFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DeleteFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DeleteFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdRenderFbToBufferFb:public cOglCmd
|
class cOglCmdRenderFbToBufferFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *buffer;
|
cOglFb *buffer;
|
||||||
GLfloat x, y;
|
GLfloat x, y;
|
||||||
GLfloat drawPortX, drawPortY;
|
GLfloat drawPortX, drawPortY;
|
||||||
GLint transparency;
|
GLint transparency;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX,
|
cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX,
|
||||||
GLint drawPortY);
|
GLint drawPortY);
|
||||||
virtual ~ cOglCmdRenderFbToBufferFb(void)
|
virtual ~cOglCmdRenderFbToBufferFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Render Framebuffer to Buffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Render Framebuffer to Buffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdCopyBufferToOutputFb:public cOglCmd
|
class cOglCmdCopyBufferToOutputFb : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglOutputFb *oFb;
|
cOglOutputFb *oFb;
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y);
|
cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y);
|
||||||
virtual ~ cOglCmdCopyBufferToOutputFb(void)
|
virtual ~cOglCmdCopyBufferToOutputFb(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Copy buffer to OutputFramebuffer"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Copy buffer to OutputFramebuffer";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdFill:public cOglCmd
|
class cOglCmdFill : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint color;
|
GLint color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdFill(cOglFb *fb, GLint color);
|
cOglCmdFill(cOglFb *fb, GLint color);
|
||||||
virtual ~ cOglCmdFill(void)
|
virtual ~cOglCmdFill(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Fill"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Fill";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawRectangle:public cOglCmd
|
class cOglCmdDrawRectangle : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint color;
|
GLint color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color);
|
cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color);
|
||||||
virtual ~ cOglCmdDrawRectangle(void)
|
virtual ~cOglCmdDrawRectangle(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawRectangle"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawRectangle";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawEllipse:public cOglCmd
|
class cOglCmdDrawEllipse : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
@ -453,39 +344,29 @@ class cOglCmdDrawEllipse:public cOglCmd
|
|||||||
GLfloat *CreateVerticesFull(int &numVertices);
|
GLfloat *CreateVerticesFull(int &numVertices);
|
||||||
GLfloat *CreateVerticesQuadrant(int &numVertices);
|
GLfloat *CreateVerticesQuadrant(int &numVertices);
|
||||||
GLfloat *CreateVerticesHalf(int &numVertices);
|
GLfloat *CreateVerticesHalf(int &numVertices);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants);
|
cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants);
|
||||||
virtual ~ cOglCmdDrawEllipse(void)
|
virtual ~cOglCmdDrawEllipse(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawEllipse"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawEllipse";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawSlope:public cOglCmd
|
class cOglCmdDrawSlope : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint width, height;
|
GLint width, height;
|
||||||
GLint color;
|
GLint color;
|
||||||
GLint type;
|
GLint type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type);
|
cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type);
|
||||||
virtual ~ cOglCmdDrawSlope(void)
|
virtual ~cOglCmdDrawSlope(void){};
|
||||||
{
|
virtual const char *Description(void) { return "DrawSlope"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "DrawSlope";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawText:public cOglCmd
|
class cOglCmdDrawText : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
GLint limitX;
|
GLint limitX;
|
||||||
@ -493,81 +374,63 @@ class cOglCmdDrawText:public cOglCmd
|
|||||||
cString fontName;
|
cString fontName;
|
||||||
int fontSize;
|
int fontSize;
|
||||||
unsigned int *symbols;
|
unsigned int *symbols;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawText(cOglFb * fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name,
|
cOglCmdDrawText(cOglFb *fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, int fontSize,
|
||||||
int fontSize, tColor colorText);
|
tColor colorText);
|
||||||
virtual ~cOglCmdDrawText(void);
|
virtual ~cOglCmdDrawText(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "DrawText"; }
|
||||||
{
|
|
||||||
return "DrawText";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawImage:public cOglCmd
|
class cOglCmdDrawImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
tColor *argb;
|
tColor *argb;
|
||||||
GLint x, y, width, height;
|
GLint x, y, width, height;
|
||||||
bool overlay;
|
bool overlay;
|
||||||
GLfloat scaleX, scaleY;
|
GLfloat scaleX, scaleY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawImage(cOglFb * fb, tColor * argb, GLint width, GLint height, GLint x, GLint y, bool overlay =
|
cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint height, GLint x, GLint y, bool overlay = true,
|
||||||
true, double scaleX = 1.0f, double scaleY = 1.0f);
|
double scaleX = 1.0f, double scaleY = 1.0f);
|
||||||
virtual ~cOglCmdDrawImage(void);
|
virtual ~cOglCmdDrawImage(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "Draw Image"; }
|
||||||
{
|
|
||||||
return "Draw Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDrawTexture:public cOglCmd
|
class cOglCmdDrawTexture : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y);
|
cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y);
|
||||||
virtual ~ cOglCmdDrawTexture(void)
|
virtual ~cOglCmdDrawTexture(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Draw Texture"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Draw Texture";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdStoreImage:public cOglCmd
|
class cOglCmdStoreImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
tColor *data;
|
tColor *data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdStoreImage(sOglImage *imageRef, tColor *argb);
|
cOglCmdStoreImage(sOglImage *imageRef, tColor *argb);
|
||||||
virtual ~cOglCmdStoreImage(void);
|
virtual ~cOglCmdStoreImage(void);
|
||||||
virtual const char *Description(void)
|
virtual const char *Description(void) { return "Store Image"; }
|
||||||
{
|
|
||||||
return "Store Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOglCmdDropImage:public cOglCmd
|
class cOglCmdDropImage : public cOglCmd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
sOglImage *imageRef;
|
sOglImage *imageRef;
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait);
|
cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait);
|
||||||
virtual ~ cOglCmdDropImage(void)
|
virtual ~cOglCmdDropImage(void){};
|
||||||
{
|
virtual const char *Description(void) { return "Drop Image"; }
|
||||||
};
|
|
||||||
virtual const char *Description(void)
|
|
||||||
{
|
|
||||||
return "Drop Image";
|
|
||||||
}
|
|
||||||
virtual bool Execute(void);
|
virtual bool Execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -577,8 +440,7 @@ class cOglCmdDropImage:public cOglCmd
|
|||||||
#define OGL_MAX_OSDIMAGES 256
|
#define OGL_MAX_OSDIMAGES 256
|
||||||
#define OGL_CMDQUEUE_SIZE 100
|
#define OGL_CMDQUEUE_SIZE 100
|
||||||
|
|
||||||
class cOglThread:public cThread
|
class cOglThread : public cThread {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cCondWait *startWait;
|
cCondWait *startWait;
|
||||||
cCondWait *wait;
|
cCondWait *wait;
|
||||||
@ -597,8 +459,10 @@ class cOglThread:public cThread
|
|||||||
void Cleanup(void);
|
void Cleanup(void);
|
||||||
int GetFreeSlot(void);
|
int GetFreeSlot(void);
|
||||||
void ClearSlot(int slot);
|
void ClearSlot(int slot);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglThread(cCondWait *startWait, int maxCacheSize);
|
cOglThread(cCondWait *startWait, int maxCacheSize);
|
||||||
virtual ~cOglThread();
|
virtual ~cOglThread();
|
||||||
@ -607,44 +471,27 @@ class cOglThread:public cThread
|
|||||||
int StoreImage(const cImage &image);
|
int StoreImage(const cImage &image);
|
||||||
void DropImageData(int imageHandle);
|
void DropImageData(int imageHandle);
|
||||||
sOglImage *GetImageRef(int slot);
|
sOglImage *GetImageRef(int slot);
|
||||||
int MaxTextureSize(void)
|
int MaxTextureSize(void) { return maxTextureSize; };
|
||||||
{
|
|
||||||
return maxTextureSize;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* cOglPixmap
|
* cOglPixmap
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
class cOglPixmap:public cPixmap
|
class cOglPixmap : public cPixmap {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *fb;
|
cOglFb *fb;
|
||||||
std::shared_ptr<cOglThread> oglThread;
|
std::shared_ptr<cOglThread> oglThread;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cOglPixmap(std::shared_ptr < cOglThread > oglThread, int Layer, const cRect & ViewPort, const cRect & DrawPort =
|
cOglPixmap(std::shared_ptr<cOglThread> oglThread, int Layer, const cRect &ViewPort,
|
||||||
cRect::Null);
|
const cRect &DrawPort = cRect::Null);
|
||||||
virtual ~cOglPixmap(void);
|
virtual ~cOglPixmap(void);
|
||||||
cOglFb *Fb(void)
|
cOglFb *Fb(void) { return fb; };
|
||||||
{
|
int X(void) { return ViewPort().X(); };
|
||||||
return fb;
|
int Y(void) { return ViewPort().Y(); };
|
||||||
};
|
virtual bool IsDirty(void) { return dirty; }
|
||||||
int X(void)
|
virtual void SetDirty(bool dirty = true) { this->dirty = dirty; }
|
||||||
{
|
|
||||||
return ViewPort().X();
|
|
||||||
};
|
|
||||||
int Y(void)
|
|
||||||
{
|
|
||||||
return ViewPort().Y();
|
|
||||||
};
|
|
||||||
virtual bool IsDirty(void)
|
|
||||||
{
|
|
||||||
return dirty;
|
|
||||||
}
|
|
||||||
virtual void SetDirty(bool dirty = true) {
|
|
||||||
this->dirty = dirty;
|
|
||||||
}
|
|
||||||
virtual void SetAlpha(int Alpha);
|
virtual void SetAlpha(int Alpha);
|
||||||
virtual void SetTile(bool Tile);
|
virtual void SetTile(bool Tile);
|
||||||
virtual void SetViewPort(const cRect &Rect);
|
virtual void SetViewPort(const cRect &Rect);
|
||||||
@ -654,8 +501,8 @@ class cOglPixmap:public cPixmap
|
|||||||
virtual void DrawImage(const cPoint &Point, const cImage &Image);
|
virtual void DrawImage(const cPoint &Point, const cImage &Image);
|
||||||
virtual void DrawImage(const cPoint &Point, int ImageHandle);
|
virtual void DrawImage(const cPoint &Point, int ImageHandle);
|
||||||
virtual void DrawPixel(const cPoint &Point, tColor Color);
|
virtual void DrawPixel(const cPoint &Point, tColor Color);
|
||||||
virtual void DrawBitmap(const cPoint & Point, const cBitmap & Bitmap, tColor ColorFg = 0, tColor ColorBg =
|
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0,
|
||||||
0, bool Overlay = false);
|
bool Overlay = false);
|
||||||
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
|
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
|
||||||
int Width = 0, int Height = 0, int Alignment = taDefault);
|
int Width = 0, int Height = 0, int Alignment = taDefault);
|
||||||
virtual void DrawRectangle(const cRect &Rect, tColor Color);
|
virtual void DrawRectangle(const cRect &Rect, tColor Color);
|
||||||
@ -670,13 +517,13 @@ class cOglPixmap:public cPixmap
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* cOglOsd
|
* cOglOsd
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
class cOglOsd:public cOsd
|
class cOglOsd : public cOsd {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
cOglFb *bFb;
|
cOglFb *bFb;
|
||||||
std::shared_ptr<cOglThread> oglThread;
|
std::shared_ptr<cOglThread> oglThread;
|
||||||
cVector<cOglPixmap *> oglPixmaps;
|
cVector<cOglPixmap *> oglPixmaps;
|
||||||
bool isSubtitleOsd;
|
bool isSubtitleOsd;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread);
|
cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread);
|
||||||
|
111
po/de_DE.po
111
po/de_DE.po
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: VDR \n"
|
"Project-Id-Version: VDR \n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2020-04-15 18:57+0200\n"
|
"POT-Creation-Date: 2021-12-30 10:23+0100\n"
|
||||||
"PO-Revision-Date: blabla\n"
|
"PO-Revision-Date: blabla\n"
|
||||||
"Last-Translator: blabla\n"
|
"Last-Translator: blabla\n"
|
||||||
"Language-Team: blabla\n"
|
"Language-Team: blabla\n"
|
||||||
@ -140,91 +140,6 @@ msgstr ""
|
|||||||
msgid "snd_pcm_drop(): %s\n"
|
msgid "snd_pcm_drop(): %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_GETOSPACE): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: write error: %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: error not all bytes written\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: error poll %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: using %sdevice '%s'\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: can't open dsp device '%s': %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(MIXER_WRITE): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: can't open mixer device '%s': %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SOUND_MIXER_READ_DEVMASK): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: channel '%s' not supported\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: channel '%s' not found\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: should not happen\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_GETODELAY): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_SETFMT): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "audio/oss: device doesn't support 16 bit sample format.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_CHANNELS): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: device doesn't support %d channels.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_SPEED): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: device doesn't support %dHz sample rate.\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: ioctl(SNDCTL_DSP_POLICY): %s\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "audio/oss: delay %ums\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "audio: can't set channels %d sample-rate %dHz\n"
|
msgid "audio: can't set channels %d sample-rate %dHz\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -306,9 +221,6 @@ msgstr ""
|
|||||||
msgid "codec/audio: can't setup resample\n"
|
msgid "codec/audio: can't setup resample\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "codec/audio: can't open resample\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "A software and GPU emulated UHD device"
|
msgid "A software and GPU emulated UHD device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -408,7 +320,7 @@ msgstr ""
|
|||||||
msgid "Hue (-314..314) "
|
msgid "Hue (-314..314) "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Monitor Colorspace"
|
msgid "Temperature 6500K + x * 100K"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Color Blindness"
|
msgid "Color Blindness"
|
||||||
@ -417,6 +329,9 @@ msgstr ""
|
|||||||
msgid "Color Correction (-100..100) "
|
msgid "Color Correction (-100..100) "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Monitor Type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Scaling"
|
msgid "Scaling"
|
||||||
msgstr "Skalierung"
|
msgstr "Skalierung"
|
||||||
|
|
||||||
@ -574,15 +489,15 @@ msgstr ""
|
|||||||
msgid "Suspend SoftHdDevice"
|
msgid "Suspend SoftHdDevice"
|
||||||
msgstr "Unterbreche SoftHdDevice"
|
msgstr "Unterbreche SoftHdDevice"
|
||||||
|
|
||||||
|
msgid "Toggle LUT on/off"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "PIP toggle on/off: off"
|
msgid "PIP toggle on/off: off"
|
||||||
msgstr "PIP deaktivieren"
|
msgstr "PIP deaktivieren"
|
||||||
|
|
||||||
msgid "PIP toggle on/off: on"
|
msgid "PIP toggle on/off: on"
|
||||||
msgstr "PIP aktivieren"
|
msgstr "PIP aktivieren"
|
||||||
|
|
||||||
msgid "PIP zapmode (not working)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "PIP channel +"
|
msgid "PIP channel +"
|
||||||
msgstr "PIP Kanal +"
|
msgstr "PIP Kanal +"
|
||||||
|
|
||||||
@ -715,6 +630,10 @@ msgstr ""
|
|||||||
msgid "[softhddev] no codec known for still picture\n"
|
msgid "[softhddev] no codec known for still picture\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, c-format
|
||||||
|
msgid "Too much shaders definded\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"
|
msgid "Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -884,6 +803,9 @@ msgstr ""
|
|||||||
msgid "Failed initializing libplacebo\n"
|
msgid "Failed initializing libplacebo\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Failed to create placebo opengl \n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Failed to create XCB Surface\n"
|
msgid "Failed to create XCB Surface\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -893,6 +815,9 @@ msgstr ""
|
|||||||
msgid "Failed creating vulkan swapchain!"
|
msgid "Failed creating vulkan swapchain!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "libplacebo: failed initializing swapchain\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Failed initializing libplacebo renderer\n"
|
msgid "Failed initializing libplacebo renderer\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
40
ringbuffer.c
40
ringbuffer.c
@ -34,8 +34,7 @@
|
|||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
/// ring buffer structure
|
/// ring buffer structure
|
||||||
struct _ring_buffer_
|
struct _ring_buffer_ {
|
||||||
{
|
|
||||||
char *Buffer; ///< ring buffer data
|
char *Buffer; ///< ring buffer data
|
||||||
const char *BufferEnd; ///< end of buffer
|
const char *BufferEnd; ///< end of buffer
|
||||||
size_t Size; ///< bytes in buffer (for faster calc)
|
size_t Size; ///< bytes in buffer (for faster calc)
|
||||||
@ -52,8 +51,7 @@ struct _ring_buffer_
|
|||||||
**
|
**
|
||||||
** @param rb Ring buffer to reset read/write pointers.
|
** @param rb Ring buffer to reset read/write pointers.
|
||||||
*/
|
*/
|
||||||
void RingBufferReset(RingBuffer * rb)
|
void RingBufferReset(RingBuffer *rb) {
|
||||||
{
|
|
||||||
rb->ReadPointer = rb->Buffer;
|
rb->ReadPointer = rb->Buffer;
|
||||||
rb->WritePointer = rb->Buffer;
|
rb->WritePointer = rb->Buffer;
|
||||||
atomic_set(&rb->Filled, 0);
|
atomic_set(&rb->Filled, 0);
|
||||||
@ -67,8 +65,7 @@ void RingBufferReset(RingBuffer * rb)
|
|||||||
** @returns Allocated ring buffer, must be freed with
|
** @returns Allocated ring buffer, must be freed with
|
||||||
** RingBufferDel(), NULL for out of memory.
|
** RingBufferDel(), NULL for out of memory.
|
||||||
*/
|
*/
|
||||||
RingBuffer *RingBufferNew(size_t size)
|
RingBuffer *RingBufferNew(size_t size) {
|
||||||
{
|
|
||||||
RingBuffer *rb;
|
RingBuffer *rb;
|
||||||
|
|
||||||
if (!(rb = malloc(sizeof(*rb)))) { // allocate structure
|
if (!(rb = malloc(sizeof(*rb)))) { // allocate structure
|
||||||
@ -89,8 +86,7 @@ RingBuffer *RingBufferNew(size_t size)
|
|||||||
/**
|
/**
|
||||||
** Free an allocated ring buffer.
|
** Free an allocated ring buffer.
|
||||||
*/
|
*/
|
||||||
void RingBufferDel(RingBuffer * rb)
|
void RingBufferDel(RingBuffer *rb) {
|
||||||
{
|
|
||||||
free(rb->Buffer);
|
free(rb->Buffer);
|
||||||
free(rb);
|
free(rb);
|
||||||
}
|
}
|
||||||
@ -103,8 +99,7 @@ void RingBufferDel(RingBuffer * rb)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferWriteAdvance(RingBuffer * rb, size_t cnt)
|
size_t RingBufferWriteAdvance(RingBuffer *rb, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = rb->Size - atomic_read(&rb->Filled);
|
n = rb->Size - atomic_read(&rb->Filled);
|
||||||
@ -142,8 +137,7 @@ size_t RingBufferWriteAdvance(RingBuffer * rb, size_t cnt)
|
|||||||
** @returns The number of bytes that could be placed in the ring
|
** @returns The number of bytes that could be placed in the ring
|
||||||
** buffer.
|
** buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferWrite(RingBuffer * rb, const void *buf, size_t cnt)
|
size_t RingBufferWrite(RingBuffer *rb, const void *buf, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = rb->Size - atomic_read(&rb->Filled);
|
n = rb->Size - atomic_read(&rb->Filled);
|
||||||
@ -184,8 +178,7 @@ size_t RingBufferWrite(RingBuffer * rb, const void *buf, size_t cnt)
|
|||||||
** @returns The number of bytes that could be placed in the ring
|
** @returns The number of bytes that could be placed in the ring
|
||||||
** buffer at the write pointer.
|
** buffer at the write pointer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp)
|
size_t RingBufferGetWritePointer(RingBuffer *rb, void **wp) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
|
||||||
@ -212,8 +205,7 @@ size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferReadAdvance(RingBuffer * rb, size_t cnt)
|
size_t RingBufferReadAdvance(RingBuffer *rb, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = atomic_read(&rb->Filled);
|
n = atomic_read(&rb->Filled);
|
||||||
@ -250,8 +242,7 @@ size_t RingBufferReadAdvance(RingBuffer * rb, size_t cnt)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes that could be read from ring buffer.
|
** @returns Number of bytes that could be read from ring buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferRead(RingBuffer * rb, void *buf, size_t cnt)
|
size_t RingBufferRead(RingBuffer *rb, void *buf, size_t cnt) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = atomic_read(&rb->Filled);
|
n = atomic_read(&rb->Filled);
|
||||||
@ -292,8 +283,7 @@ size_t RingBufferRead(RingBuffer * rb, void *buf, size_t cnt)
|
|||||||
** @returns The number of bytes that could be read from the ring
|
** @returns The number of bytes that could be read from the ring
|
||||||
** buffer at the read pointer.
|
** buffer at the read pointer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferGetReadPointer(RingBuffer * rb, const void **rp)
|
size_t RingBufferGetReadPointer(RingBuffer *rb, const void **rp) {
|
||||||
{
|
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
|
||||||
@ -319,10 +309,7 @@ size_t RingBufferGetReadPointer(RingBuffer * rb, const void **rp)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes free in buffer.
|
** @returns Number of bytes free in buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferFreeBytes(RingBuffer * rb)
|
size_t RingBufferFreeBytes(RingBuffer *rb) { return rb->Size - atomic_read(&rb->Filled); }
|
||||||
{
|
|
||||||
return rb->Size - atomic_read(&rb->Filled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Get used bytes in ring buffer.
|
** Get used bytes in ring buffer.
|
||||||
@ -331,7 +318,4 @@ size_t RingBufferFreeBytes(RingBuffer * rb)
|
|||||||
**
|
**
|
||||||
** @returns Number of bytes used in buffer.
|
** @returns Number of bytes used in buffer.
|
||||||
*/
|
*/
|
||||||
size_t RingBufferUsedBytes(RingBuffer * rb)
|
size_t RingBufferUsedBytes(RingBuffer *rb) { return atomic_read(&rb->Filled); }
|
||||||
{
|
|
||||||
return atomic_read(&rb->Filled);
|
|
||||||
}
|
|
||||||
|
123
shaders.h
123
shaders.h
@ -24,65 +24,47 @@ const char *gl_version = "#version 300 es ";
|
|||||||
* is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector.
|
* is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector.
|
||||||
* The matrix might also be used for other conversions and colorspaces.
|
* The matrix might also be used for other conversions and colorspaces.
|
||||||
*/
|
*/
|
||||||
struct mp_cmat
|
struct mp_cmat {
|
||||||
{
|
|
||||||
GLfloat m[3][3]; // colormatrix
|
GLfloat m[3][3]; // colormatrix
|
||||||
GLfloat c[3]; // colormatrix_c
|
GLfloat c[3]; // colormatrix_c
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mp_mat
|
struct mp_mat {
|
||||||
{
|
|
||||||
GLfloat m[3][3];
|
GLfloat m[3][3];
|
||||||
};
|
};
|
||||||
|
|
||||||
// YUV input limited range (16-235 for luma, 16-240 for chroma)
|
// YUV input limited range (16-235 for luma, 16-240 for chroma)
|
||||||
// ITU-R BT.601 (SD)
|
// ITU-R BT.601 (SD)
|
||||||
struct mp_cmat yuv_bt601 = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt601 = {
|
||||||
{0.00000, -0.391762, 2.017232},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.391762, 2.017232}, {1.596027, -0.812968, 0.000000}},
|
||||||
{1.596027, -0.812968, 0.000000}},
|
{-0.874202, 0.531668, -1.085631}};
|
||||||
{-0.874202, 0.531668, -1.085631}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.709 (HD)
|
// ITU-R BT.709 (HD)
|
||||||
struct mp_cmat yuv_bt709 = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt709 = {
|
||||||
{0.00000, -0.213249, 2.112402},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.213249, 2.112402}, {1.792741, -0.532909, 0.000000}},
|
||||||
{1.792741, -0.532909, 0.000000}},
|
{-0.972945, 0.301483, -1.133402}};
|
||||||
{-0.972945, 0.301483, -1.133402}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.2020 non-constant luminance system
|
// ITU-R BT.2020 non-constant luminance system
|
||||||
struct mp_cmat yuv_bt2020ncl = { {{1.164384, 1.164384, 1.164384},
|
struct mp_cmat yuv_bt2020ncl = {
|
||||||
{0.00000, -0.187326, 2.141772},
|
{{1.164384, 1.164384, 1.164384}, {0.00000, -0.187326, 2.141772}, {1.678674, -0.650424, 0.000000}},
|
||||||
{1.678674, -0.650424, 0.000000}},
|
{-0.915688, 0.347459, -1.148145}};
|
||||||
{-0.915688, 0.347459, -1.148145}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ITU-R BT.2020 constant luminance system
|
// ITU-R BT.2020 constant luminance system
|
||||||
struct mp_cmat yuv_bt2020cl = { {{0.0000, 1.164384, 0.000000},
|
struct mp_cmat yuv_bt2020cl = {
|
||||||
{0.00000, 0.000000, 1.138393},
|
{{0.0000, 1.164384, 0.000000}, {0.00000, 0.000000, 1.138393}, {1.138393, 0.000000, 0.000000}},
|
||||||
{1.138393, 0.000000, 0.000000}},
|
{-0.571429, -0.073059, -0.571429}};
|
||||||
{-0.571429, -0.073059, -0.571429}
|
|
||||||
};
|
|
||||||
|
|
||||||
float cms_matrix[3][3] = { {1.660497, -0.124547, -0.018154},
|
float cms_matrix[3][3] = {
|
||||||
{-0.587657, 1.132895, -0.100597},
|
{1.660497, -0.124547, -0.018154}, {-0.587657, 1.132895, -0.100597}, {-0.072840, -0.008348, 1.118751}};
|
||||||
{-0.072840, -0.008348, 1.118751}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Common constants for SMPTE ST.2084 (PQ)
|
// Common constants for SMPTE ST.2084 (PQ)
|
||||||
static const float PQ_M1 = 2610. / 4096 * 1. / 4,
|
static const float PQ_M1 = 2610. / 4096 * 1. / 4, PQ_M2 = 2523. / 4096 * 128, PQ_C1 = 3424. / 4096,
|
||||||
PQ_M2 = 2523. / 4096 * 128,
|
PQ_C2 = 2413. / 4096 * 32, PQ_C3 = 2392. / 4096 * 32;
|
||||||
PQ_C1 = 3424. / 4096,
|
|
||||||
PQ_C2 = 2413. / 4096 * 32,
|
|
||||||
PQ_C3 = 2392. / 4096 * 32;
|
|
||||||
|
|
||||||
// Common constants for ARIB STD-B67 (HLG)
|
// Common constants for ARIB STD-B67 (HLG)
|
||||||
static const float HLG_A = 0.17883277,
|
static const float HLG_A = 0.17883277, HLG_B = 0.28466892, HLG_C = 0.55991073;
|
||||||
HLG_B = 0.28466892,
|
|
||||||
HLG_C = 0.55991073;
|
|
||||||
|
|
||||||
struct gl_vao_entry
|
struct gl_vao_entry {
|
||||||
{
|
|
||||||
// used for shader / glBindAttribLocation
|
// used for shader / glBindAttribLocation
|
||||||
const char *name;
|
const char *name;
|
||||||
// glVertexAttribPointer() arguments
|
// glVertexAttribPointer() arguments
|
||||||
@ -92,20 +74,17 @@ struct gl_vao_entry
|
|||||||
int offset;
|
int offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex_pt
|
struct vertex_pt {
|
||||||
{
|
|
||||||
float x, y;
|
float x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex_pi
|
struct vertex_pi {
|
||||||
{
|
|
||||||
GLint x, y;
|
GLint x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXUNIT_VIDEO_NUM 6
|
#define TEXUNIT_VIDEO_NUM 6
|
||||||
|
|
||||||
struct vertex
|
struct vertex {
|
||||||
{
|
|
||||||
struct vertex_pt position;
|
struct vertex_pt position;
|
||||||
struct vertex_pt texcoord[TEXUNIT_VIDEO_NUM];
|
struct vertex_pt texcoord[TEXUNIT_VIDEO_NUM];
|
||||||
};
|
};
|
||||||
@ -114,8 +93,7 @@ static const struct gl_vao_entry vertex_vao[] = {
|
|||||||
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
|
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
|
||||||
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
|
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
|
||||||
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
|
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
|
||||||
{0}
|
{0}};
|
||||||
};
|
|
||||||
|
|
||||||
#define GLSL(...) pl_shader_append(__VA_ARGS__)
|
#define GLSL(...) pl_shader_append(__VA_ARGS__)
|
||||||
#define GLSLV(...) pl_shader_append_v(__VA_ARGS__)
|
#define GLSLV(...) pl_shader_append_v(__VA_ARGS__)
|
||||||
@ -123,18 +101,11 @@ static const struct gl_vao_entry vertex_vao[] = {
|
|||||||
char sh[SHADER_LENGTH];
|
char sh[SHADER_LENGTH];
|
||||||
char shv[SHADER_LENGTH];
|
char shv[SHADER_LENGTH];
|
||||||
|
|
||||||
void GL_init()
|
void GL_init() { sh[0] = 0; }
|
||||||
{
|
|
||||||
sh[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLV_init()
|
void GLV_init() { shv[0] = 0; }
|
||||||
{
|
|
||||||
shv[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pl_shader_append(const char *fmt, ...)
|
void pl_shader_append(const char *fmt, ...) {
|
||||||
{
|
|
||||||
char temp[1000];
|
char temp[1000];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@ -145,11 +116,9 @@ void pl_shader_append(const char *fmt, ...)
|
|||||||
if (strlen(sh) + strlen(temp) > SHADER_LENGTH)
|
if (strlen(sh) + strlen(temp) > SHADER_LENGTH)
|
||||||
Fatal(_("Shaderlenght fault\n"));
|
Fatal(_("Shaderlenght fault\n"));
|
||||||
strcat(sh, temp);
|
strcat(sh, temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pl_shader_append_v(const char *fmt, ...)
|
void pl_shader_append_v(const char *fmt, ...) {
|
||||||
{
|
|
||||||
char temp[1000];
|
char temp[1000];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@ -160,11 +129,9 @@ void pl_shader_append_v(const char *fmt, ...)
|
|||||||
if (strlen(shv) + strlen(temp) > SHADER_LENGTH)
|
if (strlen(shv) + strlen(temp) > SHADER_LENGTH)
|
||||||
Fatal(_("Shaderlenght fault\n"));
|
Fatal(_("Shaderlenght fault\n"));
|
||||||
strcat(shv, temp);
|
strcat(shv, temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compile_attach_shader(GLuint program, GLenum type, const char *source)
|
static void compile_attach_shader(GLuint program, GLenum type, const char *source) {
|
||||||
{
|
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
GLint status = 1234, log_length;
|
GLint status = 1234, log_length;
|
||||||
char log[4000];
|
char log[4000];
|
||||||
@ -183,11 +150,9 @@ static void compile_attach_shader(GLuint program, GLenum type, const char *sourc
|
|||||||
|
|
||||||
glAttachShader(program, shader);
|
glAttachShader(program, shader);
|
||||||
glDeleteShader(shader);
|
glDeleteShader(shader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void link_shader(GLuint program)
|
static void link_shader(GLuint program) {
|
||||||
{
|
|
||||||
GLint status, log_length;
|
GLint status, log_length;
|
||||||
|
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
@ -198,8 +163,7 @@ static void link_shader(GLuint program)
|
|||||||
Debug(3, "Link Status %d loglen %d\n", status, log_length);
|
Debug(3, "Link Status %d loglen %d\n", status, log_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint sc_generate_osd(GLuint gl_prog)
|
static GLuint sc_generate_osd(GLuint gl_prog) {
|
||||||
{
|
|
||||||
|
|
||||||
Debug(3, "vor create osd\n");
|
Debug(3, "vor create osd\n");
|
||||||
gl_prog = glCreateProgram();
|
gl_prog = glCreateProgram();
|
||||||
@ -243,8 +207,7 @@ static GLuint sc_generate_osd(GLuint gl_prog)
|
|||||||
return gl_prog;
|
return gl_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) {
|
||||||
{
|
|
||||||
|
|
||||||
char vname[80];
|
char vname[80];
|
||||||
int n;
|
int n;
|
||||||
@ -333,15 +296,20 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n");
|
GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n");
|
||||||
}
|
}
|
||||||
GLSL("// color conversion\n");
|
GLSL("// color conversion\n");
|
||||||
GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n");
|
GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; "
|
||||||
|
"\n");
|
||||||
GLSL("color.a = 1.0; \n");
|
GLSL("color.a = 1.0; \n");
|
||||||
|
|
||||||
GLSL("// pl_shader_linearize \n");
|
GLSL("// pl_shader_linearize \n");
|
||||||
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
||||||
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
||||||
// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n");
|
// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n");
|
||||||
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f) , bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
|
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb -
|
||||||
GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\n");
|
// vec3(%f)) * vec3(1.0/%f)) + vec3(%f) ,
|
||||||
|
// bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
|
||||||
|
GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - "
|
||||||
|
"vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), "
|
||||||
|
"bvec3(lessThan(vec3(0.5), color.rgb)));\n");
|
||||||
GLSL("color.rgb *= vec3(1.0/3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
|
GLSL("color.rgb *= vec3(1.0/3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
|
||||||
GLSL("// color mapping \n");
|
GLSL("// color mapping \n");
|
||||||
GLSL("color.rgb = cms_matrix * color.rgb; \n");
|
GLSL("color.rgb = cms_matrix * color.rgb; \n");
|
||||||
@ -351,7 +319,9 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
|
||||||
// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n");
|
// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n");
|
||||||
GLSL("color.rgb *= vec3(3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
|
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");
|
GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * "
|
||||||
|
"log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), "
|
||||||
|
"bvec3(lessThan(vec3(1.0), color.rgb))); \n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
GLSL("out_color = color; \n");
|
GLSL("out_color = color; \n");
|
||||||
@ -375,7 +345,9 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
#ifndef GAMMA
|
#ifndef GAMMA
|
||||||
GLSL("// delinearize gamma to sRGB \n");
|
GLSL("// delinearize gamma to sRGB \n");
|
||||||
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
GLSL("color.rgb = max(color.rgb, 0.0); \n");
|
||||||
GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n");
|
GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * "
|
||||||
|
"pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), "
|
||||||
|
"bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n");
|
||||||
#endif
|
#endif
|
||||||
GLSL("// color mapping \n");
|
GLSL("// color mapping \n");
|
||||||
GLSL("out_color = color; \n");
|
GLSL("out_color = color; \n");
|
||||||
@ -416,8 +388,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
|
|||||||
return gl_prog;
|
return gl_prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_pass_quad(int flip, float xcrop, float ycrop)
|
static void render_pass_quad(int flip, float xcrop, float ycrop) {
|
||||||
{
|
|
||||||
struct vertex va[4];
|
struct vertex va[4];
|
||||||
int n;
|
int n;
|
||||||
const struct gl_vao_entry *e;
|
const struct gl_vao_entry *e;
|
||||||
|
643
softhdcuvid.cpp
643
softhdcuvid.cpp
File diff suppressed because it is too large
Load Diff
373
softhddev.c
373
softhddev.c
@ -24,19 +24,19 @@
|
|||||||
#define noUSE_PIP ///< include PIP support + new API
|
#define noUSE_PIP ///< include PIP support + new API
|
||||||
#define noDUMP_TRICKSPEED ///< dump raw trickspeed packets
|
#define noDUMP_TRICKSPEED ///< dump raw trickspeed packets
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#define _(str) gettext(str) ///< gettext shortcut
|
#define _(str) gettext(str) ///< gettext shortcut
|
||||||
@ -54,9 +54,11 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "softhddev.h"
|
#include "softhddev.h"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int DumpH264(const uint8_t *data, int size);
|
static int DumpH264(const uint8_t *data, int size);
|
||||||
@ -108,32 +110,26 @@ int AudioDelay = 0;
|
|||||||
static const uint16_t BitRateTable[2][4][16] = {
|
static const uint16_t BitRateTable[2][4][16] = {
|
||||||
// MPEG Version 1
|
// MPEG Version 1
|
||||||
{{},
|
{{},
|
||||||
{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,
|
{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
|
||||||
0},
|
|
||||||
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
|
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
|
||||||
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}},
|
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}},
|
||||||
// MPEG Version 2 & 2.5
|
// MPEG Version 2 & 2.5
|
||||||
{{},
|
{{},
|
||||||
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
|
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
|
||||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
|
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
|
||||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
|
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Mpeg samperate table.
|
/// Mpeg samperate table.
|
||||||
///
|
///
|
||||||
static const uint16_t SampleRateTable[4] = {
|
static const uint16_t SampleRateTable[4] = {44100, 48000, 32000, 0};
|
||||||
44100, 48000, 32000, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Fast check for Mpeg audio.
|
/// Fast check for Mpeg audio.
|
||||||
///
|
///
|
||||||
/// 4 bytes 0xFFExxxxx Mpeg audio
|
/// 4 bytes 0xFFExxxxx Mpeg audio
|
||||||
///
|
///
|
||||||
static inline int FastMpegCheck(const uint8_t * p)
|
static inline int FastMpegCheck(const uint8_t *p) {
|
||||||
{
|
|
||||||
if (p[0] != 0xFF) { // 11bit frame sync
|
if (p[0] != 0xFF) { // 11bit frame sync
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -185,8 +181,7 @@ static inline int FastMpegCheck(const uint8_t * p)
|
|||||||
/// Layer II & III:
|
/// Layer II & III:
|
||||||
/// FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
|
/// FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
|
||||||
///
|
///
|
||||||
static int MpegCheck(const uint8_t * data, int size)
|
static int MpegCheck(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
int mpeg2;
|
int mpeg2;
|
||||||
int mpeg25;
|
int mpeg25;
|
||||||
int layer;
|
int layer;
|
||||||
@ -232,7 +227,10 @@ static int MpegCheck(const uint8_t * data, int size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (0) {
|
if (0) {
|
||||||
Debug(3, "pesdemux: mpeg%s layer%d bitrate=%d samplerate=%d %d bytes\n", mpeg25 ? "2.5" : mpeg2 ? "2" : "1",
|
Debug(3, "pesdemux: mpeg%s layer%d bitrate=%d samplerate=%d %d bytes\n",
|
||||||
|
mpeg25 ? "2.5"
|
||||||
|
: mpeg2 ? "2"
|
||||||
|
: "1",
|
||||||
layer, bit_rate, sample_rate, frame_size);
|
layer, bit_rate, sample_rate, frame_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,8 +250,7 @@ static int MpegCheck(const uint8_t * data, int size)
|
|||||||
///
|
///
|
||||||
/// 3 bytes 0x56Exxx AAC LATM audio
|
/// 3 bytes 0x56Exxx AAC LATM audio
|
||||||
///
|
///
|
||||||
static inline int FastLatmCheck(const uint8_t * p)
|
static inline int FastLatmCheck(const uint8_t *p) {
|
||||||
{
|
|
||||||
if (p[0] != 0x56) { // 11bit sync
|
if (p[0] != 0x56) { // 11bit sync
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -275,8 +272,7 @@ static inline int FastLatmCheck(const uint8_t * p)
|
|||||||
/// @retval 0 no valid AAC LATM audio
|
/// @retval 0 no valid AAC LATM audio
|
||||||
/// @retval >0 valid AAC LATM audio
|
/// @retval >0 valid AAC LATM audio
|
||||||
///
|
///
|
||||||
static int LatmCheck(const uint8_t * data, int size)
|
static int LatmCheck(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
|
||||||
// 13 bit frame size without header
|
// 13 bit frame size without header
|
||||||
@ -300,15 +296,13 @@ static int LatmCheck(const uint8_t * data, int size)
|
|||||||
/// from ATSC A/52 table 5.18 frame size code table.
|
/// from ATSC A/52 table 5.18 frame size code table.
|
||||||
///
|
///
|
||||||
const uint16_t Ac3FrameSizeTable[38][3] = {
|
const uint16_t Ac3FrameSizeTable[38][3] = {
|
||||||
{64, 69, 96}, {64, 70, 96}, {80, 87, 120}, {80, 88, 120},
|
{64, 69, 96}, {64, 70, 96}, {80, 87, 120}, {80, 88, 120}, {96, 104, 144},
|
||||||
{96, 104, 144}, {96, 105, 144}, {112, 121, 168}, {112, 122, 168},
|
{96, 105, 144}, {112, 121, 168}, {112, 122, 168}, {128, 139, 192}, {128, 140, 192},
|
||||||
{128, 139, 192}, {128, 140, 192}, {160, 174, 240}, {160, 175, 240},
|
{160, 174, 240}, {160, 175, 240}, {192, 208, 288}, {192, 209, 288}, {224, 243, 336},
|
||||||
{192, 208, 288}, {192, 209, 288}, {224, 243, 336}, {224, 244, 336},
|
{224, 244, 336}, {256, 278, 384}, {256, 279, 384}, {320, 348, 480}, {320, 349, 480},
|
||||||
{256, 278, 384}, {256, 279, 384}, {320, 348, 480}, {320, 349, 480},
|
{384, 417, 576}, {384, 418, 576}, {448, 487, 672}, {448, 488, 672}, {512, 557, 768},
|
||||||
{384, 417, 576}, {384, 418, 576}, {448, 487, 672}, {448, 488, 672},
|
{512, 558, 768}, {640, 696, 960}, {640, 697, 960}, {768, 835, 1152}, {768, 836, 1152},
|
||||||
{512, 557, 768}, {512, 558, 768}, {640, 696, 960}, {640, 697, 960},
|
{896, 975, 1344}, {896, 976, 1344}, {1024, 1114, 1536}, {1024, 1115, 1536}, {1152, 1253, 1728},
|
||||||
{768, 835, 1152}, {768, 836, 1152}, {896, 975, 1344}, {896, 976, 1344},
|
|
||||||
{1024, 1114, 1536}, {1024, 1115, 1536}, {1152, 1253, 1728},
|
|
||||||
{1152, 1254, 1728}, {1280, 1393, 1920}, {1280, 1394, 1920},
|
{1152, 1254, 1728}, {1280, 1393, 1920}, {1280, 1394, 1920},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -317,8 +311,7 @@ const uint16_t Ac3FrameSizeTable[38][3] = {
|
|||||||
///
|
///
|
||||||
/// 5 bytes 0x0B77xxxxxx AC-3 audio
|
/// 5 bytes 0x0B77xxxxxx AC-3 audio
|
||||||
///
|
///
|
||||||
static inline int FastAc3Check(const uint8_t * p)
|
static inline int FastAc3Check(const uint8_t *p) {
|
||||||
{
|
|
||||||
if (p[0] != 0x0B) { // 16bit sync
|
if (p[0] != 0x0B) { // 16bit sync
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -360,8 +353,7 @@ static inline int FastAc3Check(const uint8_t * p)
|
|||||||
/// o e 2x Framesize code
|
/// o e 2x Framesize code
|
||||||
/// o f 2x Framesize code 2
|
/// o f 2x Framesize code 2
|
||||||
///
|
///
|
||||||
static int Ac3Check(const uint8_t * data, int size)
|
static int Ac3Check(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
|
||||||
if (size < 5) { // need 5 bytes to see if AC-3/E-AC-3
|
if (size < 5) { // need 5 bytes to see if AC-3/E-AC-3
|
||||||
@ -408,8 +400,7 @@ static int Ac3Check(const uint8_t * data, int size)
|
|||||||
///
|
///
|
||||||
/// 7/9 bytes 0xFFFxxxxxxxxxxx(xxxx) ADTS audio
|
/// 7/9 bytes 0xFFFxxxxxxxxxxx(xxxx) ADTS audio
|
||||||
///
|
///
|
||||||
static inline int FastAdtsCheck(const uint8_t * p)
|
static inline int FastAdtsCheck(const uint8_t *p) {
|
||||||
{
|
|
||||||
if (p[0] != 0xFF) { // 12bit sync
|
if (p[0] != 0xFF) { // 12bit sync
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -445,8 +436,7 @@ static inline int FastAdtsCheck(const uint8_t * p)
|
|||||||
/// o ..
|
/// o ..
|
||||||
/// o M*13 frame length
|
/// o M*13 frame length
|
||||||
///
|
///
|
||||||
static int AdtsCheck(const uint8_t * data, int size)
|
static int AdtsCheck(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
|
||||||
if (size < 6) {
|
if (size < 6) {
|
||||||
@ -475,8 +465,7 @@ static int AdtsCheck(const uint8_t * data, int size)
|
|||||||
///
|
///
|
||||||
/// PES type.
|
/// PES type.
|
||||||
///
|
///
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
PES_PROG_STREAM_MAP = 0xBC,
|
PES_PROG_STREAM_MAP = 0xBC,
|
||||||
PES_PRIVATE_STREAM1 = 0xBD,
|
PES_PRIVATE_STREAM1 = 0xBD,
|
||||||
PES_PADDING_STREAM = 0xBE, ///< filler, padding stream
|
PES_PADDING_STREAM = 0xBE, ///< filler, padding stream
|
||||||
@ -498,8 +487,7 @@ enum
|
|||||||
///
|
///
|
||||||
/// PES parser state.
|
/// PES parser state.
|
||||||
///
|
///
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
PES_INIT, ///< unknown codec
|
PES_INIT, ///< unknown codec
|
||||||
|
|
||||||
PES_SKIP, ///< skip packet
|
PES_SKIP, ///< skip packet
|
||||||
@ -520,8 +508,7 @@ enum
|
|||||||
///
|
///
|
||||||
/// PES demuxer.
|
/// PES demuxer.
|
||||||
///
|
///
|
||||||
typedef struct _pes_demux_
|
typedef struct _pes_demux_ {
|
||||||
{
|
|
||||||
// int Pid; ///< packet id
|
// int Pid; ///< packet id
|
||||||
// int PcrPid; ///< program clock reference pid
|
// int PcrPid; ///< program clock reference pid
|
||||||
// int StreamType; ///< stream type
|
// int StreamType; ///< stream type
|
||||||
@ -544,8 +531,7 @@ typedef struct _pes_demux_
|
|||||||
///
|
///
|
||||||
/// Reset packetized elementary stream demuxer.
|
/// Reset packetized elementary stream demuxer.
|
||||||
///
|
///
|
||||||
static void PesReset(PesDemux * pesdx)
|
static void PesReset(PesDemux *pesdx) {
|
||||||
{
|
|
||||||
pesdx->State = PES_INIT;
|
pesdx->State = PES_INIT;
|
||||||
pesdx->Index = 0;
|
pesdx->Index = 0;
|
||||||
pesdx->Skip = 0;
|
pesdx->Skip = 0;
|
||||||
@ -559,8 +545,7 @@ static void PesReset(PesDemux * pesdx)
|
|||||||
///
|
///
|
||||||
/// @param pesdx packetized elementary stream demuxer
|
/// @param pesdx packetized elementary stream demuxer
|
||||||
///
|
///
|
||||||
static void PesInit(PesDemux * pesdx)
|
static void PesInit(PesDemux *pesdx) {
|
||||||
{
|
|
||||||
memset(pesdx, 0, sizeof(*pesdx));
|
memset(pesdx, 0, sizeof(*pesdx));
|
||||||
pesdx->Size = PES_MAX_PAYLOAD;
|
pesdx->Size = PES_MAX_PAYLOAD;
|
||||||
pesdx->Buffer = av_malloc(PES_MAX_PAYLOAD + AV_INPUT_BUFFER_PADDING_SIZE);
|
pesdx->Buffer = av_malloc(PES_MAX_PAYLOAD + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
@ -578,8 +563,7 @@ static void PesInit(PesDemux * pesdx)
|
|||||||
/// @param size number of payload data bytes
|
/// @param size number of payload data bytes
|
||||||
/// @param is_start flag, start of pes packet
|
/// @param is_start flag, start of pes packet
|
||||||
///
|
///
|
||||||
static void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_start)
|
static void PesParse(PesDemux *pesdx, const uint8_t *data, int size, int is_start) {
|
||||||
{
|
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
const uint8_t *q;
|
const uint8_t *q;
|
||||||
|
|
||||||
@ -728,8 +712,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_st
|
|||||||
unsigned code;
|
unsigned code;
|
||||||
|
|
||||||
// bad mpeg pes packet start code prefix 0x00001xx
|
// bad mpeg pes packet start code prefix 0x00001xx
|
||||||
if (pesdx->Header[0] || pesdx->Header[1]
|
if (pesdx->Header[0] || pesdx->Header[1] || pesdx->Header[2] != 0x01) {
|
||||||
|| pesdx->Header[2] != 0x01) {
|
|
||||||
Debug(3, "pesdemux: bad pes packet\n");
|
Debug(3, "pesdemux: bad pes packet\n");
|
||||||
pesdx->State = PES_SKIP;
|
pesdx->State = PES_SKIP;
|
||||||
return;
|
return;
|
||||||
@ -776,21 +759,16 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_st
|
|||||||
int64_t dts;
|
int64_t dts;
|
||||||
|
|
||||||
if ((pesdx->Header[7] & 0xC0) == 0x80) {
|
if ((pesdx->Header[7] & 0xC0) == 0x80) {
|
||||||
pts =
|
pts = (int64_t)(data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 |
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7
|
data[12] << 7 | (data[13] & 0xFE) >> 1;
|
||||||
| (data[13]
|
|
||||||
& 0xFE) >> 1;
|
|
||||||
pesdx->PTS = pts;
|
pesdx->PTS = pts;
|
||||||
pesdx->DTS = AV_NOPTS_VALUE;
|
pesdx->DTS = AV_NOPTS_VALUE;
|
||||||
} else if ((pesdx->Header[7] & 0xC0) == 0xC0) {
|
} else if ((pesdx->Header[7] & 0xC0) == 0xC0) {
|
||||||
pts =
|
pts = (int64_t)(data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 |
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7
|
data[12] << 7 | (data[13] & 0xFE) >> 1;
|
||||||
| (data[13]
|
|
||||||
& 0xFE) >> 1;
|
|
||||||
pesdx->PTS = pts;
|
pesdx->PTS = pts;
|
||||||
dts =
|
dts = (int64_t)(data[14] & 0x0E) << 29 | data[15] << 22 | (data[16] & 0xFE) << 14 |
|
||||||
(int64_t) (data[14] & 0x0E) << 29 | data[15] << 22 | (data[16] & 0xFE) << 14 | data[17] <<
|
data[17] << 7 | (data[18] & 0xFE) >> 1;
|
||||||
7 | (data[18] & 0xFE) >> 1;
|
|
||||||
pesdx->DTS = dts;
|
pesdx->DTS = dts;
|
||||||
Debug(4, "pesdemux: pts %#012" PRIx64 " %#012" PRIx64 "\n", pts, dts);
|
Debug(4, "pesdemux: pts %#012" PRIx64 " %#012" PRIx64 "\n", pts, dts);
|
||||||
}
|
}
|
||||||
@ -896,8 +874,7 @@ typedef struct _ts_demux_ TsDemux;
|
|||||||
///
|
///
|
||||||
/// transport stream demuxer structure.
|
/// transport stream demuxer structure.
|
||||||
///
|
///
|
||||||
struct _ts_demux_
|
struct _ts_demux_ {
|
||||||
{
|
|
||||||
int Packets; ///< packets between PCR
|
int Packets; ///< packets between PCR
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -912,8 +889,7 @@ static PesDemux PesDemuxAudio[1]; ///< audio demuxer
|
|||||||
///
|
///
|
||||||
/// @returns number of bytes consumed from buffer.
|
/// @returns number of bytes consumed from buffer.
|
||||||
///
|
///
|
||||||
static int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size)
|
static int TsDemuxer(TsDemux *tsdx, const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
|
|
||||||
p = data;
|
p = data;
|
||||||
@ -987,8 +963,7 @@ static int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size)
|
|||||||
** @param size size of PES packet
|
** @param size size of PES packet
|
||||||
** @param id PES packet type
|
** @param id PES packet type
|
||||||
*/
|
*/
|
||||||
int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
int PlayAudio(const uint8_t *data, int size, uint8_t id) {
|
||||||
{
|
|
||||||
int n;
|
int n;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
|
|
||||||
@ -1045,15 +1020,14 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data[7] & 0x80 && n >= 5) {
|
if (data[7] & 0x80 && n >= 5) {
|
||||||
AudioAvPkt->pts =
|
AudioAvPkt->pts = (int64_t)(data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 |
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 | (data[13] &
|
(data[13] & 0xFE) >> 1;
|
||||||
0xFE) >> 1;
|
|
||||||
// Debug(3, "audio: pts %#012" PRIx64 "\n", AudioAvPkt->pts);
|
// Debug(3, "audio: pts %#012" PRIx64 "\n", AudioAvPkt->pts);
|
||||||
}
|
}
|
||||||
if (0) { // dts is unused
|
if (0) { // dts is unused
|
||||||
if (data[7] & 0x40) {
|
if (data[7] & 0x40) {
|
||||||
AudioAvPkt->dts = (int64_t) (data[14] & 0x0E) << 29 | data[15] << 22 | (data[16]
|
AudioAvPkt->dts = (int64_t)(data[14] & 0x0E) << 29 | data[15] << 22 | (data[16] & 0xFE) << 14 |
|
||||||
& 0xFE) << 14 | data[17] << 7 | (data[18] & 0xFE) >> 1;
|
data[17] << 7 | (data[18] & 0xFE) >> 1;
|
||||||
Debug(3, "audio: dts %#012" PRIx64 "\n", AudioAvPkt->dts);
|
Debug(3, "audio: dts %#012" PRIx64 "\n", AudioAvPkt->dts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1219,8 +1193,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
**
|
**
|
||||||
** @returns number of bytes consumed;
|
** @returns number of bytes consumed;
|
||||||
*/
|
*/
|
||||||
int PlayTsAudio(const uint8_t * data, int size)
|
int PlayTsAudio(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
static TsDemux tsdx[1];
|
static TsDemux tsdx[1];
|
||||||
|
|
||||||
if (SkipAudio || !MyAudioDecoder) { // skip audio
|
if (SkipAudio || !MyAudioDecoder) { // skip audio
|
||||||
@ -1256,7 +1229,6 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
usleep(AudioDelay * 1000);
|
usleep(AudioDelay * 1000);
|
||||||
AudioDelay = 0;
|
AudioDelay = 0;
|
||||||
// TsDemuxer(tsdx, data, size); // insert dummy audio
|
// TsDemuxer(tsdx, data, size); // insert dummy audio
|
||||||
|
|
||||||
}
|
}
|
||||||
return TsDemuxer(tsdx, data, size);
|
return TsDemuxer(tsdx, data, size);
|
||||||
}
|
}
|
||||||
@ -1268,16 +1240,12 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
**
|
**
|
||||||
** @param volume VDR volume (0 .. 255)
|
** @param volume VDR volume (0 .. 255)
|
||||||
*/
|
*/
|
||||||
void SetVolumeDevice(int volume)
|
void SetVolumeDevice(int volume) { AudioSetVolume((volume * 1000) / 255); }
|
||||||
{
|
|
||||||
AudioSetVolume((volume * 1000) / 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*** Resets channel ID (restarts audio).
|
*** Resets channel ID (restarts audio).
|
||||||
**/
|
**/
|
||||||
void ResetChannelId(void)
|
void ResetChannelId(void) {
|
||||||
{
|
|
||||||
AudioChannelID = -1;
|
AudioChannelID = -1;
|
||||||
Debug(3, "audio/demux: reset channel id\n");
|
Debug(3, "audio/demux: reset channel id\n");
|
||||||
}
|
}
|
||||||
@ -1292,8 +1260,7 @@ void ResetChannelId(void)
|
|||||||
/**
|
/**
|
||||||
** Video output stream device structure. Parser, decoder, display.
|
** Video output stream device structure. Parser, decoder, display.
|
||||||
*/
|
*/
|
||||||
struct __video_stream__
|
struct __video_stream__ {
|
||||||
{
|
|
||||||
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
VideoHwDecoder *HwDecoder; ///< video hardware decoder
|
||||||
VideoDecoder *Decoder; ///< video decoder
|
VideoDecoder *Decoder; ///< video decoder
|
||||||
pthread_mutex_t DecoderLockMutex; ///< video decoder lock mutex
|
pthread_mutex_t DecoderLockMutex; ///< video decoder lock mutex
|
||||||
@ -1348,8 +1315,7 @@ static volatile char Usr1Signal; ///< true got usr1 signal
|
|||||||
**
|
**
|
||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
*/
|
*/
|
||||||
static void VideoPacketInit(VideoStream * stream)
|
static void VideoPacketInit(VideoStream *stream) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
||||||
@ -1371,8 +1337,7 @@ static void VideoPacketInit(VideoStream * stream)
|
|||||||
**
|
**
|
||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
*/
|
*/
|
||||||
static void VideoPacketExit(VideoStream * stream)
|
static void VideoPacketExit(VideoStream *stream) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
atomic_set(&stream->PacketsFilled, 0);
|
atomic_set(&stream->PacketsFilled, 0);
|
||||||
@ -1390,8 +1355,7 @@ static void VideoPacketExit(VideoStream * stream)
|
|||||||
** @param data data of pes packet
|
** @param data data of pes packet
|
||||||
** @param size size of pes packet
|
** @param size size of pes packet
|
||||||
*/
|
*/
|
||||||
static void VideoEnqueue(VideoStream * stream, int64_t pts, int64_t dts, const void *data, int size)
|
static void VideoEnqueue(VideoStream *stream, int64_t pts, int64_t dts, const void *data, int size) {
|
||||||
{
|
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
|
|
||||||
// Debug(3, "video: enqueue %d\n", size);
|
// Debug(3, "video: enqueue %d\n", size);
|
||||||
@ -1408,8 +1372,7 @@ static void VideoEnqueue(VideoStream * stream, int64_t pts, int64_t dts, const v
|
|||||||
// avpkt->stream_index + size);
|
// avpkt->stream_index + size);
|
||||||
|
|
||||||
// new + grow reserves FF_INPUT_BUFFER_PADDING_SIZE
|
// new + grow reserves FF_INPUT_BUFFER_PADDING_SIZE
|
||||||
av_grow_packet(avpkt, ((size + VIDEO_BUFFER_SIZE / 2)
|
av_grow_packet(avpkt, ((size + VIDEO_BUFFER_SIZE / 2) / (VIDEO_BUFFER_SIZE / 2)) * (VIDEO_BUFFER_SIZE / 2));
|
||||||
/ (VIDEO_BUFFER_SIZE / 2)) * (VIDEO_BUFFER_SIZE / 2));
|
|
||||||
// FIXME: out of memory!
|
// FIXME: out of memory!
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (avpkt->size <= avpkt->stream_index + size) {
|
if (avpkt->size <= avpkt->stream_index + size) {
|
||||||
@ -1435,8 +1398,7 @@ static void VideoEnqueue(VideoStream * stream, int64_t pts, int64_t dts, const v
|
|||||||
**
|
**
|
||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
*/
|
*/
|
||||||
static void VideoResetPacket(VideoStream * stream)
|
static void VideoResetPacket(VideoStream *stream) {
|
||||||
{
|
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
|
|
||||||
stream->StartCodeState = 0; // reset start code state
|
stream->StartCodeState = 0; // reset start code state
|
||||||
@ -1454,8 +1416,7 @@ static void VideoResetPacket(VideoStream * stream)
|
|||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
** @param codec_id codec id of packet (MPEG/H264)
|
** @param codec_id codec id of packet (MPEG/H264)
|
||||||
*/
|
*/
|
||||||
static void VideoNextPacket(VideoStream * stream, int codec_id)
|
static void VideoNextPacket(VideoStream *stream, int codec_id) {
|
||||||
{
|
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
|
|
||||||
avpkt = &stream->PacketRb[stream->PacketWrite];
|
avpkt = &stream->PacketRb[stream->PacketWrite];
|
||||||
@ -1506,8 +1467,7 @@ static void VideoNextPacket(VideoStream * stream, int codec_id)
|
|||||||
** @param data data of pes packet
|
** @param data data of pes packet
|
||||||
** @param size size of pes packet
|
** @param size size of pes packet
|
||||||
*/
|
*/
|
||||||
static void VideoMpegEnqueue(VideoStream * stream, int64_t pts, int64_t dts, const uint8_t * data, int size)
|
static void VideoMpegEnqueue(VideoStream *stream, int64_t pts, int64_t dts, const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
static const char startcode[3] = {0x00, 0x00, 0x01};
|
static const char startcode[3] = {0x00, 0x00, 0x01};
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
int n;
|
int n;
|
||||||
@ -1666,8 +1626,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts, int64_t dts, con
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef USE_PIP
|
#ifndef USE_PIP
|
||||||
static void FixPacketForFFMpeg(VideoDecoder * vdecoder, AVPacket * avpkt)
|
static void FixPacketForFFMpeg(VideoDecoder *vdecoder, AVPacket *avpkt) {
|
||||||
{
|
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int n;
|
int n;
|
||||||
AVPacket tmp[1];
|
AVPacket tmp[1];
|
||||||
@ -1732,8 +1691,7 @@ static void FixPacketForFFMpeg(VideoDecoder * vdecoder, AVPacket * avpkt)
|
|||||||
**
|
**
|
||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
*/
|
*/
|
||||||
static void VideoStreamOpen(VideoStream * stream)
|
static void VideoStreamOpen(VideoStream *stream) {
|
||||||
{
|
|
||||||
stream->SkipStream = 1;
|
stream->SkipStream = 1;
|
||||||
stream->CodecID = AV_CODEC_ID_NONE;
|
stream->CodecID = AV_CODEC_ID_NONE;
|
||||||
stream->LastCodecID = AV_CODEC_ID_NONE;
|
stream->LastCodecID = AV_CODEC_ID_NONE;
|
||||||
@ -1753,8 +1711,7 @@ static void VideoStreamOpen(VideoStream * stream)
|
|||||||
** @note must be called from the video thread, otherwise xcb has a
|
** @note must be called from the video thread, otherwise xcb has a
|
||||||
** deadlock.
|
** deadlock.
|
||||||
*/
|
*/
|
||||||
static void VideoStreamClose(VideoStream * stream, int delhw)
|
static void VideoStreamClose(VideoStream *stream, int delhw) {
|
||||||
{
|
|
||||||
stream->SkipStream = 1;
|
stream->SkipStream = 1;
|
||||||
if (stream->Decoder) {
|
if (stream->Decoder) {
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
@ -1791,8 +1748,7 @@ static void VideoStreamClose(VideoStream * stream, int delhw)
|
|||||||
** @retval 1 something todo
|
** @retval 1 something todo
|
||||||
** @retval -1 empty stream
|
** @retval -1 empty stream
|
||||||
*/
|
*/
|
||||||
int VideoPollInput(VideoStream * stream)
|
int VideoPollInput(VideoStream *stream) {
|
||||||
{
|
|
||||||
if (!stream->Decoder || !stream->HwDecoder) { // closing
|
if (!stream->Decoder || !stream->HwDecoder) { // closing
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "no decoder\n");
|
fprintf(stderr, "no decoder\n");
|
||||||
@ -1832,8 +1788,7 @@ int VideoPollInput(VideoStream * stream)
|
|||||||
** @retval 1 stream paused
|
** @retval 1 stream paused
|
||||||
** @retval -1 empty stream
|
** @retval -1 empty stream
|
||||||
*/
|
*/
|
||||||
int VideoDecodeInput(VideoStream * stream, int trick)
|
int VideoDecodeInput(VideoStream *stream, int trick) {
|
||||||
{
|
|
||||||
int filled;
|
int filled;
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
int saved_size;
|
int saved_size;
|
||||||
@ -1982,18 +1937,14 @@ int VideoDecodeInput(VideoStream * stream, int trick)
|
|||||||
**
|
**
|
||||||
** @param stream video stream
|
** @param stream video stream
|
||||||
*/
|
*/
|
||||||
int VideoGetBuffers(const VideoStream * stream)
|
int VideoGetBuffers(const VideoStream *stream) { return atomic_read(&stream->PacketsFilled); }
|
||||||
{
|
|
||||||
return atomic_read(&stream->PacketsFilled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Try video start.
|
** Try video start.
|
||||||
**
|
**
|
||||||
** NOT TRUE: Could be called, when already started.
|
** NOT TRUE: Could be called, when already started.
|
||||||
*/
|
*/
|
||||||
static void StartVideo(void)
|
static void StartVideo(void) {
|
||||||
{
|
|
||||||
VideoInit(X11DisplayName);
|
VideoInit(X11DisplayName);
|
||||||
|
|
||||||
if (ConfigFullscreen) {
|
if (ConfigFullscreen) {
|
||||||
@ -2010,8 +1961,7 @@ static void StartVideo(void)
|
|||||||
/**
|
/**
|
||||||
** Stop video.
|
** Stop video.
|
||||||
*/
|
*/
|
||||||
static void StopVideo(void)
|
static void StopVideo(void) {
|
||||||
{
|
|
||||||
VideoOsdExit();
|
VideoOsdExit();
|
||||||
VideoExit();
|
VideoExit();
|
||||||
AudioSyncStream = NULL;
|
AudioSyncStream = NULL;
|
||||||
@ -2050,8 +2000,7 @@ static void StopVideo(void)
|
|||||||
**
|
**
|
||||||
** Function to dump a mpeg packet, not needed.
|
** Function to dump a mpeg packet, not needed.
|
||||||
*/
|
*/
|
||||||
static void DumpMpeg(const uint8_t * data, int size)
|
static void DumpMpeg(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
fprintf(stderr, "%8d: ", size);
|
fprintf(stderr, "%8d: ", size);
|
||||||
|
|
||||||
// b3 b4 b8 00 b5 ... 00 b5 ...
|
// b3 b4 b8 00 b5 ... 00 b5 ...
|
||||||
@ -2074,8 +2023,7 @@ static void DumpMpeg(const uint8_t * data, int size)
|
|||||||
**
|
**
|
||||||
** Function to Dump a h264 packet, not needed.
|
** Function to Dump a h264 packet, not needed.
|
||||||
*/
|
*/
|
||||||
static int DumpH264(const uint8_t * data, int size)
|
static int DumpH264(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
printf("H264:");
|
printf("H264:");
|
||||||
do {
|
do {
|
||||||
if (size < 4) {
|
if (size < 4) {
|
||||||
@ -2098,8 +2046,7 @@ static int DumpH264(const uint8_t * data, int size)
|
|||||||
**
|
**
|
||||||
** Function to validate a mpeg packet, not needed.
|
** Function to validate a mpeg packet, not needed.
|
||||||
*/
|
*/
|
||||||
static int ValidateMpeg(const uint8_t * data, int size)
|
static int ValidateMpeg(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
int pes_l;
|
int pes_l;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -2138,8 +2085,7 @@ static int ValidateMpeg(const uint8_t * data, int size)
|
|||||||
** @return number of bytes used, 0 if internal buffer are full.
|
** @return number of bytes used, 0 if internal buffer are full.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
|
int PlayVideo3(VideoStream *stream, const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
const uint8_t *check;
|
const uint8_t *check;
|
||||||
int64_t pts, dts;
|
int64_t pts, dts;
|
||||||
int n;
|
int n;
|
||||||
@ -2201,8 +2147,8 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
#ifdef USE_SOFTLIMIT
|
#ifdef USE_SOFTLIMIT
|
||||||
// soft limit buffer full
|
// soft limit buffer full
|
||||||
if (AudioSyncStream == stream && atomic_read(&stream->PacketsFilled) > 3
|
if (AudioSyncStream == stream && atomic_read(&stream->PacketsFilled) > 3 &&
|
||||||
&& AudioUsedBytes() > AUDIO_MIN_BUFFER_FREE * 2) {
|
AudioUsedBytes() > AUDIO_MIN_BUFFER_FREE * 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2210,17 +2156,14 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
|
|||||||
pts = AV_NOPTS_VALUE;
|
pts = AV_NOPTS_VALUE;
|
||||||
dts = AV_NOPTS_VALUE;
|
dts = AV_NOPTS_VALUE;
|
||||||
if ((data[7] & 0xc0) == 0x80) {
|
if ((data[7] & 0xc0) == 0x80) {
|
||||||
pts =
|
pts = (int64_t)(data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 |
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 | (data[13] &
|
(data[13] & 0xFE) >> 1;
|
||||||
0xFE) >> 1;
|
|
||||||
}
|
}
|
||||||
if ((data[7] & 0xC0) == 0xc0) {
|
if ((data[7] & 0xC0) == 0xc0) {
|
||||||
pts =
|
pts = (int64_t)(data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 |
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] & 0xFE) << 14 | data[12] << 7 | (data[13] &
|
(data[13] & 0xFE) >> 1;
|
||||||
0xFE) >> 1;
|
dts = (int64_t)(data[14] & 0x0E) << 29 | data[15] << 22 | (data[16] & 0xFE) << 14 | data[17] << 7 |
|
||||||
dts =
|
(data[18] & 0xFE) >> 1;
|
||||||
(int64_t) (data[14] & 0x0E) << 29 | data[15] << 22 | (data[16] & 0xFE) << 14 | data[17] << 7 | (data[18] &
|
|
||||||
0xFE) >> 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check = data + 9 + n;
|
check = data + 9 + n;
|
||||||
@ -2370,10 +2313,7 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
|
|||||||
**
|
**
|
||||||
** @todo FIXME: combine the 5 ifs at start of the function
|
** @todo FIXME: combine the 5 ifs at start of the function
|
||||||
*/
|
*/
|
||||||
int PlayVideo(const uint8_t * data, int size)
|
int PlayVideo(const uint8_t *data, int size) { return PlayVideo3(MyVideoStream, data, size); }
|
||||||
{
|
|
||||||
return PlayVideo3(MyVideoStream, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// call VDR support function
|
/// call VDR support function
|
||||||
extern uint8_t *CreateJpeg(uint8_t *, int *, int, int, int);
|
extern uint8_t *CreateJpeg(uint8_t *, int *, int, int, int);
|
||||||
@ -2392,8 +2332,7 @@ extern uint8_t *CreateJpeg(uint8_t *, int *, int, int, int);
|
|||||||
**
|
**
|
||||||
** @returns allocated jpeg image.
|
** @returns allocated jpeg image.
|
||||||
*/
|
*/
|
||||||
uint8_t *CreateJpeg(uint8_t * image, int raw_size, int *size, int quality, int width, int height)
|
uint8_t *CreateJpeg(uint8_t *image, int raw_size, int *size, int quality, int width, int height) {
|
||||||
{
|
|
||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
struct jpeg_error_mgr jerr;
|
struct jpeg_error_mgr jerr;
|
||||||
JSAMPROW row_ptr[1];
|
JSAMPROW row_ptr[1];
|
||||||
@ -2440,8 +2379,7 @@ uint8_t *CreateJpeg(uint8_t * image, int raw_size, int *size, int quality, int w
|
|||||||
** @param width number of horizontal pixels in the frame
|
** @param width number of horizontal pixels in the frame
|
||||||
** @param height number of vertical pixels in the frame
|
** @param height number of vertical pixels in the frame
|
||||||
*/
|
*/
|
||||||
uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height)
|
uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height) {
|
||||||
{
|
|
||||||
if (jpeg) {
|
if (jpeg) {
|
||||||
uint8_t *image;
|
uint8_t *image;
|
||||||
int raw_size;
|
int raw_size;
|
||||||
@ -2468,8 +2406,7 @@ uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height)
|
|||||||
**
|
**
|
||||||
** @param play_mode play mode (none, video+audio, audio-only, ...)
|
** @param play_mode play mode (none, video+audio, audio-only, ...)
|
||||||
*/
|
*/
|
||||||
int SetPlayMode(int play_mode)
|
int SetPlayMode(int play_mode) {
|
||||||
{
|
|
||||||
Debug(3, "Set Playmode %d\n", play_mode);
|
Debug(3, "Set Playmode %d\n", play_mode);
|
||||||
switch (play_mode) {
|
switch (play_mode) {
|
||||||
case 0: // audio/video from decoder
|
case 0: // audio/video from decoder
|
||||||
@ -2520,8 +2457,7 @@ int SetPlayMode(int play_mode)
|
|||||||
** Gets the current System Time Counter, which can be used to
|
** Gets the current System Time Counter, which can be used to
|
||||||
** synchronize audio, video and subtitles.
|
** synchronize audio, video and subtitles.
|
||||||
*/
|
*/
|
||||||
int64_t GetSTC(void)
|
int64_t GetSTC(void) {
|
||||||
{
|
|
||||||
if (MyVideoStream->HwDecoder) {
|
if (MyVideoStream->HwDecoder) {
|
||||||
return VideoGetClock(MyVideoStream->HwDecoder);
|
return VideoGetClock(MyVideoStream->HwDecoder);
|
||||||
}
|
}
|
||||||
@ -2537,8 +2473,7 @@ int64_t GetSTC(void)
|
|||||||
** @param height[OUT] height of video stream
|
** @param height[OUT] height of video stream
|
||||||
** @param aspect[OUT] aspect ratio (4/3, 16/9, ...) of video stream
|
** @param aspect[OUT] aspect ratio (4/3, 16/9, ...) of video stream
|
||||||
*/
|
*/
|
||||||
void GetVideoSize(int *width, int *height, double *aspect)
|
void GetVideoSize(int *width, int *height, double *aspect) {
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int done_width;
|
static int done_width;
|
||||||
static int done_height;
|
static int done_height;
|
||||||
@ -2572,8 +2507,7 @@ void GetVideoSize(int *width, int *height, double *aspect)
|
|||||||
**
|
**
|
||||||
** @param speed trick speed
|
** @param speed trick speed
|
||||||
*/
|
*/
|
||||||
void TrickSpeed(int speed)
|
void TrickSpeed(int speed) {
|
||||||
{
|
|
||||||
MyVideoStream->TrickSpeed = speed;
|
MyVideoStream->TrickSpeed = speed;
|
||||||
if (MyVideoStream->HwDecoder) {
|
if (MyVideoStream->HwDecoder) {
|
||||||
VideoSetTrickSpeed(MyVideoStream->HwDecoder, speed);
|
VideoSetTrickSpeed(MyVideoStream->HwDecoder, speed);
|
||||||
@ -2588,8 +2522,7 @@ void TrickSpeed(int speed)
|
|||||||
/**
|
/**
|
||||||
** Clears all video and audio data from the device.
|
** Clears all video and audio data from the device.
|
||||||
*/
|
*/
|
||||||
void Clear(void)
|
void Clear(void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
VideoResetPacket(MyVideoStream); // terminate work
|
VideoResetPacket(MyVideoStream); // terminate work
|
||||||
@ -2611,8 +2544,7 @@ void Clear(void)
|
|||||||
/**
|
/**
|
||||||
** Sets the device into play mode.
|
** Sets the device into play mode.
|
||||||
*/
|
*/
|
||||||
void Play(void)
|
void Play(void) {
|
||||||
{
|
|
||||||
TrickSpeed(0); // normal play
|
TrickSpeed(0); // normal play
|
||||||
SkipAudio = 0;
|
SkipAudio = 0;
|
||||||
AudioPlay();
|
AudioPlay();
|
||||||
@ -2621,8 +2553,7 @@ void Play(void)
|
|||||||
/**
|
/**
|
||||||
** Sets the device into "freeze frame" mode.
|
** Sets the device into "freeze frame" mode.
|
||||||
*/
|
*/
|
||||||
void Freeze(void)
|
void Freeze(void) {
|
||||||
{
|
|
||||||
StreamFreezed = 1;
|
StreamFreezed = 1;
|
||||||
MyVideoStream->Freezed = 1;
|
MyVideoStream->Freezed = 1;
|
||||||
AudioPause();
|
AudioPause();
|
||||||
@ -2631,8 +2562,7 @@ void Freeze(void)
|
|||||||
/**
|
/**
|
||||||
** Turns off audio while replaying.
|
** Turns off audio while replaying.
|
||||||
*/
|
*/
|
||||||
void Mute(void)
|
void Mute(void) {
|
||||||
{
|
|
||||||
SkipAudio = 1;
|
SkipAudio = 1;
|
||||||
AudioFlushBuffers();
|
AudioFlushBuffers();
|
||||||
// AudioSetVolume(0);
|
// AudioSetVolume(0);
|
||||||
@ -2644,8 +2574,7 @@ void Mute(void)
|
|||||||
** @param data pes frame data
|
** @param data pes frame data
|
||||||
** @param size number of bytes in frame
|
** @param size number of bytes in frame
|
||||||
*/
|
*/
|
||||||
void StillPicture(const uint8_t * data, int size)
|
void StillPicture(const uint8_t *data, int size) {
|
||||||
{
|
|
||||||
static uint8_t seq_end_mpeg[] = {0x00, 0x00, 0x01, 0xB7};
|
static uint8_t seq_end_mpeg[] = {0x00, 0x00, 0x01, 0xB7};
|
||||||
// H264 NAL End of Sequence
|
// H264 NAL End of Sequence
|
||||||
static uint8_t seq_end_h264[] = {0x00, 0x00, 0x00, 0x01, 0x0A};
|
static uint8_t seq_end_h264[] = {0x00, 0x00, 0x00, 0x01, 0x0A};
|
||||||
@ -2718,7 +2647,8 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
n -= 6 + len;
|
n -= 6 + len;
|
||||||
} while (n > 6);
|
} while (n > 6);
|
||||||
|
|
||||||
VideoNextPacket(MyVideoStream, MyVideoStream->CodecID); // terminate last packet
|
VideoNextPacket(MyVideoStream,
|
||||||
|
MyVideoStream->CodecID); // terminate last packet
|
||||||
} else { // ES packet
|
} else { // ES packet
|
||||||
if (MyVideoStream->CodecID != AV_CODEC_ID_MPEG2VIDEO) {
|
if (MyVideoStream->CodecID != AV_CODEC_ID_MPEG2VIDEO) {
|
||||||
VideoNextPacket(MyVideoStream, AV_CODEC_ID_NONE); // close last stream
|
VideoNextPacket(MyVideoStream, AV_CODEC_ID_NONE); // close last stream
|
||||||
@ -2733,7 +2663,8 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
} else {
|
} else {
|
||||||
VideoEnqueue(MyVideoStream, AV_NOPTS_VALUE, AV_NOPTS_VALUE, seq_end_mpeg, sizeof(seq_end_mpeg));
|
VideoEnqueue(MyVideoStream, AV_NOPTS_VALUE, AV_NOPTS_VALUE, seq_end_mpeg, sizeof(seq_end_mpeg));
|
||||||
}
|
}
|
||||||
VideoNextPacket(MyVideoStream, MyVideoStream->CodecID); // terminate last packet
|
VideoNextPacket(MyVideoStream,
|
||||||
|
MyVideoStream->CodecID); // terminate last packet
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for empty buffers
|
// wait for empty buffers
|
||||||
@ -2763,8 +2694,7 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
** @retval true if ready
|
** @retval true if ready
|
||||||
** @retval false if busy
|
** @retval false if busy
|
||||||
*/
|
*/
|
||||||
int Poll(int timeout)
|
int Poll(int timeout) {
|
||||||
{
|
|
||||||
// poll is only called during replay, flush buffers after replay
|
// poll is only called during replay, flush buffers after replay
|
||||||
MyVideoStream->ClearClose = 1;
|
MyVideoStream->ClearClose = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -2777,8 +2707,8 @@ int Poll(int timeout)
|
|||||||
// FIXME: no video!
|
// FIXME: no video!
|
||||||
filled = atomic_read(&MyVideoStream->PacketsFilled);
|
filled = atomic_read(&MyVideoStream->PacketsFilled);
|
||||||
// soft limit + hard limit
|
// soft limit + hard limit
|
||||||
full = (used > AUDIO_MIN_BUFFER_FREE && filled > 3)
|
full = (used > AUDIO_MIN_BUFFER_FREE && filled > 3) || AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE ||
|
||||||
|| AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE || filled >= VIDEO_PACKET_MAX - 10;
|
filled >= VIDEO_PACKET_MAX - 10;
|
||||||
|
|
||||||
if (!full || !timeout) {
|
if (!full || !timeout) {
|
||||||
return !full;
|
return !full;
|
||||||
@ -2798,8 +2728,7 @@ int Poll(int timeout)
|
|||||||
**
|
**
|
||||||
** @param timeout timeout to flush in ms
|
** @param timeout timeout to flush in ms
|
||||||
*/
|
*/
|
||||||
int Flush(int timeout)
|
int Flush(int timeout) {
|
||||||
{
|
|
||||||
if (atomic_read(&MyVideoStream->PacketsFilled)) {
|
if (atomic_read(&MyVideoStream->PacketsFilled)) {
|
||||||
if (timeout) { // let display thread work
|
if (timeout) { // let display thread work
|
||||||
usleep(timeout * 1000);
|
usleep(timeout * 1000);
|
||||||
@ -2820,8 +2749,7 @@ int Flush(int timeout)
|
|||||||
** @param height[OUT] height of OSD
|
** @param height[OUT] height of OSD
|
||||||
** @param aspect[OUT] aspect ratio (4/3, 16/9, ...) of OSD
|
** @param aspect[OUT] aspect ratio (4/3, 16/9, ...) of OSD
|
||||||
*/
|
*/
|
||||||
void GetOsdSize(int *width, int *height, double *aspect)
|
void GetOsdSize(int *width, int *height, double *aspect) {
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int done_width;
|
static int done_width;
|
||||||
static int done_height;
|
static int done_height;
|
||||||
@ -2842,10 +2770,7 @@ void GetOsdSize(int *width, int *height, double *aspect)
|
|||||||
/**
|
/**
|
||||||
** Close OSD.
|
** Close OSD.
|
||||||
*/
|
*/
|
||||||
void OsdClose(void)
|
void OsdClose(void) { VideoOsdClear(); }
|
||||||
{
|
|
||||||
VideoOsdClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Draw an OSD pixmap.
|
** Draw an OSD pixmap.
|
||||||
@ -2859,8 +2784,7 @@ void OsdClose(void)
|
|||||||
** @param x x-coordinate on screen of argb image
|
** @param x x-coordinate on screen of argb image
|
||||||
** @param y y-coordinate on screen of argb image
|
** @param y y-coordinate on screen of argb image
|
||||||
*/
|
*/
|
||||||
void OsdDrawARGB(int xi, int yi, int height, int width, int pitch, const uint8_t * argb, int x, int y)
|
void OsdDrawARGB(int xi, int yi, int height, int width, int pitch, const uint8_t *argb, int x, int y) {
|
||||||
{
|
|
||||||
// wakeup display for showing remote learning dialog
|
// wakeup display for showing remote learning dialog
|
||||||
VideoDisplayWakeup();
|
VideoDisplayWakeup();
|
||||||
VideoOsdDrawARGB(xi, yi, height, width, pitch, argb, x, y);
|
VideoOsdDrawARGB(xi, yi, height, width, pitch, argb, x, y);
|
||||||
@ -2871,27 +2795,33 @@ void OsdDrawARGB(int xi, int yi, int height, int width, int pitch, const uint8_t
|
|||||||
/**
|
/**
|
||||||
** Return command line help string.
|
** Return command line help string.
|
||||||
*/
|
*/
|
||||||
const char *CommandLineHelp(void)
|
const char *CommandLineHelp(void) {
|
||||||
{
|
|
||||||
return " -a device\taudio device (fe. alsa: hw:0,0 oss: /dev/dsp)\n"
|
return " -a device\taudio device (fe. alsa: hw:0,0 oss: /dev/dsp)\n"
|
||||||
" -p device\taudio device for pass-through (hw:0,1 or /dev/dsp1)\n"
|
" -p device\taudio device for pass-through (hw:0,1 or /dev/dsp1)\n"
|
||||||
" -c channel\taudio mixer channel name (fe. PCM)\n" " -d display\tdisplay of x11 server (fe. :0.0)\n"
|
" -c channel\taudio mixer channel name (fe. PCM)\n"
|
||||||
|
" -d display\tdisplay of x11 server (fe. :0.0)\n"
|
||||||
" -f\t\tstart with fullscreen window (only with window manager)\n"
|
" -f\t\tstart with fullscreen window (only with window manager)\n"
|
||||||
" -g geometry\tx11 window geometry wxh+x+y\n" " -r Refresh\tRefreshrate for DRM (default is 50 Hz)\n"
|
" -g geometry\tx11 window geometry wxh+x+y\n"
|
||||||
|
" -r Refresh\tRefreshrate for DRM (default is 50 Hz)\n"
|
||||||
" -C Connector\tConnector for DRM (default is current Connector)\n"
|
" -C Connector\tConnector for DRM (default is current Connector)\n"
|
||||||
" -S shader\tShader to use.\n\t\tOnly with placebo. Can be repeated for more shaders\n"
|
" -S shader\tShader to use.\n\t\tOnly with placebo. Can be repeated "
|
||||||
" -v device\tvideo driver device (cuvid)\n" " -s\t\tstart in suspended mode\n"
|
"for more shaders\n"
|
||||||
|
" -v device\tvideo driver device (cuvid)\n"
|
||||||
|
" -s\t\tstart in suspended mode\n"
|
||||||
" -x\t\tstart x11 server, with -xx try to connect, if this fails\n"
|
" -x\t\tstart x11 server, with -xx try to connect, if this fails\n"
|
||||||
" -X args\tX11 server arguments (f.e. -nocursor)\n" " -w workaround\tenable/disable workarounds\n"
|
" -X args\tX11 server arguments (f.e. -nocursor)\n"
|
||||||
|
" -w workaround\tenable/disable workarounds\n"
|
||||||
"\tno-hw-decoder\t\tdisable hw decoder, use software decoder only\n"
|
"\tno-hw-decoder\t\tdisable hw decoder, use software decoder only\n"
|
||||||
"\tno-mpeg-hw-decoder\tdisable hw decoder for mpeg only\n"
|
"\tno-mpeg-hw-decoder\tdisable hw decoder for mpeg only\n"
|
||||||
"\tstill-hw-decoder\tenable hardware decoder for still-pictures\n"
|
"\tstill-hw-decoder\tenable hardware decoder for still-pictures\n"
|
||||||
"\tstill-h264-hw-decoder\tenable h264 hw decoder for still-pictures\n"
|
"\tstill-h264-hw-decoder\tenable h264 hw decoder for still-pictures\n"
|
||||||
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
||||||
"\talsa-no-close-open\tdisable close open to fix alsa no sound bug\n"
|
"\talsa-no-close-open\tdisable close open to fix alsa no sound bug\n"
|
||||||
"\talsa-close-open-delay\tenable close open delay to fix no sound bug\n"
|
"\talsa-close-open-delay\tenable close open delay to fix no sound "
|
||||||
|
"bug\n"
|
||||||
"\tignore-repeat-pict\tdisable repeat pict message\n"
|
"\tignore-repeat-pict\tdisable repeat pict message\n"
|
||||||
"\tuse-possible-defect-frames prefer faster channel switch\n" " -D\t\tstart in detached mode\n";
|
"\tuse-possible-defect-frames prefer faster channel switch\n"
|
||||||
|
" -D\t\tstart in detached mode\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2900,8 +2830,7 @@ const char *CommandLineHelp(void)
|
|||||||
** @param argc number of arguments
|
** @param argc number of arguments
|
||||||
** @param argv arguments vector
|
** @param argv arguments vector
|
||||||
*/
|
*/
|
||||||
int ProcessArgs(int argc, char *const argv[])
|
int ProcessArgs(int argc, char *const argv[]) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// Parse arguments.
|
// Parse arguments.
|
||||||
//
|
//
|
||||||
@ -2943,8 +2872,8 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
continue;
|
continue;
|
||||||
case 'g': // geometry
|
case 'g': // geometry
|
||||||
if (VideoSetGeometry(optarg) < 0) {
|
if (VideoSetGeometry(optarg) < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, _("Bad formated geometry please use: "
|
||||||
_("Bad formated geometry please use: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"));
|
"[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -3032,8 +2961,7 @@ static pid_t X11ServerPid; ///< x11 server pid
|
|||||||
**
|
**
|
||||||
** @param sig signal number
|
** @param sig signal number
|
||||||
*/
|
*/
|
||||||
static void Usr1Handler(int __attribute__((unused)) sig)
|
static void Usr1Handler(int __attribute__((unused)) sig) {
|
||||||
{
|
|
||||||
++Usr1Signal;
|
++Usr1Signal;
|
||||||
|
|
||||||
Debug(3, "x-setup: got signal usr1\n");
|
Debug(3, "x-setup: got signal usr1\n");
|
||||||
@ -3042,8 +2970,7 @@ static void Usr1Handler(int __attribute__((unused)) sig)
|
|||||||
/**
|
/**
|
||||||
** Start the X server
|
** Start the X server
|
||||||
*/
|
*/
|
||||||
static void StartXServer(void)
|
static void StartXServer(void) {
|
||||||
{
|
|
||||||
struct sigaction usr1;
|
struct sigaction usr1;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
const char *sval;
|
const char *sval;
|
||||||
@ -3126,8 +3053,7 @@ static void StartXServer(void)
|
|||||||
/**
|
/**
|
||||||
** Exit + cleanup.
|
** Exit + cleanup.
|
||||||
*/
|
*/
|
||||||
void SoftHdDeviceExit(void)
|
void SoftHdDeviceExit(void) {
|
||||||
{
|
|
||||||
// lets hope that vdr does a good thread cleanup
|
// lets hope that vdr does a good thread cleanup
|
||||||
|
|
||||||
AudioExit();
|
AudioExit();
|
||||||
@ -3190,8 +3116,7 @@ void SoftHdDeviceExit(void)
|
|||||||
** @retval 1 suspended start
|
** @retval 1 suspended start
|
||||||
** @retval -1 detached start
|
** @retval -1 detached start
|
||||||
*/
|
*/
|
||||||
int Start(void)
|
int Start(void) {
|
||||||
{
|
|
||||||
if (ConfigStartX11Server) {
|
if (ConfigStartX11Server) {
|
||||||
StartXServer();
|
StartXServer();
|
||||||
}
|
}
|
||||||
@ -3234,8 +3159,7 @@ int Start(void)
|
|||||||
**
|
**
|
||||||
** @note stop everything, but don't cleanup, module is still called.
|
** @note stop everything, but don't cleanup, module is still called.
|
||||||
*/
|
*/
|
||||||
void Stop(void)
|
void Stop(void) {
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Debug(3, "video: max used PES packet size: %d\n", VideoMaxPacketSize);
|
Debug(3, "video: max used PES packet size: %d\n", VideoMaxPacketSize);
|
||||||
#endif
|
#endif
|
||||||
@ -3244,8 +3168,7 @@ void Stop(void)
|
|||||||
/**
|
/**
|
||||||
** Perform any cleanup or other regular tasks.
|
** Perform any cleanup or other regular tasks.
|
||||||
*/
|
*/
|
||||||
void Housekeeping(void)
|
void Housekeeping(void) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// when starting an own X11 server fails, try to connect to a already
|
// when starting an own X11 server fails, try to connect to a already
|
||||||
// running X11 server. This can take some time.
|
// running X11 server. This can take some time.
|
||||||
@ -3274,8 +3197,7 @@ void Housekeeping(void)
|
|||||||
/**
|
/**
|
||||||
** Main thread hook, periodic called from main thread.
|
** Main thread hook, periodic called from main thread.
|
||||||
*/
|
*/
|
||||||
void MainThreadHook(void)
|
void MainThreadHook(void) {
|
||||||
{
|
|
||||||
if (Usr1Signal) { // x11 server ready
|
if (Usr1Signal) { // x11 server ready
|
||||||
// FIYME: x11 server keeps sending sigusr1 signals
|
// FIYME: x11 server keeps sending sigusr1 signals
|
||||||
signal(SIGUSR1, SIG_IGN); // ignore further signals
|
signal(SIGUSR1, SIG_IGN); // ignore further signals
|
||||||
@ -3299,8 +3221,7 @@ extern void DelPip(void);
|
|||||||
** @param audio suspend closes audio
|
** @param audio suspend closes audio
|
||||||
** @param dox11 suspend closes x11 server
|
** @param dox11 suspend closes x11 server
|
||||||
*/
|
*/
|
||||||
void Suspend(int video, int audio, int dox11)
|
void Suspend(int video, int audio, int dox11) {
|
||||||
{
|
|
||||||
pthread_mutex_lock(&SuspendLockMutex);
|
pthread_mutex_lock(&SuspendLockMutex);
|
||||||
if (MyVideoStream->SkipStream && SkipAudio) { // already suspended
|
if (MyVideoStream->SkipStream && SkipAudio) { // already suspended
|
||||||
pthread_mutex_unlock(&SuspendLockMutex);
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
@ -3342,8 +3263,7 @@ void Suspend(int video, int audio, int dox11)
|
|||||||
/**
|
/**
|
||||||
** Resume plugin.
|
** Resume plugin.
|
||||||
*/
|
*/
|
||||||
void Resume(void)
|
void Resume(void) {
|
||||||
{
|
|
||||||
if (!MyVideoStream->SkipStream && !SkipAudio) { // we are not suspended
|
if (!MyVideoStream->SkipStream && !SkipAudio) { // we are not suspended
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3382,8 +3302,7 @@ void Resume(void)
|
|||||||
** @param[out] count number of decoded frames
|
** @param[out] count number of decoded frames
|
||||||
*/
|
*/
|
||||||
void GetStats(int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height,
|
void GetStats(int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height,
|
||||||
int *color, int *eotf)
|
int *color, int *eotf) {
|
||||||
{
|
|
||||||
*missed = 0;
|
*missed = 0;
|
||||||
*duped = 0;
|
*duped = 0;
|
||||||
*dropped = 0;
|
*dropped = 0;
|
||||||
@ -3407,12 +3326,14 @@ void GetStats(int *missed, int *duped, int *dropped, int *counter, float *framet
|
|||||||
** @param width video window width OSD relative
|
** @param width video window width OSD relative
|
||||||
** @param height video window height OSD relative
|
** @param height video window height OSD relative
|
||||||
*/
|
*/
|
||||||
void ScaleVideo(int x, int y, int width, int height)
|
void ScaleVideo(int x, int y, int width, int height) {
|
||||||
{
|
|
||||||
#ifdef USE_PIP
|
#ifdef USE_PIP
|
||||||
if (PiPActive && !(x & y & width & height)) {
|
if (PiPActive && !(x & y & width & height)) {
|
||||||
Info("[softhddev]%s: fullscreen with PiP active.\n", __FUNCTION__);
|
Info("[softhddev]%s: fullscreen with PiP active.\n", __FUNCTION__);
|
||||||
x = mwx; y = mwy; width = mww; height = mwh;
|
x = mwx;
|
||||||
|
y = mwy;
|
||||||
|
width = mww;
|
||||||
|
height = mwh;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (MyVideoStream->HwDecoder) {
|
if (MyVideoStream->HwDecoder) {
|
||||||
@ -3438,8 +3359,7 @@ void ScaleVideo(int x, int y, int width, int height)
|
|||||||
** @param pip_width pip window width OSD relative
|
** @param pip_width pip window width OSD relative
|
||||||
** @param pip_height pip window height OSD relative
|
** @param pip_height pip window height OSD relative
|
||||||
*/
|
*/
|
||||||
void PipSetPosition(int x, int y, int width, int height, int pip_x, int pip_y, int pip_width, int pip_height)
|
void PipSetPosition(int x, int y, int width, int height, int pip_x, int pip_y, int pip_width, int pip_height) {
|
||||||
{
|
|
||||||
if (!MyVideoStream->HwDecoder) { // video not running
|
if (!MyVideoStream->HwDecoder) { // video not running
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3463,8 +3383,7 @@ void PipSetPosition(int x, int y, int width, int height, int pip_x, int pip_y, i
|
|||||||
** @param pip_width pip window width OSD relative
|
** @param pip_width pip window width OSD relative
|
||||||
** @param pip_height pip window height OSD relative
|
** @param pip_height pip window height OSD relative
|
||||||
*/
|
*/
|
||||||
void PipStart(int x, int y, int width, int height, int pip_x, int pip_y, int pip_width, int pip_height)
|
void PipStart(int x, int y, int width, int height, int pip_x, int pip_y, int pip_width, int pip_height) {
|
||||||
{
|
|
||||||
if (!MyVideoStream->HwDecoder) { // video not running
|
if (!MyVideoStream->HwDecoder) { // video not running
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3473,15 +3392,17 @@ void PipStart(int x, int y, int width, int height, int pip_x, int pip_y, int pip
|
|||||||
VideoStreamOpen(PipVideoStream);
|
VideoStreamOpen(PipVideoStream);
|
||||||
}
|
}
|
||||||
PipSetPosition(x, y, width, height, pip_x, pip_y, pip_width, pip_height);
|
PipSetPosition(x, y, width, height, pip_x, pip_y, pip_width, pip_height);
|
||||||
mwx = x; mwy = y; mww = width; mwh = height;
|
mwx = x;
|
||||||
|
mwy = y;
|
||||||
|
mww = width;
|
||||||
|
mwh = height;
|
||||||
PiPActive = 1;
|
PiPActive = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Stop PIP.
|
** Stop PIP.
|
||||||
*/
|
*/
|
||||||
void PipStop(void)
|
void PipStop(void) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!MyVideoStream->HwDecoder) { // video not running
|
if (!MyVideoStream->HwDecoder) { // video not running
|
||||||
@ -3489,7 +3410,10 @@ void PipStop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PiPActive = 0;
|
PiPActive = 0;
|
||||||
mwx = 0; mwy = 0; mww = 0; mwh = 0;
|
mwx = 0;
|
||||||
|
mwy = 0;
|
||||||
|
mww = 0;
|
||||||
|
mwh = 0;
|
||||||
ScaleVideo(0, 0, 0, 0);
|
ScaleVideo(0, 0, 0, 0);
|
||||||
|
|
||||||
PipVideoStream->Close = 1;
|
PipVideoStream->Close = 1;
|
||||||
@ -3507,9 +3431,6 @@ void PipStop(void)
|
|||||||
**
|
**
|
||||||
** @return number of bytes used, 0 if internal buffer are full.
|
** @return number of bytes used, 0 if internal buffer are full.
|
||||||
*/
|
*/
|
||||||
int PipPlayVideo(const uint8_t * data, int size)
|
int PipPlayVideo(const uint8_t *data, int size) { return PlayVideo3(PipVideoStream, data, size); }
|
||||||
{
|
|
||||||
return PlayVideo3(PipVideoStream, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
/// C callback feed key press
|
/// C callback feed key press
|
||||||
extern void FeedKeyPress(const char *, const char *, int, int, const char *);
|
extern void FeedKeyPress(const char *, const char *, int, int, const char *);
|
||||||
|
@ -26,11 +26,9 @@
|
|||||||
#define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1"
|
#define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1"
|
||||||
#define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0"
|
#define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0"
|
||||||
|
|
||||||
enum
|
enum { GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
|
||||||
{ GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int structSize;
|
int structSize;
|
||||||
|
|
||||||
// request data
|
// request data
|
||||||
@ -45,13 +43,11 @@ typedef struct
|
|||||||
void *img;
|
void *img;
|
||||||
} SoftHDDevice_AtmoGrabService_v1_0_t;
|
} SoftHDDevice_AtmoGrabService_v1_0_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int Mode;
|
int Mode;
|
||||||
} SoftHDDevice_Osd3DModeService_v1_0_t;
|
} SoftHDDevice_Osd3DModeService_v1_0_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
// request/reply data
|
// request/reply data
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
|
1
video.h
1
video.h
@ -45,6 +45,7 @@ extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
|||||||
extern int VideoAudioDelay; ///< audio/video delay
|
extern int VideoAudioDelay; ///< audio/video delay
|
||||||
extern char ConfigStartX11Server; ///< flag start the x11 server
|
extern char ConfigStartX11Server; ///< flag start the x11 server
|
||||||
extern char MyConfigDir[];
|
extern char MyConfigDir[];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Prototypes
|
// Prototypes
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user