Compare commits

..

No commits in common. "master" and "0.5.2" have entirely different histories.

20 changed files with 1962 additions and 7380 deletions

214
ChangeLog
View File

@ -1,217 +1,3 @@
User johns
Date:
Preparations for new ffmpeg VDPAU API.
Added VDPAU multi decoder loop changes to VA-API code.
Reenabled VA-API auto detection.
Check and enforce USE_PIP is defined, for new code.
Fix comment spelling.
Disabled old code before removement.
Handle change of audio ac3 downmix direct.
Speedup queuing output surface, when decoder buffers are full.
Fix bug: info shows wrong decoded video surfaces.
Calculate queued output surfaces and show them in info message.
Add support for new API of vdr 2.3.1.
Fix bug: EnableDPMSatBlackScreen only available with USE_SCREENSAVER.
- H264_EOS_TRICKSPEED and USE_MPEG_COMPLETE enabled as default.
User master_red
Date: Mon Aug 10 15:29:33 CEST 2015
Configurable enable DPMS, while black screen is displayed.
User johns
Date: Tue Jun 30 10:12:09 CET 2015
Fix bug: wrong and crash, if vdr draws pixmaps outside OSD.
Fix bug: wrong version number check for av_frame_alloc(), ...
Workaround for ffmpeg 2.6 artifacts.
Fix bug: brightness and .. are calculated wrong.
Add automatic frame rate detection for older ffmpeg versions.
Fix bug: destroyed vdpau surfaces still used in queue.
Fix bug: need signed char, if compiler has unsigned chars.
Try smaller audio puffer, if default size fails.
Fix bug: center cut-out didn't use cut off pixels.
Fix bug #2058: support for Make.plgcfg.
Fix for compile with vdr 2.1.10, for older vdr versions.
User jinx
Date: Mon Feb 16 09:58:06 CET 2015
Enable toggle AC3 downmix.
User johns
Date: Thu Feb 12 10:30:50 CET 2015
Compile with vdr 2.1.10.
Fix bug: AVCodecContext.framerate not supported.
Use video stream frame rate for A/V sync.
User Antti Seppälä
Date: Thu Oct 16 14:15:15 CEST 2014
Corrected black surface for va-api.
User johns
Date: Thu Oct 16 14:05:17 CEST 2014
Newer va-api intel drivers support PutImage.
Use more portable fork for vfork.
Fix crash with VA-API vdpau backend.
User mini73
Date: Sat Oct 11 16:53:18 CEST 2014
Fix bug: random rubbish at the end of letter.
User johns
Date: Tue Sep 23 12:36:39 CEST 2014
Fix audio thread close race condition.
Support ffmpeg new AVFrame API in the audio codec.
Config for automatic AES parameters.
Use GCC built-in functions for atomic operations.
User master_red
Date: Wed Jun 4 14:44:32 CEST 2014
Support detach or suspend in plugin menu.
User johns
Date: Fri May 30 10:18:20 CEST 2014
Fix "make clean-plugins".
Fix compile with newer libav.
Fix OSD bugs.
Add some VA-API VPP info outputs.
Remove build files for old unstable VDR.
User hd.brummy
Date: Thu Jan 30 10:40:49 CET 2014
Update gentoo ebuild.
User johns
Date: Thu Jan 30 10:36:53 CET 2014
Fix spelling in arguments help.
Add Workaround for alsa blocking audio device.
Improves thread handling for audio flush and close.
User mini73
Date: Fri Jan 24 11:30:49 CET 2014
Fix bug: learing x11 remote keys fails.
Add support for umlauts in input fields.
User johns
Date: Tue Jan 14 14:59:44 CET 2014
Fix alternative OSD support with VDPAU bitmap surfaces.
Fix compile error with VDR 2.1.3.
Fix bug: memory leak.
PIP close clears the last used PIP channel.
Fix bug: -DOSD_DEBUG uses old (deleted) variable.
Fix bug: Option softhddevice.BlackPicture has no effect.
User Dr. Seltsam
Date: Tue Nov 5 16:46:34 CET 2013
Add support to configure and clear buffers on channel switch.
User johns
Date: Tue Oct 8 10:18:04 CET 2013
CLOCK_REALTIME -> CLOCK_MONOTONIC to allow time changes.
Add function VideoStreamOpen and always use VideoStreamClose.
Softer audio/video sync.
Add function GetStats to the video output module.
Add function ResetStart to the video output module.
Add function SetClosing to the video output module.
Generalize GetVaapiContext to GetHwAccelContext.
Add compile time configurable trickspeed packets dump.
Fix bug #1410: wrong spelled AC-3 and E-AC-3.
Add compile time selectable h264 trickspeed workaround.
Use ffmpeg new names AVCodecID, AV_CODEC_... .
Fix bug: video lagging behind after recording stop.
Reduce PES error messages.
Fix bug #1392: Wrong value for mixing LFE.
Fix bug: wrong grab size, introduced with AMD VDPAU.
Use VDR SPU decoder as default.
Fix bug: grab image negative quality isn't the default 100.
Support AMD VDPAU with surface size != requested size.
Add cache for auto-crop buffer.
Fix opengl and opengl threads bugs.
Initial opengl support with va-api only.
Fix "broken driver" message if empty ring buffer.
Enable seamless audio track change.
Fix bug #1302: Unsupported pixel format crash.
Fix the fix, when sillpicture is called in suspend mode.
Fix crash, when sillpicture is called in suspend mode.
Add workaround for zero width+height and ffmpeg >= 1.2.
User johns
Date: Sun Mar 17 15:52:42 CET 2013
Release Version 0.6.0
Adds H264 only hardware decoder for still-pictures.
Enable optional VDR-SPU deocder support.
User anbr
Date: Sun Mar 17 15:49:46 CET 2013
Update german translation.
User cyril
Date: Wed Mar 6 17:05:10 CET 2013
Adds raise softhddevice video window support.
User johns
Date: Wed Mar 6 10:30:27 CET 2013
Adds optional only complete mpeg packets support.
Fixes text of EAC-3 pass-through setup.
Try to start or connect to X11 server with -xx.
Try to use HBR (High Bit-Rate) for EAC3.
Improved pass-through (PCM+EAC3) support.
Support VDR 1.7.36 new build system.
Improves VDPAU display preemption handling.
Add modifiers to X11 remote key names (from Sibbi).
Add compatibility with >=ffmpeg 1.1.
Adds PIP (Picture-in-Picture) support.
Split mpeg packets in receiver thread.
User horchi
Date: Tue Jan 1 17:58:54 CET 2013
Adds VDR SeduAtmo Plugin support.
User johns
Date: Tue Jan 1 15:21:28 CET 2013
Support multiple streams with ScaleVideo.
Makes 4:3 and 16:9 display format configurable.
Don't use DVB display format.
User Zoolook
Date: Tue Jan 1 12:49:19 CET 2013
Add support for new vdr ScaleVideo API.
User johns
Date: Tue Jan 1 12:40:12 CET 2013
Add support for old PES HDTV recording.
Disable trickspeed hack, to prevent ffmpeg crash.
Makes X11 server arguments configurable.
Add german translation.
User FireFly
Date: Sun Nov 18 21:15:50 CET 2012
Add german translation.
User johns
Date: Thu Nov 15 22:28:55 CET 2012

244
Makefile
View File

@ -6,209 +6,152 @@
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
# By default the main source file also carries this name.
# IMPORTANT: the presence of this macro is important for the Make.config
# file. So it must be defined, even if it is not used here!
#
PLUGIN = softhddevice
### Configuration (edit this for your needs)
# support alsa audio output module
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
# support OSS audio output module
OSS ?= 1
# support VDPAU video output module
VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
# support VA-API video output module (deprecated)
VAAPI ?= $(shell pkg-config --exists libva && echo 1)
# support glx output
OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
# screensaver disable/enable
SCREENSAVER ?= 1
# use ffmpeg libswresample
SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1)
# use libav libavresample
ifneq ($(SWRESAMPLE),1)
AVRESAMPLE ?= $(shell pkg-config --exists libavresample && echo 1)
endif
CONFIG := # -DDEBUG #-DOSD_DEBUG # enable debug output+functions
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
CONFIG += -DUSE_PIP # PIP support
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets
CONFIG += -DH264_EOS_TRICKSPEED # insert seq end packets for trickspeed
#CONDIF += -DDUMP_TRICKSPEED # dump trickspeed packets
#CONFIG += -DUSE_BITMAP # VDPAU, use bitmap surface for OSD
CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
#CONFIG += -DUSE_SOFTLIMIT # (tobe removed) limit the buffer fill
### The version number of this plugin (taken from the main source file):
VERSION = $(shell grep 'static const char \*const VERSION *=' $(PLUGIN).cpp | awk '{ print $$7 }' | sed -e 's/[";]//g')
GIT_REV = $(shell git describe --always 2>/dev/null)
### Configuration (edit this for your needs)
CONFIG := #-DDEBUG #-DOSD_DEBUG
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # debug a/v sync
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
CONFIG += $(shell pkg-config --exists vdpau && echo "-DUSE_VDPAU")
CONFIG += $(shell pkg-config --exists libva && echo "-DUSE_VAAPI")
CONFIG += $(shell pkg-config --exists alsa && echo "-DUSE_ALSA")
CONFIG += -DUSE_OSS
### The C++ compiler and options:
CC ?= gcc
CXX ?= g++
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
-Wdeclaration-after-statement \
-ftree-vectorize -msse3 -flax-vector-conversions
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Werror=overloaded-virtual
### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory:
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg)
#
VDRDIR ?= ../../..
LIBDIR ?= ../../lib
TMPDIR ?= /tmp
### The compiler options:
### Make sure that necessary options are included:
export CFLAGS = $(call PKGCFG,cflags)
export CXXFLAGS = $(call PKGCFG,cxxflags)
ifeq ($(CFLAGS),)
$(warning CFLAGS not set)
endif
ifeq ($(CXXFLAGS),)
$(warning CXXFLAGS not set)
endif
### The version number of VDR's plugin API:
APIVERSION = $(call PKGCFG,apiversion)
-include $(VDRDIR)/Make.global
### Allow user defined options to overwrite defaults:
-include $(PLGCFG)
-include $(VDRDIR)/Make.config
### The version number of VDR's plugin API (taken from VDR's "config.h"):
APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
### The name of the distribution archive:
ARCHIVE = $(PLUGIN)-$(VERSION)
PACKAGE = vdr-$(ARCHIVE)
### The name of the shared object file:
### Includes, Defines and dependencies (add further entries here):
SOFILE = libvdr-$(PLUGIN).so
INCLUDES += -I$(VDRDIR)/include
### Parse softhddevice config
ifeq ($(ALSA),1)
CONFIG += -DUSE_ALSA
_CFLAGS += $(shell pkg-config --cflags alsa)
LIBS += $(shell pkg-config --libs alsa)
endif
ifeq ($(OSS),1)
CONFIG += -DUSE_OSS
endif
ifeq ($(VDPAU),1)
CONFIG += -DUSE_VDPAU
_CFLAGS += $(shell pkg-config --cflags vdpau)
LIBS += $(shell pkg-config --libs vdpau)
endif
ifeq ($(VAAPI),1)
CONFIG += -DUSE_VAAPI
_CFLAGS += $(shell pkg-config --cflags libva-x11 libva)
LIBS += $(shell pkg-config --libs libva-x11 libva)
ifeq ($(OPENGL),1)
_CFLAGS += $(shell pkg-config --cflags libva-glx)
LIBS += $(shell pkg-config --libs libva-glx)
endif
endif
ifeq ($(OPENGL),1)
CONFIG += -DUSE_GLX
_CFLAGS += $(shell pkg-config --cflags gl glu)
LIBS += $(shell pkg-config --libs gl glu)
endif
ifeq ($(SCREENSAVER),1)
CONFIG += -DUSE_SCREENSAVER
_CFLAGS += $(shell pkg-config --cflags xcb-screensaver xcb-dpms)
LIBS += $(shell pkg-config --libs xcb-screensaver xcb-dpms)
endif
ifeq ($(SWRESAMPLE),1)
CONFIG += -DUSE_SWRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libswresample)
LIBS += $(shell pkg-config --libs libswresample)
endif
ifeq ($(AVRESAMPLE),1)
CONFIG += -DUSE_AVRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libavresample)
LIBS += $(shell pkg-config --libs libavresample)
endif
_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
### Includes and Defines (add further entries here):
INCLUDES +=
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' \
$(if $(GIT_REV), -DGIT_REV='"$(GIT_REV)"')
### Make it standard
_CFLAGS = $(DEFINES) $(INCLUDES) \
$(shell pkg-config --cflags libavcodec) \
`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 CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
-g -W -Wall -Wextra -Winit-self -Werror=overloaded-virtual
override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
-g -W -Wall -Wextra -Winit-self -Wdeclaration-after-statement
#override _CFLAGS += -Werror
override CXXFLAGS += $(_CFLAGS)
override CFLAGS += $(_CFLAGS)
LIBS += -lrt \
$(shell pkg-config --libs libavcodec) \
`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):
OBJS = $(PLUGIN).o softhddev.o video.o audio.o codec.o ringbuffer.o
SRCS = $(wildcard $(OBJS:.o=.c)) $(PLUGIN).cpp
### The main target:
all: $(SOFILE) i18n
all: libvdr-$(PLUGIN).so i18n
### Implicit rules:
#
#%.o: %.cpp
# $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
### Dependencies:
MAKEDEP = $(CXX) -MM -MG
MAKEDEP = $(CC) -MM -MG
DEPFILE = .dependencies
$(DEPFILE): Makefile
@$(MAKEDEP) $(CXXFLAGS) $(SRCS) > $@
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SRCS) >$@
$(OBJS): Makefile
-include $(DEPFILE)
### Internationalization (I18N):
PODIR = po
LOCALEDIR = $(VDRDIR)/locale
I18Npo = $(wildcard $(PODIR)/*.po)
I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
I18Npot = $(PODIR)/$(PLUGIN).pot
%.mo: %.po
msgfmt -c -o $@ $<
$(I18Npot): $(SRCS)
$(I18Npot): $(wildcard *.cpp) $(wildcard *.c)
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP \
-k_ -k_N --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) \
--msgid-bugs-address='<see README>' -o $@ `ls $^`
-k_ -k_N --package-name=VDR --package-version=$(VDRVERSION) \
--msgid-bugs-address='<see README>' -o $@ $^
%.po: $(I18Npot)
msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
@touch $@
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
install -D -m644 $< $@
$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
@mkdir -p $(dir $@)
cp $< $@
.PHONY: i18n
i18n: $(I18Nmo) $(I18Npot)
install-i18n: $(I18Nmsgs)
i18n: $(I18Nmsgs) $(I18Npot)
### Targets:
$(OBJS): Makefile
$(SOFILE): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
install: install-lib install-i18n
libvdr-$(PLUGIN).so: $(OBJS) Makefile
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -fPIC $(OBJS) -o $@ $(LIBS)
@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
dist: $(I18Npo) clean
@-rm -rf $(TMPDIR)/$(ARCHIVE)
@ -219,20 +162,19 @@ dist: $(I18Npo) clean
@echo Distribution package created as $(PACKAGE).tgz
clean:
@-rm -f $(PODIR)/*.mo $(PODIR)/*.pot
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
## Private Targets:
install: libvdr-$(PLUGIN).so
cp --remove-destination libvdr-$(PLUGIN).so \
/usr/lib/vdr/plugins/libvdr-$(PLUGIN).so.$(APIVERSION)
HDRS= $(wildcard *.h)
indent:
for i in $(SRCS) $(HDRS); do \
indent $$i; \
unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \
mv $$i.up $$i; \
for i in $(wildcard $(OBJS:.o=.c)) $(HDRS); do \
indent $$i; unexpand -a $$i > $$i.up; mv $$i.up $$i; \
done
video_test: video.c Makefile
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< \
$(LIBS) -o $@
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
-o $@

View File

@ -1,6 +1,6 @@
@file README.txt @brief A software HD output device for VDR
Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
Contributor(s):
@ -20,27 +20,25 @@ $Id$
A software and GPU emulated HD output device plugin for VDR.
o Video decoder CPU / VDPAU
o Video output VDPAU
o Video decoder CPU / VA-API / VDPAU
o Video output VA-API / VDPAU
o Audio FFMpeg / Alsa / Analog
o Audio FFMpeg / Alsa / Digital
o Audio FFMpeg / OSS / Analog
o HDMI/SPDIF pass-through
o Software volume, compression, normalize and channel resample
o VDR ScaleVideo API
o YaepgHD support
o Software deinterlacer Bob (VA-API only)
o Autocrop
o Grab image (VDPAU only)
o Suspend / Dettach
o Suspend
o Letterbox, Stretch and Center cut-out video display modes
o atmo light support with plugin http://github.com/durchflieger/DFAtmo
o PIP (Picture-in-Picture) (VDPAU only)
o planned: Remove VA-API decoder and output support
o planned: Video decoder OpenMax
o planned: Video output Opengl / Xv
o planned: Improved software deinterlacer (yadif or/and ffmpeg filters)
o XvBa support is no longer planned (use future Radeon UVD VDPAU)
o planned: Video decoder VA-API Branch: vaapi-ext/staging
o planned: Video output XvBA / Opengl / Xv
o planned: VA-API grab image
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
To compile you must have the 'requires' installed.
@ -58,8 +56,8 @@ Install:
git clone git://projects.vdr-developer.org/vdr-plugin-softhddevice.git
cd vdr-plugin-softhddevice
make
make install
make VDRDIR=<path-to-your-vdr-files> LIBDIR=.
gentoo: make VDRDIR=/usr/include/vdr LIBDIR=.
2a) tarball
@ -68,11 +66,10 @@ Install:
tar vxf vdr-softhddevice-*.tar.bz2
cd softhddevice-*
make
make install
make VDRDIR=<path-to-your-vdr-files> LIBDIR=.
You can edit Makefile to enable/disable VDPAU / VA-API / Alsa / OSS
support. The default is to autodetect as much as possible.
support.
Setup: environment
------
@ -84,12 +81,14 @@ Setup: environment
if set don't use the hardware decoders
NO_MPEG_HW=1
if set don't use the hardware decoder for mpeg1/2
STUDIO_LEVELS=1
if set use studio levels with vdpau (deprecated use setup)
only if alsa is configured
ALSA_DEVICE=default
alsa PCM device name
ALSA_PASSTHROUGH_DEVICE=
alsa pass-though (AC-3,E-AC-3,DTS,...) device name
ALSA_AC3_DEVICE=
alsa AC3/pass-though device name
ALSA_MIXER=default
alsa control device name
ALSA_MIXER_CHANNEL=PCM
@ -98,8 +97,8 @@ Setup: environment
only if oss is configured
OSS_AUDIODEV=/dev/dsp
oss dsp device name
OSS_PASSTHROUGHDEV=
oss pass-though (AC-3,E-AC-3,DTS,...) device name
OSS_AC3_AUDIODEV=
oss AC3/pass-though device name
OSS_MIXERDEV=/dev/mixer
oss mixer device name
OSS_MIXER_CHANNEL=pcm
@ -129,7 +128,7 @@ Setup: /etc/vdr/setup.conf
softhddevice.<res>.Deinterlace = 0
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
(only 0, 1, 4 supported with VA-API)
(only 0, 1 supported with vaapi)
softhddevice.<res>.SkipChromaDeinterlace = 0
0 = disabled, 1 = enabled (for slower cards, poor qualität)
@ -155,17 +154,13 @@ Setup: /etc/vdr/setup.conf
delay audio or delay video
softhddevice.AudioPassthrough = 0
0 = none, 1 = PCM, 2 = MPA, 4 = AC-3, 8 = EAC-3, -X disable
0 = none, 1 = AC-3
for PCM/AC-3/EAC-3 the pass-through device is used and the audio
stream is passed undecoded to the output device.
z.b. 12 = AC-3+EAC-3, 13 = PCM+AC-3+EAC-3
note: MPA/DTS/TrueHD/... aren't supported yet
negative values disable passthrough
for AC-3 the pass-through device is used.
softhddevice.AudioDownmix = 0
0 = none, 1 = downmix
Use ffmpeg/libav downmix of AC-3/EAC-3 audio to stereo.
downmix AC-3 to stero.
softhddevice.AudioSoftvol = 0
0 = off, use hardware volume control
@ -233,45 +228,11 @@ Setup: /etc/vdr/setup.conf
0 disable black picture during channel switch
1 enable black picture during channel switch
softhddevice.ClearOnSwitch = 0
0 keep video und audio buffers during channel switch
1 clear video and audio buffers on channel switch
softhddevice.Video4to3DisplayFormat = 1
VideoDisplayFormat = ?
0 pan and scan
1 letter box
2 center cut-out
softhddevice.VideoOtherDisplayFormat = 1
0 pan and scan
1 pillar box
2 center cut-out
softhddevice.pip.X = 79
softhddevice.pip.Y = 78
softhddevice.pip.Width = 18
softhddevice.pip.Height = 18
PIP pip window position and size in percent.
softhddevice.pip.VideoX = 0
softhddevice.pip.VideoY = 0
softhddevice.pip.VideoWidth = 0
softhddevice.pip.VideoHeight = 0
PIP video window position and size in percent.
softhddevice.pip.Alt.X = 0
softhddevice.pip.Alt.Y = 50
softhddevice.pip.Alt.Width = 0
softhddevice.pip.Alt.Height = 50
PIP alternative pip window position and size in percent.
softhddevice.pip.Alt.VideoX = 0
softhddevice.pip.Alt.VideoY = 0
softhddevice.pip.Alt.VideoWidth = 0
softhddevice.pip.Alt.VideoHeight = 50
PIP alternative video window position and size in percent.
Setup: /etc/vdr/remote.conf
------
@ -321,7 +282,6 @@ Keymacros:
@softhddevice Blue 1 2 toggle pass-through
@softhddevice Blue 1 3 decrease audio delay by 10ms
@softhddevice Blue 1 4 increase audio delay by 10ms
@softhddevice Blue 1 5 toggle ac3 mixdown
@softhddevice Blue 2 0 disable fullscreen
@softhddevice Blue 2 1 enable fullscreen
@softhddevice Blue 2 2 toggle fullscreen
@ -345,19 +305,14 @@ Warning:
Known Bugs:
-----------
VA-API doesn't v-sync h264 interlaced streams
VA-API doesn't v-sync 1080i streams
vdr-image not working
Requires:
---------
media-video/vdr (version >=1.7.xx)
Video Disk Recorder - turns a pc into a powerful set top box
for DVB.
http://www.tvdr.de/
media-video/ffmpeg (version >=0.7)
Complete solution to record, convert and stream audio and
video. Includes libavcodec and libswresample.
video. Includes libavcodec.
http://ffmpeg.org
media-libs/alsa-lib
Advanced Linux Sound Architecture Library
@ -365,7 +320,7 @@ Requires:
or
kernel support for oss/oss4 or alsa oss emulation
x11-libs/libva (deprecated)
x11-libs/libva
Video Acceleration (VA) API for Linux
http://www.freedesktop.org/wiki/Software/vaapi
x11-libs/libva-intel-driver

20
Todo
View File

@ -1,6 +1,6 @@
@file Todo @brief A software HD output device for VDR
Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
Contributor(s):
@ -19,9 +19,6 @@ GNU Affero General Public License for more details.
$Id: $
missing:
documentation of the PIP hotkeys.
svdrp help page missing PIP hotkeys.
svdrp stat: add X11 crashed status.
more software deinterlace (yadif, ...)
more software decoder with software deinterlace
suspend output / energie saver: stop and restart X11
@ -42,16 +39,11 @@ video:
some low-bandwidth tv channels have hiccups.
check start with 24Hz display rate
crash with ffmpeg without vaapi and vdpau.
still-picture of PES recordings should use VideoMpegEnqueue.
convert PIX_FMT_... PixelFormat to new names AV_PIX_FMT_..., AVPixelFormat.
atmo service support 3D grab
no warnings during still picture
vdpau:
software deinterlace path not working.
OSD looses transparency, during channel switch.
OSD looses transparency, while moving cut marks.
ffmpeg >=1.2 supports same API like VA-API.
libva:
yaepghd (VaapiSetOutputPosition) support
@ -62,8 +54,6 @@ libva:
[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
[drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ...
missing OSD support for 3d SBS / Top-Bottom streams, like VPDAU.
PIP support / multistream handling
VA-AP VaapiCleanup crash after channel without video.
libva: branch vaapi-ext / staging
add support for vaapi-ext / staging
@ -120,21 +110,23 @@ plugins:
setup:
Setup of decoder type.
Setup of output type.
Setup of display type.
Setup 4:3 zoom type
Some setup parameters are not used until restart.
Can a notice be added to the setup menu?
unsorted:
stoping vdr while plugin is suspended opens and closes a window.
svdrp prim: support plugin names for device numbers.
Workaround exists: hangup PipVideoStream -> Vdpau_get_format -> xcb -> poll
+ lock DecoderLockMutex
check compiletime and runtime ffmpeg/libav version during init.
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
multistream handling
pip support
save and use auto-crop with channel zapping
upmix stereo to AC-3 (supported by alsa plugin)

410
audio.c
View File

@ -1,7 +1,7 @@
///
/// @file audio.c @brief Audio module
///
/// Copyright (c) 2009 - 2014 by Johns. All Rights Reserved.
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -40,7 +40,6 @@
//#define USE_ALSA ///< enable alsa support
//#define USE_OSS ///< enable OSS support
#define USE_AUDIO_THREAD ///< use thread for audio playback
#define USE_AUDIO_MIXER ///< use audio module mixer
#include <stdio.h>
#include <stdint.h>
@ -88,7 +87,7 @@
#endif
#endif
#include "iatomic.h" // portable atomic_t
#include <alsa/iatomic.h> // portable atomic_t
#include "ringbuffer.h"
#include "misc.h"
@ -123,16 +122,13 @@ static const AudioModule NoopModule; ///< forward definition of noop module
//----------------------------------------------------------------------------
char AudioAlsaDriverBroken; ///< disable broken driver message
char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
static const char *AudioModuleName; ///< which audio module to use
/// Selected audio module.
static const AudioModule *AudioUsedModule = &NoopModule;
static const char *AudioPCMDevice; ///< PCM device name
static const char *AudioPassthroughDevice; ///< Passthrough device name
static char AudioAppendAES; ///< flag automatic append AES
static const char *AudioAC3Device; ///< AC3 device name
static const char *AudioMixerDevice; ///< mixer device name
static const char *AudioMixerChannel; ///< mixer channel name
static char AudioDoingInit; ///> flag in init, reduce error
@ -149,7 +145,6 @@ static int AudioBufferTime = 336; ///< audio buffer time in ms
static pthread_t AudioThread; ///< audio play thread
static pthread_mutex_t AudioMutex; ///< audio condition mutex
static pthread_cond_t AudioStartCond; ///< condition variable
static char AudioThreadStop; ///< stop audio thread
#else
static const int AudioThread; ///< dummy audio thread
#endif
@ -168,6 +163,7 @@ static int AudioStereoDescent; ///< volume descent for stereo
static int AudioVolume; ///< current volume (0 .. 1000)
extern int VideoAudioDelay; ///< import audio/video delay
extern int VideoGetBuffers(void); ///< Get number of input buffers.
/// default ring buffer size ~2s 8ch 16bit (3 * 5 * 7 * 8)
static const unsigned AudioRingBufferSize = 3 * 5 * 7 * 8 * 2 * 1000;
@ -182,7 +178,7 @@ enum _audio_rates
//Audio88200, ///< 88.2Khz
//Audio96000, ///< 96.0Khz
//Audio176400, ///< 176.4Khz
Audio192000, ///< 192.0Khz
//Audio192000, ///< 192.0Khz
AudioRatesMax ///< max index
};
@ -192,9 +188,9 @@ static int AudioRatesInHw[AudioRatesMax];
/// input to hardware channel matrix
static int AudioChannelMatrix[AudioRatesMax][9];
/// rates tables (must be sorted by frequency)
/// rates tables
static const unsigned AudioRatesTable[AudioRatesMax] = {
44100, 48000, 192000
44100, 48000,
};
//----------------------------------------------------------------------------
@ -405,8 +401,6 @@ static void AudioSoftAmplifier(int16_t * samples, int count)
}
}
#ifdef USE_AUDIO_MIXER
/**
** Upmix mono to stereo.
**
@ -490,7 +484,7 @@ static void AudioSurround2Stereo(const int16_t * in, int in_chan, int frames,
r += in[3] * 200; // Rs
l += in[4] * 300; // C
r += in[4] * 300;
l += in[5] * 100; // LFE
l += in[5] * 300; // LFE
r += in[5] * 100;
break;
case 7: // 7.0
@ -553,13 +547,6 @@ static void AudioUpmix(const int16_t * in, int in_chan, int frames,
/**
** Resample ffmpeg sample format to hardware format.
**
** FIXME: use libswresample for this and move it to codec.
** FIXME: ffmpeg to alsa conversion is already done in codec.c.
**
** ffmpeg L R C Ls Rs -> alsa L R Ls Rs C
** ffmpeg L R C LFE Ls Rs -> alsa L R Ls Rs C LFE
** ffmpeg L R C LFE Ls Rs Rl Rr -> alsa L R Ls Rs C LFE Rl Rr
**
** @param in input sample buffer
** @param in_chan nr. of input channels
** @param frames number of frames in sample buffer
@ -595,9 +582,6 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
AudioSurround2Stereo(in, in_chan, frames, out);
break;
case 5 * 8 + 6:
case 3 * 8 + 8:
case 5 * 8 + 8:
case 6 * 8 + 8:
AudioUpmix(in, in_chan, frames, out, out_chan);
break;
@ -610,8 +594,6 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
}
}
#endif
//----------------------------------------------------------------------------
// ring buffer
//----------------------------------------------------------------------------
@ -624,7 +606,7 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
typedef struct _audio_ring_ring_
{
char FlushBuffers; ///< flag: flush buffers
char Passthrough; ///< flag: use pass-through (AC-3, ...)
char UseAc3; ///< flag: use ac3 pass-through
int16_t PacketSize; ///< packet size
unsigned HwSampleRate; ///< hardware sample rate in Hz
unsigned HwChannels; ///< hardware number of channels
@ -642,34 +624,29 @@ static atomic_t AudioRingFilled; ///< how many of the ring is used
static unsigned AudioStartThreshold; ///< start play, if filled
/**
** Add sample-rate, number of channels change to ring.
** Add sample-rate, number of channel change to ring.
**
** @param sample_rate sample-rate frequency
** @param channels number of channels
** @param passthrough use /pass-through (AC-3, ...) device
** @param use_ac3 use ac3/pass-through device
**
** @retval -1 error
** @retval 0 okay
**
** @note this function shouldn't fail. Checks are done during AudoInit.
*/
static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
static int AudioRingAdd(unsigned sample_rate, int channels, int use_ac3)
{
unsigned u;
// search supported sample-rates
for (u = 0; u < AudioRatesMax; ++u) {
if (AudioRatesTable[u] == sample_rate) {
goto found;
}
if (AudioRatesTable[u] > sample_rate) {
break;
}
}
Error(_("audio: %dHz sample-rate unsupported\n"), sample_rate);
return -1; // unsupported sample-rate
found:
if (u == AudioRatesMax) { // unsupported sample-rate
Error(_("audio: %dHz sample-rate unsupported\n"), sample_rate);
return -1;
}
if (!AudioChannelMatrix[u][channels]) {
Error(_("audio: %d channels unsupported\n"), channels);
return -1; // unsupported nr. of channels
@ -682,8 +659,9 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
}
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
AudioRing[AudioRingWrite].FlushBuffers = 0;
AudioRing[AudioRingWrite].Passthrough = passthrough;
// FIXME: don't flush buffers here
AudioRing[AudioRingWrite].FlushBuffers = 1;
AudioRing[AudioRingWrite].UseAc3 = use_ac3;
AudioRing[AudioRingWrite].PacketSize = 0;
AudioRing[AudioRingWrite].InSampleRate = sample_rate;
AudioRing[AudioRingWrite].InChannels = channels;
@ -692,9 +670,6 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
AudioRing[AudioRingWrite].PTS = INT64_C(0x8000000000000000);
RingBufferReset(AudioRing[AudioRingWrite].RingBuffer);
Debug(3, "audio: %d ring buffer prepared\n",
atomic_read(&AudioRingFilled) + 1);
atomic_inc(&AudioRingFilled);
#ifdef USE_AUDIO_THREAD
@ -842,9 +817,8 @@ static int AlsaPlayRingbuffer(void)
if (!avail) { // full or buffer empty
break;
}
// muting pass-through AC-3, can produce disturbance
if (AudioMute || (AudioSoftVolume
&& !AudioRing[AudioRingRead].Passthrough)) {
// muting ac3, can produce disturbance
if (AudioMute || (AudioSoftVolume && !AudioRing[AudioRingRead].UseAc3)) {
// FIXME: quick&dirty cast
AudioSoftAmplifier((int16_t *) p, avail);
// FIXME: if not all are written, we double amplify them
@ -943,6 +917,7 @@ static int AlsaThread(void)
return -1;
}
for (;;) {
pthread_testcancel();
if (AudioPaused) {
return 1;
}
@ -990,43 +965,23 @@ static int AlsaThread(void)
/**
** Open alsa pcm device.
**
** @param passthrough use pass-through (AC-3, ...) device
** @param use_ac3 use ac3/pass-through device
*/
static snd_pcm_t *AlsaOpenPCM(int passthrough)
static snd_pcm_t *AlsaOpenPCM(int use_ac3)
{
const char *device;
snd_pcm_t *handle;
int err;
// &&|| hell
if (!(passthrough && ((device = AudioPassthroughDevice)
|| (device = getenv("ALSA_PASSTHROUGH_DEVICE"))))
if (!(use_ac3 && ((device = AudioAC3Device)
|| (device = getenv("ALSA_AC3_DEVICE"))))
&& !(device = AudioPCMDevice) && !(device = getenv("ALSA_DEVICE"))) {
device = "default";
}
if (!AudioDoingInit) { // reduce blabla during init
Info(_("audio/alsa: using %sdevice '%s'\n"),
passthrough ? "pass-through " : "", device);
}
//
// for AC3 pass-through try to set the non-audio bit, use AES0=6
//
if (passthrough && AudioAppendAES) {
#if 0
// FIXME: not yet finished
char *buf;
const char *s;
int n;
n = strlen(device);
buf = alloca(n + sizeof(":AES0=6") + 1);
strcpy(buf, device);
if (!(s = strchr(buf, ':'))) {
// no alsa parameters
strcpy(buf + n, ":AES=6");
}
Debug(3, "audio/alsa: try '%s'\n", buf);
#endif
Info(_("audio/alsa: using %sdevice '%s'\n"), use_ac3 ? "ac3 " : "",
device);
}
// open none blocking; if device is already used, we don't want wait
if ((err =
@ -1193,7 +1148,7 @@ static int64_t AlsaGetDelay(void)
**
** @param freq sample frequency
** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device
** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@ -1201,7 +1156,7 @@ static int64_t AlsaGetDelay(void)
**
** @todo FIXME: remove pointer for freq + channels
*/
static int AlsaSetup(int *freq, int *channels, int passthrough)
static int AlsaSetup(int *freq, int *channels, int use_ac3)
{
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
@ -1209,26 +1164,20 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
int delay;
if (!AlsaPCMHandle) { // alsa not running yet
// FIXME: if open fails for fe. pass-through, we never recover
// FIXME: if open fails for ac3, we never recover
return -1;
}
if (!AudioAlsaNoCloseOpen) { // close+open to fix HDMI no sound bug
if (1) { // close+open to fix HDMI no sound bug
snd_pcm_t *handle;
handle = AlsaPCMHandle;
// no lock needed, thread exit in main loop only
//Debug(3, "audio: %s [\n", __FUNCTION__);
// FIXME: need lock
AlsaPCMHandle = NULL; // other threads should check handle
snd_pcm_close(handle);
if (AudioAlsaCloseOpenDelay) {
usleep(50 * 1000); // 50ms delay for alsa recovery
}
// FIXME: can use multiple retries
if (!(handle = AlsaOpenPCM(passthrough))) {
if (!(handle = AlsaOpenPCM(use_ac3))) {
return -1;
}
AlsaPCMHandle = handle;
//Debug(3, "audio: %s ]\n", __FUNCTION__);
}
for (;;) {
@ -1237,29 +1186,21 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
AlsaUseMmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED :
SND_PCM_ACCESS_RW_INTERLEAVED, *channels, *freq, 1,
96 * 1000))) {
// try reduced buffer size (needed for sunxi)
// FIXME: alternativ make this configurable
if ((err =
snd_pcm_set_params(AlsaPCMHandle, SND_PCM_FORMAT_S16,
AlsaUseMmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED :
SND_PCM_ACCESS_RW_INTERLEAVED, *channels, *freq, 1,
72 * 1000))) {
/*
if ( err == -EBADFD ) {
snd_pcm_close(AlsaPCMHandle);
AlsaPCMHandle = NULL;
continue;
}
*/
/*
if ( err == -EBADFD ) {
snd_pcm_close(AlsaPCMHandle);
AlsaPCMHandle = NULL;
continue;
}
*/
if (!AudioDoingInit) {
Error(_("audio/alsa: set params error: %s\n"),
snd_strerror(err));
}
// FIXME: must stop sound, AudioChannels ... invalid
return -1;
if (!AudioDoingInit) {
Error(_("audio/alsa: set params error: %s\n"),
snd_strerror(err));
}
// FIXME: must stop sound, AudioChannels ... invalid
return -1;
}
break;
}
@ -1493,7 +1434,7 @@ static int OssPlayRingbuffer(void)
break; // bi.bytes could become negative!
}
if (AudioSoftVolume && !AudioRing[AudioRingRead].Passthrough) {
if (AudioSoftVolume && !AudioRing[AudioRingRead].UseAc3) {
// FIXME: quick&dirty cast
AudioSoftAmplifier((int16_t *) p, bi.bytes);
// FIXME: if not all are written, we double amplify them
@ -1558,6 +1499,7 @@ static int OssThread(void)
for (;;) {
struct pollfd fds[1];
pthread_testcancel();
if (AudioPaused) {
return 1;
}
@ -1599,22 +1541,22 @@ static int OssThread(void)
/**
** Open OSS pcm device.
**
** @param passthrough use pass-through (AC-3, ...) device
** @param use_ac3 use ac3/pass-through device
*/
static int OssOpenPCM(int passthrough)
static int OssOpenPCM(int use_ac3)
{
const char *device;
int fildes;
// &&|| hell
if (!(passthrough && ((device = AudioPassthroughDevice)
|| (device = getenv("OSS_PASSTHROUGHDEV"))))
if (!(use_ac3 && ((device = AudioAC3Device)
|| (device = getenv("OSS_AC3_AUDIODEV"))))
&& !(device = AudioPCMDevice) && !(device = getenv("OSS_AUDIODEV"))) {
device = "/dev/dsp";
}
if (!AudioDoingInit) {
Info(_("audio/oss: using %sdevice '%s'\n"),
passthrough ? "pass-through " : "", device);
Info(_("audio/oss: using %sdevice '%s'\n"), use_ac3 ? "ac3 " : "",
device);
}
if ((fildes = open(device, O_WRONLY)) < 0) {
@ -1761,15 +1703,15 @@ static int64_t OssGetDelay(void)
/**
** Setup OSS audio for requested format.
**
** @param sample_rate sample rate/frequency
** @param sample_rate sample rate/frequency
** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device
** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
** @retval -1 something gone wrong
*/
static int OssSetup(int *sample_rate, int *channels, int passthrough)
static int OssSetup(int *sample_rate, int *channels, int use_ac3)
{
int ret;
int tmp;
@ -1777,17 +1719,17 @@ static int OssSetup(int *sample_rate, int *channels, int passthrough)
audio_buf_info bi;
if (OssPcmFildes == -1) { // OSS not ready
// FIXME: if open fails for fe. pass-through, we never recover
// FIXME: if open fails for ac3, we never recover
return -1;
}
if (1) { // close+open for pcm / AC-3
if (1) { // close+open for pcm / ac3
int fildes;
fildes = OssPcmFildes;
OssPcmFildes = -1;
close(fildes);
if (!(fildes = OssOpenPCM(passthrough))) {
if (!(fildes = OssOpenPCM(use_ac3))) {
return -1;
}
OssPcmFildes = fildes;
@ -1968,14 +1910,13 @@ static void NoopSetVolume( __attribute__ ((unused))
/**
** Noop setup.
**
** @param freq sample frequency
** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device
** @param freq sample frequency
** @param channels number of channels
*/
static int NoopSetup( __attribute__ ((unused))
int *channels, __attribute__ ((unused))
int *freq, __attribute__ ((unused))
int passthrough)
int use_ac3)
{
return -1;
}
@ -2013,17 +1954,16 @@ static const AudioModule NoopModule = {
*/
static int AudioNextRing(void)
{
int passthrough;
int use_ac3;
int sample_rate;
int channels;
size_t used;
// update audio format
// not always needed, but check if needed is too complex
passthrough = AudioRing[AudioRingRead].Passthrough;
use_ac3 = AudioRing[AudioRingRead].UseAc3;
sample_rate = AudioRing[AudioRingRead].HwSampleRate;
channels = AudioRing[AudioRingRead].HwChannels;
if (AudioUsedModule->Setup(&sample_rate, &channels, passthrough)) {
if (AudioUsedModule->Setup(&sample_rate, &channels, use_ac3)) {
Error(_("audio: can't set channels %d sample-rate %dHz\n"), channels,
sample_rate);
// FIXME: handle error
@ -2036,18 +1976,12 @@ static int AudioNextRing(void)
AudioResetCompressor();
AudioResetNormalizer();
Debug(3, "audio: a/v next buf(%d,%4zdms)\n", atomic_read(&AudioRingFilled),
(RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer) * 1000)
/ (AudioRing[AudioRingWrite].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample));
// stop, if not enough in next buffer
used = RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer);
if (AudioStartThreshold * 4 < used || (AudioVideoIsReady
&& AudioStartThreshold < used)) {
return 0;
if (AudioStartThreshold >=
RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer)) {
return 1;
}
return 1;
return 0;
}
/**
@ -2059,12 +1993,6 @@ static void *AudioPlayHandlerThread(void *dummy)
{
Debug(3, "audio: play thread started\n");
for (;;) {
// check if we should stop the thread
if (AudioThreadStop) {
Debug(3, "audio: play thread stopped\n");
return PTHREAD_CANCELED;
}
Debug(3, "audio: wait on start condition\n");
pthread_mutex_lock(&AudioMutex);
AudioRunning = 0;
@ -2075,59 +2003,46 @@ static void *AudioPlayHandlerThread(void *dummy)
pthread_mutex_unlock(&AudioMutex);
Debug(3, "audio: ----> %dms start\n", (AudioUsedBytes() * 1000)
/ (!AudioRing[AudioRingWrite].HwSampleRate +
!AudioRing[AudioRingWrite].HwChannels +
AudioRing[AudioRingWrite].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample));
/ (!AudioRing[AudioRingRead].HwSampleRate +
!AudioRing[AudioRingRead].HwChannels +
AudioRing[AudioRingRead].HwSampleRate *
AudioRing[AudioRingRead].HwChannels * AudioBytesProSample));
do {
int filled;
int read;
int flush;
int err;
int i;
// check if we should stop the thread
if (AudioThreadStop) {
Debug(3, "audio: play thread stopped\n");
return PTHREAD_CANCELED;
}
// look if there is a flush command in the queue
flush = 0;
filled = atomic_read(&AudioRingFilled);
read = AudioRingRead;
i = filled;
while (i--) {
while (filled--) {
read = (read + 1) % AUDIO_RING_MAX;
if (AudioRing[read].FlushBuffers) {
AudioRing[read].FlushBuffers = 0;
AudioRingRead = read;
atomic_set(&AudioRingFilled, filled);
// handle all flush in queue
flush = filled - i;
flush = 1;
}
}
if (flush) {
Debug(3, "audio: flush %d ring buffer(s)\n", flush);
AudioUsedModule->FlushBuffers();
atomic_sub(flush, &AudioRingFilled);
if (AudioNextRing()) {
Debug(3, "audio: break after flush\n");
break;
}
Debug(3, "audio: continue after flush\n");
}
// try to play some samples
err = 0;
if (RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer)) {
err = AudioUsedModule->Thread();
}
err = AudioUsedModule->Thread();
// underrun, check if new ring buffer is available
if (!err) {
int passthrough;
int use_ac3;
int sample_rate;
int channels;
int old_passthrough;
int old_use_ac3;
int old_sample_rate;
int old_channels;
@ -2137,21 +2052,20 @@ static void *AudioPlayHandlerThread(void *dummy)
}
Debug(3, "audio: next ring buffer\n");
old_passthrough = AudioRing[AudioRingRead].Passthrough;
old_use_ac3 = AudioRing[AudioRingRead].UseAc3;
old_sample_rate = AudioRing[AudioRingRead].HwSampleRate;
old_channels = AudioRing[AudioRingRead].HwChannels;
atomic_dec(&AudioRingFilled);
AudioRingRead = (AudioRingRead + 1) % AUDIO_RING_MAX;
passthrough = AudioRing[AudioRingRead].Passthrough;
use_ac3 = AudioRing[AudioRingRead].UseAc3;
sample_rate = AudioRing[AudioRingRead].HwSampleRate;
channels = AudioRing[AudioRingRead].HwChannels;
Debug(3, "audio: thread channels %d frequency %dHz %s\n",
channels, sample_rate, passthrough ? "pass-through" : "");
channels, sample_rate, use_ac3 ? "ac3" : "pcm");
// audio config changed?
if (old_passthrough != passthrough
|| old_sample_rate != sample_rate
if (old_use_ac3 != use_ac3 || old_sample_rate != sample_rate
|| old_channels != channels) {
// FIXME: wait for buffer drain
if (AudioNextRing()) {
@ -2176,7 +2090,6 @@ static void *AudioPlayHandlerThread(void *dummy)
*/
static void AudioInitThread(void)
{
AudioThreadStop = 0;
pthread_mutex_init(&AudioMutex, NULL);
pthread_cond_init(&AudioStartCond, NULL);
pthread_create(&AudioThread, NULL, AudioPlayHandlerThread, NULL);
@ -2190,12 +2103,10 @@ static void AudioExitThread(void)
{
void *retval;
Debug(3, "audio: %s\n", __FUNCTION__);
if (AudioThread) {
AudioThreadStop = 1;
AudioRunning = 1; // wakeup thread, if needed
pthread_cond_signal(&AudioStartCond);
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"));
}
@ -2233,6 +2144,7 @@ void AudioEnqueue(const void *samples, int count)
{
size_t n;
int16_t *buffer;
int frames;
#ifdef noDEBUG
static uint32_t last_tick;
@ -2254,40 +2166,28 @@ void AudioEnqueue(const void *samples, int count)
AudioRing[AudioRingWrite].PacketSize = count;
Debug(3, "audio: a/v packet size %d bytes\n", count);
}
// audio sample modification allowed and needed?
buffer = (void *)samples;
if (!AudioRing[AudioRingWrite].Passthrough && (AudioCompression
|| AudioNormalize
|| AudioRing[AudioRingWrite].InChannels !=
AudioRing[AudioRingWrite].HwChannels)) {
int frames;
// resample into ring-buffer is too complex in the case of a roundabout
// just use a temporary buffer
if (AudioRing[AudioRingWrite].UseAc3) {
buffer = (void *)samples;
} else {
//
// Convert / resample input to hardware format
//
frames =
count / (AudioRing[AudioRingWrite].InChannels *
AudioBytesProSample);
buffer =
alloca(frames * AudioRing[AudioRingWrite].HwChannels *
AudioBytesProSample);
#ifdef USE_AUDIO_MIXER
// Convert / resample input to hardware format
AudioResample(samples, AudioRing[AudioRingWrite].InChannels, frames,
buffer, AudioRing[AudioRingWrite].HwChannels);
#else
#ifdef DEBUG
if (AudioRing[AudioRingWrite].InChannels !=
AudioRing[AudioRingWrite].HwChannels) {
Debug(3, "audio: internal failure channels mismatch\n");
return;
}
#endif
memcpy(buffer, samples, count);
#endif
count =
frames * AudioRing[AudioRingWrite].HwChannels *
AudioBytesProSample;
// resample into ring-buffer is too complex in the case of a roundabout
// just use a temporary buffer
if (AudioCompression) { // in place operation
AudioCompressor(buffer, count);
}
@ -2376,12 +2276,11 @@ void AudioVideoReady(int64_t pts)
(used * 90 * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample);
Debug(3, "audio: a/v sync buf(%d,%4zdms) %s|%s = %dms %s\n",
atomic_read(&AudioRingFilled),
Debug(3, "audio: a/v buf:%4zdms %s|%s = %dms video ready\n",
(used * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample),
Timestamp2String(pts), Timestamp2String(audio_pts),
(int)(pts - audio_pts) / 90, AudioRunning ? "running" : "ready");
Timestamp2String(audio_pts), Timestamp2String(pts),
(int)(pts - audio_pts) / 90);
if (!AudioRunning) {
int skip;
@ -2392,7 +2291,7 @@ void AudioVideoReady(int64_t pts)
pts - 15 * 20 * 90 - AudioBufferTime * 90 - audio_pts +
VideoAudioDelay;
#ifdef DEBUG
fprintf(stderr, "%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
printf("%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
VideoAudioDelay / 90, skip / 90);
#endif
// guard against old PTS
@ -2405,7 +2304,7 @@ void AudioVideoReady(int64_t pts)
AudioSkip = skip - used;
skip = used;
}
Debug(3, "audio: sync advance %dms %d/%zd\n",
Debug(3, "audio: advance %dms %d/%zd\n",
(skip * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels *
AudioBytesProSample), skip, used);
@ -2473,26 +2372,10 @@ void AudioFlushBuffers(void)
int old;
int i;
if (atomic_read(&AudioRingFilled) >= AUDIO_RING_MAX) {
// wait for space in ring buffer, should never happen
for (i = 0; i < 24 * 2; ++i) {
if (atomic_read(&AudioRingFilled) < AUDIO_RING_MAX) {
break;
}
Debug(3, "audio: flush out of ring buffers\n");
usleep(1 * 1000); // avoid hot polling
}
if (atomic_read(&AudioRingFilled) >= AUDIO_RING_MAX) {
// FIXME: We can set the flush flag in the last wrote ring buffer
Error(_("audio: flush out of ring buffers\n"));
return;
}
}
old = AudioRingWrite;
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
AudioRing[AudioRingWrite].FlushBuffers = 1;
AudioRing[AudioRingWrite].Passthrough = AudioRing[old].Passthrough;
AudioRing[AudioRingWrite].UseAc3 = AudioRing[old].UseAc3;
AudioRing[AudioRingWrite].HwSampleRate = AudioRing[old].HwSampleRate;
AudioRing[AudioRingWrite].HwChannels = AudioRing[old].HwChannels;
AudioRing[AudioRingWrite].InSampleRate = AudioRing[old].InSampleRate;
@ -2506,13 +2389,12 @@ void AudioFlushBuffers(void)
atomic_inc(&AudioRingFilled);
// FIXME: wait for flush complete needed?
// FIXME: wait for flush complete?
for (i = 0; i < 24 * 2; ++i) {
if (!AudioRunning) { // wakeup thread to flush buffers
AudioRunning = 1;
pthread_cond_signal(&AudioStartCond);
}
// FIXME: waiting on zero isn't correct, but currently works
if (!atomic_read(&AudioRingFilled)) {
break;
}
@ -2605,7 +2487,7 @@ int64_t AudioGetClock(void)
// delay zero, if no valid time stamp
if ((delay = AudioGetDelay())) {
if (AudioRing[AudioRingRead].Passthrough) {
if (AudioRing[AudioRingRead].UseAc3) {
return AudioRing[AudioRingRead].PTS + 0 * 90 - delay;
}
return AudioRing[AudioRingRead].PTS + 0 * 90 - delay;
@ -2625,7 +2507,7 @@ void AudioSetVolume(int volume)
AudioMute = !volume;
// reduce loudness for stereo output
if (AudioStereoDescent && AudioRing[AudioRingRead].InChannels == 2
&& !AudioRing[AudioRingRead].Passthrough) {
&& !AudioRing[AudioRingRead].UseAc3) {
volume -= AudioStereoDescent;
if (volume < 0) {
volume = 0;
@ -2642,20 +2524,18 @@ void AudioSetVolume(int volume)
/**
** Setup audio for requested format.
**
** @param freq sample frequency
** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device
** @param freq sample frequency
** @param channels number of channels
** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
** @retval -1 something gone wrong
**
** @todo add support to report best fitting format.
*/
int AudioSetup(int *freq, int *channels, int passthrough)
int AudioSetup(int *freq, int *channels, int use_ac3)
{
Debug(3, "audio: setup channels %d frequency %dHz %s\n", *channels, *freq,
passthrough ? "pass-through" : "");
use_ac3 ? "ac3" : "pcm");
// invalid parameter
if (!freq || !channels || !*freq || !*channels) {
@ -2663,7 +2543,7 @@ int AudioSetup(int *freq, int *channels, int passthrough)
// FIXME: set flag invalid setup
return -1;
}
return AudioRingAdd(*freq, *channels, passthrough);
return AudioRingAdd(*freq, *channels, use_ac3);
}
/**
@ -2799,7 +2679,7 @@ void AudioSetDevice(const char *device)
**
** @note this is currently usable with alsa only.
*/
void AudioSetPassthroughDevice(const char *device)
void AudioSetDeviceAC3(const char *device)
{
if (!AudioModuleName) {
AudioModuleName = "alsa"; // detect alsa/OSS
@ -2809,7 +2689,7 @@ void AudioSetPassthroughDevice(const char *device)
AudioModuleName = "oss";
}
}
AudioPassthroughDevice = device;
AudioAC3Device = device;
}
/**
@ -2824,20 +2704,6 @@ void AudioSetChannel(const char *channel)
AudioMixerChannel = channel;
}
/**
** Set automatic AES flag handling.
**
** @param onoff turn setting AES flag on or off
*/
void AudioSetAutoAES(int onoff)
{
if (onoff < 0) {
AudioAppendAES ^= 1;
} else {
AudioAppendAES = onoff;
}
}
/**
** Initialize audio output module.
**
@ -2882,16 +2748,10 @@ void AudioInit(void)
// Check which channels/rates/formats are supported
// FIXME: we force 44.1Khz and 48Khz must be supported equal
// FIXME: should use bitmap of channels supported in RatesInHw
// FIXME: use loop over sample-rates
freq = 44100;
AudioRatesInHw[Audio44100] = 0;
for (chan = 1; chan < 9; ++chan) {
int tchan;
int tfreq;
tchan = chan;
tfreq = freq;
if (AudioUsedModule->Setup(&tfreq, &tchan, 0)) {
if (AudioUsedModule->Setup(&freq, &chan, 0)) {
AudioChannelsInHw[chan] = 0;
} else {
AudioChannelsInHw[chan] = chan;
@ -2901,39 +2761,16 @@ void AudioInit(void)
freq = 48000;
AudioRatesInHw[Audio48000] = 0;
for (chan = 1; chan < 9; ++chan) {
int tchan;
int tfreq;
if (!AudioChannelsInHw[chan]) {
continue;
}
tchan = chan;
tfreq = freq;
if (AudioUsedModule->Setup(&tfreq, &tchan, 0)) {
//AudioChannelsInHw[chan] = 0;
if (AudioUsedModule->Setup(&freq, &chan, 0)) {
AudioChannelsInHw[chan] = 0;
} else {
AudioChannelsInHw[chan] = chan;
AudioRatesInHw[Audio48000] |= (1 << chan);
}
}
freq = 192000;
AudioRatesInHw[Audio192000] = 0;
for (chan = 1; chan < 9; ++chan) {
int tchan;
int tfreq;
if (!AudioChannelsInHw[chan]) {
continue;
}
tchan = chan;
tfreq = freq;
if (AudioUsedModule->Setup(&tfreq, &tchan, 0)) {
//AudioChannelsInHw[chan] = 0;
} else {
AudioChannelsInHw[chan] = chan;
AudioRatesInHw[Audio192000] |= (1 << chan);
}
}
// build channel support and conversion table
for (u = 0; u < AudioRatesMax; ++u) {
for (chan = 1; chan < 9; ++chan) {
@ -3015,18 +2852,13 @@ void AudioInit(void)
*/
void AudioExit(void)
{
const AudioModule *module;
Debug(3, "audio: %s\n", __FUNCTION__);
#ifdef USE_AUDIO_THREAD
if (AudioUsedModule->Thread) { // supports threads
AudioExitThread();
}
#endif
module = AudioUsedModule;
AudioUsedModule->Exit();
AudioUsedModule = &NoopModule;
module->Exit();
AudioRingExit();
AudioRunning = 0;
AudioPaused = 0;
@ -3073,7 +2905,7 @@ static void PrintVersion(void)
#ifdef GIT_REV
"(GIT-" GIT_REV ")"
#endif
",\n\t(c) 2009 - 2013 by Johns\n"
",\n\t(c) 2009 - 2012 by Johns\n"
"\tLicense AGPLv3: GNU Affero General Public License version 3\n");
}
@ -3130,7 +2962,7 @@ int main(int argc, char *const argv[])
return -1;
default:
PrintVersion();
fprintf(stderr, "Unknown option '%c'\n", optopt);
fprintf(stderr, "Unkown option '%c'\n", optopt);
return -1;
}
break;

View File

@ -1,7 +1,7 @@
///
/// @file audio.h @brief Audio module headerfile
///
/// Copyright (c) 2009 - 2014 by Johns. All Rights Reserved.
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -48,11 +48,8 @@ extern void AudioSetCompression(int, int); ///< set compression parameters
extern void AudioSetStereoDescent(int); ///< set stereo loudness descent
extern void AudioSetDevice(const char *); ///< set PCM audio device
/// set pass-through device
extern void AudioSetPassthroughDevice(const char *);
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
extern void AudioSetChannel(const char *); ///< set mixer channel
extern void AudioSetAutoAES(int); ///< set automatic AES flag handling
extern void AudioInit(void); ///< setup audio module
extern void AudioExit(void); ///< cleanup and exit audio module
@ -61,7 +58,5 @@ extern void AudioExit(void); ///< cleanup and exit audio module
//----------------------------------------------------------------------------
extern char AudioAlsaDriverBroken; ///< disable broken driver message
extern char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
/// @}

920
codec.c

File diff suppressed because it is too large Load Diff

23
codec.h
View File

@ -1,7 +1,7 @@
///
/// @file codec.h @brief Codec module headerfile
///
/// Copyright (c) 2009 - 2013, 2015 by Johns. All Rights Reserved.
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -23,16 +23,6 @@
/// @addtogroup Codec
/// @{
//----------------------------------------------------------------------------
// Defines
//----------------------------------------------------------------------------
#define CodecPCM 0x01 ///< PCM bit mask
#define CodecMPA 0x02 ///< MPA bit mask (planned)
#define CodecAC3 0x04 ///< AC-3 bit mask
#define CodecEAC3 0x08 ///< E-AC-3 bit mask
#define CodecDTS 0x10 ///< DTS bit mask (planned)
//----------------------------------------------------------------------------
// Typedefs
//----------------------------------------------------------------------------
@ -43,13 +33,6 @@ typedef struct _video_decoder_ VideoDecoder;
/// Audio decoder typedef.
typedef struct _audio_decoder_ AudioDecoder;
//----------------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------------
/// Flag prefer fast xhannel switch
extern char CodecUsePossibleDefectFrames;
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
@ -61,7 +44,7 @@ extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
extern void CodecVideoDelDecoder(VideoDecoder *);
/// Open video codec.
extern void CodecVideoOpen(VideoDecoder *, int);
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
/// Close video codec.
extern void CodecVideoClose(VideoDecoder *);
@ -79,7 +62,7 @@ extern AudioDecoder *CodecAudioNewDecoder(void);
extern void CodecAudioDelDecoder(AudioDecoder *);
/// Open audio codec.
extern void CodecAudioOpen(AudioDecoder *, int);
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
/// Close audio codec.
extern void CodecAudioClose(AudioDecoder *);

View File

@ -1,97 +0,0 @@
///
/// @file iatomic.h @brief Misc function header file
///
/// Copyright (c) 2014 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
/// License: AGPLv3
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as
/// published by the Free Software Foundation, either version 3 of the
/// License.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup iatomic
/// @{
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
// gcc before 4.7 didn't support atomic builtins,
// use alsa atomic functions.
#if GCC_VERSION < 40700
#include <alsa/iatomic.h>
#else
//////////////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Declares
//////////////////////////////////////////////////////////////////////////////
///
/// atomic type, 24 bit useable,
///
typedef volatile int atomic_t;
//////////////////////////////////////////////////////////////////////////////
// Prototypes
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Inlines
//////////////////////////////////////////////////////////////////////////////
///
/// Set atomic value.
///
#define atomic_set(ptr, val) \
__atomic_store_n(ptr, val, __ATOMIC_SEQ_CST)
///
/// Read atomic value.
///
#define atomic_read(ptr) \
__atomic_load_n(ptr, __ATOMIC_SEQ_CST)
///
/// Increment atomic value.
///
#define atomic_inc(ptr) \
__atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
///
/// Decrement atomic value.
///
#define atomic_dec(ptr) \
__atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
///
/// Add to atomic value.
///
#define atomic_add(val, ptr) \
__atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST)
///
/// Subtract from atomic value.
///
#define atomic_sub(val, ptr) \
__atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST)
#endif
/// @}

2
make.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
exec make VDRDIR=/usr/include/vdr LIBDIR=. "$@"

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
///
/// @file ringbuffer.c @brief Ringbuffer module
///
/// Copyright (c) 2009, 2011, 2014 by Johns. All Rights Reserved.
/// Copyright (c) 2009, 2011 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -30,7 +30,8 @@
#include <stdlib.h>
#include <string.h>
#include "iatomic.h"
#include <alsa/iatomic.h>
#include "ringbuffer.h"
/// ring buffer structure

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
///
/// @file softhddev.h @brief software HD device plugin header file.
///
/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved.
/// Copyright (c) 2011 - 2012 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -25,8 +25,7 @@ extern "C"
{
#endif
/// C callback feed key press
extern void FeedKeyPress(const char *, const char *, int, int,
const char *);
extern void FeedKeyPress(const char *, const char *, int, int);
/// C plugin get osd size and ascpect
extern void GetOsdSize(int *, int *, double *);
@ -34,8 +33,7 @@ extern "C"
/// C plugin close osd
extern void OsdClose(void);
/// C plugin draw osd pixmap
extern void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
int);
extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
/// C plugin play audio packet
extern int PlayAudio(const uint8_t *, int, uint8_t);
@ -43,8 +41,6 @@ extern "C"
extern int PlayTsAudio(const uint8_t *, int);
/// C plugin set audio volume
extern void SetVolumeDevice(int);
/// C plugin reset channel id (restarts audio)
extern void ResetChannelId(void);
/// C plugin play video packet
extern int PlayVideo(const uint8_t *, int);
@ -99,19 +95,6 @@ extern "C"
/// Get decoder statistics
extern void GetStats(int *, int *, int *, int *);
/// C plugin scale video
extern void ScaleVideo(int, int, int, int);
/// Set Pip position
extern void PipSetPosition(int, int, int, int, int, int, int, int);
/// Pip start
extern void PipStart(int, int, int, int, int, int, int, int);
/// Pip stop
extern void PipStop(void);
/// Pip play video packet
extern int PipPlayVideo(const uint8_t *, int);
extern const char *X11DisplayName; ///< x11 display name
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
///
/// @file softhddevice.h @brief software HD device plugin header file.
///
/// Copyright (c) 2011, 2014 by Johns. All Rights Reserved.
/// Copyright (c) 2011 by Johns. All Rights Reserved.
///
/// Contributor(s):
///

View File

@ -23,7 +23,6 @@
#pragma once
#define ATMO_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.0"
#define ATMO1_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.1"
#define OSD_3DMODE_SERVICE "SoftHDDevice-Osd3DModeService-v1.0"
enum
@ -49,17 +48,3 @@ typedef struct
{
int Mode;
} SoftHDDevice_Osd3DModeService_v1_0_t;
typedef struct
{
// request/reply data
int width;
int height;
// reply data
int size;
void *img;
} SoftHDDevice_AtmoGrabService_v1_1_t;

View File

@ -1,73 +1,74 @@
# Copyright 1999-2014 Gentoo Foundation
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
EAPI="5"
EAPI="3"
inherit vdr-plugin-2 git-2
inherit eutils vdr-plugin
RESTRICT="test"
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
EGIT_REPO_URI="git://projects.vdr-developer.org/vdr-plugin-softhddevice.git"
KEYWORDS=""
DESCRIPTION="VDR Plugin: Software and GPU emulated HD output device"
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"
IUSE="alsa +debug opengl oss vaapi vdpau xscreensaver"
KEYWORDS="~x86 ~amd64"
IUSE="vaapi vdpau alsa oss yaepg opengl debug"
RDEPEND=">=media-video/vdr-2
x11-libs/libX11
>=x11-libs/libxcb-1.8
x11-libs/xcb-util-wm
x11-libs/xcb-util-keysyms
x11-libs/xcb-util-renderutil
alsa? ( media-libs/alsa-lib )
opengl? ( virtual/opengl )
vaapi? ( x11-libs/libva
virtual/ffmpeg[vaapi] )
vdpau? ( x11-libs/libvdpau
virtual/ffmpeg[vdpau] )"
DEPEND="${RDEPEND}
virtual/pkgconfig
x11-libs/xcb-util"
DEPEND=">=x11-libs/libxcb-1.8
x11-libs/xcb-util
x11-libs/xcb-util-wm
x11-libs/xcb-util-keysyms
x11-libs/xcb-util-renderutil
x11-libs/libX11
opengl? ( virtual/opengl )
>=virtual/ffmpeg-0.7
sys-devel/gettext
sys-devel/make
dev-util/pkgconfig
yaepg? ( >=media-video/vdr-1.7.23[yaepg] )
!yaepg? ( >=media-video/vdr-1.7.23 )
vdpau? ( x11-libs/libvdpau virtual/ffmpeg[vdpau] )
vaapi? ( x11-libs/libva virtual/ffmpeg[vaapi] )
alsa? ( media-libs/alsa-lib )
oss? ( sys-kernel/linux-headers )
"
REQUIRED_USE="opengl? ( vaapi )
|| ( vaapi vdpau )
|| ( alsa oss )"
#VDR_CONFD_FILE="${FILESDIR}/confd-0.6.0"
#VDR_RCADDON_FILE="${FILESDIR}/rc-addon-0.6.0.sh"
pkg_setup() {
vdr-plugin-2_pkg_setup
append-cppflags -DHAVE_PTHREAD_NAME
use debug && append-cppflags -DDEBUG -DOSD_DEBUG
}
src_prepare() {
vdr-plugin-2_src_prepare
vdr-plugin_src_prepare
}
BUILD_PARAMS+=" ALSA=$(usex alsa 1 0)"
BUILD_PARAMS+=" OPENGL=$(usex opengl 1 0)"
BUILD_PARAMS+=" OSS=$(usex oss 1 0)"
BUILD_PARAMS+=" VAAPI=$(usex vaapi 1 0)"
BUILD_PARAMS+=" VDPAU=$(usex vdpau 1 0)"
BUILD_PARAMS+=" SCREENSAVER=$(usex xscreensaver 1 0)"
src_compile() {
local myconf
if has_version ">=media-video/ffmpeg-0.8"; then
BUILD_PARAMS+=" SWRESAMPLE=1"
fi
if has_version ">=media-video/libav-0.8"; then
BUILD_PARAMS+=" AVRESAMPLE=1"
fi
myconf="-DHAVE_PTHREAD_NAME"
use vdpau && myconf="${myconf} -DUSE_VDPAU"
use vaapi && myconf="${myconf} -DUSE_VAAPI"
use alsa && myconf="${myconf} -DUSE_ALSA"
use oss && myconf="${myconf} -DUSE_OSS"
use debug && myconf="${myconf} -DDEBUG"
emake all CC="$(tc-getCC)" CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" CONFIG="${myconf}" LIBDIR="." || die
}
src_install() {
vdr-plugin-2_src_install
vdr-plugin_src_install
nonfatal dodoc ChangeLog Todo
dodoc README.txt
#dodir /etc/vdr/plugins || die
#insinto /etc/vdr/plugins
#fowners -R vdr:vdr /etc/vdr || die
#insinto /etc/conf.d
#doins vdr.softhddevice
}

2983
video.c

File diff suppressed because it is too large Load Diff

47
video.h
View File

@ -1,7 +1,7 @@
///
/// @file video.h @brief Video module header file
///
/// Copyright (c) 2009 - 2015 by Johns. All Rights Reserved.
/// Copyright (c) 2009 - 2012 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@ -30,35 +30,31 @@
/// Video hardware decoder typedef
typedef struct _video_hw_decoder_ VideoHwDecoder;
/// Video output stream typedef
typedef struct __video_stream__ VideoStream;
//----------------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------------
extern signed char VideoHardwareDecoder; ///< flag use hardware decoder
extern char VideoHardwareDecoder; ///< flag use hardware decoder
extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
extern int VideoAudioDelay; ///< audio/video delay
extern char ConfigStartX11Server; ///< flag start the x11 server
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
/// Allocate new video hardware decoder.
extern VideoHwDecoder *VideoNewHwDecoder(VideoStream *);
extern VideoHwDecoder *VideoNewHwDecoder(void);
/// Deallocate video hardware decoder.
extern void VideoDelHwDecoder(VideoHwDecoder *);
#ifdef LIBAVCODEC_VERSION
/// Get and allocate a video hardware surface.
extern unsigned VideoGetSurface(VideoHwDecoder *, const AVCodecContext *);
extern unsigned VideoGetSurface(VideoHwDecoder *);
/// Release a video hardware surface
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
#ifdef LIBAVCODEC_VERSION
/// Callback to negotiate the PixelFormat.
extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
const enum PixelFormat *);
@ -67,8 +63,8 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
const AVFrame *);
/// Get hwaccel context for ffmpeg.
extern void *VideoGetHwAccelContext(VideoHwDecoder *);
/// Get ffmpeg vaapi context.
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
#ifdef AVCODEC_VDPAU_H
/// Draw vdpau render state.
@ -114,16 +110,13 @@ extern void VideoSetSaturation(int);
extern void VideoSetHue(int);
/// Set video output position.
extern void VideoSetOutputPosition(VideoHwDecoder *, int, int, int, int);
extern void VideoSetOutputPosition(int, int, int, int);
/// Set video mode.
extern void VideoSetVideoMode(int, int, int, int);
/// Set 4:3 display format.
extern void VideoSet4to3DisplayFormat(int);
/// Set other display format.
extern void VideoSetOtherDisplayFormat(int);
/// Set display format.
extern void VideoSetDisplayFormat(int);
/// Set video fullscreen mode.
extern void VideoSetFullscreen(int);
@ -168,8 +161,7 @@ extern void VideoSetAutoCrop(int, int, int);
extern void VideoOsdClear(void);
/// Draw an OSD ARGB image.
extern void VideoOsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
int);
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
/// Get OSD size.
extern void VideoGetOsdSize(int *, int *);
@ -213,19 +205,8 @@ extern void VideoOsdExit(void); ///< Cleanup osd.
extern void VideoInit(const char *); ///< Setup video module.
extern void VideoExit(void); ///< Cleanup and exit video module.
/// Poll video input buffers.
extern int VideoPollInput(VideoStream *);
/// Decode video input buffers.
extern int VideoDecodeInput(VideoStream *);
/// Get number of input buffers.
extern int VideoGetBuffers(const VideoStream *);
/// Set DPMS at Blackscreen switch
extern void SetDPMSatBlackScreen(int);
/// Raise the frontend window
extern int VideoRaiseWindow(void);
extern int VideoPollInput(void); ///< Poll video input buffers.
extern int VideoDecodeInput(void); ///< Decode video input buffers.
extern int VideoGetBuffers(void); ///< Get number of input buffers.
/// @}