mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7f0cf6d6f | ||
|
|
346953d209 | ||
|
|
97af9c6de2 | ||
|
|
8dd95dab5e | ||
|
|
6775173e4f | ||
|
|
9170fcf485 | ||
|
|
919428cb80 | ||
|
|
4331692ee5 | ||
|
|
5aa826bdb0 | ||
|
|
6736db082e | ||
|
|
807b4df381 | ||
| 56edfd4f54 | |||
|
|
0a1a258d2a | ||
|
|
09a0880d07 | ||
|
|
a98a4adc7e | ||
|
|
f872f54e2a | ||
| 33c638d538 | |||
|
|
0a2a221fa9 | ||
|
|
24a065e5de | ||
|
|
6df970ca9e | ||
|
|
616cd9e133 | ||
|
|
a91533f6d1 | ||
|
|
baa4500a2c | ||
|
|
f28a737a9a | ||
|
|
19cec561ba | ||
|
|
d8f63adaad | ||
|
|
8c16466d31 | ||
|
|
ced54a5cf1 | ||
|
|
08246b5ac3 | ||
|
|
c3a1de8c7b | ||
|
|
918170d00b | ||
|
|
bc50f37c4d | ||
|
|
09cf1f5c85 | ||
|
|
947f6b312e | ||
|
|
99728258f1 | ||
|
|
c972f8c4dd | ||
|
|
7d38dff5bf | ||
|
|
8db8b68edd | ||
|
|
00cafd18ed | ||
|
|
ab4e89132e | ||
|
|
3585f1df19 | ||
|
|
e258c35537 | ||
|
|
91dbe46786 | ||
|
|
a7389111ff | ||
|
|
27e9a88e2f | ||
|
|
33e9c71aea | ||
|
|
bd84e3f3b9 | ||
|
|
364cc04736 | ||
| ec4a899bb8 | |||
|
|
dab31e2367 | ||
|
|
e613ff1f7e | ||
|
|
1886b745e5 | ||
|
|
422c378a5e | ||
|
|
eed708b9ea | ||
|
|
60a7c36fa6 | ||
|
|
4d74ed1bfc | ||
|
|
c3b924a239 | ||
|
|
f8d198636b | ||
|
|
bcf6ecabc1 | ||
|
|
9063b4e3ff | ||
|
|
e3681812bd | ||
|
|
9d14522121 | ||
| 2dff69dc14 | |||
|
|
5668fa22d2 | ||
|
|
c7cebe1aeb | ||
|
|
037f582bad | ||
|
|
6ca4d3c44f | ||
|
|
2ac2eb39c6 | ||
|
|
217545542d | ||
|
|
5f43803236 | ||
|
|
993d831190 | ||
|
|
1969b2a0a7 | ||
|
|
0fad02285d | ||
|
|
9546233175 | ||
|
|
98d2e0f728 | ||
| 970493fb23 | |||
|
|
329dbc5f07 | ||
|
|
bc8a13e1ef | ||
|
|
bd7e6143c7 | ||
|
|
fa27a1c73a | ||
|
|
e32857a27a | ||
|
|
5ba88bb822 | ||
|
|
0422b6aa5a | ||
|
|
eb024558de | ||
|
|
1593d5dd83 | ||
|
|
09f62307d4 | ||
|
|
87f7aa63cc | ||
|
|
b1ce88923e | ||
|
|
c6e66e0787 | ||
|
|
19d4eeed82 | ||
|
|
9f668c4750 | ||
|
|
e419742a40 | ||
|
|
2cacdc6c90 | ||
|
|
6efe558f78 | ||
|
|
80100299f3 | ||
|
|
5509d768ac | ||
|
|
c0d0a4ae7c |
157
ChangeLog
157
ChangeLog
@@ -1,4 +1,161 @@
|
||||
User johns
|
||||
Date: Thu Feb 16 09:59:14 CET 2012
|
||||
|
||||
Release Version 0.4.8
|
||||
Fix bug: wrong start of video packet.
|
||||
VDPAU: Enables inverse telecine configuration.
|
||||
Find AC3 (Dolby Digital) inside PES packet.
|
||||
Fix bug: audio increments invalid audio PTS.
|
||||
Fix bug: dvd plugin not working.
|
||||
Fix bug: used frame-> instead of video_ctx-> for old libav/ffmpeg.
|
||||
|
||||
User johns
|
||||
Date: Mon Feb 13 23:20:26 CET 2012
|
||||
|
||||
Release Version 0.4.7
|
||||
|
||||
User FireFly
|
||||
Date: Mon Feb 13 20:14:11 CET 2012
|
||||
|
||||
Fix bug: unscaled jpeg includes PNG header.
|
||||
|
||||
User johns
|
||||
Date: Mon Feb 13 14:58:26 CET 2012
|
||||
|
||||
VDPAU: Studio levels could be configured in the setup menu.
|
||||
Window size defaults to fullscreen, if no geometry is given.
|
||||
|
||||
User m.Rcu
|
||||
Date: Sun Feb 12 20:28:22 CET 2012
|
||||
|
||||
Jpeg screengrab use VDR RgbToJpeg function.
|
||||
|
||||
User johns
|
||||
Date: Sun Feb 12 20:14:43 CET 2012
|
||||
|
||||
Add play/pause audio support.
|
||||
Fix bug: audible glitch when switching AC-3 pass-through <-> none.
|
||||
Fix bug: mpeg stills not displayed.
|
||||
Detect audio stream type only after stream switch.
|
||||
Detect more h264 streams with leading zeros.
|
||||
VDPAU: support for studio levels added.
|
||||
Add support for skip chroma deinterlace to software deinterlacer.
|
||||
Type of software deinterlacer now configurable from setup menu.
|
||||
Mixer channel could be set through command line option.
|
||||
Fix bug: LFE moved to wrong position.
|
||||
Guard suspend/resume against multiple calls.
|
||||
Add support for AAC LATM audio streams.
|
||||
Fix bug: alsa and ffmpeg use different channel layout.
|
||||
Support more LPCM sample rates and number of channels.
|
||||
Quick&dirty support for mpeg LPCM streams.
|
||||
Workaround for text2skin undrawn OSD areas.
|
||||
Detect dvb LPCM stream and ignore it.
|
||||
|
||||
User johns
|
||||
Date: Thu Feb 2 23:29:35 CET 2012
|
||||
|
||||
Release Version 0.4.6
|
||||
Warn only on the first duplicated frame in sequence.
|
||||
Increase audio buffer, if bigger audio delay is used.
|
||||
Makes SkipLines configure in setup menu.
|
||||
Auto-crop only enabled with normal 4:3 display mode.
|
||||
Vaapi updates OSD when cropping changes.
|
||||
Add A-V info output and compile time option.
|
||||
Fix bug: VA-API intel software decoder broken by aspect commit.
|
||||
Add support for 4:3 output modes.
|
||||
Quicker auto-crop after channel switch.
|
||||
Add auto-crop support for Intel VA-API backend.
|
||||
Fix bug: Auto-Crop logo skip didn't use displayed width.
|
||||
Workaround for mpeg2 FFMpeg + VA-API + Intel GPU hung.
|
||||
Fix bug: Missing vaSyncSurface and vaDestroyImage.
|
||||
Fix bug: Only black picture with VA-API hw decoder.
|
||||
|
||||
User HelAu
|
||||
Date: Mon Jan 30 16:54:47 CET 2012
|
||||
|
||||
Add support to start the plugin in suspended mode.
|
||||
|
||||
User johns
|
||||
Date: Mon Jan 30 15:58:21 CET 2012
|
||||
|
||||
Finished rewrite of video code, to support output modules.
|
||||
Add aspect change support to software decoder path.
|
||||
Repair software decoder with vaapi vdpau backend.
|
||||
Add workaround for Intel VA-API MPEG GPU hung.
|
||||
|
||||
User johns
|
||||
Date: Sat Jan 28 13:32:12 CET 2012
|
||||
|
||||
Release Version 0.4.5
|
||||
Add configurable skip lines at video top and bottom.
|
||||
Add auto-crop tolerance configuration.
|
||||
Reduces audio latency, increases audio buffer time.
|
||||
Made video_test working again.
|
||||
Disabled VA-API Intel vaAssociateSubpicture workaround.
|
||||
Fix bug: Must release lock for VideoPollEvent.
|
||||
Allow faster video and audio sync.
|
||||
Fix bug: Software decoder use vaPutImage with intel backend.
|
||||
Fix bug: Artefacts are shown after mpeg2 channel switch.
|
||||
Fix bug: VideoReleaseSurface called after VideoExit.
|
||||
Support external players.
|
||||
Add VDPAU display preemption support.
|
||||
|
||||
User m.Rcu
|
||||
Date: Tue Jan 24 22:38:30 CET 2012
|
||||
|
||||
Add support for grab jpeg image.
|
||||
|
||||
User johns
|
||||
Date: Tue Jan 24 22:25:33 CET 2012
|
||||
|
||||
Fix bug: VaapiOsdExit doesn't deassociate osd surface.
|
||||
Fix bug: First OSD can show random pixels.
|
||||
Wait for X11 exit and kill it, if not.
|
||||
Fix still picture handling.
|
||||
Fix for dead-lock in VdpauExit.
|
||||
Workaround for dead-lock in VdpauExit.
|
||||
VDPAU: Add very primitive software scaler for grab image.
|
||||
VA-API: Add auto-crop support.
|
||||
Suspend can close/open X11 window, connection and audio device.
|
||||
|
||||
User Morone
|
||||
Date: Sun Jan 22 16:43:23 CET 2012
|
||||
|
||||
Use different alsa devices for AC3/pass-through and pcm.
|
||||
|
||||
User johns
|
||||
Date: Sun Jan 22 11:12:57 CET 2012
|
||||
|
||||
Add dummy player and control for suspend mode.
|
||||
Buffertime compile time configurable in ms.
|
||||
|
||||
Date: Sat Jan 21 15:49:16 CET 2012
|
||||
|
||||
Release Version 0.4.0
|
||||
VDPAU: Add grab image support.
|
||||
VDPAU: Add auto-crop support.
|
||||
VDPAU: Changed OSD alpha calculation.
|
||||
Fix bug: Used VideoSharpen for denoise settings.
|
||||
Instant update deinterlace/... configuration changes.
|
||||
Fix bug: AudioExit called without AudioInit crash.
|
||||
|
||||
Date: Thu Jan 19 15:58:40 CET 2012
|
||||
|
||||
Release Version 0.3.5
|
||||
OSD improvements:
|
||||
Use OSD size equal to video window.
|
||||
Update only dirty area(s) of OSD.
|
||||
Show/mix only used area of OSD.
|
||||
Fix bug: vpdau use previous resolution for deint, ...
|
||||
Fix software deinterlace with VA-API.
|
||||
Fix bug: transposed digits 567 should be 576.
|
||||
Audio module cleanup:
|
||||
Alsa + OSS can be included/build at the same time.
|
||||
Alsa or OSS can be runtime selected with -a.
|
||||
Add audio thread support to OSS module.
|
||||
Add polled audio support to alsa module.
|
||||
Removed some debug source code.
|
||||
|
||||
Date: Sun Jan 15 16:56:04 CET 2012
|
||||
|
||||
Release Version 0.3.1
|
||||
|
||||
38
Makefile
38
Makefile
@@ -14,22 +14,25 @@ PLUGIN = softhddevice
|
||||
### The version number of this plugin (taken from the main source file):
|
||||
|
||||
VERSION = $(shell grep 'static const char \*const VERSION *=' $(PLUGIN).cpp | awk '{ print $$7 }' | sed -e 's/[";]//g')
|
||||
GIT_REV = $(shell git describe --always 2>/dev/null)
|
||||
|
||||
### Configuration (edit this for your needs)
|
||||
|
||||
CONFIG := #-DDEBUG
|
||||
CONFIG += -DAV_INFO
|
||||
#CONFIG += -DHAVE_PTHREAD_NAME
|
||||
CONFIG += $(shell pkg-config --exists vdpau && echo "-DUSE_VDPAU")
|
||||
CONFIG += $(shell pkg-config --exists libva && echo "-DUSE_VAAPI")
|
||||
CONFIG += $(shell pkg-config --exists alsa && echo "-DUSE_ALSA")
|
||||
#CONFIG += -DUSE_OSS
|
||||
CONFIG += -DUSE_OSS
|
||||
|
||||
### The C++ compiler and options:
|
||||
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
||||
-Wdeclaration-after-statement
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
||||
-Wdeclaration-after-statement \
|
||||
-ftree-vectorize -msse3 -flax-vector-conversions
|
||||
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Woverloaded-virtual
|
||||
|
||||
### The directory environment:
|
||||
@@ -59,7 +62,8 @@ PACKAGE = vdr-$(ARCHIVE)
|
||||
|
||||
INCLUDES += -I$(VDRDIR)/include
|
||||
|
||||
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' \
|
||||
$(if $(GIT_REV), -DGIT_REV='"$(GIT_REV)"')
|
||||
|
||||
_CFLAGS = $(DEFINES) $(INCLUDES) \
|
||||
$(shell pkg-config --cflags libavcodec libavformat) \
|
||||
@@ -67,15 +71,15 @@ _CFLAGS = $(DEFINES) $(INCLUDES) \
|
||||
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||
`pkg-config --cflags gl glu` \
|
||||
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
||||
`pkg-config --cflags vdpau`) \
|
||||
`pkg-config --cflags vdpau`) \
|
||||
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
||||
`pkg-config --cflags libva-x11 libva-glx libva`) \
|
||||
`pkg-config --cflags libva-x11 libva-glx libva`) \
|
||||
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
||||
`pkg-config --cflags alsa`)
|
||||
`pkg-config --cflags alsa`)
|
||||
|
||||
#override _CFLAGS += -Werror
|
||||
override CXXFLAGS += $(_CFLAGS)
|
||||
override CFLAGS += $(_CFLAGS)
|
||||
override CFLAGS += $(_CFLAGS)
|
||||
|
||||
LIBS += -lrt \
|
||||
$(shell pkg-config --libs libavcodec libavformat) \
|
||||
@@ -83,11 +87,11 @@ LIBS += -lrt \
|
||||
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||
`pkg-config --libs gl glu` \
|
||||
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
||||
`pkg-config --libs vdpau`) \
|
||||
`pkg-config --libs vdpau`) \
|
||||
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
||||
`pkg-config --libs libva-x11 libva-glx libva`) \
|
||||
`pkg-config --libs libva-x11 libva-glx libva`) \
|
||||
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
||||
`pkg-config --libs alsa`)
|
||||
`pkg-config --libs alsa`)
|
||||
|
||||
### The object files (add further files here):
|
||||
|
||||
@@ -116,11 +120,11 @@ $(OBJS): Makefile
|
||||
|
||||
### Internationalization (I18N):
|
||||
|
||||
PODIR = po
|
||||
PODIR = po
|
||||
LOCALEDIR = $(VDRDIR)/locale
|
||||
I18Npo = $(wildcard $(PODIR)/*.po)
|
||||
I18Npo = $(wildcard $(PODIR)/*.po)
|
||||
I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
|
||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||
I18Npot = $(PODIR)/$(PLUGIN).pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -c -o $@ $<
|
||||
@@ -169,6 +173,6 @@ indent:
|
||||
indent $$i; unexpand -a $$i > $$i.up; mv $$i.up $$i; \
|
||||
done
|
||||
|
||||
video_test: video.c
|
||||
video_test: video.c Makefile
|
||||
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
|
||||
-o $@
|
||||
|
||||
84
README.txt
84
README.txt
@@ -24,17 +24,20 @@ A software and GPU emulated HD output device plugin for VDR.
|
||||
o Video CPU/VA-API
|
||||
o Video VDPAU/VDPAU
|
||||
o Video CPU/VDPAU
|
||||
o Audio FFMpeg/Alsa/Analog
|
||||
o Audio FFMpeg/Alsa/Digital
|
||||
o Audio FFMpeg/OSS/Analog
|
||||
o HDMI/SPDIF Passthrough
|
||||
o VA-API bob software deinterlace
|
||||
o Auto-crop
|
||||
|
||||
o planned: Video VA-API/Opengl
|
||||
o planned: Video VDPAU/Opengl
|
||||
o planned: Video CPU/Xv
|
||||
o planned: Video CPU/Opengl
|
||||
o planned: Software Deinterlacer
|
||||
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
||||
o planned: Video XvBA/XvBA
|
||||
o Audio FFMpeg/Alsa/Analog
|
||||
o Audio FFMpeg/Alsa/Digital
|
||||
o Audio FFMpeg/OSS/Analog
|
||||
o Alsa HDMI/SPDIF Passthrough
|
||||
o planned: OSS HDMI/SPDIF Passthrough
|
||||
o planned: atmo light support
|
||||
|
||||
To compile you must have the 'requires' installed.
|
||||
|
||||
@@ -61,7 +64,7 @@ Install:
|
||||
http://projects.vdr-developer.org/projects/plg-softhddevice/files
|
||||
|
||||
tar vxf vdr-softhddevice-*.tar.bz2
|
||||
cd vdr-softhddevice
|
||||
cd softhddevice-*
|
||||
make VDRDIR=<path-to-your-vdr-files> LIBDIR=.
|
||||
|
||||
You can edit Makefile to enable/disable VDPAU / VA-API / Alsa / OSS
|
||||
@@ -73,16 +76,28 @@ Setup: environment
|
||||
|
||||
DISPLAY=:0.0
|
||||
x11 display name
|
||||
NO_HW=1
|
||||
if set don't use the hardware decoders
|
||||
NO_MPEG_HW=1
|
||||
if set don't use the hardware decoder for mpeg1/2
|
||||
STUDIO_LEVELS=1
|
||||
if set use studio levels with vdpau (deprecated use setup)
|
||||
|
||||
only if alsa is configured
|
||||
ALSA_DEVICE=default
|
||||
alsa PCM device name
|
||||
ALSA_AC3_DEVICE=
|
||||
alsa AC3/pass-though device name
|
||||
ALSA_MIXER=default
|
||||
alsa control device name
|
||||
ALSA_MIXER_CHANNEL=PCM
|
||||
alsa control channel name
|
||||
|
||||
only if oss is configured
|
||||
OSS_AUDIODEV=/dev/dsp
|
||||
oss dsp device name
|
||||
OSS_AC3_AUDIODEV=
|
||||
oss AC3/pass-though device name
|
||||
OSS_MIXERDEV=/dev/mixer
|
||||
oss mixer device name
|
||||
OSS_MIXER_CHANNEL=pcm
|
||||
@@ -98,7 +113,7 @@ Setup: /etc/vdr/setup.conf
|
||||
softhddevice.HideMainMenuEntry = 0
|
||||
0 = show softhddevice main menu entry, 1 = hide entry
|
||||
|
||||
<res> of the next parameters is 567i, 720p, 1080i_fake or 1080i.
|
||||
<res> of the next parameters is 576i, 720p, 1080i_fake or 1080i.
|
||||
1080i_fake is 1280x1080 or 1440x1080
|
||||
1080i is "real" 1920x1080
|
||||
|
||||
@@ -112,6 +127,9 @@ Setup: /etc/vdr/setup.conf
|
||||
softhddevice.<res>.SkipChromaDeinterlace = 0
|
||||
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
||||
|
||||
softhddevice.<res>.InverseTelecine = 0
|
||||
0 = disabled, 1 = enabled
|
||||
|
||||
softhddevice.<res>.Denoise = 0
|
||||
0 .. 1000 noise reduction level (0 off, 1000 max)
|
||||
|
||||
@@ -125,6 +143,39 @@ Setup: /etc/vdr/setup.conf
|
||||
softhddevice.AudioPassthrough = 0
|
||||
0 = none, 1 = AC-3
|
||||
|
||||
for AC-3 the pass-through device is used.
|
||||
|
||||
softhddevice.AutoCrop.Interval = 0
|
||||
0 disables auto-crop
|
||||
n each 'n' frames auto-crop is checked.
|
||||
|
||||
softhddevice.AutoCrop.Delay = 0
|
||||
if auto-crop is over 'n' intervals the same, the cropping is
|
||||
used.
|
||||
|
||||
softhddevice.AutoCrop.Tolerance = 0
|
||||
if detected crop area is too small, cut max 'n' pixels at top and
|
||||
bottom.
|
||||
|
||||
softhddevice.SkipLines = 0
|
||||
skip 'n' lines at top and bottom of the video picture.
|
||||
|
||||
softhddevice.StudioLevels = 0
|
||||
0 use PC levels (0-255) with vdpau.
|
||||
1 use studio levels (16-235) with vdpau.
|
||||
|
||||
softhddevice.Suspend.Close = 0
|
||||
1 suspend closes x11 window, connection and audio device.
|
||||
(use svdrpsend plug softhddevice RESU to resume, if you have no lirc)
|
||||
|
||||
softhddevice.Suspend.X11 = 0
|
||||
1 suspend stops X11 server (not working yet)
|
||||
|
||||
VideoDisplayFormat = ?
|
||||
0 pan and scan
|
||||
1 letter box
|
||||
2 center cut-out
|
||||
|
||||
Setup: /etc/vdr/remote.conf
|
||||
------
|
||||
|
||||
@@ -144,7 +195,22 @@ Setup: /etc/vdr/remote.conf
|
||||
Commandline:
|
||||
------------
|
||||
|
||||
Use vdr -h to see the command line arguments support by the plugin.
|
||||
Use vdr -h to see the command line arguments supported by the plugin.
|
||||
|
||||
-a audio_device
|
||||
|
||||
Selects audio output module and device.
|
||||
"" to disable audio output
|
||||
/... to use oss audio module (if compiled with oss
|
||||
support)
|
||||
other to use alsa audio module (if compiled with alsa
|
||||
support)
|
||||
|
||||
SVDRP:
|
||||
------
|
||||
|
||||
Use 'svdrpsend.pl plug softhddevice HELP' to see the SVDRP commands
|
||||
help and which are supported by the plugin.
|
||||
|
||||
Running:
|
||||
--------
|
||||
|
||||
87
Todo
87
Todo
@@ -19,67 +19,84 @@ GNU Affero General Public License for more details.
|
||||
$Id: $
|
||||
|
||||
missing:
|
||||
software deinterlace
|
||||
auto crop
|
||||
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
||||
suspend output / energie saver: stop audio, stop video, configurable
|
||||
software deinterlace (yadif, ...)
|
||||
software decoder with software deinterlace
|
||||
suspend output / energie saver: stop and restart X11
|
||||
suspend plugin didn't restore full-screen (is this wanted?)
|
||||
Option deinterlace off / deinterlace force!
|
||||
Make output drivers better moduluar.
|
||||
ColorSpace aren't configurable with the gui.
|
||||
Inverse telecine isn't configurable with the gui.
|
||||
|
||||
crash:
|
||||
AudioPlayHandlerThread -> pthread_cond_wait
|
||||
|
||||
video:
|
||||
subtitle not cleared
|
||||
subtitle could be asyncron
|
||||
reduce warnings after channel switch
|
||||
grab image with hardware and better scaling support
|
||||
hard channel switch
|
||||
OSD can only be shown after some stream could be shown
|
||||
yaepghd changed position is lost on channel switch
|
||||
pause (live tv) has sometime problems with SAT1 HD Pro7 HD
|
||||
|
||||
vdpau:
|
||||
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
||||
1080i with temporal spatial too slow with my GT 520 on some channels
|
||||
SkipChromaDeinterlace improves performance
|
||||
Improve OSD handling, show only what is used. Big OSD costs performance
|
||||
VdpPreemptionCallback handling
|
||||
hard channel switch
|
||||
suspendoutput didn't show logo or black picture.
|
||||
software decoder path not working
|
||||
|
||||
libva:
|
||||
hard channel switch
|
||||
yaepghd (VaapiSetOutputPosition) support
|
||||
can associate only displayed part of osd
|
||||
grab image for va-api
|
||||
remove stderr output of libva init
|
||||
still many: (workaround export NO_MPEG_HW=1)
|
||||
[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
|
||||
[drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ...
|
||||
|
||||
libva: branch vaapi-ext
|
||||
add support for vaapi-ext
|
||||
|
||||
libva-intel-driver:
|
||||
intel still has hangups most with 1080i
|
||||
1080i does no v-sync (workaround written)
|
||||
osd has sometimes wrong size (workaround written)
|
||||
deinterlace only supported with vaapi-ext
|
||||
1080i does no v-sync (sometimes correct working with vaapi-ext)
|
||||
OSD has sometimes wrong size (workaround written)
|
||||
sometimes software decoder deinterlace isn't working and 1080i channels
|
||||
show artefacts
|
||||
|
||||
libva-vdpau-driver:
|
||||
G210 osd update too slow (needs hardware problem workaround)
|
||||
OSD update is too slow
|
||||
G210/GT520 OSD update too slow (needs hardware problem workaround)
|
||||
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
||||
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
||||
OSD still has some problems with auto-crop and 4:3 zoom.
|
||||
|
||||
libva-xvba-driver:
|
||||
|
||||
x11:
|
||||
disable screensaver
|
||||
skip multiple configure-notify, handle only the last one.
|
||||
support embedded mode
|
||||
|
||||
audio:
|
||||
write TS -> PES parser, which feeds audio before the next start packet
|
||||
Combine alsa+oss ringbuffer code.
|
||||
Make alsa thread/polled and oss thread/polled output module runtime
|
||||
selectable.
|
||||
software volume support (could be done with asound.conf)
|
||||
Mute should do a real mute and not only set volume to zero.
|
||||
Starting suspended and muted, didn't register the mute.
|
||||
|
||||
audio/alsa:
|
||||
done? video/audio asyncron
|
||||
random crashes in av_parser_parse2, when switching channels
|
||||
sometimes alsa hangs
|
||||
fixed? snd_pcm_state: Assertion `pcm' failed. while switching channels
|
||||
(thread problem)
|
||||
|
||||
better downmix of >2 channels on 2 channel hardware
|
||||
remix support of unsupported sample rates
|
||||
libav supports only resample of mono to 2 channels
|
||||
ffmpeg didn't support resample of 5 to 2 channels
|
||||
CodecAudioOpen can fail "can't open audio codec" and does Fatal exit.
|
||||
|
||||
audio:
|
||||
write TS -> PES parser, which feeds audio before the next start packet
|
||||
|
||||
audio/oss:
|
||||
alsa oss emulation mixer "pcm" not working
|
||||
oss4 mixer channel not working
|
||||
ring buffer overflow with alsa oss emulation
|
||||
|
||||
HDMI/SPDIF Passthrough:
|
||||
only AC-3 written
|
||||
Channels are wrong setup, if changing setting during operation.
|
||||
split pcm and ac-3 out into two devices
|
||||
|
||||
playback of recording
|
||||
pause is not reset, when replay exit
|
||||
@@ -92,7 +109,9 @@ setup:
|
||||
Setup 4:3 zoom type
|
||||
Some setup parameters are not used until restart.
|
||||
Can a notice be added to the setup menu?
|
||||
576i, 720p, fake 1080i, 1080i
|
||||
|
||||
unsorted:
|
||||
stoping vdr while plugin is suspended opens and closes a window.
|
||||
|
||||
future features (not planed for 1.0 - 1.5)
|
||||
|
||||
@@ -102,5 +121,7 @@ future features (not planed for 1.0 - 1.5)
|
||||
software decoder for xv / opengl
|
||||
atmolight support
|
||||
multistream handling
|
||||
pip support
|
||||
save and use auto-crop with channel zapping
|
||||
|
||||
upmix stereo to AC-3
|
||||
upmix stereo to AC-3 (supported by alsa plugin)
|
||||
|
||||
22
audio.h
22
audio.h
@@ -30,22 +30,28 @@
|
||||
extern void AudioEnqueue(const void *, int); ///< buffer audio samples
|
||||
extern void AudioFlushBuffers(void); ///< flush audio buffers
|
||||
extern void AudioPoller(void); ///< poll audio events/handling
|
||||
|
||||
extern int AudioFreeBytes(void); ///< free bytes in audio output
|
||||
|
||||
//extern int AudioUsedBytes(void); ///< used bytes in audio output
|
||||
extern uint64_t AudioGetDelay(void); ///< get current audio delay
|
||||
extern void AudioSetClock(int64_t); ///< set audio clock base
|
||||
extern int64_t AudioGetClock(); ///< get current audio clock
|
||||
extern uint64_t AudioGetDelay(void); ///< get current audio delay
|
||||
|
||||
extern int AudioSetup(int *, int *); ///< setup audio output
|
||||
|
||||
//extern void AudioPlay(void); ///< play audio
|
||||
//extern void AudioPause(void); ///< pause audio
|
||||
extern void AudioSetVolume(int); ///< set volume
|
||||
extern int AudioSetup(int *, int *, int); ///< setup audio output
|
||||
|
||||
extern void AudioSetDevice(const char *); ///< set alsa PCM audio device
|
||||
extern void AudioPlay(void); ///< play audio
|
||||
extern void AudioPause(void); ///< pause audio
|
||||
|
||||
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
||||
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
||||
extern void AudioSetChannel(const char *); ///< set mixer channel
|
||||
extern void AudioInit(void); ///< setup audio module
|
||||
extern void AudioExit(void); ///< cleanup and exit audio module
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Variables
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
||||
|
||||
/// @}
|
||||
|
||||
122
codec.c
122
codec.c
@@ -320,20 +320,30 @@ static void Codec_draw_horiz_band(AVCodecContext * video_ctx,
|
||||
**
|
||||
** @param hw_decoder video hardware decoder
|
||||
**
|
||||
** @returns private decoder pointer for audio/video decoder.
|
||||
** @returns private decoder pointer for video decoder.
|
||||
*/
|
||||
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
||||
{
|
||||
VideoDecoder *decoder;
|
||||
|
||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||
Fatal(_("codec: Can't allocate vodeo decoder\n"));
|
||||
Fatal(_("codec: can't allocate vodeo decoder\n"));
|
||||
}
|
||||
decoder->HwDecoder = hw_decoder;
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
/**
|
||||
** Deallocate a video decoder context.
|
||||
**
|
||||
** @param decoder private video decoder
|
||||
*/
|
||||
void CodecVideoDelDecoder(VideoDecoder * decoder)
|
||||
{
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
** Open video decoder.
|
||||
**
|
||||
@@ -347,6 +357,9 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
|
||||
|
||||
Debug(3, "codec: using codec %s or ID %#04x\n", name, codec_id);
|
||||
|
||||
if (decoder->VideoCtx) {
|
||||
Error(_("codec: missing close\n"));
|
||||
}
|
||||
//
|
||||
// ffmpeg compatibility hack
|
||||
//
|
||||
@@ -548,13 +561,13 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
||||
video_ctx->frame_number, used);
|
||||
}
|
||||
if (used != pkt->size) {
|
||||
if (used >= 0) {
|
||||
if (used >= 0 && used < pkt->size) {
|
||||
// some tv channels, produce this
|
||||
Debug(4,
|
||||
"codec: ooops didn't use complete video packet used %d of %d\n",
|
||||
used, pkt->size);
|
||||
pkt->data += used;
|
||||
pkt->size -= used;
|
||||
pkt->data += used;
|
||||
goto next_part;
|
||||
}
|
||||
Debug(3, "codec: bad frame %d\n", used);
|
||||
@@ -592,6 +605,7 @@ struct _audio_decoder_
|
||||
|
||||
/// audio parser to support insane dvb streaks
|
||||
AVCodecParserContext *AudioParser;
|
||||
int PassthroughAC3; ///< current ac-3 pass-through
|
||||
int SampleRate; ///< current stream sample rate
|
||||
int Channels; ///< current stream channels
|
||||
|
||||
@@ -608,26 +622,37 @@ static char CodecPassthroughAC3; ///< pass ac3 through
|
||||
|
||||
//static char CodecPassthroughDTS; ///< pass dts through (unsupported)
|
||||
//static char CodecPassthroughMPA; ///< pass mpa through (unsupported)
|
||||
#else
|
||||
|
||||
static const int CodecPassthroughAC3 = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
** Allocate a new audio decoder context.
|
||||
**
|
||||
** @param hw_decoder video hardware decoder
|
||||
**
|
||||
** @returns private decoder pointer for audio/video decoder.
|
||||
** @returns private decoder pointer for audio decoder.
|
||||
*/
|
||||
AudioDecoder *CodecAudioNewDecoder(void)
|
||||
{
|
||||
AudioDecoder *audio_decoder;
|
||||
|
||||
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
||||
Fatal(_("codec: Can't allocate audio decoder\n"));
|
||||
Fatal(_("codec: can't allocate audio decoder\n"));
|
||||
}
|
||||
|
||||
return audio_decoder;
|
||||
}
|
||||
|
||||
/**
|
||||
** Deallocate an audio decoder context.
|
||||
**
|
||||
** @param decoder private audio decoder
|
||||
*/
|
||||
void CodecAudioDelDecoder(AudioDecoder * decoder)
|
||||
{
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
** Open audio decoder.
|
||||
**
|
||||
@@ -714,10 +739,65 @@ void CodecSetAudioPassthrough(int mask)
|
||||
#ifdef USE_PASSTHROUGH
|
||||
CodecPassthroughAC3 = mask & 1 ? 1 : 0;
|
||||
#endif
|
||||
// FIXME: must update audio decoder (nr. of channels wrong)
|
||||
(void)mask;
|
||||
}
|
||||
|
||||
/**
|
||||
** Reorder audio frame.
|
||||
**
|
||||
** ffmpeg L R C Ls Rs -> alsa L R Ls Rs C
|
||||
** ffmpeg L R C LFE Ls Rs -> alsa L R Ls Rs C LFE
|
||||
** ffmpeg L R C LFE Ls Rs Rl Rr -> alsa L R Ls Rs C LFE Rl Rr
|
||||
*/
|
||||
static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
||||
{
|
||||
int i;
|
||||
int c;
|
||||
int ls;
|
||||
int rs;
|
||||
int lfe;
|
||||
|
||||
switch (channels) {
|
||||
case 5:
|
||||
size /= 2;
|
||||
for (i = 0; i < size; i += 5) {
|
||||
c = buf[i + 2];
|
||||
ls = buf[i + 3];
|
||||
rs = buf[i + 4];
|
||||
buf[i + 2] = ls;
|
||||
buf[i + 3] = rs;
|
||||
buf[i + 4] = c;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
size /= 2;
|
||||
for (i = 0; i < size; i += 6) {
|
||||
c = buf[i + 2];
|
||||
lfe = buf[i + 3];
|
||||
ls = buf[i + 4];
|
||||
rs = buf[i + 5];
|
||||
buf[i + 2] = ls;
|
||||
buf[i + 3] = rs;
|
||||
buf[i + 4] = c;
|
||||
buf[i + 5] = lfe;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
size /= 2;
|
||||
for (i = 0; i < size; i += 8) {
|
||||
c = buf[i + 2];
|
||||
lfe = buf[i + 3];
|
||||
ls = buf[i + 4];
|
||||
rs = buf[i + 5];
|
||||
buf[i + 2] = ls;
|
||||
buf[i + 3] = rs;
|
||||
buf[i + 4] = c;
|
||||
buf[i + 5] = lfe;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_AVPARSER
|
||||
|
||||
/**
|
||||
@@ -775,6 +855,10 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
dpkt->dts = audio_decoder->AudioParser->dts;
|
||||
buf_sz = sizeof(buf);
|
||||
l = avcodec_decode_audio3(audio_ctx, buf, &buf_sz, dpkt);
|
||||
if (l == AVERROR(EAGAIN)) {
|
||||
index += n; // this is needed for aac latm
|
||||
continue;
|
||||
}
|
||||
if (l < 0) { // no audio frame could be decompressed
|
||||
Error(_("codec: error audio data at %d\n"), index);
|
||||
break;
|
||||
@@ -791,10 +875,15 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
AudioSetClock(dpkt->pts);
|
||||
}
|
||||
// FIXME: must first play remainings bytes, than change and play new.
|
||||
if (audio_decoder->SampleRate != audio_ctx->sample_rate
|
||||
if (audio_decoder->PassthroughAC3 != CodecPassthroughAC3
|
||||
|| audio_decoder->SampleRate != audio_ctx->sample_rate
|
||||
|| audio_decoder->Channels != audio_ctx->channels) {
|
||||
int err;
|
||||
int isAC3;
|
||||
|
||||
audio_decoder->PassthroughAC3 = CodecPassthroughAC3;
|
||||
// FIXME: use swr_convert from swresample (only in ffmpeg!)
|
||||
// FIXME: tell ac3 decoder to use downmix
|
||||
if (audio_decoder->ReSample) {
|
||||
audio_resample_close(audio_decoder->ReSample);
|
||||
audio_decoder->ReSample = NULL;
|
||||
@@ -803,20 +892,19 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
||||
audio_decoder->Channels = audio_ctx->channels;
|
||||
#ifdef USE_PASSTHROUGH
|
||||
// SPDIF/HDMI passthrough
|
||||
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
|
||||
audio_decoder->HwChannels = 2;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
isAC3 = 1;
|
||||
} else {
|
||||
audio_decoder->HwChannels = audio_ctx->channels;
|
||||
isAC3 = 0;
|
||||
}
|
||||
|
||||
// channels not support?
|
||||
if ((err =
|
||||
AudioSetup(&audio_decoder->HwSampleRate,
|
||||
&audio_decoder->HwChannels))) {
|
||||
&audio_decoder->HwChannels, isAC3))) {
|
||||
Debug(3, "codec/audio: resample %dHz *%d -> %dHz *%d\n",
|
||||
audio_ctx->sample_rate, audio_ctx->channels,
|
||||
audio_decoder->HwSampleRate,
|
||||
@@ -869,6 +957,8 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
audio_decoder->HwChannels *
|
||||
av_get_bytes_per_sample(audio_ctx->sample_fmt);
|
||||
Debug(4, "codec/audio: %d -> %d\n", buf_sz, outlen);
|
||||
CodecReorderAudioFrame(outbuf, outlen,
|
||||
audio_decoder->HwChannels);
|
||||
AudioEnqueue(outbuf, outlen);
|
||||
}
|
||||
} else {
|
||||
@@ -947,6 +1037,8 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
// True HD?
|
||||
#endif
|
||||
#endif
|
||||
CodecReorderAudioFrame(buf, buf_sz,
|
||||
audio_decoder->HwChannels);
|
||||
AudioEnqueue(buf, buf_sz);
|
||||
}
|
||||
}
|
||||
|
||||
6
codec.h
6
codec.h
@@ -40,6 +40,9 @@ typedef struct _audio_decoder_ AudioDecoder;
|
||||
/// Allocate a new video decoder context.
|
||||
extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
|
||||
|
||||
/// Deallocate a video decoder context.
|
||||
extern void CodecVideoDelDecoder(VideoDecoder *);
|
||||
|
||||
/// Open video codec.
|
||||
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
|
||||
|
||||
@@ -55,6 +58,9 @@ extern void CodecVideoFlushBuffers(VideoDecoder *);
|
||||
/// Allocate a new audio decoder context.
|
||||
extern AudioDecoder *CodecAudioNewDecoder(void);
|
||||
|
||||
/// Deallocate an audio decoder context.
|
||||
extern void CodecAudioDelDecoder(AudioDecoder *);
|
||||
|
||||
/// Open audio codec.
|
||||
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
|
||||
|
||||
|
||||
2
misc.h
2
misc.h
@@ -86,7 +86,7 @@ static inline void Syslog(const int level, const char *format, ...)
|
||||
/**
|
||||
** Show fatal error.
|
||||
*/
|
||||
#define Fatal(fmt...) do { Error(fmt); exit(-1); } while (0)
|
||||
#define Fatal(fmt...) do { Error(fmt); abort(); } while (0)
|
||||
|
||||
/**
|
||||
** Show warning.
|
||||
|
||||
841
softhddev.c
841
softhddev.c
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,8 @@ extern "C"
|
||||
extern int PlayVideo(const uint8_t *, int);
|
||||
/// C plugin play TS video packet
|
||||
extern void PlayTsVideo(const uint8_t *, int);
|
||||
/// C plugin grab an image
|
||||
extern uint8_t *GrabImage(int *, int, int, int, int);
|
||||
|
||||
/// C plugin set play mode
|
||||
extern void SetPlayMode(void);
|
||||
@@ -77,7 +79,7 @@ extern "C"
|
||||
extern void MainThreadHook(void);
|
||||
|
||||
/// Suspend plugin
|
||||
extern void Suspend(void);
|
||||
extern void Suspend(int, int, int);
|
||||
/// Resume plugin
|
||||
extern void Resume(void);
|
||||
#ifdef __cplusplus
|
||||
|
||||
567
softhddevice.cpp
567
softhddevice.cpp
@@ -42,7 +42,7 @@ extern "C"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char *const VERSION = "0.3.1";
|
||||
static const char *const VERSION = "0.4.8";
|
||||
static const char *const DESCRIPTION =
|
||||
trNOOP("A software and GPU emulated HD device");
|
||||
|
||||
@@ -53,6 +53,7 @@ static class cSoftHdDevice *MyDevice;
|
||||
|
||||
#define RESOLUTIONS 4 ///< number of resolutions
|
||||
|
||||
/// resolutions names
|
||||
static const char *const Resolution[RESOLUTIONS] = {
|
||||
"576i", "720p", "1080i_fake", "1080i"
|
||||
};
|
||||
@@ -60,12 +61,18 @@ static const char *const Resolution[RESOLUTIONS] = {
|
||||
static char ConfigMakePrimary; ///< config primary wanted
|
||||
static char ConfigHideMainMenuEntry; ///< config hide main menu entry
|
||||
|
||||
static int ConfigVideoSkipLines; ///< config skip lines top/bottom
|
||||
static int ConfigVideoStudioLevels; ///< config use studio levels
|
||||
|
||||
/// config deinterlace
|
||||
static int ConfigVideoDeinterlace[RESOLUTIONS];
|
||||
|
||||
/// config skip chroma
|
||||
static int ConfigVideoSkipChromaDeinterlace[RESOLUTIONS];
|
||||
|
||||
/// config inverse telecine
|
||||
static int ConfigVideoInverseTelecine[RESOLUTIONS];
|
||||
|
||||
/// config denoise
|
||||
static int ConfigVideoDenoise[RESOLUTIONS];
|
||||
|
||||
@@ -78,6 +85,13 @@ static int ConfigVideoScaling[RESOLUTIONS];
|
||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||
static int ConfigAudioPassthrough; ///< config audio pass-through
|
||||
|
||||
static int ConfigAutoCropInterval; ///< auto crop detection interval
|
||||
static int ConfigAutoCropDelay; ///< auto crop detection delay
|
||||
static int ConfigAutoCropTolerance; ///< auto crop detection tolerance
|
||||
|
||||
static char ConfigSuspendClose; ///< suspend should close devices
|
||||
static char ConfigSuspendX11; ///< suspend should stop x11
|
||||
|
||||
static volatile char DoMakePrimary; ///< flag switch primary
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -122,7 +136,7 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
|
||||
csoft = new cSoftRemote(keymap);
|
||||
}
|
||||
|
||||
dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
||||
//dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
|
||||
csoft->Put(key, repeat, release);
|
||||
}
|
||||
|
||||
@@ -138,36 +152,69 @@ class cSoftOsd:public cOsd
|
||||
cSoftOsd(int, int, uint);
|
||||
virtual ~ cSoftOsd(void);
|
||||
virtual void Flush(void);
|
||||
// virtual void SetActive(bool);
|
||||
virtual void SetActive(bool);
|
||||
};
|
||||
|
||||
static volatile char OsdDirty; ///< flag force redraw everything
|
||||
|
||||
/**
|
||||
** Sets this OSD to be the active one.
|
||||
**
|
||||
** @param on true on, false off
|
||||
**
|
||||
** @note only needed as workaround for text2skin plugin with
|
||||
** undrawn areas.
|
||||
*/
|
||||
void cSoftOsd::SetActive(bool on)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, on);
|
||||
|
||||
if (Active() == on) {
|
||||
return; // already active, no action
|
||||
}
|
||||
cOsd::SetActive(on);
|
||||
if (on) {
|
||||
OsdDirty = 1;
|
||||
} else {
|
||||
OsdClose();
|
||||
}
|
||||
}
|
||||
|
||||
cSoftOsd::cSoftOsd(int left, int top, uint level)
|
||||
:cOsd(left, top, level)
|
||||
{
|
||||
// FIXME: OsdWidth/OsdHeight not correct!
|
||||
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
||||
OsdHeight(), left, top, level);
|
||||
/* FIXME: OsdWidth/OsdHeight not correct!
|
||||
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
||||
OsdHeight(), left, top, level);
|
||||
*/
|
||||
|
||||
this->Level = level;
|
||||
//SetActive(true);
|
||||
SetActive(true);
|
||||
}
|
||||
|
||||
cSoftOsd::~cSoftOsd(void)
|
||||
{
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
SetActive(false);
|
||||
// done by SetActive: OsdClose();
|
||||
|
||||
#ifdef USE_YAEPG
|
||||
if (vidWin.bpp) {
|
||||
VideoSetOutputPosition(0, 0, 1920, 1080);
|
||||
// support yaepghd, video window
|
||||
if (vidWin.bpp) { // restore fullsized video
|
||||
int width;
|
||||
int height;
|
||||
double video_aspect;
|
||||
|
||||
::GetOsdSize(&width, &height, &video_aspect);
|
||||
// works osd relative
|
||||
VideoSetOutputPosition(0, 0, width, height);
|
||||
}
|
||||
#endif
|
||||
OsdClose();
|
||||
}
|
||||
|
||||
///
|
||||
/// Actually commits all data to the OSD hardware.
|
||||
///
|
||||
/**
|
||||
** Actually commits all data to the OSD hardware.
|
||||
*/
|
||||
void cSoftOsd::Flush(void)
|
||||
{
|
||||
cPixmapMemory *pm;
|
||||
@@ -175,8 +222,8 @@ void cSoftOsd::Flush(void)
|
||||
if (!Active()) {
|
||||
return;
|
||||
}
|
||||
// support yaepghd, video window
|
||||
#ifdef USE_YAEPG
|
||||
// support yaepghd, video window
|
||||
if (vidWin.bpp) {
|
||||
dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, vidWin.Width(),
|
||||
vidWin.Height(), vidWin.x1, vidWin.y2);
|
||||
@@ -210,44 +257,53 @@ void cSoftOsd::Flush(void)
|
||||
int y2;
|
||||
|
||||
// get dirty bounding box
|
||||
if (!bitmap->Dirty(x1, y1, x2, y2)) {
|
||||
if (OsdDirty) { // forced complete update
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
x2 = bitmap->Width() - 1;
|
||||
y2 = bitmap->Height() - 1;
|
||||
} else if (!bitmap->Dirty(x1, y1, x2, y2)) {
|
||||
continue; // nothing dirty continue
|
||||
}
|
||||
// FIXME: need only to convert and upload dirty areas
|
||||
// convert and upload only dirty areas
|
||||
w = x2 - x1 + 1;
|
||||
h = y2 - y1 + 1;
|
||||
if (1) { // just for the case it makes trouble
|
||||
int width;
|
||||
int height;
|
||||
double video_aspect;
|
||||
|
||||
// DrawBitmap(bitmap);
|
||||
w = bitmap->Width();
|
||||
h = bitmap->Height();
|
||||
::GetOsdSize(&width, &height, &video_aspect);
|
||||
if (w > width) {
|
||||
w = width;
|
||||
x2 = x1 + width - 1;
|
||||
}
|
||||
if (h > height) {
|
||||
h = height;
|
||||
y2 = y1 + height - 1;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (w > bitmap->Width() || h > bitmap->Height()) {
|
||||
esyslog(tr("softhdev: dirty area too big\n"));
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
argb = (uint8_t *) malloc(w * h * sizeof(uint32_t));
|
||||
|
||||
for (y = 0; y < h; ++y) {
|
||||
for (x = 0; x < w; ++x) {
|
||||
((uint32_t *) argb)[x + y * w] = bitmap->GetColor(x, y);
|
||||
for (y = y1; y <= y2; ++y) {
|
||||
for (x = x1; x <= x2; ++x) {
|
||||
((uint32_t *) argb)[x - x1 + (y - y1) * w] =
|
||||
bitmap->GetColor(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
// check if subtitles
|
||||
if (this->Level == OSD_LEVEL_SUBTITLES) {
|
||||
int video_width;
|
||||
int video_height;
|
||||
|
||||
if (0) {
|
||||
dsyslog("[softhddev]%s: subtitle %d, %d\n", __FUNCTION__,
|
||||
Left() + bitmap->X0(), Top() + bitmap->Y0());
|
||||
}
|
||||
video_width = 1920;
|
||||
video_height = 1080;
|
||||
OsdDrawARGB((1920 - video_width) / 2 + Left() + bitmap->X0(),
|
||||
1080 - video_height + Top() + bitmap->Y0(),
|
||||
bitmap->Width(), bitmap->Height(), argb);
|
||||
} else {
|
||||
OsdDrawARGB(Left() + bitmap->X0(), Top() + bitmap->Y0(),
|
||||
bitmap->Width(), bitmap->Height(), argb);
|
||||
}
|
||||
OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
|
||||
w, h, argb);
|
||||
|
||||
bitmap->Clean();
|
||||
// FIXME: reuse argb
|
||||
free(argb);
|
||||
}
|
||||
OsdDirty = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -264,8 +320,8 @@ void cSoftOsd::Flush(void)
|
||||
h = pm->ViewPort().Height();
|
||||
|
||||
/*
|
||||
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h, x,
|
||||
y, pm->Data());
|
||||
dsyslog("[softhddev]%s: draw %dx%d+%d+%d %p\n", __FUNCTION__, w, h,
|
||||
x, y, pm->Data());
|
||||
*/
|
||||
|
||||
OsdDrawARGB(x, y, w, h, pm->Data());
|
||||
@@ -292,6 +348,10 @@ cOsd *cSoftOsdProvider::Osd; ///< single osd
|
||||
|
||||
/**
|
||||
** Create a new OSD.
|
||||
**
|
||||
** @param left x-coordinate of OSD
|
||||
** @param top y-coordinate of OSD
|
||||
** @param level layer level of OSD
|
||||
*/
|
||||
cOsd *cSoftOsdProvider::CreateOsd(int left, int top, uint level)
|
||||
{
|
||||
@@ -327,13 +387,21 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
protected:
|
||||
int MakePrimary;
|
||||
int HideMainMenuEntry;
|
||||
int SkipLines;
|
||||
int StudioLevels;
|
||||
int Scaling[RESOLUTIONS];
|
||||
int Deinterlace[RESOLUTIONS];
|
||||
int SkipChromaDeinterlace[RESOLUTIONS];
|
||||
int InverseTelecine[RESOLUTIONS];
|
||||
int Denoise[RESOLUTIONS];
|
||||
int Sharpen[RESOLUTIONS];
|
||||
int AudioDelay;
|
||||
int AudioPassthrough;
|
||||
int AutoCropInterval;
|
||||
int AutoCropDelay;
|
||||
int AutoCropTolerance;
|
||||
int SuspendClose;
|
||||
int SuspendX11;
|
||||
protected:
|
||||
virtual void Store(void);
|
||||
public:
|
||||
@@ -342,6 +410,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
|
||||
/**
|
||||
** Create a seperator item.
|
||||
**
|
||||
** @param label text inside separator
|
||||
*/
|
||||
static inline cOsdItem *SeparatorItem(const char *label)
|
||||
{
|
||||
@@ -359,7 +429,8 @@ static inline cOsdItem *SeparatorItem(const char *label)
|
||||
cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
{
|
||||
static const char *const deinterlace[] = {
|
||||
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software"
|
||||
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software Bob",
|
||||
"Software Spatial",
|
||||
};
|
||||
static const char *const scaling[] = {
|
||||
"Normal", "Fast", "HQ", "Anamorphic"
|
||||
@@ -376,24 +447,35 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
// cMenuEditStrItem cMenuEditStraItem cMenuEditIntItem
|
||||
MakePrimary = ConfigMakePrimary;
|
||||
Add(new cMenuEditBoolItem(tr("Make primary device"), &MakePrimary,
|
||||
tr("no"), tr("yes")));
|
||||
trVDR("no"), trVDR("yes")));
|
||||
HideMainMenuEntry = ConfigHideMainMenuEntry;
|
||||
Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &HideMainMenuEntry,
|
||||
tr("no"), tr("yes")));
|
||||
trVDR("no"), trVDR("yes")));
|
||||
//
|
||||
// video
|
||||
//
|
||||
Add(SeparatorItem(tr("Video")));
|
||||
|
||||
SkipLines = ConfigVideoSkipLines;
|
||||
Add(new cMenuEditIntItem(tr("Skip lines top+bot (pixel)"), &SkipLines, 0,
|
||||
64));
|
||||
StudioLevels = ConfigVideoStudioLevels;
|
||||
Add(new cMenuEditBoolItem(tr("Use studio levels (vdpau only)"),
|
||||
&StudioLevels, trVDR("no"), trVDR("yes")));
|
||||
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
Add(SeparatorItem(resolution[i]));
|
||||
Scaling[i] = ConfigVideoScaling[i];
|
||||
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling[i], 4, scaling));
|
||||
Deinterlace[i] = ConfigVideoDeinterlace[i];
|
||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i], 5,
|
||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i], 6,
|
||||
deinterlace));
|
||||
SkipChromaDeinterlace[i] = ConfigVideoSkipChromaDeinterlace[i];
|
||||
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
||||
&SkipChromaDeinterlace[i], tr("no"), tr("yes")));
|
||||
&SkipChromaDeinterlace[i], trVDR("no"), trVDR("yes")));
|
||||
InverseTelecine[i] = ConfigVideoInverseTelecine[i];
|
||||
Add(new cMenuEditBoolItem(tr("Inverse Telecine (vdpau)"),
|
||||
&InverseTelecine[i], trVDR("no"), trVDR("yes")));
|
||||
Denoise[i] = ConfigVideoDenoise[i];
|
||||
Add(new cMenuEditIntItem(tr("Denoise (0..1000) (vdpau)"), &Denoise[i],
|
||||
0, 1000));
|
||||
@@ -411,6 +493,29 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
AudioPassthrough = ConfigAudioPassthrough;
|
||||
Add(new cMenuEditStraItem(tr("Audio pass-through"), &AudioPassthrough, 2,
|
||||
passthrough));
|
||||
//
|
||||
// auto-crop
|
||||
//
|
||||
Add(SeparatorItem(tr("Auto-crop")));
|
||||
AutoCropInterval = ConfigAutoCropInterval;
|
||||
Add(new cMenuEditIntItem(tr("autocrop interval (frames)"),
|
||||
&AutoCropInterval, 0, 200));
|
||||
AutoCropDelay = ConfigAutoCropDelay;
|
||||
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
|
||||
&AutoCropDelay, 0, 200));
|
||||
AutoCropTolerance = ConfigAutoCropTolerance;
|
||||
Add(new cMenuEditIntItem(tr("autocrop tolerance (pixel)"),
|
||||
&AutoCropTolerance, 0, 32));
|
||||
//
|
||||
// suspend
|
||||
//
|
||||
Add(SeparatorItem(tr("Suspend")));
|
||||
SuspendClose = ConfigSuspendClose;
|
||||
Add(new cMenuEditBoolItem(tr("suspend closes video+audio"), &SuspendClose,
|
||||
trVDR("no"), trVDR("yes")));
|
||||
SuspendX11 = ConfigSuspendX11;
|
||||
Add(new cMenuEditBoolItem(tr("suspend stops x11"), &SuspendX11,
|
||||
trVDR("no"), trVDR("yes")));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,6 +529,11 @@ void cMenuSetupSoft::Store(void)
|
||||
SetupStore("HideMainMenuEntry", ConfigHideMainMenuEntry =
|
||||
HideMainMenuEntry);
|
||||
|
||||
SetupStore("SkipLines", ConfigVideoSkipLines = SkipLines);
|
||||
VideoSetSkipLines(ConfigVideoSkipLines);
|
||||
SetupStore("StudioLevels", ConfigVideoStudioLevels = StudioLevels);
|
||||
VideoSetStudioLevels(ConfigVideoStudioLevels);
|
||||
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
char buf[128];
|
||||
|
||||
@@ -435,6 +545,8 @@ void cMenuSetupSoft::Store(void)
|
||||
"SkipChromaDeinterlace");
|
||||
SetupStore(buf, ConfigVideoSkipChromaDeinterlace[i] =
|
||||
SkipChromaDeinterlace[i]);
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "InverseTelecine");
|
||||
SetupStore(buf, ConfigVideoInverseTelecine[i] = InverseTelecine[i]);
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Denoise");
|
||||
SetupStore(buf, ConfigVideoDenoise[i] = Denoise[i]);
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Sharpen");
|
||||
@@ -443,6 +555,7 @@ void cMenuSetupSoft::Store(void)
|
||||
VideoSetScaling(ConfigVideoScaling);
|
||||
VideoSetDeinterlace(ConfigVideoDeinterlace);
|
||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
||||
VideoSetInverseTelecine(ConfigVideoInverseTelecine);
|
||||
VideoSetDenoise(ConfigVideoDenoise);
|
||||
VideoSetSharpen(ConfigVideoSharpen);
|
||||
|
||||
@@ -450,6 +563,97 @@ void cMenuSetupSoft::Store(void)
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||
|
||||
SetupStore("AutoCrop.Interval", ConfigAutoCropInterval = AutoCropInterval);
|
||||
SetupStore("AutoCrop.Delay", ConfigAutoCropDelay = AutoCropDelay);
|
||||
SetupStore("AutoCrop.Tolerance", ConfigAutoCropTolerance =
|
||||
AutoCropTolerance);
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay,
|
||||
ConfigAutoCropTolerance);
|
||||
|
||||
SetupStore("Suspend.Close", ConfigSuspendClose = SuspendClose);
|
||||
SetupStore("Suspend.X11", ConfigSuspendX11 = SuspendX11);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// cPlayer
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
** Dummy player for suspend mode.
|
||||
*/
|
||||
class cSoftHdPlayer:public cPlayer
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
cSoftHdPlayer(void);
|
||||
virtual ~ cSoftHdPlayer();
|
||||
};
|
||||
|
||||
cSoftHdPlayer::cSoftHdPlayer(void)
|
||||
{
|
||||
}
|
||||
|
||||
cSoftHdPlayer::~cSoftHdPlayer()
|
||||
{
|
||||
Detach();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// cControl
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
** Dummy control for suspend mode.
|
||||
*/
|
||||
class cSoftHdControl:public cControl
|
||||
{
|
||||
public:
|
||||
static cSoftHdPlayer *Player; ///< dummy player
|
||||
virtual void Hide(void)
|
||||
{
|
||||
}
|
||||
virtual eOSState ProcessKey(eKeys);
|
||||
|
||||
cSoftHdControl(void);
|
||||
|
||||
virtual ~ cSoftHdControl();
|
||||
};
|
||||
|
||||
cSoftHdPlayer *cSoftHdControl::Player;
|
||||
|
||||
/**
|
||||
** Handle a key event.
|
||||
**
|
||||
** @param key key pressed
|
||||
*/
|
||||
eOSState cSoftHdControl::ProcessKey(eKeys key)
|
||||
{
|
||||
if (!ISMODELESSKEY(key) || key == kBack || key == kStop) {
|
||||
if (Player) {
|
||||
delete Player;
|
||||
|
||||
Player = NULL;
|
||||
}
|
||||
Resume();
|
||||
return osEnd;
|
||||
}
|
||||
return osContinue;
|
||||
}
|
||||
|
||||
cSoftHdControl::cSoftHdControl(void)
|
||||
: cControl(Player = new cSoftHdPlayer)
|
||||
{
|
||||
}
|
||||
|
||||
cSoftHdControl::~cSoftHdControl()
|
||||
{
|
||||
if (Player) {
|
||||
delete Player;
|
||||
|
||||
Player = NULL;
|
||||
}
|
||||
Resume();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -460,7 +664,7 @@ class cSoftHdDevice:public cDevice
|
||||
{
|
||||
public:
|
||||
cSoftHdDevice(void);
|
||||
virtual ~ cSoftHdDevice(void);
|
||||
virtual ~ cSoftHdDevice(void);
|
||||
|
||||
virtual bool HasDecoder(void) const;
|
||||
virtual bool CanReplay(void) const;
|
||||
@@ -470,46 +674,40 @@ class cSoftHdDevice:public cDevice
|
||||
virtual void Play(void);
|
||||
virtual void Freeze(void);
|
||||
virtual void Mute(void);
|
||||
virtual void SetVolumeDevice(int);
|
||||
virtual void StillPicture(const uchar *, int);
|
||||
virtual bool Poll(cPoller &, int = 0);
|
||||
virtual bool Flush(int = 0);
|
||||
virtual int64_t GetSTC(void);
|
||||
virtual void GetVideoSize(int &width, int &height, double &aspect)
|
||||
{
|
||||
width = 1920;
|
||||
height = 1080;
|
||||
aspect = (double)width / height;
|
||||
}
|
||||
virtual void SetVideoDisplayFormat(eVideoDisplayFormat);
|
||||
virtual void GetVideoSize(int &, int &, double &);
|
||||
virtual void GetOsdSize(int &, int &, double &);
|
||||
virtual int PlayVideo(const uchar *, int);
|
||||
|
||||
//virtual int PlayTsVideo(const uchar *, int);
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
#ifndef USE_AUDIO_THREAD // FIXME: testing none threaded
|
||||
virtual int PlayTsAudio(const uchar *, int);
|
||||
#endif
|
||||
virtual void SetAudioChannelDevice(int);
|
||||
virtual int GetAudioChannelDevice(void);
|
||||
virtual void SetDigitalAudioDevice(bool);
|
||||
virtual void SetAudioTrackDevice(eTrackType);
|
||||
virtual void SetVolumeDevice(int);
|
||||
virtual int PlayAudio(const uchar *, int, uchar);
|
||||
|
||||
// Image Grab facilities
|
||||
|
||||
virtual uchar *GrabImage(int &, bool, int, int, int);
|
||||
|
||||
virtual int ProvidesCa(const cChannel *) const;
|
||||
|
||||
#if 0
|
||||
// SPU facilities
|
||||
private:
|
||||
cDvbSpuDecoder * spuDecoder;
|
||||
cDvbSpuDecoder * spuDecoder;
|
||||
public:
|
||||
virtual cSpuDecoder * GetSpuDecoder(void);
|
||||
virtual cSpuDecoder * GetSpuDecoder(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void MakePrimaryDevice(bool);
|
||||
virtual void MakePrimaryDevice(bool);
|
||||
};
|
||||
|
||||
cSoftHdDevice::cSoftHdDevice(void)
|
||||
@@ -519,6 +717,7 @@ cSoftHdDevice::cSoftHdDevice(void)
|
||||
#if 0
|
||||
spuDecoder = NULL;
|
||||
#endif
|
||||
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
|
||||
}
|
||||
|
||||
cSoftHdDevice::~cSoftHdDevice(void)
|
||||
@@ -526,6 +725,11 @@ cSoftHdDevice::~cSoftHdDevice(void)
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
** Informs a device that it will be the primary device.
|
||||
**
|
||||
** @param on flag if becoming or loosing primary
|
||||
*/
|
||||
void cSoftHdDevice::MakePrimaryDevice(bool on)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, on);
|
||||
@@ -536,18 +740,9 @@ void cSoftHdDevice::MakePrimaryDevice(bool on)
|
||||
}
|
||||
}
|
||||
|
||||
int cSoftHdDevice::ProvidesCa(
|
||||
__attribute__ ((unused)) const cChannel *
|
||||
channel) const
|
||||
{
|
||||
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
cSpuDecoder *cSoftHdDevice::GetSpuDecoder(void)
|
||||
cSpuDecoder *cSoftHdDevice::GetSpuDecoder(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
@@ -564,16 +759,22 @@ bool cSoftHdDevice::HasDecoder(void) const
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
** Returns true if this device can currently start a replay session.
|
||||
*/
|
||||
bool cSoftHdDevice::CanReplay(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSoftHdDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
/**
|
||||
** Sets the device into the given play mode.
|
||||
*/
|
||||
bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, PlayMode);
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, play_mode);
|
||||
|
||||
switch (PlayMode) {
|
||||
switch (play_mode) {
|
||||
case pmAudioVideo:
|
||||
break;
|
||||
case pmAudioOnly:
|
||||
@@ -584,18 +785,24 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
case pmNone:
|
||||
return true;
|
||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||
break;
|
||||
dsyslog("[softhddev] play mode external\n");
|
||||
Suspend(1, 1, 0);
|
||||
return true;
|
||||
default:
|
||||
dsyslog("[softhddev]playmode not implemented... %d\n", PlayMode);
|
||||
dsyslog("[softhddev]playmode not implemented... %d\n", play_mode);
|
||||
break;
|
||||
}
|
||||
::SetPlayMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
** Gets the current System Time Counter, which can be used to
|
||||
** synchronize audio, video and subtitles.
|
||||
*/
|
||||
int64_t cSoftHdDevice::GetSTC(void)
|
||||
{
|
||||
// dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
return::VideoGetClock();
|
||||
}
|
||||
@@ -637,6 +844,9 @@ void cSoftHdDevice::Freeze(void)
|
||||
::Freeze();
|
||||
}
|
||||
|
||||
/**
|
||||
** Turns off audio while replaying.
|
||||
*/
|
||||
void cSoftHdDevice::Mute(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
@@ -645,20 +855,13 @@ void cSoftHdDevice::Mute(void)
|
||||
::Mute();
|
||||
}
|
||||
|
||||
void cSoftHdDevice::SetVolumeDevice(int volume)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
||||
|
||||
::SetVolumeDevice(volume);
|
||||
}
|
||||
|
||||
/**
|
||||
** Display the given I-frame as a still picture.
|
||||
*/
|
||||
void cSoftHdDevice::StillPicture(const uchar * data, int length)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %s\n", __FUNCTION__,
|
||||
data[0] == 0x47 ? "ts" : "pes");
|
||||
dsyslog("[softhddev]%s: %s %p %d\n", __FUNCTION__,
|
||||
data[0] == 0x47 ? "ts" : "pes", data, length);
|
||||
|
||||
if (data[0] == 0x47) { // ts sync
|
||||
cDevice::StillPicture(data, length);
|
||||
@@ -677,7 +880,7 @@ void cSoftHdDevice::StillPicture(const uchar * data, int length)
|
||||
bool cSoftHdDevice::Poll(
|
||||
__attribute__ ((unused)) cPoller & poller, int timeout_ms)
|
||||
{
|
||||
// dsyslog("[softhddev]%s: %d\n", __FUNCTION__, timeout_ms);
|
||||
//dsyslog("[softhddev]%s: %d\n", __FUNCTION__, timeout_ms);
|
||||
|
||||
return::Poll(timeout_ms);
|
||||
}
|
||||
@@ -697,7 +900,42 @@ bool cSoftHdDevice::Flush(int timeout_ms)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
** Returns the With, Height and PixelAspect ratio the OSD.
|
||||
** Sets the video display format to the given one (only useful if this
|
||||
** device has an MPEG decoder).
|
||||
**
|
||||
** @note this function isn't called on the initial channel
|
||||
*/
|
||||
void cSoftHdDevice::SetVideoDisplayFormat(
|
||||
eVideoDisplayFormat video_display_format)
|
||||
{
|
||||
static int last = -1;
|
||||
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, video_display_format);
|
||||
|
||||
cDevice::SetVideoDisplayFormat(video_display_format);
|
||||
|
||||
// called on every channel switch, no need to kill osd...
|
||||
if (last != video_display_format) {
|
||||
last = video_display_format;
|
||||
|
||||
::VideoSetDisplayFormat(video_display_format);
|
||||
OsdDirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Returns the width, height and video_aspect ratio of the currently
|
||||
** displayed video material.
|
||||
**
|
||||
** @note the size is used to scale the subtitle.
|
||||
*/
|
||||
void cSoftHdDevice::GetVideoSize(int &width, int &height, double &video_aspect)
|
||||
{
|
||||
::GetOsdSize(&width, &height, &video_aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
** Returns the width, height and pixel_aspect ratio the OSD.
|
||||
**
|
||||
** FIXME: Called every second, for nothing (no OSD displayed)?
|
||||
*/
|
||||
@@ -741,11 +979,23 @@ int cSoftHdDevice::GetAudioChannelDevice(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Sets the audio volume on this device (Volume = 0...255).
|
||||
**
|
||||
** @param volume device volume
|
||||
*/
|
||||
void cSoftHdDevice::SetVolumeDevice(int volume)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
||||
|
||||
::SetVolumeDevice(volume);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
///
|
||||
/// Play a video packet.
|
||||
///
|
||||
/**
|
||||
** Play a video packet.
|
||||
*/
|
||||
int cSoftHdDevice::PlayVideo(const uchar * data, int length)
|
||||
{
|
||||
//dsyslog("[softhddev]%s: %p %d\n", __FUNCTION__, data, length);
|
||||
@@ -757,33 +1007,57 @@ int cSoftHdDevice::PlayVideo(const uchar * data, int length)
|
||||
///
|
||||
/// Play a TS video packet.
|
||||
///
|
||||
int cSoftHdDevice::PlayTsVideo(const uchar * Data, int Length)
|
||||
int cSoftHdDevice::PlayTsVideo(const uchar * data, int length)
|
||||
{
|
||||
// many code to repeat
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_OSS // FIXME: testing only oss
|
||||
#ifndef USE_AUDIO_THREAD // FIXME: testing none threaded
|
||||
|
||||
///
|
||||
/// Play a TS audio packet.
|
||||
///
|
||||
/// misuse this function as audio poller
|
||||
///
|
||||
/// @param data ts data buffer
|
||||
/// @param length ts packet length
|
||||
///
|
||||
int cSoftHdDevice::PlayTsAudio(const uchar * data, int length)
|
||||
{
|
||||
AudioPoller();
|
||||
|
||||
return cDevice::PlayTsAudio(data, length);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int sizex,
|
||||
int sizey)
|
||||
/**
|
||||
** Grabs the currently visible screen image.
|
||||
**
|
||||
** @param size size of the returned data
|
||||
** @param jpeg flag true, create JPEG data
|
||||
** @param quality JPEG quality
|
||||
** @param width number of horizontal pixels in the frame
|
||||
** @param height number of vertical pixels in the frame
|
||||
*/
|
||||
uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int width,
|
||||
int height)
|
||||
{
|
||||
dsyslog("[softhddev]%s: %d, %d, %d, %dx%d\n", __FUNCTION__, size, jpeg,
|
||||
quality, sizex, sizey);
|
||||
quality, width, height);
|
||||
|
||||
return NULL;
|
||||
return::GrabImage(&size, jpeg, quality, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
** Call rgb to jpeg for C Plugin.
|
||||
*/
|
||||
extern "C" uint8_t * CreateJpeg(uint8_t * image, int *size, int quality,
|
||||
int width, int height)
|
||||
{
|
||||
return (uint8_t *) RgbToJpeg((uchar *) image, width, height, *size,
|
||||
quality);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -802,7 +1076,7 @@ class cPluginSoftHdDevice:public cPlugin
|
||||
virtual bool Initialize(void);
|
||||
virtual bool Start(void);
|
||||
virtual void Stop(void);
|
||||
// virtual void Housekeeping(void);
|
||||
// virtual void Housekeeping(void);
|
||||
virtual void MainThreadHook(void);
|
||||
virtual const char *MainMenuEntry(void);
|
||||
virtual cOsdObject *MainMenuAction(void);
|
||||
@@ -901,9 +1175,14 @@ void cPluginSoftHdDevice::Stop(void)
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
** Perform any cleanup or other regular tasks.
|
||||
*/
|
||||
void cPluginSoftHdDevice::Housekeeping(void)
|
||||
{
|
||||
// Perform any cleanup or other regular tasks.
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
// ::Housekeeping();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -923,11 +1202,18 @@ const char *cPluginSoftHdDevice::MainMenuEntry(void)
|
||||
*/
|
||||
cOsdObject *cPluginSoftHdDevice::MainMenuAction(void)
|
||||
{
|
||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||
|
||||
cDevice::PrimaryDevice()->StopReplay();
|
||||
Suspend();
|
||||
ShutdownHandler.SetUserInactive();
|
||||
//MyDevice->StopReplay();
|
||||
if (!cSoftHdControl::Player) { // not already suspended
|
||||
cControl::Launch(new cSoftHdControl);
|
||||
cControl::Attach();
|
||||
Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
|
||||
if (ShutdownHandler.GetUserInactiveTime()) {
|
||||
dsyslog("[softhddev]%s: set user inactive\n", __FUNCTION__);
|
||||
ShutdownHandler.SetUserInactive();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -948,7 +1234,7 @@ void cPluginSoftHdDevice::MainThreadHook(void)
|
||||
// check if user is inactive, automatic enter suspend mode
|
||||
if (ShutdownHandler.IsUserInactive()) {
|
||||
// this is regular called, but guarded against double calls
|
||||
Suspend();
|
||||
Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
|
||||
}
|
||||
|
||||
::MainThreadHook();
|
||||
@@ -966,11 +1252,15 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
||||
|
||||
/**
|
||||
** Parse setup parameters
|
||||
**
|
||||
** @param name paramter name (case sensetive)
|
||||
** @param value value as string
|
||||
**
|
||||
** @returns true if the parameter is supported.
|
||||
*/
|
||||
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
{
|
||||
int i;
|
||||
char buf[128];
|
||||
|
||||
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||
|
||||
@@ -982,7 +1272,17 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
ConfigHideMainMenuEntry = atoi(value);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "SkipLines")) {
|
||||
VideoSetSkipLines(ConfigVideoSkipLines = atoi(value));
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "StudioLevels")) {
|
||||
VideoSetStudioLevels(ConfigVideoStudioLevels = atoi(value));
|
||||
return true;
|
||||
}
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
||||
if (!strcmp(name, buf)) {
|
||||
ConfigVideoScaling[i] = atoi(value);
|
||||
@@ -1002,6 +1302,12 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
||||
return true;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "InverseTelecine");
|
||||
if (!strcmp(name, buf)) {
|
||||
ConfigVideoInverseTelecine[i] = atoi(value);
|
||||
VideoSetInverseTelecine(ConfigVideoInverseTelecine);
|
||||
return true;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Denoise");
|
||||
if (!strcmp(name, buf)) {
|
||||
ConfigVideoDenoise[i] = atoi(value);
|
||||
@@ -1015,6 +1321,7 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(name, "AudioDelay")) {
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
||||
return true;
|
||||
@@ -1024,6 +1331,30 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "AutoCrop.Interval")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval =
|
||||
atoi(value), ConfigAutoCropDelay, ConfigAutoCropTolerance);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "AutoCrop.Delay")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay =
|
||||
atoi(value), ConfigAutoCropTolerance);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "AutoCrop.Tolerance")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay,
|
||||
ConfigAutoCropTolerance = atoi(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "Suspend.Close")) {
|
||||
ConfigSuspendClose = atoi(value);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(name, "Suspend.X11")) {
|
||||
ConfigSuspendX11 = atoi(value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1052,8 +1383,8 @@ const char **cPluginSoftHdDevice::SVDRPHelpPages(void)
|
||||
{
|
||||
// FIXME: translation?
|
||||
static const char *text[] = {
|
||||
"SUSP\n",
|
||||
" Suspend plugin",
|
||||
"SUSP\n" " Suspend plugin.\n",
|
||||
"RESU\n" " Resume plugin.\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1068,9 +1399,25 @@ cString cPluginSoftHdDevice::SVDRPCommand(const char *command,
|
||||
__attribute__ ((unused)) int &reply_code)
|
||||
{
|
||||
if (!strcasecmp(command, "SUSP")) {
|
||||
Suspend();
|
||||
if (cSoftHdControl::Player) { // already suspended
|
||||
return "SoftHdDevice already suspended";
|
||||
}
|
||||
// should be after suspend, but SetPlayMode resumes
|
||||
cControl::Launch(new cSoftHdControl);
|
||||
cControl::Attach();
|
||||
Suspend(ConfigSuspendClose, ConfigSuspendClose, ConfigSuspendX11);
|
||||
return "SoftHdDevice is suspended";
|
||||
}
|
||||
if (!strcasecmp(command, "RESU")) {
|
||||
if (ShutdownHandler.GetUserInactiveTime()) {
|
||||
ShutdownHandler.SetUserInactiveTimeout();
|
||||
}
|
||||
if (cSoftHdControl::Player) { // suspended
|
||||
cControl::Shutdown(); // not need, if not suspended
|
||||
}
|
||||
Resume();
|
||||
return "SoftHdDevice is resumed";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,24 +21,26 @@ SRC_URI=""
|
||||
LICENSE="AGPL-3"
|
||||
SLOT="0"
|
||||
KEYWORDS="~x86 ~amd64"
|
||||
IUSE="vaapi vdpau alsa oss yaepg"
|
||||
IUSE="vaapi vdpau alsa oss yaepg opengl jpeg"
|
||||
|
||||
DEPEND=">=x11-libs/libxcb-1.7
|
||||
DEPEND=">=x11-libs/libxcb-1.8
|
||||
x11-libs/xcb-util
|
||||
x11-libs/xcb-util-wm
|
||||
x11-libs/xcb-util-wm
|
||||
x11-libs/xcb-util-keysyms
|
||||
x11-libs/xcb-util-renderutil
|
||||
x11-libs/libX11
|
||||
>=media-video/ffmpeg-0.7
|
||||
opengl? ( virtual/opengl )
|
||||
>=virtual/ffmpeg-0.7
|
||||
sys-devel/gettext
|
||||
sys-devel/make
|
||||
dev-util/pkgconfig
|
||||
yaepg? ( >=media-video/vdr-1.7[yaepg] )
|
||||
!yaepg? ( >=media-video/vdr-1.7 )
|
||||
yaepg? ( >=media-video/vdr-1.7.23[yaepg] )
|
||||
!yaepg? ( >=media-video/vdr-1.7.23 )
|
||||
vdpau? ( x11-libs/libvdpau )
|
||||
vaapi? ( x11-libs/libva )
|
||||
alsa? ( media-libs/alsa-lib )
|
||||
oss? ( sys-kernel/linux-headers )
|
||||
jpeg? ( virtual/jpeg )
|
||||
"
|
||||
|
||||
src_prepare() {
|
||||
@@ -48,11 +50,12 @@ src_prepare() {
|
||||
src_compile() {
|
||||
local myconf
|
||||
|
||||
myconf=""
|
||||
myconf="-DHAVE_PTHREAD_NAME"
|
||||
use vdpau && myconf="${myconf} -DUSE_VDPAU"
|
||||
use vaapi && myconf="${myconf} -DUSE_VAAPI"
|
||||
use alsa && myconf="${myconf} -DUSE_ALSA"
|
||||
use oss && myconf="${myconf} -DUSE_OSS"
|
||||
use jpeg && myconf="${myconf} -DUSE_JPEG"
|
||||
|
||||
emake all CC="$(tc-getCC)" CFLAGS="${CFLAGS}" \
|
||||
LDFLAGS="${LDFLAGS}" CONFIG="${myconf}" LIBDIR="." || die
|
||||
@@ -61,10 +64,11 @@ src_compile() {
|
||||
src_install() {
|
||||
vdr-plugin_src_install
|
||||
|
||||
dodir /etc/vdr/plugins || die
|
||||
dodoc README.txt
|
||||
|
||||
insinto /etc/vdr/plugins
|
||||
fowners -R vdr:vdr /etc/vdr || die
|
||||
#dodir /etc/vdr/plugins || die
|
||||
#insinto /etc/vdr/plugins
|
||||
#fowners -R vdr:vdr /etc/vdr || die
|
||||
|
||||
#insinto /etc/conf.d
|
||||
#doins vdr.softhddevice
|
||||
|
||||
37
video.h
37
video.h
@@ -37,6 +37,9 @@ typedef struct _video_hw_decoder_ VideoHwDecoder;
|
||||
/// Allocate new video hardware decoder.
|
||||
extern VideoHwDecoder *VideoNewHwDecoder(void);
|
||||
|
||||
/// Deallocate video hardware decoder.
|
||||
extern void VideoDelHwDecoder(VideoHwDecoder *);
|
||||
|
||||
/// Get and allocate a video hardware surface.
|
||||
extern unsigned VideoGetSurface(VideoHwDecoder *);
|
||||
|
||||
@@ -44,16 +47,17 @@ extern unsigned VideoGetSurface(VideoHwDecoder *);
|
||||
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
||||
|
||||
#ifdef LIBAVCODEC_VERSION
|
||||
/// Render a ffmpeg frame.
|
||||
extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *);
|
||||
|
||||
/// Get ffmpeg vaapi context.
|
||||
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
||||
|
||||
/// Callback to negotiate the PixelFormat.
|
||||
extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
||||
const enum PixelFormat *);
|
||||
|
||||
/// Render a ffmpeg frame.
|
||||
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
|
||||
const AVFrame *);
|
||||
|
||||
/// Get ffmpeg vaapi context.
|
||||
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
||||
|
||||
#ifdef AVCODEC_VDPAU_H
|
||||
/// Draw vdpau render state.
|
||||
extern void VideoDrawRenderState(VideoHwDecoder *,
|
||||
@@ -76,6 +80,9 @@ extern void VideoSetOutputPosition(int, int, int, int);
|
||||
/// Set video mode.
|
||||
extern void VideoSetVideoMode(int, int, int, int);
|
||||
|
||||
/// Set display format.
|
||||
extern void VideoSetDisplayFormat(int);
|
||||
|
||||
/// Set video fullscreen mode.
|
||||
extern void VideoSetFullscreen(int);
|
||||
|
||||
@@ -85,6 +92,9 @@ extern void VideoSetDeinterlace(int[]);
|
||||
/// Set skip chroma deinterlace.
|
||||
extern void VideoSetSkipChromaDeinterlace(int[]);
|
||||
|
||||
/// Set inverse telecine.
|
||||
extern void VideoSetInverseTelecine(int[]);
|
||||
|
||||
/// Set scaling.
|
||||
extern void VideoSetScaling(int[]);
|
||||
|
||||
@@ -94,17 +104,32 @@ extern void VideoSetDenoise(int[]);
|
||||
/// Set sharpen.
|
||||
extern void VideoSetSharpen(int[]);
|
||||
|
||||
/// Set skip lines.
|
||||
extern void VideoSetSkipLines(int);
|
||||
|
||||
/// Set studio levels.
|
||||
extern void VideoSetStudioLevels(int);
|
||||
|
||||
/// Set audio delay.
|
||||
extern void VideoSetAudioDelay(int);
|
||||
|
||||
/// Set auto-crop parameters.
|
||||
extern void VideoSetAutoCrop(int, int, int);
|
||||
|
||||
/// Clear OSD.
|
||||
extern void VideoOsdClear(void);
|
||||
|
||||
/// Draw an OSD ARGB image.
|
||||
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
||||
|
||||
/// Get OSD size.
|
||||
extern void VideoGetOsdSize(int *, int *);
|
||||
|
||||
extern int64_t VideoGetClock(void); ///< Get video clock.
|
||||
|
||||
/// Grab screen.
|
||||
extern uint8_t *VideoGrab(int *, int *, int *, int);
|
||||
|
||||
extern void VideoOsdInit(void); ///< Setup osd.
|
||||
extern void VideoOsdExit(void); ///< Cleanup osd.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user