mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e619f5c836 | ||
|
|
973fcfe4dd | ||
|
|
eec30433b6 | ||
|
|
baf577aba5 | ||
|
|
81d7ef9755 | ||
|
|
7f7de8678f | ||
|
|
92bb00c410 | ||
|
|
d3b98b90f4 | ||
|
|
788636ee6b | ||
|
|
8e53cbd4a9 | ||
|
|
54661f90ea | ||
|
|
30d8e8afe9 | ||
|
|
19a37bb0bf | ||
|
|
2087968d55 | ||
|
|
d983f780b3 | ||
| 712b2e0de1 | |||
|
|
54f92e67fc | ||
|
|
960cd27ab5 | ||
|
|
3a97700981 | ||
|
|
8d624224e9 | ||
|
|
96eefca699 | ||
|
|
5e005eeff5 | ||
|
|
f6df79e8e6 | ||
|
|
f1551cd321 | ||
|
|
9568c5bd93 | ||
|
|
fd60c3c132 | ||
|
|
7b6d0ecf94 |
42
ChangeLog
42
ChangeLog
@@ -1,5 +1,45 @@
|
|||||||
User johns
|
User johns
|
||||||
Data: Sat Jan 7 13:20:07 CET 2012
|
Date: Sun Jan 15 16:56:04 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.3.1
|
||||||
|
Fix bug: AudioFreeBytes didn't check if audio running/compiled.
|
||||||
|
Fix bug: snd_pcm_state: Assertion `pcm' failed.
|
||||||
|
Add support for fullscreen and fullscreen toogle.
|
||||||
|
Instant update deinterlace configuration changes.
|
||||||
|
Fix subtitle position.
|
||||||
|
Add SVDRP support.
|
||||||
|
Suspend when user is inactive.
|
||||||
|
|
||||||
|
User Christian Rupper
|
||||||
|
Date: Tue Jan 10 22:33:14 CET 2012
|
||||||
|
|
||||||
|
Move objects before $LIBS to avoid link failures with --as-needed.
|
||||||
|
Do not override CFLAGS for video test.
|
||||||
|
Rearrange *FLAGS incl. some minor fixes.
|
||||||
|
Don't override VDRDIR, LIBDIR and TMPDIR in makefile.
|
||||||
|
Don't abuse LDFLAGS in makefile.
|
||||||
|
Define CC in makefile.
|
||||||
|
Include GL/gl.h for the GL_COLOR_BUFFER_BIT definition.
|
||||||
|
VideoInit() needs an argument.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Tue Jan 10 22:32:50 CET 2012
|
||||||
|
|
||||||
|
Add main menu entry, which suspends the plugin.
|
||||||
|
Add support for resize window.
|
||||||
|
Close window sends "close" as remote key press.
|
||||||
|
|
||||||
|
Date: Mon Jan 9 22:09:38 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.3.0
|
||||||
|
Add support of resolution dependend video parameters (deint, scale, ...).
|
||||||
|
Add support for recording play back.
|
||||||
|
Add workaround for alsa crash in snd_pcm_prepare.
|
||||||
|
Fix bug: audio crash on exit.
|
||||||
|
Fix build with vdr without yaepg support.
|
||||||
|
Support yaepghd video picture output position change.
|
||||||
|
|
||||||
|
Date: Sat Jan 7 13:20:07 CET 2012
|
||||||
|
|
||||||
Release Version 0.2.0
|
Release Version 0.2.0
|
||||||
Add support for ac3 audio pass through.
|
Add support for ac3 audio pass through.
|
||||||
|
|||||||
73
Makefile
73
Makefile
@@ -26,40 +26,17 @@ CONFIG += $(shell pkg-config --exists alsa && echo "-DUSE_ALSA")
|
|||||||
|
|
||||||
### The C++ compiler and options:
|
### The C++ compiler and options:
|
||||||
|
|
||||||
|
CC ?= gcc
|
||||||
CXX ?= g++
|
CXX ?= g++
|
||||||
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Woverloaded-virtual -fPIC
|
|
||||||
override CXXFLAGS += $(DEFINES) $(INCLUDES)
|
|
||||||
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
||||||
-Wdeclaration-after-statement -fPIC
|
-Wdeclaration-after-statement
|
||||||
#CFLAGS += -Werror
|
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Woverloaded-virtual
|
||||||
override CFLAGS += $(DEFINES) $(INCLUDES) \
|
|
||||||
$(shell pkg-config --cflags libavcodec libavformat) \
|
|
||||||
`pkg-config --cflags x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
|
||||||
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
|
||||||
`pkg-config --cflags gl glu` \
|
|
||||||
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
|
||||||
`pkg-config --cflags vdpau`) \
|
|
||||||
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
|
||||||
`pkg-config --cflags libva-x11 libva-glx libva`) \
|
|
||||||
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
|
||||||
`pkg-config --cflags alsa`)
|
|
||||||
override LDFLAGS += -lrt \
|
|
||||||
$(shell pkg-config --libs libavcodec libavformat) \
|
|
||||||
`pkg-config --libs x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
|
||||||
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
|
||||||
`pkg-config --libs gl glu` \
|
|
||||||
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
|
||||||
`pkg-config --libs vdpau`) \
|
|
||||||
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
|
||||||
`pkg-config --libs libva-x11 libva-glx libva`) \
|
|
||||||
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
|
||||||
`pkg-config --libs alsa`)
|
|
||||||
|
|
||||||
### The directory environment:
|
### The directory environment:
|
||||||
|
|
||||||
VDRDIR = ../../..
|
VDRDIR ?= ../../..
|
||||||
LIBDIR = ../../lib
|
LIBDIR ?= ../../lib
|
||||||
TMPDIR = /tmp
|
TMPDIR ?= /tmp
|
||||||
|
|
||||||
### Make sure that necessary options are included:
|
### Make sure that necessary options are included:
|
||||||
|
|
||||||
@@ -78,12 +55,40 @@ APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDI
|
|||||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||||
PACKAGE = vdr-$(ARCHIVE)
|
PACKAGE = vdr-$(ARCHIVE)
|
||||||
|
|
||||||
### Includes and Defines (add further entries here):
|
### Includes, Defines and dependencies (add further entries here):
|
||||||
|
|
||||||
INCLUDES += -I$(VDRDIR)/include
|
INCLUDES += -I$(VDRDIR)/include
|
||||||
|
|
||||||
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
||||||
|
|
||||||
|
_CFLAGS = $(DEFINES) $(INCLUDES) \
|
||||||
|
$(shell pkg-config --cflags libavcodec libavformat) \
|
||||||
|
`pkg-config --cflags x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
||||||
|
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||||
|
`pkg-config --cflags gl glu` \
|
||||||
|
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
||||||
|
`pkg-config --cflags vdpau`) \
|
||||||
|
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
||||||
|
`pkg-config --cflags libva-x11 libva-glx libva`) \
|
||||||
|
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
||||||
|
`pkg-config --cflags alsa`)
|
||||||
|
|
||||||
|
#override _CFLAGS += -Werror
|
||||||
|
override CXXFLAGS += $(_CFLAGS)
|
||||||
|
override CFLAGS += $(_CFLAGS)
|
||||||
|
|
||||||
|
LIBS += -lrt \
|
||||||
|
$(shell pkg-config --libs libavcodec libavformat) \
|
||||||
|
`pkg-config --libs x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
||||||
|
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||||
|
`pkg-config --libs gl glu` \
|
||||||
|
$(if $(findstring USE_VDPAU,$(CONFIG)), \
|
||||||
|
`pkg-config --libs vdpau`) \
|
||||||
|
$(if $(findstring USE_VAAPI,$(CONFIG)), \
|
||||||
|
`pkg-config --libs libva-x11 libva-glx libva`) \
|
||||||
|
$(if $(findstring USE_ALSA,$(CONFIG)), \
|
||||||
|
`pkg-config --libs alsa`)
|
||||||
|
|
||||||
### The object files (add further files here):
|
### The object files (add further files here):
|
||||||
|
|
||||||
OBJS = $(PLUGIN).o softhddev.o video.o audio.o codec.o ringbuffer.o
|
OBJS = $(PLUGIN).o softhddev.o video.o audio.o codec.o ringbuffer.o
|
||||||
@@ -105,6 +110,8 @@ DEPFILE = .dependencies
|
|||||||
$(DEPFILE): Makefile
|
$(DEPFILE): Makefile
|
||||||
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SRCS) >$@
|
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SRCS) >$@
|
||||||
|
|
||||||
|
$(OBJS): Makefile
|
||||||
|
|
||||||
-include $(DEPFILE)
|
-include $(DEPFILE)
|
||||||
|
|
||||||
### Internationalization (I18N):
|
### Internationalization (I18N):
|
||||||
@@ -137,7 +144,7 @@ i18n: $(I18Nmsgs) $(I18Npot)
|
|||||||
### Targets:
|
### Targets:
|
||||||
|
|
||||||
libvdr-$(PLUGIN).so: $(OBJS) Makefile
|
libvdr-$(PLUGIN).so: $(OBJS) Makefile
|
||||||
$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ $(LDFLAGS)
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -fPIC $(OBJS) -o $@ $(LIBS)
|
||||||
@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
|
@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
|
||||||
|
|
||||||
dist: $(I18Npo) clean
|
dist: $(I18Npo) clean
|
||||||
@@ -163,5 +170,5 @@ indent:
|
|||||||
done
|
done
|
||||||
|
|
||||||
video_test: video.c
|
video_test: video.c
|
||||||
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $(LIBS) \
|
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
|
||||||
-O0 -g -o $@ $<
|
-o $@
|
||||||
|
|||||||
44
README.txt
44
README.txt
@@ -33,7 +33,7 @@ A software and GPU emulated HD output device plugin for VDR.
|
|||||||
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 Audio FFMpeg/OSS/Analog
|
||||||
o planned: Alsa HDMI/SPDIF Passthrough
|
o Alsa HDMI/SPDIF Passthrough
|
||||||
o planned: OSS HDMI/SPDIF Passthrough
|
o planned: OSS HDMI/SPDIF Passthrough
|
||||||
|
|
||||||
To compile you must have the 'requires' installed.
|
To compile you must have the 'requires' installed.
|
||||||
@@ -95,35 +95,63 @@ Setup: /etc/vdr/setup.conf
|
|||||||
softhddevice.MakePrimary = 1
|
softhddevice.MakePrimary = 1
|
||||||
0 = no change, 1 make softhddevice primary at start
|
0 = no change, 1 make softhddevice primary at start
|
||||||
|
|
||||||
softhddevice.Deinterlace = 0
|
softhddevice.HideMainMenuEntry = 0
|
||||||
|
0 = show softhddevice main menu entry, 1 = hide entry
|
||||||
|
|
||||||
|
<res> of the next parameters is 567i, 720p, 1080i_fake or 1080i.
|
||||||
|
1080i_fake is 1280x1080 or 1440x1080
|
||||||
|
1080i is "real" 1920x1080
|
||||||
|
|
||||||
|
softhddevice.<res>.Scaling = 0
|
||||||
|
0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic
|
||||||
|
|
||||||
|
softhddevice.<res>.Deinterlace = 0
|
||||||
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
|
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
|
||||||
(only 0, 1 supported with vaapi)
|
(only 0, 1 supported with vaapi)
|
||||||
|
|
||||||
softhddevice.SkipChromaDeinterlace = 0
|
softhddevice.<res>.SkipChromaDeinterlace = 0
|
||||||
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
||||||
|
|
||||||
softhddevice.Denoise = 0
|
softhddevice.<res>.Denoise = 0
|
||||||
0 .. 1000 noise reduction level (0 off, 1000 max)
|
0 .. 1000 noise reduction level (0 off, 1000 max)
|
||||||
|
|
||||||
softhddevice.Sharpness = 0
|
softhddevice.<res>.Sharpness = 0
|
||||||
-1000 .. 1000 noise reduction level (0 off, -1000 max blur,
|
-1000 .. 1000 noise reduction level (0 off, -1000 max blur,
|
||||||
1000 max sharp)
|
1000 max sharp)
|
||||||
|
|
||||||
softhddevice.Scaling = 0
|
|
||||||
0 = normal, 1 = fast, 2 = HQ, 3 = anamorphic
|
|
||||||
|
|
||||||
softhddevice.AudioDelay = 0
|
softhddevice.AudioDelay = 0
|
||||||
+n or -n ms
|
+n or -n ms
|
||||||
|
|
||||||
softhddevice.AudioPassthrough = 0
|
softhddevice.AudioPassthrough = 0
|
||||||
0 = none, 1 = AC-3
|
0 = none, 1 = AC-3
|
||||||
|
|
||||||
|
Setup: /etc/vdr/remote.conf
|
||||||
|
------
|
||||||
|
|
||||||
|
Add "XKeySym." definitions to /etc/vdr/remote.conf to control
|
||||||
|
the vdr and plugin with the connected input device.
|
||||||
|
|
||||||
|
fe.
|
||||||
|
XKeySym.Up Up
|
||||||
|
XKeySym.Down Down
|
||||||
|
...
|
||||||
|
|
||||||
|
Additional to the x11 input sends the window close button "Close".
|
||||||
|
|
||||||
|
fe.
|
||||||
|
XKeySym.Power Close
|
||||||
|
|
||||||
Commandline:
|
Commandline:
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Use vdr -h to see the command line arguments support by the plugin.
|
Use vdr -h to see the command line arguments support by the plugin.
|
||||||
|
|
||||||
|
Running:
|
||||||
|
--------
|
||||||
|
|
||||||
|
Click into video window to toggle fullscreen/window mode, only if you
|
||||||
|
have a window manager running.
|
||||||
|
|
||||||
Warning:
|
Warning:
|
||||||
--------
|
--------
|
||||||
libav is not supported, expect many bugs with it.
|
libav is not supported, expect many bugs with it.
|
||||||
|
|||||||
43
Todo
43
Todo
@@ -19,17 +19,13 @@ GNU Affero General Public License for more details.
|
|||||||
$Id: $
|
$Id: $
|
||||||
|
|
||||||
missing:
|
missing:
|
||||||
video out with xv
|
|
||||||
video out with opengl
|
|
||||||
software decoder for xv / opengl
|
|
||||||
software deinterlace
|
software deinterlace
|
||||||
auto crop
|
auto crop
|
||||||
atmolight
|
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
||||||
zoom/fit-zoom 4:3
|
|
||||||
multistream handling
|
|
||||||
disable screensaver
|
|
||||||
disable window cursor
|
|
||||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
||||||
|
suspend output / energie saver: stop audio, stop video, configurable
|
||||||
|
Option deinterlace off / deinterlace force!
|
||||||
|
Make output drivers better moduluar.
|
||||||
|
|
||||||
vdpau:
|
vdpau:
|
||||||
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
||||||
@@ -38,9 +34,11 @@ vdpau:
|
|||||||
Improve OSD handling, show only what is used. Big OSD costs performance
|
Improve OSD handling, show only what is used. Big OSD costs performance
|
||||||
VdpPreemptionCallback handling
|
VdpPreemptionCallback handling
|
||||||
hard channel switch
|
hard channel switch
|
||||||
|
suspendoutput didn't show logo or black picture.
|
||||||
|
|
||||||
libva:
|
libva:
|
||||||
hard channel switch
|
hard channel switch
|
||||||
|
yaepghd (VaapiSetOutputPosition) support
|
||||||
|
|
||||||
libva-intel-driver:
|
libva-intel-driver:
|
||||||
intel still has hangups most with 1080i
|
intel still has hangups most with 1080i
|
||||||
@@ -56,16 +54,14 @@ libva-vdpau-driver:
|
|||||||
libva-xvba-driver:
|
libva-xvba-driver:
|
||||||
|
|
||||||
x11:
|
x11:
|
||||||
support resize of x11 window
|
disable screensaver
|
||||||
support fullscreen window
|
|
||||||
support fullscreen / window toggle
|
|
||||||
close window should send power button
|
|
||||||
disable cursor
|
|
||||||
|
|
||||||
audio/alsa:
|
audio/alsa:
|
||||||
done? video/audio asyncron
|
done? video/audio asyncron
|
||||||
random crashes in av_parser_parse2, when switching channels
|
random crashes in av_parser_parse2, when switching channels
|
||||||
sometimes alsa hangs
|
sometimes alsa hangs
|
||||||
|
fixed? snd_pcm_state: Assertion `pcm' failed. while switching channels
|
||||||
|
(thread problem)
|
||||||
|
|
||||||
better downmix of >2 channels on 2 channel hardware
|
better downmix of >2 channels on 2 channel hardware
|
||||||
remix support of unsupported sample rates
|
remix support of unsupported sample rates
|
||||||
@@ -73,21 +69,38 @@ audio/alsa:
|
|||||||
ffmpeg didn't support resample of 5 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.
|
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:
|
audio/oss:
|
||||||
alsa oss emulation mixer "pcm" not working
|
alsa oss emulation mixer "pcm" not working
|
||||||
ring buffer overflow with alsa oss emulation
|
ring buffer overflow with alsa oss emulation
|
||||||
|
|
||||||
HDMI/SPDIF Passthrough:
|
HDMI/SPDIF Passthrough:
|
||||||
only AC-3 written
|
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
|
playback of recording
|
||||||
play back is too fast
|
|
||||||
pause is not reset, when replay exit
|
pause is not reset, when replay exit
|
||||||
|
replay/pause need 100% cpu
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
Setup of decoder type.
|
Setup of decoder type.
|
||||||
Setup of output type.
|
Setup of output type.
|
||||||
Setup of display type.
|
Setup of display type.
|
||||||
Setup 4:3 zoom type
|
Setup 4:3 zoom type
|
||||||
Setup parameters are not used until restart.
|
Some setup parameters are not used until restart.
|
||||||
Can a notice be added to the setup menu?
|
Can a notice be added to the setup menu?
|
||||||
|
576i, 720p, fake 1080i, 1080i
|
||||||
|
|
||||||
|
future features (not planed for 1.0 - 1.5)
|
||||||
|
|
||||||
|
video out with xv
|
||||||
|
video out with opengl
|
||||||
|
video out with xvba
|
||||||
|
software decoder for xv / opengl
|
||||||
|
atmolight support
|
||||||
|
multistream handling
|
||||||
|
|
||||||
|
upmix stereo to AC-3
|
||||||
|
|||||||
144
audio.c
144
audio.c
@@ -296,6 +296,7 @@ static int AlsaPlayRingbuffer(void)
|
|||||||
if (first) {
|
if (first) {
|
||||||
// happens with broken alsa drivers
|
// happens with broken alsa drivers
|
||||||
Error(_("audio/alsa: broken driver %d\n"), avail);
|
Error(_("audio/alsa: broken driver %d\n"), avail);
|
||||||
|
usleep(5 * 1000);
|
||||||
}
|
}
|
||||||
Debug(4, "audio/alsa: break state %s\n",
|
Debug(4, "audio/alsa: break state %s\n",
|
||||||
snd_pcm_state_name(snd_pcm_state(AlsaPCMHandle)));
|
snd_pcm_state_name(snd_pcm_state(AlsaPCMHandle)));
|
||||||
@@ -342,6 +343,11 @@ static int AlsaPlayRingbuffer(void)
|
|||||||
if (err == -EAGAIN) {
|
if (err == -EAGAIN) {
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if (err == -EBADFD) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
*/
|
||||||
Error(_("audio/alsa: underrun error?\n"));
|
Error(_("audio/alsa: underrun error?\n"));
|
||||||
err = snd_pcm_recover(AlsaPCMHandle, err, 0);
|
err = snd_pcm_recover(AlsaPCMHandle, err, 0);
|
||||||
if (err >= 0) {
|
if (err >= 0) {
|
||||||
@@ -368,11 +374,21 @@ static int AlsaPlayRingbuffer(void)
|
|||||||
static void AlsaFlushBuffers(void)
|
static void AlsaFlushBuffers(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
snd_pcm_state_t state;
|
||||||
|
|
||||||
RingBufferReadAdvance(AlsaRingBuffer, RingBufferUsedBytes(AlsaRingBuffer));
|
RingBufferReadAdvance(AlsaRingBuffer, RingBufferUsedBytes(AlsaRingBuffer));
|
||||||
if ((err = snd_pcm_drop(AlsaPCMHandle))) {
|
state = snd_pcm_state(AlsaPCMHandle);
|
||||||
Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err));
|
Debug(3, "audio/alsa: state %d - %s\n", state, snd_pcm_state_name(state));
|
||||||
|
if (state != SND_PCM_STATE_OPEN) {
|
||||||
|
if ((err = snd_pcm_drop(AlsaPCMHandle)) < 0) {
|
||||||
|
Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err));
|
||||||
|
}
|
||||||
|
// ****ing alsa crash, when in open state here
|
||||||
|
if ((err = snd_pcm_prepare(AlsaPCMHandle)) < 0) {
|
||||||
|
Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
AudioPTS = INT64_C(0x8000000000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -567,8 +583,20 @@ static void AlsaThread(void)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
Debug(4, "audio: play loop\n");
|
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
if (AlsaFlushBuffer) {
|
||||||
|
// we can flush too many, but wo cares
|
||||||
|
Debug(3, "audio/alsa: flushing buffers\n");
|
||||||
|
AlsaFlushBuffers();
|
||||||
|
/*
|
||||||
|
if ((err = snd_pcm_prepare(AlsaPCMHandle))) {
|
||||||
|
Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
AlsaFlushBuffer = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// wait for space in kernel buffers
|
||||||
if ((err = snd_pcm_wait(AlsaPCMHandle, 100)) < 0) {
|
if ((err = snd_pcm_wait(AlsaPCMHandle, 100)) < 0) {
|
||||||
Error(_("audio/alsa: wait underrun error?\n"));
|
Error(_("audio/alsa: wait underrun error?\n"));
|
||||||
err = snd_pcm_recover(AlsaPCMHandle, err, 0);
|
err = snd_pcm_recover(AlsaPCMHandle, err, 0);
|
||||||
@@ -580,14 +608,7 @@ static void AlsaThread(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (AlsaFlushBuffer) {
|
if (AlsaFlushBuffer) {
|
||||||
// we can flush too many, but wo cares
|
continue;
|
||||||
Debug(3, "audio/alsa: flushing buffers\n");
|
|
||||||
AlsaFlushBuffers();
|
|
||||||
if ((err = snd_pcm_prepare(AlsaPCMHandle))) {
|
|
||||||
Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err));
|
|
||||||
}
|
|
||||||
AlsaFlushBuffer = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if ((err = AlsaPlayRingbuffer())) { // empty / error
|
if ((err = AlsaPlayRingbuffer())) { // empty / error
|
||||||
snd_pcm_state_t state;
|
snd_pcm_state_t state;
|
||||||
@@ -600,7 +621,8 @@ static void AlsaThread(void)
|
|||||||
Debug(3, "audio/alsa: stopping play\n");
|
Debug(3, "audio/alsa: stopping play\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
usleep(20 * 1000);
|
pthread_yield();
|
||||||
|
usleep(20 * 1000); // let fill the buffers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -834,23 +856,9 @@ static int AlsaSetup(int *freq, int *channels)
|
|||||||
if (!AlsaPCMHandle) { // alsa not running yet
|
if (!AlsaPCMHandle) { // alsa not running yet
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#if 1
|
#if 1 // easy alsa hw setup way
|
||||||
// flush any buffered data
|
// flush any buffered data
|
||||||
#ifndef SEARCH_HDMI_BUG2
|
AudioFlushBuffers();
|
||||||
#ifdef USE_AUDIO_THREAD
|
|
||||||
if (AudioRunning) {
|
|
||||||
while (AudioRunning) {
|
|
||||||
AlsaFlushBuffer = 1;
|
|
||||||
usleep(1 * 1000);
|
|
||||||
}
|
|
||||||
AlsaFlushBuffer = 0;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
AlsaFlushBuffers();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
AudioPTS = INT64_C(0x8000000000000000);
|
|
||||||
|
|
||||||
if (1) { // close+open to fix hdmi no sound bugs
|
if (1) { // close+open to fix hdmi no sound bugs
|
||||||
handle = AlsaPCMHandle;
|
handle = AlsaPCMHandle;
|
||||||
@@ -1195,6 +1203,21 @@ static int OssPlayRingbuffer(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush oss buffers.
|
||||||
|
*/
|
||||||
|
static void OssFlushBuffers(void)
|
||||||
|
{
|
||||||
|
RingBufferReadAdvance(OssRingBuffer, RingBufferUsedBytes(OssRingBuffer));
|
||||||
|
// flush kernel buffers
|
||||||
|
if (ioctl(OssPcmFildes, SNDCTL_DSP_HALT_OUTPUT, NULL) < 0) {
|
||||||
|
Error(_("audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"),
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AudioPTS = INT64_C(0x8000000000000000);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// OSS pcm polled
|
// OSS pcm polled
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -1410,16 +1433,8 @@ static int OssSetup(int *freq, int *channels)
|
|||||||
// flush any buffered data
|
// flush any buffered data
|
||||||
{
|
{
|
||||||
AudioRunning = 0;
|
AudioRunning = 0;
|
||||||
RingBufferReadAdvance(OssRingBuffer,
|
OssFlushBuffers();
|
||||||
RingBufferUsedBytes(OssRingBuffer));
|
|
||||||
// flush kernel buffers
|
|
||||||
if (ioctl(OssPcmFildes, SNDCTL_DSP_HALT_OUTPUT, NULL) == -1) {
|
|
||||||
Error(_("audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"),
|
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AudioPTS = INT64_C(0x8000000000000000);
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@@ -1639,14 +1654,16 @@ static void AudioExitThread(void)
|
|||||||
{
|
{
|
||||||
void *retval;
|
void *retval;
|
||||||
|
|
||||||
if (pthread_cancel(AudioThread)) {
|
if (AudioThread) {
|
||||||
Error(_("audio: can't queue cancel play thread\n"));
|
if (pthread_cancel(AudioThread)) {
|
||||||
|
Error(_("audio: can't queue cancel play thread\n"));
|
||||||
|
}
|
||||||
|
if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) {
|
||||||
|
Error(_("audio: can't cancel play thread\n"));
|
||||||
|
}
|
||||||
|
pthread_cond_destroy(&AudioStartCond);
|
||||||
|
pthread_mutex_destroy(&AudioMutex);
|
||||||
}
|
}
|
||||||
if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) {
|
|
||||||
Error(_("audio: can't cancel play thread\n"));
|
|
||||||
}
|
|
||||||
pthread_cond_destroy(&AudioStartCond);
|
|
||||||
pthread_mutex_destroy(&AudioMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1672,6 +1689,31 @@ void AudioEnqueue(const void *samples, int count)
|
|||||||
(void)count;
|
(void)count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush audio buffers.
|
||||||
|
*/
|
||||||
|
void AudioFlushBuffers(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_ALSA
|
||||||
|
#ifdef USE_AUDIO_THREAD
|
||||||
|
// signal thread to flush buffers
|
||||||
|
if (AudioThread) {
|
||||||
|
AlsaFlushBuffer = 1;
|
||||||
|
do {
|
||||||
|
AudioRunning = 1; // wakeup in case of sleeping
|
||||||
|
pthread_cond_signal(&AudioStartCond);
|
||||||
|
usleep(1 * 1000);
|
||||||
|
} while (AlsaFlushBuffer); // wait until flushed
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
AlsaFlushBuffers();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef USE_OSS
|
||||||
|
OssFlushBuffers();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Call back to play audio polled.
|
** Call back to play audio polled.
|
||||||
*/
|
*/
|
||||||
@@ -1687,6 +1729,20 @@ void AudioPoller(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Get free bytes in audio output.
|
||||||
|
*/
|
||||||
|
int AudioFreeBytes(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_ALSA
|
||||||
|
return AlsaRingBuffer ? RingBufferFreeBytes(AlsaRingBuffer) : INT32_MAX;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_OSS
|
||||||
|
return OssRingBuffer ? RingBufferFreeBytes(OssRingBuffer) : INT32_MAX;
|
||||||
|
#endif
|
||||||
|
return INT32_MAX; // no driver, much space
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Set audio clock base.
|
** Set audio clock base.
|
||||||
**
|
**
|
||||||
|
|||||||
8
audio.h
8
audio.h
@@ -1,7 +1,7 @@
|
|||||||
///
|
///
|
||||||
/// @file audio.h @brief Audio module headerfile
|
/// @file audio.h @brief Audio module headerfile
|
||||||
///
|
///
|
||||||
/// Copyright (c) 2009 - 2011 by Johns. All Rights Reserved.
|
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
|
||||||
///
|
///
|
||||||
/// Contributor(s):
|
/// Contributor(s):
|
||||||
///
|
///
|
||||||
@@ -28,12 +28,14 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
extern void AudioEnqueue(const void *, int); ///< buffer audio samples
|
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 AudioFreeBytes(void); ///< free bytes in audio output
|
|
||||||
//extern int AudioUsedBytes(void); ///< used bytes in audio output
|
//extern int AudioUsedBytes(void); ///< used bytes in audio output
|
||||||
extern void AudioSetClock(int64_t); ///< set audio clock base
|
extern void AudioSetClock(int64_t); ///< set audio clock base
|
||||||
extern int64_t AudioGetClock(); ///< get current audio clock
|
extern int64_t AudioGetClock(); ///< get current audio clock
|
||||||
|
|
||||||
extern uint64_t AudioGetDelay(void); ///< get current audio delay
|
extern uint64_t AudioGetDelay(void); ///< get current audio delay
|
||||||
|
|
||||||
extern int AudioSetup(int *, int *); ///< setup audio output
|
extern int AudioSetup(int *, int *); ///< setup audio output
|
||||||
|
|||||||
23
codec.c
23
codec.c
@@ -561,6 +561,16 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush the video decoder.
|
||||||
|
**
|
||||||
|
** @param decoder video decoder data
|
||||||
|
*/
|
||||||
|
void CodecVideoFlushBuffers(VideoDecoder * decoder)
|
||||||
|
{
|
||||||
|
avcodec_flush_buffers(decoder->VideoCtx);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Audio
|
// Audio
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -738,9 +748,11 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
spkt->pts = avpkt->pts;
|
spkt->pts = avpkt->pts;
|
||||||
spkt->dts = avpkt->dts;
|
spkt->dts = avpkt->dts;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEBUG
|
||||||
if (!audio_decoder->AudioParser) {
|
if (!audio_decoder->AudioParser) {
|
||||||
Fatal(_("codec: internal error parser freeded while running\n"));
|
Fatal(_("codec: internal error parser freeded while running\n"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
audio_ctx = audio_decoder->AudioCtx;
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
index = 0;
|
index = 0;
|
||||||
@@ -1026,6 +1038,17 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush the audio decoder.
|
||||||
|
**
|
||||||
|
** @param decoder audio decoder data
|
||||||
|
*/
|
||||||
|
void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
||||||
|
{
|
||||||
|
// FIXME: reset audio parser
|
||||||
|
avcodec_flush_buffers(decoder->AudioCtx);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Codec
|
// Codec
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
24
codec.h
24
codec.h
@@ -1,7 +1,7 @@
|
|||||||
///
|
///
|
||||||
/// @file codec.h @brief Codec module headerfile
|
/// @file codec.h @brief Codec module headerfile
|
||||||
///
|
///
|
||||||
/// Copyright (c) 2009 - 2011 by Johns. All Rights Reserved.
|
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
|
||||||
///
|
///
|
||||||
/// Contributor(s):
|
/// Contributor(s):
|
||||||
///
|
///
|
||||||
@@ -40,26 +40,32 @@ typedef struct _audio_decoder_ AudioDecoder;
|
|||||||
/// Allocate a new video decoder context.
|
/// Allocate a new video decoder context.
|
||||||
extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
|
extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Open video codec
|
/// Open video codec.
|
||||||
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
|
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
|
||||||
|
|
||||||
/// Close video codec
|
/// Close video codec.
|
||||||
extern void CodecVideoClose(VideoDecoder *);
|
extern void CodecVideoClose(VideoDecoder *);
|
||||||
|
|
||||||
/// Decode a video packet
|
/// Decode a video packet.
|
||||||
extern void CodecVideoDecode(VideoDecoder *, const AVPacket * pkt);
|
extern void CodecVideoDecode(VideoDecoder *, const AVPacket *);
|
||||||
|
|
||||||
|
/// Flush video buffers.
|
||||||
|
extern void CodecVideoFlushBuffers(VideoDecoder *);
|
||||||
|
|
||||||
/// Allocate a new audio decoder context.
|
/// Allocate a new audio decoder context.
|
||||||
extern AudioDecoder *CodecAudioNewDecoder(void);
|
extern AudioDecoder *CodecAudioNewDecoder(void);
|
||||||
|
|
||||||
/// Open audio codec
|
/// Open audio codec.
|
||||||
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
|
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
|
||||||
|
|
||||||
/// Close audio codec
|
/// Close audio codec.
|
||||||
extern void CodecAudioClose(AudioDecoder *);
|
extern void CodecAudioClose(AudioDecoder *);
|
||||||
|
|
||||||
/// Decode an audio packet
|
/// Decode an audio packet.
|
||||||
extern void CodecAudioDecode(AudioDecoder *, const AVPacket * pkt);
|
extern void CodecAudioDecode(AudioDecoder *, const AVPacket *);
|
||||||
|
|
||||||
|
/// Flush audio buffers.
|
||||||
|
extern void CodecAudioFlushBuffers(AudioDecoder *);
|
||||||
|
|
||||||
/// Setup and initialize codec module.
|
/// Setup and initialize codec module.
|
||||||
extern void CodecInit(void);
|
extern void CodecInit(void);
|
||||||
|
|||||||
234
softhddev.c
234
softhddev.c
@@ -35,6 +35,11 @@
|
|||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
|
||||||
|
#ifndef __USE_GNU
|
||||||
|
#define __USE_GNU
|
||||||
|
#endif
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "softhddev.h"
|
#include "softhddev.h"
|
||||||
|
|
||||||
@@ -52,18 +57,23 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
|
|||||||
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char DeviceStopped = 1; ///< flag device stopped
|
static char ConfigFullscreen; ///< fullscreen modus
|
||||||
|
static char ConfigSuspendClose = 1; ///< suspend should close devices
|
||||||
|
static char ConfigSuspendX11 = 1; ///< suspend should stop x11
|
||||||
|
|
||||||
|
static pthread_mutex_t SuspendLockMutex; ///< suspend lock mutex
|
||||||
|
|
||||||
|
static volatile char VideoFreezed; ///< video freezed
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Audio
|
// Audio
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static volatile char NewAudioStream; ///< new audio stream
|
static volatile char NewAudioStream; ///< new audio stream
|
||||||
|
static volatile char SkipAudio; ///< skip audio stream
|
||||||
static AudioDecoder *MyAudioDecoder; ///< audio decoder
|
static AudioDecoder *MyAudioDecoder; ///< audio decoder
|
||||||
static enum CodecID AudioCodecID; ///< current codec id
|
static enum CodecID AudioCodecID; ///< current codec id
|
||||||
|
|
||||||
extern void AudioTest(void); // FIXME:
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** mpeg bitrate table.
|
** mpeg bitrate table.
|
||||||
**
|
**
|
||||||
@@ -187,26 +197,37 @@ static int FindAudioSync(const AVPacket * avpkt)
|
|||||||
** @param size size of PES packet
|
** @param size size of PES packet
|
||||||
** @param id PES packet type
|
** @param id PES packet type
|
||||||
*/
|
*/
|
||||||
void PlayAudio(const uint8_t * data, int size,
|
int PlayAudio(const uint8_t * data, int size,
|
||||||
__attribute__ ((unused)) uint8_t id)
|
__attribute__ ((unused)) uint8_t id)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
int osize;
|
||||||
AVPacket avpkt[1];
|
AVPacket avpkt[1];
|
||||||
|
|
||||||
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
||||||
|
|
||||||
|
if (VideoFreezed) { // video freezed
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (NewAudioStream) {
|
if (NewAudioStream) {
|
||||||
// FIXME: does this clear the audio ringbuffer?
|
// FIXME: does this clear the audio ringbuffer?
|
||||||
CodecAudioClose(MyAudioDecoder);
|
CodecAudioClose(MyAudioDecoder);
|
||||||
AudioCodecID = CODEC_ID_NONE;
|
AudioCodecID = CODEC_ID_NONE;
|
||||||
NewAudioStream = 0;
|
NewAudioStream = 0;
|
||||||
}
|
}
|
||||||
|
if (SkipAudio) { // skip audio
|
||||||
|
return size;
|
||||||
|
}
|
||||||
// PES header 0x00 0x00 0x01 ID
|
// PES header 0x00 0x00 0x01 ID
|
||||||
// ID 0xBD 0xC0-0xCF
|
// ID 0xBD 0xC0-0xCF
|
||||||
|
|
||||||
if (size < 9) {
|
if (size < 9) {
|
||||||
Error(_("[softhddev] invalid audio packet\n"));
|
Error(_("[softhddev] invalid audio packet\n"));
|
||||||
return;
|
return size;
|
||||||
|
}
|
||||||
|
// Don't overrun audio buffers on replay
|
||||||
|
if (AudioFreeBytes() < 3072 * 8 * 8) { // 8 channels 8 packets
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = data[8]; // header size
|
n = data[8]; // header size
|
||||||
@@ -227,11 +248,12 @@ void PlayAudio(const uint8_t * data, int size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osize = size;
|
||||||
data += 9 + n;
|
data += 9 + n;
|
||||||
size -= 9 + n; // skip pes header
|
size -= 9 + n; // skip pes header
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
Error(_("[softhddev] invalid audio packet\n"));
|
Error(_("[softhddev] invalid audio packet\n"));
|
||||||
return;
|
return osize;
|
||||||
}
|
}
|
||||||
// Detect audio code
|
// Detect audio code
|
||||||
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
||||||
@@ -273,7 +295,7 @@ void PlayAudio(const uint8_t * data, int size,
|
|||||||
avpkt->size = size;
|
avpkt->size = size;
|
||||||
n = FindAudioSync(avpkt);
|
n = FindAudioSync(avpkt);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return;
|
return osize;
|
||||||
}
|
}
|
||||||
if (!MyAudioDecoder) {
|
if (!MyAudioDecoder) {
|
||||||
MyAudioDecoder = CodecAudioNewDecoder();
|
MyAudioDecoder = CodecAudioNewDecoder();
|
||||||
@@ -288,13 +310,15 @@ void PlayAudio(const uint8_t * data, int size,
|
|||||||
|
|
||||||
// no decoder or codec known
|
// no decoder or codec known
|
||||||
if (!MyAudioDecoder || AudioCodecID == CODEC_ID_NONE) {
|
if (!MyAudioDecoder || AudioCodecID == CODEC_ID_NONE) {
|
||||||
return;
|
return osize;
|
||||||
}
|
}
|
||||||
|
|
||||||
avpkt->data = (void *)data;
|
avpkt->data = (void *)data;
|
||||||
avpkt->size = size;
|
avpkt->size = size;
|
||||||
//memset(avpkt->data + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
//memset(avpkt->data + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
CodecAudioDecode(MyAudioDecoder, avpkt);
|
CodecAudioDecode(MyAudioDecoder, avpkt);
|
||||||
|
|
||||||
|
return osize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,7 +326,8 @@ void PlayAudio(const uint8_t * data, int size,
|
|||||||
*/
|
*/
|
||||||
void Mute(void)
|
void Mute(void)
|
||||||
{
|
{
|
||||||
AudioSetVolume(0);
|
SkipAudio = 1;
|
||||||
|
//AudioSetVolume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,8 +362,8 @@ static AVPacket VideoPacketRb[VIDEO_PACKET_MAX];
|
|||||||
static int VideoPacketWrite; ///< write pointer
|
static int VideoPacketWrite; ///< write pointer
|
||||||
static int VideoPacketRead; ///< read pointer
|
static int VideoPacketRead; ///< read pointer
|
||||||
static atomic_t VideoPacketsFilled; ///< how many of the buffer is used
|
static atomic_t VideoPacketsFilled; ///< how many of the buffer is used
|
||||||
static volatile char VideoFreezed; ///< video freezed
|
|
||||||
static volatile char VideoClearBuffers; ///< clear video buffers
|
static volatile char VideoClearBuffers; ///< clear video buffers
|
||||||
|
static volatile char SkipVideo; ///< skip video
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int VideoMaxPacketSize; ///< biggest used packet buffer
|
static int VideoMaxPacketSize; ///< biggest used packet buffer
|
||||||
@@ -351,8 +376,6 @@ static void VideoPacketInit(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Debug(4, "[softhddev]: %s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
|
|
||||||
@@ -374,16 +397,10 @@ static void VideoPacketExit(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Debug(4, "[softhddev]: %s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
atomic_set(&VideoPacketsFilled, 0);
|
atomic_set(&VideoPacketsFilled, 0);
|
||||||
|
|
||||||
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
|
||||||
AVPacket *avpkt;
|
av_free_packet(&VideoPacketRb[i]);
|
||||||
|
|
||||||
avpkt = &VideoPacketRb[i];
|
|
||||||
// build a clean ffmpeg av packet
|
|
||||||
av_free_packet(avpkt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,13 +483,13 @@ static void VideoNextPacket(int codec_id)
|
|||||||
VideoPacketWrite = (VideoPacketWrite + 1) % VIDEO_PACKET_MAX;
|
VideoPacketWrite = (VideoPacketWrite + 1) % VIDEO_PACKET_MAX;
|
||||||
atomic_inc(&VideoPacketsFilled);
|
atomic_inc(&VideoPacketsFilled);
|
||||||
|
|
||||||
|
VideoDisplayWakeup();
|
||||||
|
|
||||||
// intialize next package to use
|
// intialize next package to use
|
||||||
avpkt = &VideoPacketRb[VideoPacketWrite];
|
avpkt = &VideoPacketRb[VideoPacketWrite];
|
||||||
avpkt->stream_index = 0;
|
avpkt->stream_index = 0;
|
||||||
avpkt->pts = AV_NOPTS_VALUE;
|
avpkt->pts = AV_NOPTS_VALUE;
|
||||||
avpkt->dts = AV_NOPTS_VALUE;
|
avpkt->dts = AV_NOPTS_VALUE;
|
||||||
|
|
||||||
VideoDisplayHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -490,6 +507,10 @@ int VideoDecode(void)
|
|||||||
}
|
}
|
||||||
if (VideoClearBuffers) {
|
if (VideoClearBuffers) {
|
||||||
atomic_set(&VideoPacketsFilled, 0);
|
atomic_set(&VideoPacketsFilled, 0);
|
||||||
|
VideoPacketRead = VideoPacketWrite;
|
||||||
|
if (MyVideoDecoder) {
|
||||||
|
CodecVideoFlushBuffers(MyVideoDecoder);
|
||||||
|
}
|
||||||
VideoClearBuffers = 0;
|
VideoClearBuffers = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -560,19 +581,23 @@ int VideoDecode(void)
|
|||||||
/**
|
/**
|
||||||
** Try video start.
|
** Try video start.
|
||||||
**
|
**
|
||||||
** 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) {
|
||||||
|
// FIXME: not good looking, mapped and then resized.
|
||||||
|
VideoSetFullscreen(1);
|
||||||
|
}
|
||||||
VideoOsdInit();
|
VideoOsdInit();
|
||||||
if (!MyVideoDecoder) {
|
if (!MyVideoDecoder) {
|
||||||
VideoHwDecoder *hw_decoder;
|
VideoHwDecoder *hw_decoder;
|
||||||
|
|
||||||
if ((hw_decoder = VideoNewHwDecoder())) {
|
if ((hw_decoder = VideoNewHwDecoder())) {
|
||||||
MyVideoDecoder = CodecVideoNewDecoder(hw_decoder);
|
MyVideoDecoder = CodecVideoNewDecoder(hw_decoder);
|
||||||
VideoCodecID = CODEC_ID_NONE;
|
|
||||||
}
|
}
|
||||||
|
VideoCodecID = CODEC_ID_NONE;
|
||||||
}
|
}
|
||||||
VideoPacketInit();
|
VideoPacketInit();
|
||||||
}
|
}
|
||||||
@@ -641,6 +666,12 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
if (!MyVideoDecoder) { // no x11 video started
|
if (!MyVideoDecoder) { // no x11 video started
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
if (SkipVideo) { // skip video
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
if (VideoFreezed) { // video freezed
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (NewVideoStream) { // channel switched
|
if (NewVideoStream) { // channel switched
|
||||||
Debug(3, "video: new stream %d\n", GetMsTicks() - VideoSwitch);
|
Debug(3, "video: new stream %d\n", GetMsTicks() - VideoSwitch);
|
||||||
// FIXME: hack to test results
|
// FIXME: hack to test results
|
||||||
@@ -661,7 +692,7 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
n = data[8]; // header size
|
n = data[8]; // header size
|
||||||
// wrong size
|
// wrong size
|
||||||
if (size < 9 + n + 4) {
|
if (size < 9 + n + 4) {
|
||||||
Error(_("[softhddev] invalid video packet\n"));
|
Error(_("[softhddev] invalid video packet %d bytes\n"), size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
// FIXME: hack to test results
|
// FIXME: hack to test results
|
||||||
@@ -728,6 +759,16 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
Debug(3, "video: h264 detected\n");
|
Debug(3, "video: h264 detected\n");
|
||||||
VideoCodecID = CODEC_ID_H264;
|
VideoCodecID = CODEC_ID_H264;
|
||||||
}
|
}
|
||||||
|
// Access Unit Delimiter (BBC-HD)
|
||||||
|
// FIXME: the 4 offset are try & error selected
|
||||||
|
} else if ((data[6] & 0xC0) == 0x80 && !check[4 + 0] && !check[4 + 1]
|
||||||
|
&& !check[4 + 2] && check[4 + 3] == 0x1 && check[4 + 4] == 0x09) {
|
||||||
|
if (VideoCodecID == CODEC_ID_H264) {
|
||||||
|
VideoNextPacket(CODEC_ID_H264);
|
||||||
|
} else {
|
||||||
|
Debug(3, "video: h264 detected\n");
|
||||||
|
VideoCodecID = CODEC_ID_H264;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// this happens when vdr sends incomplete packets
|
// this happens when vdr sends incomplete packets
|
||||||
if (VideoCodecID == CODEC_ID_NONE) {
|
if (VideoCodecID == CODEC_ID_NONE) {
|
||||||
@@ -754,6 +795,7 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
*/
|
*/
|
||||||
void SetPlayMode(void)
|
void SetPlayMode(void)
|
||||||
{
|
{
|
||||||
|
Resume();
|
||||||
if (MyVideoDecoder) {
|
if (MyVideoDecoder) {
|
||||||
if (VideoCodecID != CODEC_ID_NONE) {
|
if (VideoCodecID != CODEC_ID_NONE) {
|
||||||
NewVideoStream = 1;
|
NewVideoStream = 1;
|
||||||
@@ -761,8 +803,13 @@ void SetPlayMode(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MyAudioDecoder) {
|
if (MyAudioDecoder) {
|
||||||
NewAudioStream = 1;
|
if (AudioCodecID != CODEC_ID_NONE) {
|
||||||
|
NewAudioStream = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
VideoFreezed = 0;
|
||||||
|
SkipAudio = 0;
|
||||||
|
SkipVideo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -770,9 +817,16 @@ void SetPlayMode(void)
|
|||||||
*/
|
*/
|
||||||
void Clear(void)
|
void Clear(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VideoNextPacket(VideoCodecID); // terminate work
|
||||||
VideoClearBuffers = 1;
|
VideoClearBuffers = 1;
|
||||||
// FIXME: avcodec_flush_buffers
|
// FIXME: avcodec_flush_buffers
|
||||||
// FIXME: flush audio buffers
|
AudioFlushBuffers();
|
||||||
|
|
||||||
|
for (i = 0; VideoClearBuffers && i < 20; ++i) {
|
||||||
|
usleep(1 * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -781,6 +835,7 @@ void Clear(void)
|
|||||||
void Play(void)
|
void Play(void)
|
||||||
{
|
{
|
||||||
VideoFreezed = 0;
|
VideoFreezed = 0;
|
||||||
|
SkipAudio = 0;
|
||||||
// FIXME: restart audio
|
// FIXME: restart audio
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,16 +846,38 @@ void Freeze(void)
|
|||||||
{
|
{
|
||||||
VideoFreezed = 1;
|
VideoFreezed = 1;
|
||||||
// FIXME: freeze audio
|
// FIXME: freeze audio
|
||||||
|
AudioFlushBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Display the given I-frame as a still picture.
|
||||||
|
*/
|
||||||
|
void StillPicture(const uint8_t * data, int size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// must be a PES start code
|
||||||
|
if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) {
|
||||||
|
Error(_("[softhddev] invalid PES video packet\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Clear(); // flush video buffers
|
||||||
|
// +1 future for deinterlace
|
||||||
|
for (i = -1; i < (VideoCodecID == CODEC_ID_MPEG2VIDEO ? 3 : 17); ++i) {
|
||||||
|
PlayVideo(data, size); // reference frames
|
||||||
|
}
|
||||||
|
VideoNextPacket(VideoCodecID); // terminate last packet
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Poll if device is ready. Called by replay.
|
** Poll if device is ready. Called by replay.
|
||||||
|
**
|
||||||
|
** @param timeout timeout to become ready in ms
|
||||||
*/
|
*/
|
||||||
int Poll(int timeout)
|
int Poll(int timeout)
|
||||||
{
|
{
|
||||||
// buffers are too full
|
// buffers are too full
|
||||||
if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX / 2) {
|
if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX / 2) {
|
||||||
Debug(3, "replay: poll %d\n", timeout);
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
// let display thread work
|
// let display thread work
|
||||||
usleep(timeout * 1000);
|
usleep(timeout * 1000);
|
||||||
@@ -810,6 +887,22 @@ int Poll(int timeout)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush the device output buffers.
|
||||||
|
**
|
||||||
|
** @param timeout timeout to flush in ms
|
||||||
|
*/
|
||||||
|
int Flush(int timeout)
|
||||||
|
{
|
||||||
|
if (atomic_read(&VideoPacketsFilled)) {
|
||||||
|
if (timeout) { // let display thread work
|
||||||
|
usleep(timeout * 1000);
|
||||||
|
}
|
||||||
|
return !atomic_read(&VideoPacketsFilled);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// OSD
|
// OSD
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -819,7 +912,9 @@ int Poll(int timeout)
|
|||||||
*/
|
*/
|
||||||
void GetOsdSize(int *width, int *height, double *aspect)
|
void GetOsdSize(int *width, int *height, double *aspect)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
static char done;
|
static char done;
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME: should be configured!
|
// FIXME: should be configured!
|
||||||
*width = 1920;
|
*width = 1920;
|
||||||
@@ -829,11 +924,13 @@ void GetOsdSize(int *width, int *height, double *aspect)
|
|||||||
|
|
||||||
*aspect = 16.0 / 9.0 / (double)*width * (double)*height;
|
*aspect = 16.0 / 9.0 / (double)*width * (double)*height;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
if (!done) {
|
if (!done) {
|
||||||
Debug(3, "[softhddev]%s: %dx%d %g\n", __FUNCTION__, *width, *height,
|
Debug(3, "[softhddev]%s: %dx%d %g\n", __FUNCTION__, *width, *height,
|
||||||
*aspect);
|
*aspect);
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -849,22 +946,24 @@ void OsdClose(void)
|
|||||||
*/
|
*/
|
||||||
void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
|
void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
|
||||||
{
|
{
|
||||||
|
Resume();
|
||||||
VideoOsdDrawARGB(x, y, height, width, argb);
|
VideoOsdDrawARGB(x, y, height, width, argb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static char StartX11Server; ///< flag start the x11 server
|
static char ConfigStartX11Server; ///< flag start the x11 server
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Return command line help string.
|
** Return command line help string.
|
||||||
*/
|
*/
|
||||||
const char *CommandLineHelp(void)
|
const char *CommandLineHelp(void)
|
||||||
{
|
{
|
||||||
return " -a device\talsa audio device (fe. hw:0,0)\n"
|
return " -a device\taudio device (fe. alsa: hw:0,0 oss: /dev/dsp)\n"
|
||||||
" -d display\tdisplay of x11 server (f.e :0.0)\n"
|
" -d display\tdisplay of x11 server (fe. :0.0)\n"
|
||||||
|
" -f\t\tstart with fullscreen window (only with window manager)\n"
|
||||||
" -g geometry\tx11 window geometry wxh+x+y\n"
|
" -g geometry\tx11 window geometry wxh+x+y\n"
|
||||||
" -x\tstart x11 server\n";
|
" -x\t\tstart x11 server\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -879,13 +978,16 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
// Parse arguments.
|
// Parse arguments.
|
||||||
//
|
//
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (getopt(argc, argv, "-a:d:g:x")) {
|
switch (getopt(argc, argv, "-a:d:fg:x")) {
|
||||||
case 'a': // audio device
|
case 'a': // audio device
|
||||||
AudioSetDevice(optarg);
|
AudioSetDevice(optarg);
|
||||||
continue;
|
continue;
|
||||||
case 'd': // x11 display name
|
case 'd': // x11 display name
|
||||||
X11DisplayName = optarg;
|
X11DisplayName = optarg;
|
||||||
continue;
|
continue;
|
||||||
|
case 'f': // fullscreen mode
|
||||||
|
ConfigFullscreen = 1;
|
||||||
|
continue;
|
||||||
case 'g': // geometry
|
case 'g': // geometry
|
||||||
if (VideoSetGeometry(optarg) < 0) {
|
if (VideoSetGeometry(optarg) < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -895,7 +997,7 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'x': // x11 server
|
case 'x': // x11 server
|
||||||
StartX11Server = 1;
|
ConfigStartX11Server = 1;
|
||||||
continue;
|
continue;
|
||||||
case EOF:
|
case EOF:
|
||||||
break;
|
break;
|
||||||
@@ -1034,13 +1136,16 @@ void SoftHdDeviceExit(void)
|
|||||||
CodecExit();
|
CodecExit();
|
||||||
VideoPacketExit();
|
VideoPacketExit();
|
||||||
|
|
||||||
if (StartX11Server) {
|
if (ConfigStartX11Server) {
|
||||||
Debug(3, "x-setup: Stop x11 server\n");
|
Debug(3, "x-setup: Stop x11 server\n");
|
||||||
|
|
||||||
if (X11ServerPid) {
|
if (X11ServerPid) {
|
||||||
kill(X11ServerPid, SIGTERM);
|
kill(X11ServerPid, SIGTERM);
|
||||||
|
// FIXME: wait for x11 finishing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&SuspendLockMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1048,15 +1153,17 @@ void SoftHdDeviceExit(void)
|
|||||||
*/
|
*/
|
||||||
void Start(void)
|
void Start(void)
|
||||||
{
|
{
|
||||||
if (StartX11Server) {
|
if (ConfigStartX11Server) {
|
||||||
StartXServer();
|
StartXServer();
|
||||||
}
|
}
|
||||||
CodecInit();
|
CodecInit();
|
||||||
// FIXME: AudioInit for HDMI after X11 startup
|
// FIXME: AudioInit for HDMI after X11 startup
|
||||||
AudioInit();
|
AudioInit();
|
||||||
if (!StartX11Server) {
|
if (!ConfigStartX11Server) {
|
||||||
StartVideo();
|
StartVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_init(&SuspendLockMutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1076,7 +1183,58 @@ void Stop(void)
|
|||||||
*/
|
*/
|
||||||
void MainThreadHook(void)
|
void MainThreadHook(void)
|
||||||
{
|
{
|
||||||
if (!DeviceStopped) {
|
}
|
||||||
VideoDisplayHandler();
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Suspend/Resume
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Suspend plugin.
|
||||||
|
*/
|
||||||
|
void Suspend(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&SuspendLockMutex);
|
||||||
|
if (SkipVideo && SkipAudio) { // already suspended
|
||||||
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
|
SkipVideo = 1;
|
||||||
|
SkipAudio = 1;
|
||||||
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
|
|
||||||
|
if (ConfigSuspendClose) {
|
||||||
|
pthread_mutex_lock(&SuspendLockMutex);
|
||||||
|
// FIXME: close audio
|
||||||
|
// FIXME: close video
|
||||||
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
|
}
|
||||||
|
if (ConfigSuspendX11) {
|
||||||
|
// FIXME: stop x11, if started
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Resume plugin.
|
||||||
|
*/
|
||||||
|
void Resume(void)
|
||||||
|
{
|
||||||
|
if (!SkipVideo && !SkipAudio) { // we are not suspended
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (ConfigSuspendX11) {
|
||||||
|
}
|
||||||
|
if (ConfigSuspendClose) {
|
||||||
|
pthread_mutex_lock(&SuspendLockMutex);
|
||||||
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipVideo = 0;
|
||||||
|
SkipAudio = 0;
|
||||||
|
}
|
||||||
|
|||||||
12
softhddev.h
12
softhddev.h
@@ -1,7 +1,7 @@
|
|||||||
///
|
///
|
||||||
/// @file softhddev.h @brief software HD device plugin header file.
|
/// @file softhddev.h @brief software HD device plugin header file.
|
||||||
///
|
///
|
||||||
/// Copyright (c) 2011 by Johns. All Rights Reserved.
|
/// Copyright (c) 2011 - 2012 by Johns. All Rights Reserved.
|
||||||
///
|
///
|
||||||
/// Contributor(s):
|
/// Contributor(s):
|
||||||
///
|
///
|
||||||
@@ -36,7 +36,7 @@ extern "C"
|
|||||||
extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
|
extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
|
||||||
|
|
||||||
/// C plugin play audio packet
|
/// C plugin play audio packet
|
||||||
extern void PlayAudio(const uint8_t *, int, uint8_t);
|
extern int PlayAudio(const uint8_t *, int, uint8_t);
|
||||||
/// C plugin mute audio
|
/// C plugin mute audio
|
||||||
extern void Mute(void);
|
extern void Mute(void);
|
||||||
/// C plugin set audio volume
|
/// C plugin set audio volume
|
||||||
@@ -55,8 +55,12 @@ extern "C"
|
|||||||
extern void Play(void);
|
extern void Play(void);
|
||||||
/// C plugin sets the device into "freeze frame" mode
|
/// C plugin sets the device into "freeze frame" mode
|
||||||
extern void Freeze(void);
|
extern void Freeze(void);
|
||||||
|
/// C plugin display I-frame as a still picture.
|
||||||
|
extern void StillPicture(const uint8_t *, int);
|
||||||
/// C plugin poll if ready
|
/// C plugin poll if ready
|
||||||
extern int Poll(int);
|
extern int Poll(int);
|
||||||
|
/// C plugin flush output buffers
|
||||||
|
extern int Flush(int);
|
||||||
|
|
||||||
/// C plugin command line help
|
/// C plugin command line help
|
||||||
extern const char *CommandLineHelp(void);
|
extern const char *CommandLineHelp(void);
|
||||||
@@ -72,6 +76,10 @@ extern "C"
|
|||||||
/// C plugin main thread hook
|
/// C plugin main thread hook
|
||||||
extern void MainThreadHook(void);
|
extern void MainThreadHook(void);
|
||||||
|
|
||||||
|
/// Suspend plugin
|
||||||
|
extern void Suspend(void);
|
||||||
|
/// Resume plugin
|
||||||
|
extern void Resume(void);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
438
softhddevice.cpp
438
softhddevice.cpp
@@ -42,23 +42,42 @@ extern "C"
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const char *const VERSION = "0.2.0";
|
static const char *const VERSION = "0.3.1";
|
||||||
static const char *const DESCRIPTION =
|
static const char *const DESCRIPTION =
|
||||||
trNOOP("A software and GPU emulated HD device");
|
trNOOP("A software and GPU emulated HD device");
|
||||||
|
|
||||||
//static const char *MAINMENUENTRY = trNOOP("Soft-HD-Device");
|
static const char *MAINMENUENTRY = trNOOP("Suspend Soft-HD-Device");
|
||||||
static class cSoftHdDevice *MyDevice;
|
static class cSoftHdDevice *MyDevice;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define RESOLUTIONS 4 ///< number of resolutions
|
||||||
|
|
||||||
|
static const char *const Resolution[RESOLUTIONS] = {
|
||||||
|
"576i", "720p", "1080i_fake", "1080i"
|
||||||
|
};
|
||||||
|
|
||||||
static char ConfigMakePrimary; ///< config primary wanted
|
static char ConfigMakePrimary; ///< config primary wanted
|
||||||
static char ConfigVideoDeinterlace; ///< config deinterlace
|
static char ConfigHideMainMenuEntry; ///< config hide main menu entry
|
||||||
static char ConfigVideoSkipChromaDeinterlace; ///< config skip chroma
|
|
||||||
static int ConfigVideoDenoise; ///< config denoise
|
/// config deinterlace
|
||||||
static int ConfigVideoSharpen; ///< config sharpen
|
static int ConfigVideoDeinterlace[RESOLUTIONS];
|
||||||
static char ConfigVideoScaling; ///< config scaling
|
|
||||||
|
/// config skip chroma
|
||||||
|
static int ConfigVideoSkipChromaDeinterlace[RESOLUTIONS];
|
||||||
|
|
||||||
|
/// config denoise
|
||||||
|
static int ConfigVideoDenoise[RESOLUTIONS];
|
||||||
|
|
||||||
|
/// config sharpen
|
||||||
|
static int ConfigVideoSharpen[RESOLUTIONS];
|
||||||
|
|
||||||
|
/// config scaling
|
||||||
|
static int ConfigVideoScaling[RESOLUTIONS];
|
||||||
|
|
||||||
static int ConfigVideoAudioDelay; ///< config audio delay
|
static int ConfigVideoAudioDelay; ///< config audio delay
|
||||||
static int ConfigAudioPassthrough; ///< config audio pass-through
|
static int ConfigAudioPassthrough; ///< config audio pass-through
|
||||||
|
|
||||||
static volatile char DoMakePrimary; ///< flag switch primary
|
static volatile char DoMakePrimary; ///< flag switch primary
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -113,8 +132,10 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
|
|||||||
|
|
||||||
class cSoftOsd:public cOsd
|
class cSoftOsd:public cOsd
|
||||||
{
|
{
|
||||||
|
int Level; ///< level: subtitle
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cSoftOsd(int, int, uint);
|
cSoftOsd(int, int, uint);
|
||||||
virtual ~ cSoftOsd(void);
|
virtual ~ cSoftOsd(void);
|
||||||
virtual void Flush(void);
|
virtual void Flush(void);
|
||||||
// virtual void SetActive(bool);
|
// virtual void SetActive(bool);
|
||||||
@@ -127,6 +148,7 @@ cSoftOsd::cSoftOsd(int left, int top, uint level)
|
|||||||
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
dsyslog("[softhddev]%s: %dx%d+%d+%d, %d\n", __FUNCTION__, OsdWidth(),
|
||||||
OsdHeight(), left, top, level);
|
OsdHeight(), left, top, level);
|
||||||
|
|
||||||
|
this->Level = level;
|
||||||
//SetActive(true);
|
//SetActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +157,11 @@ cSoftOsd::~cSoftOsd(void)
|
|||||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
SetActive(false);
|
SetActive(false);
|
||||||
|
|
||||||
|
#ifdef USE_YAEPG
|
||||||
|
if (vidWin.bpp) {
|
||||||
|
VideoSetOutputPosition(0, 0, 1920, 1080);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
OsdClose();
|
OsdClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +175,18 @@ void cSoftOsd::Flush(void)
|
|||||||
if (!Active()) {
|
if (!Active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
// support yaepghd, video window
|
||||||
|
#ifdef USE_YAEPG
|
||||||
|
if (vidWin.bpp) {
|
||||||
|
dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, vidWin.Width(),
|
||||||
|
vidWin.Height(), vidWin.x1, vidWin.y2);
|
||||||
|
|
||||||
|
// FIXME: vidWin is OSD relative not video window.
|
||||||
|
VideoSetOutputPosition(Left() + vidWin.x1, Top() + vidWin.y1,
|
||||||
|
vidWin.Width(), vidWin.Height());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!IsTrueColor()) {
|
if (!IsTrueColor()) {
|
||||||
static char warned;
|
static char warned;
|
||||||
cBitmap *bitmap;
|
cBitmap *bitmap;
|
||||||
@@ -188,8 +226,24 @@ void cSoftOsd::Flush(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OsdDrawARGB(Left() + bitmap->X0(), Top() + bitmap->Y0(),
|
// check if subtitles
|
||||||
bitmap->Width(), bitmap->Height(), argb);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
bitmap->Clean();
|
bitmap->Clean();
|
||||||
free(argb);
|
free(argb);
|
||||||
@@ -255,6 +309,9 @@ bool cSoftOsdProvider::ProvidesTrueColor(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Create cOsdProvider class.
|
||||||
|
*/
|
||||||
cSoftOsdProvider::cSoftOsdProvider(void)
|
cSoftOsdProvider::cSoftOsdProvider(void)
|
||||||
: cOsdProvider()
|
: cOsdProvider()
|
||||||
{
|
{
|
||||||
@@ -269,11 +326,12 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
int MakePrimary;
|
int MakePrimary;
|
||||||
int Deinterlace;
|
int HideMainMenuEntry;
|
||||||
int SkipChromaDeinterlace;
|
int Scaling[RESOLUTIONS];
|
||||||
int Denoise;
|
int Deinterlace[RESOLUTIONS];
|
||||||
int Sharpen;
|
int SkipChromaDeinterlace[RESOLUTIONS];
|
||||||
int Scaling;
|
int Denoise[RESOLUTIONS];
|
||||||
|
int Sharpen[RESOLUTIONS];
|
||||||
int AudioDelay;
|
int AudioDelay;
|
||||||
int AudioPassthrough;
|
int AudioPassthrough;
|
||||||
protected:
|
protected:
|
||||||
@@ -282,13 +340,26 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
cMenuSetupSoft(void);
|
cMenuSetupSoft(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Create a seperator item.
|
||||||
|
*/
|
||||||
|
static inline cOsdItem *SeparatorItem(const char *label)
|
||||||
|
{
|
||||||
|
cOsdItem *item;
|
||||||
|
|
||||||
|
item = new cOsdItem(cString::sprintf("* %s: ", label));
|
||||||
|
item->SetSelectable(false);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Constructor setup menu.
|
** Constructor setup menu.
|
||||||
*/
|
*/
|
||||||
cMenuSetupSoft::cMenuSetupSoft(void)
|
cMenuSetupSoft::cMenuSetupSoft(void)
|
||||||
{
|
{
|
||||||
static const char *const deinterlace[] = {
|
static const char *const deinterlace[] = {
|
||||||
"Bob", "Weave", "Temporal", "TemporalSpatial", "Software"
|
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software"
|
||||||
};
|
};
|
||||||
static const char *const scaling[] = {
|
static const char *const scaling[] = {
|
||||||
"Normal", "Fast", "HQ", "Anamorphic"
|
"Normal", "Fast", "HQ", "Anamorphic"
|
||||||
@@ -296,26 +367,44 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
|||||||
static const char *const passthrough[] = {
|
static const char *const passthrough[] = {
|
||||||
"None", "AC-3"
|
"None", "AC-3"
|
||||||
};
|
};
|
||||||
|
static const char *const resolution[RESOLUTIONS] = {
|
||||||
|
"576i", "720p", "fake 1080i", "1080i"
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
// cMenuEditBoolItem cMenuEditBitItem cMenuEditNumItem
|
// cMenuEditBoolItem cMenuEditBitItem cMenuEditNumItem
|
||||||
// cMenuEditStrItem cMenuEditStraItem cMenuEditIntItem
|
// cMenuEditStrItem cMenuEditStraItem cMenuEditIntItem
|
||||||
MakePrimary = ConfigMakePrimary;
|
MakePrimary = ConfigMakePrimary;
|
||||||
Add(new cMenuEditBoolItem(tr("Make primary device"), &MakePrimary,
|
Add(new cMenuEditBoolItem(tr("Make primary device"), &MakePrimary,
|
||||||
tr("no"), tr("yes")));
|
tr("no"), tr("yes")));
|
||||||
Deinterlace = ConfigVideoDeinterlace;
|
HideMainMenuEntry = ConfigHideMainMenuEntry;
|
||||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace, 5,
|
Add(new cMenuEditBoolItem(tr("Hide main menu entry"), &HideMainMenuEntry,
|
||||||
deinterlace));
|
tr("no"), tr("yes")));
|
||||||
SkipChromaDeinterlace = ConfigVideoSkipChromaDeinterlace;
|
//
|
||||||
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
// video
|
||||||
&SkipChromaDeinterlace, tr("no"), tr("yes")));
|
//
|
||||||
Denoise = ConfigVideoDenoise;
|
Add(SeparatorItem(tr("Video")));
|
||||||
Add(new cMenuEditIntItem(tr("Denoise (vdpau 0..1000)"), &Denoise, 0,
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
1000));
|
Add(SeparatorItem(resolution[i]));
|
||||||
Sharpen = ConfigVideoSharpen;
|
Scaling[i] = ConfigVideoScaling[i];
|
||||||
Add(new cMenuEditIntItem(tr("Sharpen (vdpau -1000..1000)"), &Sharpen,
|
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling[i], 4, scaling));
|
||||||
-1000, 1000));
|
Deinterlace[i] = ConfigVideoDeinterlace[i];
|
||||||
Scaling = ConfigVideoScaling;
|
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i], 5,
|
||||||
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling, 4, scaling));
|
deinterlace));
|
||||||
|
SkipChromaDeinterlace[i] = ConfigVideoSkipChromaDeinterlace[i];
|
||||||
|
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
||||||
|
&SkipChromaDeinterlace[i], tr("no"), tr("yes")));
|
||||||
|
Denoise[i] = ConfigVideoDenoise[i];
|
||||||
|
Add(new cMenuEditIntItem(tr("Denoise (0..1000) (vdpau)"), &Denoise[i],
|
||||||
|
0, 1000));
|
||||||
|
Sharpen[i] = ConfigVideoSharpen[i];
|
||||||
|
Add(new cMenuEditIntItem(tr("Sharpen (-1000..1000) (vdpau)"),
|
||||||
|
&Sharpen[i], -1000, 1000));
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// audio
|
||||||
|
//
|
||||||
|
Add(SeparatorItem(tr("Audio")));
|
||||||
AudioDelay = ConfigVideoAudioDelay;
|
AudioDelay = ConfigVideoAudioDelay;
|
||||||
Add(new cMenuEditIntItem(tr("Audio delay (ms)"), &AudioDelay, -1000,
|
Add(new cMenuEditIntItem(tr("Audio delay (ms)"), &AudioDelay, -1000,
|
||||||
1000));
|
1000));
|
||||||
@@ -329,18 +418,34 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
|||||||
*/
|
*/
|
||||||
void cMenuSetupSoft::Store(void)
|
void cMenuSetupSoft::Store(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary);
|
SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary);
|
||||||
SetupStore("Deinterlace", ConfigVideoDeinterlace = Deinterlace);
|
SetupStore("HideMainMenuEntry", ConfigHideMainMenuEntry =
|
||||||
VideoSetDeinterlace(ConfigVideoDeinterlace);
|
HideMainMenuEntry);
|
||||||
SetupStore("SkipChromaDeinterlace", ConfigVideoSkipChromaDeinterlace =
|
|
||||||
SkipChromaDeinterlace);
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
char buf[128];
|
||||||
SetupStore("Denoise", ConfigVideoDenoise = Denoise);
|
|
||||||
VideoSetDenoise(ConfigVideoDenoise);
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
||||||
SetupStore("Sharpen", ConfigVideoSharpen = Sharpen);
|
SetupStore(buf, ConfigVideoScaling[i] = Scaling[i]);
|
||||||
VideoSetSharpen(ConfigVideoSharpen);
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Deinterlace");
|
||||||
SetupStore("Scaling", ConfigVideoScaling = Scaling);
|
SetupStore(buf, ConfigVideoDeinterlace[i] = Deinterlace[i]);
|
||||||
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i],
|
||||||
|
"SkipChromaDeinterlace");
|
||||||
|
SetupStore(buf, ConfigVideoSkipChromaDeinterlace[i] =
|
||||||
|
SkipChromaDeinterlace[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");
|
||||||
|
SetupStore(buf, ConfigVideoSharpen[i] = Sharpen[i]);
|
||||||
|
}
|
||||||
VideoSetScaling(ConfigVideoScaling);
|
VideoSetScaling(ConfigVideoScaling);
|
||||||
|
VideoSetDeinterlace(ConfigVideoDeinterlace);
|
||||||
|
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
||||||
|
VideoSetDenoise(ConfigVideoDenoise);
|
||||||
|
VideoSetSharpen(ConfigVideoSharpen);
|
||||||
|
|
||||||
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
||||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||||
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
SetupStore("AudioPassthrough", ConfigAudioPassthrough = AudioPassthrough);
|
||||||
@@ -370,8 +475,15 @@ class cSoftHdDevice:public cDevice
|
|||||||
virtual bool Poll(cPoller &, int = 0);
|
virtual bool Poll(cPoller &, int = 0);
|
||||||
virtual bool Flush(int = 0);
|
virtual bool Flush(int = 0);
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
|
virtual void GetVideoSize(int &width, int &height, double &aspect)
|
||||||
|
{
|
||||||
|
width = 1920;
|
||||||
|
height = 1080;
|
||||||
|
aspect = (double)width / height;
|
||||||
|
}
|
||||||
virtual void GetOsdSize(int &, int &, double &);
|
virtual void GetOsdSize(int &, int &, double &);
|
||||||
virtual int PlayVideo(const uchar *, int);
|
virtual int PlayVideo(const uchar *, int);
|
||||||
|
|
||||||
//virtual int PlayTsVideo(const uchar *, int);
|
//virtual int PlayTsVideo(const uchar *, int);
|
||||||
#ifdef USE_OSS // FIXME: testing only oss
|
#ifdef USE_OSS // FIXME: testing only oss
|
||||||
virtual int PlayTsAudio(const uchar *, int);
|
virtual int PlayTsAudio(const uchar *, int);
|
||||||
@@ -388,11 +500,13 @@ class cSoftHdDevice:public cDevice
|
|||||||
|
|
||||||
virtual int ProvidesCa(const cChannel *) const;
|
virtual int ProvidesCa(const cChannel *) const;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// SPU facilities
|
// SPU facilities
|
||||||
private:
|
private:
|
||||||
cDvbSpuDecoder * spuDecoder;
|
cDvbSpuDecoder * spuDecoder;
|
||||||
public:
|
public:
|
||||||
virtual cSpuDecoder * GetSpuDecoder(void);
|
virtual cSpuDecoder * GetSpuDecoder(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void MakePrimaryDevice(bool);
|
virtual void MakePrimaryDevice(bool);
|
||||||
@@ -402,7 +516,9 @@ cSoftHdDevice::cSoftHdDevice(void)
|
|||||||
{
|
{
|
||||||
//dsyslog("[softhddev]%s\n", __FUNCTION__);
|
//dsyslog("[softhddev]%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
#if 0
|
||||||
spuDecoder = NULL;
|
spuDecoder = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cSoftHdDevice::~cSoftHdDevice(void)
|
cSoftHdDevice::~cSoftHdDevice(void)
|
||||||
@@ -420,15 +536,18 @@ void cSoftHdDevice::MakePrimaryDevice(bool on)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cSoftHdDevice::ProvidesCa(
|
int cSoftHdDevice::ProvidesCa(
|
||||||
__attribute__ ((unused)) const cChannel * channel) const
|
__attribute__ ((unused)) const cChannel *
|
||||||
{
|
channel) const
|
||||||
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
{
|
||||||
|
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSpuDecoder *cSoftHdDevice::GetSpuDecoder(void)
|
#if 0
|
||||||
|
|
||||||
|
cSpuDecoder *cSoftHdDevice::GetSpuDecoder(void)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
@@ -438,6 +557,8 @@ cSpuDecoder *cSoftHdDevice::GetSpuDecoder(void)
|
|||||||
return spuDecoder;
|
return spuDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
bool cSoftHdDevice::HasDecoder(void) const
|
bool cSoftHdDevice::HasDecoder(void) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -461,7 +582,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode PlayMode)
|
|||||||
case pmVideoOnly:
|
case pmVideoOnly:
|
||||||
break;
|
break;
|
||||||
case pmNone:
|
case pmNone:
|
||||||
break;
|
return true;
|
||||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -479,9 +600,14 @@ int64_t cSoftHdDevice::GetSTC(void)
|
|||||||
return::VideoGetClock();
|
return::VideoGetClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSoftHdDevice::TrickSpeed(int Speed)
|
/**
|
||||||
|
** Set trick play speed.
|
||||||
|
**
|
||||||
|
** @param speed trick speed
|
||||||
|
*/
|
||||||
|
void cSoftHdDevice::TrickSpeed(int speed)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, Speed);
|
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSoftHdDevice::Clear(void)
|
void cSoftHdDevice::Clear(void)
|
||||||
@@ -500,6 +626,9 @@ void cSoftHdDevice::Play(void)
|
|||||||
::Play();
|
::Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Puts the device into "freeze frame" mode.
|
||||||
|
*/
|
||||||
void cSoftHdDevice::Freeze(void)
|
void cSoftHdDevice::Freeze(void)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
@@ -513,24 +642,38 @@ void cSoftHdDevice::Mute(void)
|
|||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
cDevice::Mute();
|
cDevice::Mute();
|
||||||
|
|
||||||
::Mute();
|
::Mute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSoftHdDevice::SetVolumeDevice(int volume)
|
void cSoftHdDevice::SetVolumeDevice(int volume)
|
||||||
{
|
{
|
||||||
//dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume);
|
||||||
|
|
||||||
::SetVolumeDevice(volume);
|
::SetVolumeDevice(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSoftHdDevice::StillPicture(
|
/**
|
||||||
__attribute__ ((unused)) const uchar * data, __attribute__ ((unused))
|
** Display the given I-frame as a still picture.
|
||||||
int length)
|
*/
|
||||||
|
void cSoftHdDevice::StillPicture(const uchar * data, int length)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
dsyslog("[softhddev]%s: %s\n", __FUNCTION__,
|
||||||
|
data[0] == 0x47 ? "ts" : "pes");
|
||||||
|
|
||||||
|
if (data[0] == 0x47) { // ts sync
|
||||||
|
cDevice::StillPicture(data, length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
::StillPicture(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Check if the device is ready for further action.
|
||||||
|
**
|
||||||
|
** @param poller file handles (unused)
|
||||||
|
** @param timeout_ms timeout in ms to become ready
|
||||||
|
*/
|
||||||
bool cSoftHdDevice::Poll(
|
bool cSoftHdDevice::Poll(
|
||||||
__attribute__ ((unused)) cPoller & poller, int timeout_ms)
|
__attribute__ ((unused)) cPoller & poller, int timeout_ms)
|
||||||
{
|
{
|
||||||
@@ -539,11 +682,16 @@ bool cSoftHdDevice::Poll(
|
|||||||
return::Poll(timeout_ms);
|
return::Poll(timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Flush the device output buffers.
|
||||||
|
**
|
||||||
|
** @param timeout_ms timeout in ms to become ready
|
||||||
|
*/
|
||||||
bool cSoftHdDevice::Flush(int timeout_ms)
|
bool cSoftHdDevice::Flush(int timeout_ms)
|
||||||
{
|
{
|
||||||
dsyslog("[softhddev]%s: %d ms\n", __FUNCTION__, timeout_ms);
|
dsyslog("[softhddev]%s: %d ms\n", __FUNCTION__, timeout_ms);
|
||||||
|
|
||||||
return true;
|
return::Flush(timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -560,13 +708,14 @@ void cSoftHdDevice::GetOsdSize(int &width, int &height, double &pixel_aspect)
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Play a audio packet.
|
||||||
|
*/
|
||||||
int cSoftHdDevice::PlayAudio(const uchar * data, int length, uchar id)
|
int cSoftHdDevice::PlayAudio(const uchar * data, int length, uchar id)
|
||||||
{
|
{
|
||||||
//dsyslog("[softhddev]%s: %p %p %d %d\n", __FUNCTION__, this, data, length, id);
|
//dsyslog("[softhddev]%s: %p %p %d %d\n", __FUNCTION__, this, data, length, id);
|
||||||
|
|
||||||
::PlayAudio(data, length, id);
|
return::PlayAudio(data, length, id);
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSoftHdDevice::SetAudioTrackDevice(
|
void cSoftHdDevice::SetAudioTrackDevice(
|
||||||
@@ -655,11 +804,13 @@ class cPluginSoftHdDevice:public cPlugin
|
|||||||
virtual void Stop(void);
|
virtual void Stop(void);
|
||||||
// virtual void Housekeeping(void);
|
// virtual void Housekeeping(void);
|
||||||
virtual void MainThreadHook(void);
|
virtual void MainThreadHook(void);
|
||||||
// virtual const char *MainMenuEntry(void);
|
virtual const char *MainMenuEntry(void);
|
||||||
// virtual cOsdObject *MainMenuAction(void);
|
virtual cOsdObject *MainMenuAction(void);
|
||||||
virtual cMenuSetupPage *SetupMenu(void);
|
virtual cMenuSetupPage *SetupMenu(void);
|
||||||
virtual bool SetupParse(const char *, const char *);
|
virtual bool SetupParse(const char *, const char *);
|
||||||
// virtual bool Service(const char *Id, void *Data = NULL);
|
// virtual bool Service(const char *, void * = NULL);
|
||||||
|
virtual const char **SVDRPHelpPages(void);
|
||||||
|
virtual cString SVDRPCommand(const char *, const char *, int &);
|
||||||
};
|
};
|
||||||
|
|
||||||
cPluginSoftHdDevice::cPluginSoftHdDevice(void)
|
cPluginSoftHdDevice::cPluginSoftHdDevice(void)
|
||||||
@@ -716,15 +867,14 @@ bool cPluginSoftHdDevice::Initialize(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Start any background activities the plugin shall perform.
|
||||||
|
*/
|
||||||
bool cPluginSoftHdDevice::Start(void)
|
bool cPluginSoftHdDevice::Start(void)
|
||||||
{
|
{
|
||||||
const cDevice *primary;
|
|
||||||
|
|
||||||
// Start any background activities the plugin shall perform.
|
|
||||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
primary = cDevice::PrimaryDevice();
|
if (!MyDevice->IsPrimaryDevice()) {
|
||||||
if (MyDevice != primary) {
|
|
||||||
isyslog("[softhddev] softhddevice is not the primary device!");
|
isyslog("[softhddev] softhddevice is not the primary device!");
|
||||||
if (ConfigMakePrimary) {
|
if (ConfigMakePrimary) {
|
||||||
// Must be done in the main thread
|
// Must be done in the main thread
|
||||||
@@ -756,14 +906,31 @@ void cPluginSoftHdDevice::Housekeeping(void)
|
|||||||
// Perform any cleanup or other regular tasks.
|
// Perform any cleanup or other regular tasks.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Create main menu entry.
|
||||||
|
*/
|
||||||
const char *cPluginSoftHdDevice::MainMenuEntry(void)
|
const char *cPluginSoftHdDevice::MainMenuEntry(void)
|
||||||
{
|
{
|
||||||
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
return tr(MAINMENUENTRY);
|
|
||||||
return NULL;
|
return ConfigHideMainMenuEntry ? NULL : tr(MAINMENUENTRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
/**
|
||||||
|
** Perform the action when selected from the main VDR menu.
|
||||||
|
*/
|
||||||
|
cOsdObject *cPluginSoftHdDevice::MainMenuAction(void)
|
||||||
|
{
|
||||||
|
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
|
cDevice::PrimaryDevice()->StopReplay();
|
||||||
|
Suspend();
|
||||||
|
ShutdownHandler.SetUserInactive();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Called for every plugin once during every cycle of VDR's main program
|
** Called for every plugin once during every cycle of VDR's main program
|
||||||
@@ -778,29 +945,15 @@ void cPluginSoftHdDevice::MainThreadHook(void)
|
|||||||
cDevice::SetPrimaryDevice(MyDevice->DeviceNumber() + 1);
|
cDevice::SetPrimaryDevice(MyDevice->DeviceNumber() + 1);
|
||||||
DoMakePrimary = 0;
|
DoMakePrimary = 0;
|
||||||
}
|
}
|
||||||
|
// check if user is inactive, automatic enter suspend mode
|
||||||
|
if (ShutdownHandler.IsUserInactive()) {
|
||||||
|
// this is regular called, but guarded against double calls
|
||||||
|
Suspend();
|
||||||
|
}
|
||||||
|
|
||||||
::MainThreadHook();
|
::MainThreadHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
bool cPluginSoftHdDevice::Service(const char *Id, void *Data)
|
|
||||||
{
|
|
||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cOsdObject *cPluginSoftHdDevice::MainMenuAction(void)
|
|
||||||
{
|
|
||||||
// Perform the action when selected from the main VDR menu.
|
|
||||||
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Return our setup menu.
|
** Return our setup menu.
|
||||||
*/
|
*/
|
||||||
@@ -816,33 +969,51 @@ cMenuSetupPage *cPluginSoftHdDevice::SetupMenu(void)
|
|||||||
*/
|
*/
|
||||||
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
//dsyslog("[softhddev]%s: '%s' = '%s'\n", __FUNCTION__, name, value);
|
||||||
|
|
||||||
// FIXME: handle the values
|
|
||||||
if (!strcmp(name, "MakePrimary")) {
|
if (!strcmp(name, "MakePrimary")) {
|
||||||
ConfigMakePrimary = atoi(value);
|
ConfigMakePrimary = atoi(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "Deinterlace")) {
|
if (!strcmp(name, "HideMainMenuEntry")) {
|
||||||
VideoSetDeinterlace(ConfigVideoDeinterlace = atoi(value));
|
ConfigHideMainMenuEntry = atoi(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "SkipChromaDeinterlace")) {
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace =
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Scaling");
|
||||||
atoi(value));
|
if (!strcmp(name, buf)) {
|
||||||
return true;
|
ConfigVideoScaling[i] = atoi(value);
|
||||||
}
|
VideoSetScaling(ConfigVideoScaling);
|
||||||
if (!strcmp(name, "Denoise")) {
|
return true;
|
||||||
VideoSetDenoise(ConfigVideoDenoise = atoi(value));
|
}
|
||||||
return true;
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Deinterlace");
|
||||||
}
|
if (!strcmp(name, buf)) {
|
||||||
if (!strcmp(name, "Sharpen")) {
|
ConfigVideoDeinterlace[i] = atoi(value);
|
||||||
VideoSetSharpen(ConfigVideoSharpen = atoi(value));
|
VideoSetDeinterlace(ConfigVideoDeinterlace);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "Scaling")) {
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i],
|
||||||
VideoSetScaling(ConfigVideoScaling = atoi(value));
|
"SkipChromaDeinterlace");
|
||||||
return true;
|
if (!strcmp(name, buf)) {
|
||||||
|
ConfigVideoSkipChromaDeinterlace[i] = atoi(value);
|
||||||
|
VideoSetSkipChromaDeinterlace(ConfigVideoSkipChromaDeinterlace);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Denoise");
|
||||||
|
if (!strcmp(name, buf)) {
|
||||||
|
ConfigVideoDenoise[i] = atoi(value);
|
||||||
|
VideoSetDenoise(ConfigVideoDenoise);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "%s.%s", Resolution[i], "Sharpen");
|
||||||
|
if (!strcmp(name, buf)) {
|
||||||
|
ConfigVideoSharpen[i] = atoi(value);
|
||||||
|
VideoSetSharpen(ConfigVideoSharpen);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!strcmp(name, "AudioDelay")) {
|
if (!strcmp(name, "AudioDelay")) {
|
||||||
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
VideoSetAudioDelay(ConfigVideoAudioDelay = atoi(value));
|
||||||
@@ -856,4 +1027,51 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
bool cPluginSoftHdDevice::Service(const char *Id, void *Data)
|
||||||
|
{
|
||||||
|
dsyslog("[softhddev]%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// cPlugin SVDRP
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Return SVDRP commands help pages.
|
||||||
|
**
|
||||||
|
** return a pointer to a list of help strings for all of the plugin's
|
||||||
|
** SVDRP commands.
|
||||||
|
*/
|
||||||
|
const char **cPluginSoftHdDevice::SVDRPHelpPages(void)
|
||||||
|
{
|
||||||
|
// FIXME: translation?
|
||||||
|
static const char *text[] = {
|
||||||
|
"SUSP\n",
|
||||||
|
" Suspend plugin",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Handle SVDRP commands.
|
||||||
|
*/
|
||||||
|
cString cPluginSoftHdDevice::SVDRPCommand(const char *command,
|
||||||
|
__attribute__ ((unused)) const char *option,
|
||||||
|
__attribute__ ((unused)) int &reply_code)
|
||||||
|
{
|
||||||
|
if (!strcasecmp(command, "SUSP")) {
|
||||||
|
Suspend();
|
||||||
|
return "SoftHdDevice is suspended";
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
VDRPLUGINCREATOR(cPluginSoftHdDevice); // Don't touch this!
|
VDRPLUGINCREATOR(cPluginSoftHdDevice); // Don't touch this!
|
||||||
|
|||||||
71
vdr-softhddevice-9999.ebuild
Normal file
71
vdr-softhddevice-9999.ebuild
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Copyright 1999-2012 Gentoo Foundation
|
||||||
|
# Distributed under the terms of the GNU General Public License v2
|
||||||
|
# $Header: $
|
||||||
|
|
||||||
|
EAPI="3"
|
||||||
|
|
||||||
|
inherit eutils vdr-plugin
|
||||||
|
|
||||||
|
if [[ ${PV} == "9999" ]] ; then
|
||||||
|
inherit git-2
|
||||||
|
EGIT_REPO_URI="git://projects.vdr-developer.org/vdr-plugin-softhddevice.git"
|
||||||
|
else
|
||||||
|
SRC_URI="http://projects.vdr-developer.org/attachments/download/838/${P}.tgz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTION="A software and GPU emulated HD output device plugin for VDR."
|
||||||
|
HOMEPAGE="http://projects.vdr-developer.org/projects/show/plg-softhddevice"
|
||||||
|
SRC_URI=""
|
||||||
|
|
||||||
|
LICENSE="AGPL-3"
|
||||||
|
SLOT="0"
|
||||||
|
KEYWORDS="~x86 ~amd64"
|
||||||
|
IUSE="vaapi vdpau alsa oss yaepg"
|
||||||
|
|
||||||
|
DEPEND=">=x11-libs/libxcb-1.7
|
||||||
|
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
|
||||||
|
sys-devel/gettext
|
||||||
|
sys-devel/make
|
||||||
|
dev-util/pkgconfig
|
||||||
|
yaepg? ( >=media-video/vdr-1.7[yaepg] )
|
||||||
|
!yaepg? ( >=media-video/vdr-1.7 )
|
||||||
|
vdpau? ( x11-libs/libvdpau )
|
||||||
|
vaapi? ( x11-libs/libva )
|
||||||
|
alsa? ( media-libs/alsa-lib )
|
||||||
|
"
|
||||||
|
|
||||||
|
src_prepare() {
|
||||||
|
vdr-plugin_src_prepare
|
||||||
|
}
|
||||||
|
|
||||||
|
src_compile() {
|
||||||
|
local myconf
|
||||||
|
|
||||||
|
myconf=""
|
||||||
|
use vdpau && myconf="${myconf} -DUSE_VDPAU"
|
||||||
|
use vaapi && myconf="${myconf} -DUSE_VAAPI"
|
||||||
|
use alsa && myconf="${myconf} -DUSE_ALSA"
|
||||||
|
use oss && myconf="${myconf} -DUSE_OSS"
|
||||||
|
|
||||||
|
emake all CC="$(tc-getCC)" CFLAGS="${CFLAGS}" \
|
||||||
|
LDFLAGS="${LDFLAGS}" CONFIG="${myconf}" LIBDIR="." || die
|
||||||
|
}
|
||||||
|
|
||||||
|
src_install() {
|
||||||
|
vdr-plugin_src_install
|
||||||
|
|
||||||
|
dodir /etc/vdr/plugins || die
|
||||||
|
|
||||||
|
insinto /etc/vdr/plugins
|
||||||
|
fowners -R vdr:vdr /etc/vdr || die
|
||||||
|
|
||||||
|
#insinto /etc/conf.d
|
||||||
|
#doins vdr.softhddevice
|
||||||
|
}
|
||||||
75
video.h
75
video.h
@@ -30,13 +30,6 @@
|
|||||||
/// Video hardware decoder typedef
|
/// Video hardware decoder typedef
|
||||||
typedef struct _video_hw_decoder_ VideoHwDecoder;
|
typedef struct _video_hw_decoder_ VideoHwDecoder;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Variables
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//extern unsigned VideoWindowWidth; ///< current video output width
|
|
||||||
//extern unsigned VideoWindowHeight; ///< current video output height
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Prototypes
|
// Prototypes
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -47,14 +40,14 @@ extern VideoHwDecoder *VideoNewHwDecoder(void);
|
|||||||
/// Get and allocate a video hardware surface.
|
/// Get and allocate a video hardware surface.
|
||||||
extern unsigned VideoGetSurface(VideoHwDecoder *);
|
extern unsigned VideoGetSurface(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Release a video hardware surface.
|
/// Release a video hardware surface
|
||||||
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
||||||
|
|
||||||
#ifdef LIBAVCODEC_VERSION
|
#ifdef LIBAVCODEC_VERSION
|
||||||
/// Render a ffmpeg frame
|
/// Render a ffmpeg frame.
|
||||||
extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *);
|
extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *);
|
||||||
|
|
||||||
/// Get ffmpeg vaapi context
|
/// Get ffmpeg vaapi context.
|
||||||
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Callback to negotiate the PixelFormat.
|
/// Callback to negotiate the PixelFormat.
|
||||||
@@ -62,57 +55,63 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
|||||||
const enum PixelFormat *);
|
const enum PixelFormat *);
|
||||||
|
|
||||||
#ifdef AVCODEC_VDPAU_H
|
#ifdef AVCODEC_VDPAU_H
|
||||||
/// Draw vdpau render state
|
/// Draw vdpau render state.
|
||||||
extern void VideoDrawRenderState(VideoHwDecoder *,
|
extern void VideoDrawRenderState(VideoHwDecoder *,
|
||||||
struct vdpau_render_state *);
|
struct vdpau_render_state *);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Display video TEST
|
/// Poll video events.
|
||||||
extern void VideoDisplayHandler(void);
|
|
||||||
|
|
||||||
/// Poll video events
|
|
||||||
extern void VideoPollEvent(void);
|
extern void VideoPollEvent(void);
|
||||||
|
|
||||||
/// set video mode
|
/// Wakeup display handler.
|
||||||
//extern void VideoSetVideoMode(int, int, int, int);
|
extern void VideoDisplayWakeup(void);
|
||||||
|
|
||||||
/// set video geometry
|
/// Set video geometry.
|
||||||
extern int VideoSetGeometry(const char *);
|
extern int VideoSetGeometry(const char *);
|
||||||
|
|
||||||
/// set deinterlace
|
/// Set video output position.
|
||||||
extern void VideoSetDeinterlace(int);
|
extern void VideoSetOutputPosition(int, int, int, int);
|
||||||
|
|
||||||
/// set skip chroma deinterlace
|
/// Set video mode.
|
||||||
extern void VideoSetSkipChromaDeinterlace(int);
|
extern void VideoSetVideoMode(int, int, int, int);
|
||||||
|
|
||||||
/// set scaling
|
/// Set video fullscreen mode.
|
||||||
extern void VideoSetScaling(int);
|
extern void VideoSetFullscreen(int);
|
||||||
|
|
||||||
/// set denoise
|
/// Set deinterlace.
|
||||||
extern void VideoSetDenoise(int);
|
extern void VideoSetDeinterlace(int[]);
|
||||||
|
|
||||||
/// set sharpen
|
/// Set skip chroma deinterlace.
|
||||||
extern void VideoSetSharpen(int);
|
extern void VideoSetSkipChromaDeinterlace(int[]);
|
||||||
|
|
||||||
/// set audio delay
|
/// Set scaling.
|
||||||
|
extern void VideoSetScaling(int[]);
|
||||||
|
|
||||||
|
/// Set denoise.
|
||||||
|
extern void VideoSetDenoise(int[]);
|
||||||
|
|
||||||
|
/// Set sharpen.
|
||||||
|
extern void VideoSetSharpen(int[]);
|
||||||
|
|
||||||
|
/// Set audio delay.
|
||||||
extern void VideoSetAudioDelay(int);
|
extern void VideoSetAudioDelay(int);
|
||||||
|
|
||||||
/// Clear OSD
|
/// Clear OSD.
|
||||||
extern void VideoOsdClear(void);
|
extern void VideoOsdClear(void);
|
||||||
|
|
||||||
/// Draw an OSD ARGB image
|
/// Draw an OSD ARGB image.
|
||||||
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
||||||
|
|
||||||
extern int64_t VideoGetClock(void); ///< get video clock
|
extern int64_t VideoGetClock(void); ///< Get video clock.
|
||||||
|
|
||||||
extern void VideoOsdInit(void); ///< setup osd
|
extern void VideoOsdInit(void); ///< Setup osd.
|
||||||
extern void VideoOsdExit(void); ///< cleanup osd
|
extern void VideoOsdExit(void); ///< Cleanup osd.
|
||||||
|
|
||||||
extern void VideoInit(const char *); ///< setup video module
|
extern void VideoInit(const char *); ///< Setup video module.
|
||||||
extern void VideoExit(void); ///< cleanup and exit video module
|
extern void VideoExit(void); ///< Cleanup and exit video module.
|
||||||
|
|
||||||
extern void VideoFlushInput(void); ///< flush codec input buffers
|
extern void VideoFlushInput(void); ///< Flush video input buffers.
|
||||||
extern int VideoDecode(void); ///< decode
|
extern int VideoDecode(void); ///< Decode video input buffers.
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
Reference in New Issue
Block a user