Compare commits

..

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

20 changed files with 1336 additions and 2618 deletions

152
ChangeLog
View File

@ -1,155 +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 User johns
Date: Sun Mar 17 15:52:42 CET 2013 Date: Sun Mar 17 15:52:42 CET 2013

122
Makefile
View File

@ -15,20 +15,14 @@ PLUGIN = softhddevice
ALSA ?= $(shell pkg-config --exists alsa && echo 1) ALSA ?= $(shell pkg-config --exists alsa && echo 1)
# support OSS audio output module # support OSS audio output module
OSS ?= 1 OSS ?= 1
# support VDPAU video output module # support VDPAU video output modue
VDPAU ?= $(shell pkg-config --exists vdpau && echo 1) VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
# support VA-API video output module (deprecated) # support VA-API video output modue
VAAPI ?= $(shell pkg-config --exists libva && echo 1) VAAPI ?= $(shell pkg-config --exists libva && echo 1)
# support glx output
OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
# screensaver disable/enable # screensaver disable/enable
SCREENSAVER ?= 1 SCREENSAVER ?= 1
# use ffmpeg libswresample # use ffmpeg libswresample
SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1) 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 := # -DDEBUG #-DOSD_DEBUG # enable debug output+functions
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level #CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
@ -38,58 +32,8 @@ CONFIG += -DUSE_PIP # PIP support
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np #CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser #CONFIG += -DNO_TS_AUDIO # disable ts audio parser
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser #CONFIG += -DUSE_TS_VIDEO # build new ts video parser
CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets #CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets
CONFIG += -DH264_EOS_TRICKSPEED # insert seq end packets for trickspeed #CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
#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)
### 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)
#
TMPDIR ?= /tmp
### The compiler options:
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)
### Allow user defined options to overwrite defaults:
-include $(PLGCFG)
### The name of the distribution archive:
ARCHIVE = $(PLUGIN)-$(VERSION)
PACKAGE = vdr-$(ARCHIVE)
### The name of the shared object file:
SOFILE = libvdr-$(PLUGIN).so
### Parse softhddevice config
ifeq ($(ALSA),1) ifeq ($(ALSA),1)
CONFIG += -DUSE_ALSA CONFIG += -DUSE_ALSA
@ -108,15 +52,6 @@ ifeq ($(VAAPI),1)
CONFIG += -DUSE_VAAPI CONFIG += -DUSE_VAAPI
_CFLAGS += $(shell pkg-config --cflags libva-x11 libva) _CFLAGS += $(shell pkg-config --cflags libva-x11 libva)
LIBS += $(shell pkg-config --libs 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 endif
ifeq ($(SCREENSAVER),1) ifeq ($(SCREENSAVER),1)
CONFIG += -DUSE_SCREENSAVER CONFIG += -DUSE_SCREENSAVER
@ -128,15 +63,54 @@ CONFIG += -DUSE_SWRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libswresample) _CFLAGS += $(shell pkg-config --cflags libswresample)
LIBS += $(shell pkg-config --libs libswresample) LIBS += $(shell pkg-config --libs libswresample)
endif endif
ifeq ($(AVRESAMPLE),1)
CONFIG += -DUSE_AVRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libavresample)
LIBS += $(shell pkg-config --libs libavresample)
endif
_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm) _CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm) LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
### 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)
### 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 --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg)
#
TMPDIR ?= /tmp
### The compiler options:
export CFLAGS = $(call PKGCFG,cflags)
export CXXFLAGS = $(call PKGCFG,cxxflags)
ifeq ($(CFLAGS),)
$(error CFLAGS not set)
endif
ifeq ($(CXXFLAGS),)
$(error CXXFLAGS not set)
endif
### The version number of VDR's plugin API:
APIVERSION = $(call PKGCFG,apiversion)
### Allow user defined options to overwrite defaults:
-include $(PLGCFG)
### The name of the distribution archive:
ARCHIVE = $(PLUGIN)-$(VERSION)
PACKAGE = vdr-$(ARCHIVE)
### The name of the shared object file:
SOFILE = libvdr-$(PLUGIN).so
### Includes and Defines (add further entries here): ### Includes and Defines (add further entries here):
INCLUDES += INCLUDES +=

188
Makefile-pre1.7.36 Normal file
View File

@ -0,0 +1,188 @@
#
# Makefile for a Video Disk Recorder plugin
#
# $Id$
# 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
### 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 += -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
# use ffmpeg libswresample
CONFIG += $(shell pkg-config --exists libswresample && echo "-DUSE_SWRESAMPLE")
CONFIG += -DUSE_SCREENSAVER # use functions to disable screensaver
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 -fPIC
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Werror=overloaded-virtual -fPIC
### The directory environment:
VDRDIR ?= ../../..
LIBDIR ?= ../../lib
TMPDIR ?= /tmp
### Make sure that necessary options are included:
-include $(VDRDIR)/Make.global
### Allow user defined options to overwrite defaults:
-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)
### Includes, Defines and dependencies (add further entries here):
INCLUDES += -I$(VDRDIR)/include
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' \
$(if $(GIT_REV), -DGIT_REV='"$(GIT_REV)"')
_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_SWRESAMPLE,$(CONFIG)), \
$(shell pkg-config --cflags libswresample)) \
$(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) \
`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_SWRESAMPLE,$(CONFIG)), \
$(shell pkg-config --libs libswresample)) \
$(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: libvdr-$(PLUGIN).so i18n
### Implicit rules:
#
#%.o: %.cpp
# $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
### Dependencies:
MAKEDEP = $(CC) -MM -MG
DEPFILE = .dependencies
$(DEPFILE): Makefile
@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(SRCS) >$@
$(OBJS): Makefile
-include $(DEPFILE)
### Internationalization (I18N):
PODIR = po
LOCALEDIR = $(VDRDIR)/locale
I18Npo = $(wildcard $(PODIR)/*.po)
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): $(wildcard *.cpp) $(wildcard *.c)
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP \
-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 $@ $<
@touch $@
$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
@mkdir -p $(dir $@)
cp $< $@
.PHONY: i18n
i18n: $(I18Nmsgs) $(I18Npot)
### Targets:
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)
@mkdir $(TMPDIR)/$(ARCHIVE)
@cp -a * $(TMPDIR)/$(ARCHIVE)
@tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
@-rm -rf $(TMPDIR)/$(ARCHIVE)
@echo Distribution package created as $(PACKAGE).tgz
clean:
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
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; \
done
video_test: video.c Makefile
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
-o $@

View File

@ -20,14 +20,14 @@ $Id$
A software and GPU emulated HD output device plugin for VDR. A software and GPU emulated HD output device plugin for VDR.
o Video decoder CPU / VDPAU o Video decoder CPU / VA-API / VDPAU
o Video output VDPAU o Video output VA-API / VDPAU
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 HDMI/SPDIF pass-through o HDMI/SPDIF pass-through
o Software volume, compression, normalize and channel resample o Software volume, compression, normalize and channel resample
o VDR ScaleVideo API o YaepgHD support / new >1.7.33 VDR ScaleVideo API support
o Software deinterlacer Bob (VA-API only) o Software deinterlacer Bob (VA-API only)
o Autocrop o Autocrop
o Grab image (VDPAU only) o Grab image (VDPAU only)
@ -36,11 +36,10 @@ A software and GPU emulated HD output device plugin for VDR.
o atmo light support with plugin http://github.com/durchflieger/DFAtmo o atmo light support with plugin http://github.com/durchflieger/DFAtmo
o PIP (Picture-in-Picture) (VDPAU only) o PIP (Picture-in-Picture) (VDPAU only)
o planned: Remove VA-API decoder and output support o planned: Video decoder VA-API Branch: vaapi-ext/staging
o planned: Video decoder OpenMax o planned: Video output XvBA / Opengl / Xv
o planned: Video output Opengl / Xv o planned: VA-API grab image
o planned: Improved software deinterlacer (yadif or/and ffmpeg filters) o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
o XvBa support is no longer planned (use future Radeon UVD VDPAU)
To compile you must have the 'requires' installed. To compile you must have the 'requires' installed.
@ -84,12 +83,14 @@ Setup: environment
if set don't use the hardware decoders if set don't use the hardware decoders
NO_MPEG_HW=1 NO_MPEG_HW=1
if set don't use the hardware decoder for mpeg1/2 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 only if alsa is configured
ALSA_DEVICE=default ALSA_DEVICE=default
alsa PCM device name alsa PCM device name
ALSA_PASSTHROUGH_DEVICE= ALSA_PASSTHROUGH_DEVICE=
alsa pass-though (AC-3,E-AC-3,DTS,...) device name alsa pass-though (AC3,EAC3,DTS,...) device name
ALSA_MIXER=default ALSA_MIXER=default
alsa control device name alsa control device name
ALSA_MIXER_CHANNEL=PCM ALSA_MIXER_CHANNEL=PCM
@ -99,7 +100,7 @@ Setup: environment
OSS_AUDIODEV=/dev/dsp OSS_AUDIODEV=/dev/dsp
oss dsp device name oss dsp device name
OSS_PASSTHROUGHDEV= OSS_PASSTHROUGHDEV=
oss pass-though (AC-3,E-AC-3,DTS,...) device name oss pass-though (AC3,EAC3,DTS,...) device name
OSS_MIXERDEV=/dev/mixer OSS_MIXERDEV=/dev/mixer
oss mixer device name oss mixer device name
OSS_MIXER_CHANNEL=pcm OSS_MIXER_CHANNEL=pcm
@ -129,7 +130,7 @@ Setup: /etc/vdr/setup.conf
softhddevice.<res>.Deinterlace = 0 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, 4 supported with VA-API) (only 0, 1 supported with vaapi)
softhddevice.<res>.SkipChromaDeinterlace = 0 softhddevice.<res>.SkipChromaDeinterlace = 0
0 = disabled, 1 = enabled (for slower cards, poor qualität) 0 = disabled, 1 = enabled (for slower cards, poor qualität)
@ -233,10 +234,6 @@ Setup: /etc/vdr/setup.conf
0 disable black picture during channel switch 0 disable black picture during channel switch
1 enable 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 softhddevice.Video4to3DisplayFormat = 1
0 pan and scan 0 pan and scan
1 letter box 1 letter box
@ -321,7 +318,6 @@ Keymacros:
@softhddevice Blue 1 2 toggle pass-through @softhddevice Blue 1 2 toggle pass-through
@softhddevice Blue 1 3 decrease audio delay by 10ms @softhddevice Blue 1 3 decrease audio delay by 10ms
@softhddevice Blue 1 4 increase 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 0 disable fullscreen
@softhddevice Blue 2 1 enable fullscreen @softhddevice Blue 2 1 enable fullscreen
@softhddevice Blue 2 2 toggle fullscreen @softhddevice Blue 2 2 toggle fullscreen
@ -357,7 +353,7 @@ Requires:
media-video/ffmpeg (version >=0.7) media-video/ffmpeg (version >=0.7)
Complete solution to record, convert and stream audio and Complete solution to record, convert and stream audio and
video. Includes libavcodec and libswresample. video. Includes libavcodec.
http://ffmpeg.org http://ffmpeg.org
media-libs/alsa-lib media-libs/alsa-lib
Advanced Linux Sound Architecture Library Advanced Linux Sound Architecture Library
@ -365,7 +361,7 @@ Requires:
or or
kernel support for oss/oss4 or alsa oss emulation kernel support for oss/oss4 or alsa oss emulation
x11-libs/libva (deprecated) x11-libs/libva
Video Acceleration (VA) API for Linux Video Acceleration (VA) API for Linux
http://www.freedesktop.org/wiki/Software/vaapi http://www.freedesktop.org/wiki/Software/vaapi
x11-libs/libva-intel-driver x11-libs/libva-intel-driver

10
Todo
View File

@ -1,6 +1,6 @@
@file Todo @brief A software HD output device for VDR @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): Contributor(s):
@ -19,9 +19,6 @@ GNU Affero General Public License for more details.
$Id: $ $Id: $
missing: missing:
documentation of the PIP hotkeys.
svdrp help page missing PIP hotkeys.
svdrp stat: add X11 crashed status.
more software deinterlace (yadif, ...) more software deinterlace (yadif, ...)
more software decoder with software deinterlace more software decoder with software deinterlace
suspend output / energie saver: stop and restart X11 suspend output / energie saver: stop and restart X11
@ -43,15 +40,11 @@ video:
check start with 24Hz display rate check start with 24Hz display rate
crash with ffmpeg without vaapi and vdpau. crash with ffmpeg without vaapi and vdpau.
still-picture of PES recordings should use VideoMpegEnqueue. 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: vdpau:
software deinterlace path not working. software deinterlace path not working.
OSD looses transparency, during channel switch. OSD looses transparency, during channel switch.
OSD looses transparency, while moving cut marks. OSD looses transparency, while moving cut marks.
ffmpeg >=1.2 supports same API like VA-API.
libva: libva:
yaepghd (VaapiSetOutputPosition) support yaepghd (VaapiSetOutputPosition) support
@ -128,7 +121,6 @@ unsorted:
svdrp prim: support plugin names for device numbers. svdrp prim: support plugin names for device numbers.
Workaround exists: hangup PipVideoStream -> Vdpau_get_format -> xcb -> poll Workaround exists: hangup PipVideoStream -> Vdpau_get_format -> xcb -> poll
+ lock DecoderLockMutex + lock DecoderLockMutex
check compiletime and runtime ffmpeg/libav version during init.
future features (not planed for 1.0 - 1.5) future features (not planed for 1.0 - 1.5)

178
audio.c
View File

@ -1,7 +1,7 @@
/// ///
/// @file audio.c @brief Audio module /// @file audio.c @brief Audio module
/// ///
/// Copyright (c) 2009 - 2014 by Johns. All Rights Reserved. /// Copyright (c) 2009 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -88,7 +88,7 @@
#endif #endif
#endif #endif
#include "iatomic.h" // portable atomic_t #include <alsa/iatomic.h> // portable atomic_t
#include "ringbuffer.h" #include "ringbuffer.h"
#include "misc.h" #include "misc.h"
@ -123,8 +123,6 @@ static const AudioModule NoopModule; ///< forward definition of noop module
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
char AudioAlsaDriverBroken; ///< disable broken driver message 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 static const char *AudioModuleName; ///< which audio module to use
@ -132,7 +130,6 @@ static const char *AudioModuleName; ///< which audio module to use
static const AudioModule *AudioUsedModule = &NoopModule; static const AudioModule *AudioUsedModule = &NoopModule;
static const char *AudioPCMDevice; ///< PCM device name static const char *AudioPCMDevice; ///< PCM device name
static const char *AudioPassthroughDevice; ///< Passthrough device name static const char *AudioPassthroughDevice; ///< Passthrough device name
static char AudioAppendAES; ///< flag automatic append AES
static const char *AudioMixerDevice; ///< mixer device name static const char *AudioMixerDevice; ///< mixer device name
static const char *AudioMixerChannel; ///< mixer channel name static const char *AudioMixerChannel; ///< mixer channel name
static char AudioDoingInit; ///> flag in init, reduce error static char AudioDoingInit; ///> flag in init, reduce error
@ -149,7 +146,6 @@ static int AudioBufferTime = 336; ///< audio buffer time in ms
static pthread_t AudioThread; ///< audio play thread static pthread_t AudioThread; ///< audio play thread
static pthread_mutex_t AudioMutex; ///< audio condition mutex static pthread_mutex_t AudioMutex; ///< audio condition mutex
static pthread_cond_t AudioStartCond; ///< condition variable static pthread_cond_t AudioStartCond; ///< condition variable
static char AudioThreadStop; ///< stop audio thread
#else #else
static const int AudioThread; ///< dummy audio thread static const int AudioThread; ///< dummy audio thread
#endif #endif
@ -490,7 +486,7 @@ static void AudioSurround2Stereo(const int16_t * in, int in_chan, int frames,
r += in[3] * 200; // Rs r += in[3] * 200; // Rs
l += in[4] * 300; // C l += in[4] * 300; // C
r += in[4] * 300; r += in[4] * 300;
l += in[5] * 100; // LFE l += in[5] * 300; // LFE
r += in[5] * 100; r += in[5] * 100;
break; break;
case 7: // 7.0 case 7: // 7.0
@ -624,7 +620,7 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
typedef struct _audio_ring_ring_ typedef struct _audio_ring_ring_
{ {
char FlushBuffers; ///< flag: flush buffers char FlushBuffers; ///< flag: flush buffers
char Passthrough; ///< flag: use pass-through (AC-3, ...) char Passthrough; ///< flag: use pass-through (AC3, ...)
int16_t PacketSize; ///< packet size int16_t PacketSize; ///< packet size
unsigned HwSampleRate; ///< hardware sample rate in Hz unsigned HwSampleRate; ///< hardware sample rate in Hz
unsigned HwChannels; ///< hardware number of channels unsigned HwChannels; ///< hardware number of channels
@ -646,7 +642,7 @@ static unsigned AudioStartThreshold; ///< start play, if filled
** **
** @param sample_rate sample-rate frequency ** @param sample_rate sample-rate frequency
** @param channels number of channels ** @param channels number of channels
** @param passthrough use /pass-through (AC-3, ...) device ** @param passthrough use /pass-through (AC3, ...) device
** **
** @retval -1 error ** @retval -1 error
** @retval 0 okay ** @retval 0 okay
@ -682,7 +678,8 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
} }
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX; AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
AudioRing[AudioRingWrite].FlushBuffers = 0; // FIXME: don't flush buffers here
AudioRing[AudioRingWrite].FlushBuffers = 1;
AudioRing[AudioRingWrite].Passthrough = passthrough; AudioRing[AudioRingWrite].Passthrough = passthrough;
AudioRing[AudioRingWrite].PacketSize = 0; AudioRing[AudioRingWrite].PacketSize = 0;
AudioRing[AudioRingWrite].InSampleRate = sample_rate; AudioRing[AudioRingWrite].InSampleRate = sample_rate;
@ -692,9 +689,6 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
AudioRing[AudioRingWrite].PTS = INT64_C(0x8000000000000000); AudioRing[AudioRingWrite].PTS = INT64_C(0x8000000000000000);
RingBufferReset(AudioRing[AudioRingWrite].RingBuffer); RingBufferReset(AudioRing[AudioRingWrite].RingBuffer);
Debug(3, "audio: %d ring buffer prepared\n",
atomic_read(&AudioRingFilled) + 1);
atomic_inc(&AudioRingFilled); atomic_inc(&AudioRingFilled);
#ifdef USE_AUDIO_THREAD #ifdef USE_AUDIO_THREAD
@ -842,7 +836,7 @@ static int AlsaPlayRingbuffer(void)
if (!avail) { // full or buffer empty if (!avail) { // full or buffer empty
break; break;
} }
// muting pass-through AC-3, can produce disturbance // muting pass-through ac3, can produce disturbance
if (AudioMute || (AudioSoftVolume if (AudioMute || (AudioSoftVolume
&& !AudioRing[AudioRingRead].Passthrough)) { && !AudioRing[AudioRingRead].Passthrough)) {
// FIXME: quick&dirty cast // FIXME: quick&dirty cast
@ -943,6 +937,7 @@ static int AlsaThread(void)
return -1; return -1;
} }
for (;;) { for (;;) {
pthread_testcancel();
if (AudioPaused) { if (AudioPaused) {
return 1; return 1;
} }
@ -990,7 +985,7 @@ static int AlsaThread(void)
/** /**
** Open alsa pcm device. ** Open alsa pcm device.
** **
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
*/ */
static snd_pcm_t *AlsaOpenPCM(int passthrough) static snd_pcm_t *AlsaOpenPCM(int passthrough)
{ {
@ -1008,26 +1003,6 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough)
Info(_("audio/alsa: using %sdevice '%s'\n"), Info(_("audio/alsa: using %sdevice '%s'\n"),
passthrough ? "pass-through " : "", device); 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
}
// open none blocking; if device is already used, we don't want wait // open none blocking; if device is already used, we don't want wait
if ((err = if ((err =
snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK,
@ -1193,7 +1168,7 @@ static int64_t AlsaGetDelay(void)
** **
** @param freq sample frequency ** @param freq sample frequency
** @param channels number of channels ** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
** **
** @retval 0 everything ok ** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination ** @retval 1 didn't support frequency/channels combination
@ -1212,23 +1187,17 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
// FIXME: if open fails for fe. pass-through, we never recover // FIXME: if open fails for fe. pass-through, we never recover
return -1; 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; snd_pcm_t *handle;
handle = AlsaPCMHandle; handle = AlsaPCMHandle;
// no lock needed, thread exit in main loop only // FIXME: need lock
//Debug(3, "audio: %s [\n", __FUNCTION__);
AlsaPCMHandle = NULL; // other threads should check handle AlsaPCMHandle = NULL; // other threads should check handle
snd_pcm_close(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(passthrough))) {
return -1; return -1;
} }
AlsaPCMHandle = handle; AlsaPCMHandle = handle;
//Debug(3, "audio: %s ]\n", __FUNCTION__);
} }
for (;;) { for (;;) {
@ -1237,29 +1206,21 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
AlsaUseMmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED : AlsaUseMmap ? SND_PCM_ACCESS_MMAP_INTERLEAVED :
SND_PCM_ACCESS_RW_INTERLEAVED, *channels, *freq, 1, SND_PCM_ACCESS_RW_INTERLEAVED, *channels, *freq, 1,
96 * 1000))) { 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 ) { if ( err == -EBADFD ) {
snd_pcm_close(AlsaPCMHandle); snd_pcm_close(AlsaPCMHandle);
AlsaPCMHandle = NULL; AlsaPCMHandle = NULL;
continue; continue;
} }
*/ */
if (!AudioDoingInit) { if (!AudioDoingInit) {
Error(_("audio/alsa: set params error: %s\n"), Error(_("audio/alsa: set params error: %s\n"),
snd_strerror(err)); snd_strerror(err));
}
// FIXME: must stop sound, AudioChannels ... invalid
return -1;
} }
// FIXME: must stop sound, AudioChannels ... invalid
return -1;
} }
break; break;
} }
@ -1558,6 +1519,7 @@ static int OssThread(void)
for (;;) { for (;;) {
struct pollfd fds[1]; struct pollfd fds[1];
pthread_testcancel();
if (AudioPaused) { if (AudioPaused) {
return 1; return 1;
} }
@ -1599,7 +1561,7 @@ static int OssThread(void)
/** /**
** Open OSS pcm device. ** Open OSS pcm device.
** **
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
*/ */
static int OssOpenPCM(int passthrough) static int OssOpenPCM(int passthrough)
{ {
@ -1763,7 +1725,7 @@ static int64_t OssGetDelay(void)
** **
** @param sample_rate sample rate/frequency ** @param sample_rate sample rate/frequency
** @param channels number of channels ** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
** **
** @retval 0 everything ok ** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination ** @retval 1 didn't support frequency/channels combination
@ -1781,7 +1743,7 @@ static int OssSetup(int *sample_rate, int *channels, int passthrough)
return -1; return -1;
} }
if (1) { // close+open for pcm / AC-3 if (1) { // close+open for pcm / ac3
int fildes; int fildes;
fildes = OssPcmFildes; fildes = OssPcmFildes;
@ -1970,7 +1932,7 @@ static void NoopSetVolume( __attribute__ ((unused))
** **
** @param freq sample frequency ** @param freq sample frequency
** @param channels number of channels ** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
*/ */
static int NoopSetup( __attribute__ ((unused)) static int NoopSetup( __attribute__ ((unused))
int *channels, __attribute__ ((unused)) int *channels, __attribute__ ((unused))
@ -2059,12 +2021,6 @@ static void *AudioPlayHandlerThread(void *dummy)
{ {
Debug(3, "audio: play thread started\n"); Debug(3, "audio: play thread started\n");
for (;;) { 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"); Debug(3, "audio: wait on start condition\n");
pthread_mutex_lock(&AudioMutex); pthread_mutex_lock(&AudioMutex);
AudioRunning = 0; AudioRunning = 0;
@ -2075,42 +2031,35 @@ static void *AudioPlayHandlerThread(void *dummy)
pthread_mutex_unlock(&AudioMutex); pthread_mutex_unlock(&AudioMutex);
Debug(3, "audio: ----> %dms start\n", (AudioUsedBytes() * 1000) Debug(3, "audio: ----> %dms start\n", (AudioUsedBytes() * 1000)
/ (!AudioRing[AudioRingWrite].HwSampleRate + / (!AudioRing[AudioRingRead].HwSampleRate +
!AudioRing[AudioRingWrite].HwChannels + !AudioRing[AudioRingRead].HwChannels +
AudioRing[AudioRingWrite].HwSampleRate * AudioRing[AudioRingRead].HwSampleRate *
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample)); AudioRing[AudioRingRead].HwChannels * AudioBytesProSample));
do { do {
int filled; int filled;
int read; int read;
int flush; int flush;
int err; 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 // look if there is a flush command in the queue
flush = 0; flush = 0;
filled = atomic_read(&AudioRingFilled); filled = atomic_read(&AudioRingFilled);
read = AudioRingRead; read = AudioRingRead;
i = filled; while (filled--) {
while (i--) {
read = (read + 1) % AUDIO_RING_MAX; read = (read + 1) % AUDIO_RING_MAX;
if (AudioRing[read].FlushBuffers) { if (AudioRing[read].FlushBuffers) {
AudioRing[read].FlushBuffers = 0; AudioRing[read].FlushBuffers = 0;
AudioRingRead = read; AudioRingRead = read;
atomic_set(&AudioRingFilled, filled);
// handle all flush in queue // handle all flush in queue
flush = filled - i; flush = 1;
} }
} }
if (flush) { if (flush) {
Debug(3, "audio: flush %d ring buffer(s)\n", flush); Debug(3, "audio: flush\n");
AudioUsedModule->FlushBuffers(); AudioUsedModule->FlushBuffers();
atomic_sub(flush, &AudioRingFilled);
if (AudioNextRing()) { if (AudioNextRing()) {
Debug(3, "audio: break after flush\n"); Debug(3, "audio: break after flush\n");
break; break;
@ -2118,10 +2067,7 @@ static void *AudioPlayHandlerThread(void *dummy)
Debug(3, "audio: continue after flush\n"); Debug(3, "audio: continue after flush\n");
} }
// try to play some samples // try to play some samples
err = 0; err = AudioUsedModule->Thread();
if (RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer)) {
err = AudioUsedModule->Thread();
}
// underrun, check if new ring buffer is available // underrun, check if new ring buffer is available
if (!err) { if (!err) {
int passthrough; int passthrough;
@ -2176,7 +2122,6 @@ static void *AudioPlayHandlerThread(void *dummy)
*/ */
static void AudioInitThread(void) static void AudioInitThread(void)
{ {
AudioThreadStop = 0;
pthread_mutex_init(&AudioMutex, NULL); pthread_mutex_init(&AudioMutex, NULL);
pthread_cond_init(&AudioStartCond, NULL); pthread_cond_init(&AudioStartCond, NULL);
pthread_create(&AudioThread, NULL, AudioPlayHandlerThread, NULL); pthread_create(&AudioThread, NULL, AudioPlayHandlerThread, NULL);
@ -2190,12 +2135,10 @@ static void AudioExitThread(void)
{ {
void *retval; void *retval;
Debug(3, "audio: %s\n", __FUNCTION__);
if (AudioThread) { if (AudioThread) {
AudioThreadStop = 1; if (pthread_cancel(AudioThread)) {
AudioRunning = 1; // wakeup thread, if needed Error(_("audio: can't queue cancel play thread\n"));
pthread_cond_signal(&AudioStartCond); }
if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) { if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) {
Error(_("audio: can't cancel play thread\n")); Error(_("audio: can't cancel play thread\n"));
} }
@ -2473,22 +2416,6 @@ void AudioFlushBuffers(void)
int old; int old;
int i; 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; old = AudioRingWrite;
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX; AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
AudioRing[AudioRingWrite].FlushBuffers = 1; AudioRing[AudioRingWrite].FlushBuffers = 1;
@ -2506,13 +2433,12 @@ void AudioFlushBuffers(void)
atomic_inc(&AudioRingFilled); atomic_inc(&AudioRingFilled);
// FIXME: wait for flush complete needed? // FIXME: wait for flush complete?
for (i = 0; i < 24 * 2; ++i) { for (i = 0; i < 24 * 2; ++i) {
if (!AudioRunning) { // wakeup thread to flush buffers if (!AudioRunning) { // wakeup thread to flush buffers
AudioRunning = 1; AudioRunning = 1;
pthread_cond_signal(&AudioStartCond); pthread_cond_signal(&AudioStartCond);
} }
// FIXME: waiting on zero isn't correct, but currently works
if (!atomic_read(&AudioRingFilled)) { if (!atomic_read(&AudioRingFilled)) {
break; break;
} }
@ -2644,7 +2570,7 @@ void AudioSetVolume(int volume)
** **
** @param freq sample frequency ** @param freq sample frequency
** @param channels number of channels ** @param channels number of channels
** @param passthrough use pass-through (AC-3, ...) device ** @param passthrough use pass-through (AC3, ...) device
** **
** @retval 0 everything ok ** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination ** @retval 1 didn't support frequency/channels combination
@ -2824,20 +2750,6 @@ void AudioSetChannel(const char *channel)
AudioMixerChannel = 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. ** Initialize audio output module.
** **
@ -3017,8 +2929,6 @@ void AudioExit(void)
{ {
const AudioModule *module; const AudioModule *module;
Debug(3, "audio: %s\n", __FUNCTION__);
#ifdef USE_AUDIO_THREAD #ifdef USE_AUDIO_THREAD
if (AudioUsedModule->Thread) { // supports threads if (AudioUsedModule->Thread) { // supports threads
AudioExitThread(); AudioExitThread();

View File

@ -1,7 +1,7 @@
/// ///
/// @file audio.h @brief Audio module headerfile /// @file audio.h @brief Audio module headerfile
/// ///
/// Copyright (c) 2009 - 2014 by Johns. All Rights Reserved. /// Copyright (c) 2009 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -52,7 +52,6 @@ extern void AudioSetDevice(const char *); ///< set PCM audio device
/// set pass-through device /// set pass-through device
extern void AudioSetPassthroughDevice(const char *); extern void AudioSetPassthroughDevice(const char *);
extern void AudioSetChannel(const char *); ///< set mixer channel 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 AudioInit(void); ///< setup audio module
extern void AudioExit(void); ///< cleanup and exit audio module extern void AudioExit(void); ///< cleanup and exit audio module
@ -61,7 +60,5 @@ extern void AudioExit(void); ///< cleanup and exit audio module
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
extern char AudioAlsaDriverBroken; ///< disable broken driver message extern char AudioAlsaDriverBroken; ///< disable broken driver message
extern char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
/// @} /// @}

305
codec.c
View File

@ -1,7 +1,7 @@
/// ///
/// @file codec.c @brief Codec functions /// @file codec.c @brief Codec functions
/// ///
/// Copyright (c) 2009 - 2015 by Johns. All Rights Reserved. /// Copyright (c) 2009 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -38,12 +38,8 @@
#define USE_AC3_DRIFT_CORRECTION #define USE_AC3_DRIFT_CORRECTION
/// use ffmpeg libswresample API (autodected, Makefile) /// use ffmpeg libswresample API (autodected, Makefile)
#define noUSE_SWRESAMPLE #define noUSE_SWRESAMPLE
/// use libav libavresample API (autodected, Makefile)
#define noUSE_AVRESAMPLE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#include <sys/endian.h> #include <sys/endian.h>
@ -58,16 +54,8 @@
#define _(str) gettext(str) ///< gettext shortcut #define _(str) gettext(str) ///< gettext shortcut
#define _N(str) str ///< gettext_noop shortcut #define _N(str) str ///< gettext_noop shortcut
#include <alsa/iatomic.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavutil/mem.h>
// support old ffmpeg versions <1.0
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
#define AVCodecID CodecID
#define AV_CODEC_ID_AC3 CODEC_ID_AC3
#define AV_CODEC_ID_EAC3 CODEC_ID_EAC3
#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
#define AV_CODEC_ID_H264 CODEC_ID_H264
#endif
#include <libavcodec/vaapi.h> #include <libavcodec/vaapi.h>
#ifdef USE_VDPAU #ifdef USE_VDPAU
#include <libavcodec/vdpau.h> #include <libavcodec/vdpau.h>
@ -75,10 +63,6 @@
#ifdef USE_SWRESAMPLE #ifdef USE_SWRESAMPLE
#include <libswresample/swresample.h> #include <libswresample/swresample.h>
#endif #endif
#ifdef USE_AVRESAMPLE
#include <libavresample/avresample.h>
#include <libavutil/opt.h>
#endif
#ifndef __USE_GNU #ifndef __USE_GNU
#define __USE_GNU #define __USE_GNU
@ -88,22 +72,11 @@
#ifdef MAIN_H #ifdef MAIN_H
#include MAIN_H #include MAIN_H
#endif #endif
#include "iatomic.h"
#include "misc.h" #include "misc.h"
#include "video.h" #include "video.h"
#include "audio.h" #include "audio.h"
#include "codec.h" #include "codec.h"
//----------------------------------------------------------------------------
// correct is AV_VERSION_INT(56,35,101) but some gentoo i* think
// they must change it.
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,26,100)
/// ffmpeg 2.6 started to show artifacts after channel switch
/// to SDTV channels
#define FFMPEG_WORKAROUND_ARTIFACTS 1
#endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Global // Global
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -116,9 +89,6 @@
/// ///
static pthread_mutex_t CodecLockMutex; static pthread_mutex_t CodecLockMutex;
/// Flag prefer fast channel switch
char CodecUsePossibleDefectFrames;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Video // Video
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -140,9 +110,6 @@ struct _video_decoder_
int GetFormatDone; ///< flag get format called! int GetFormatDone; ///< flag get format called!
AVCodec *VideoCodec; ///< video codec AVCodec *VideoCodec; ///< video codec
AVCodecContext *VideoCtx; ///< video codec context AVCodecContext *VideoCtx; ///< video codec context
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
int FirstKeyFrame; ///< flag first frame
#endif
AVFrame *Frame; ///< decoded video frame AVFrame *Frame; ///< decoded video frame
}; };
@ -227,9 +194,7 @@ static int Codec_get_buffer(AVCodecContext * video_ctx, AVFrame * frame)
//Debug(3, "codec: use surface %#010x\n", surface); //Debug(3, "codec: use surface %#010x\n", surface);
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,48,101)
frame->type = FF_BUFFER_TYPE_USER; frame->type = FF_BUFFER_TYPE_USER;
#endif
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,46,0) #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,46,0)
frame->age = 256 * 256 * 256 * 64; frame->age = 256 * 256 * 256 * 64;
#endif #endif
@ -239,14 +204,12 @@ static int Codec_get_buffer(AVCodecContext * video_ctx, AVFrame * frame)
frame->data[2] = NULL; frame->data[2] = NULL;
frame->data[3] = NULL; frame->data[3] = NULL;
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,66,100)
// reordered frames // reordered frames
if (video_ctx->pkt) { if (video_ctx->pkt) {
frame->pkt_pts = video_ctx->pkt->pts; frame->pkt_pts = video_ctx->pkt->pts;
} else { } else {
frame->pkt_pts = AV_NOPTS_VALUE; frame->pkt_pts = AV_NOPTS_VALUE;
} }
#endif
return 0; return 0;
} }
#endif #endif
@ -258,9 +221,7 @@ static int Codec_get_buffer(AVCodecContext * video_ctx, AVFrame * frame)
//Debug(3, "codec: use surface %#010x\n", surface); //Debug(3, "codec: use surface %#010x\n", surface);
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,48,101)
frame->type = FF_BUFFER_TYPE_USER; frame->type = FF_BUFFER_TYPE_USER;
#endif
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,46,0) #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,46,0)
frame->age = 256 * 256 * 256 * 64; frame->age = 256 * 256 * 256 * 64;
#endif #endif
@ -268,14 +229,12 @@ static int Codec_get_buffer(AVCodecContext * video_ctx, AVFrame * frame)
frame->data[0] = (void *)(size_t) surface; frame->data[0] = (void *)(size_t) surface;
frame->data[3] = (void *)(size_t) surface; frame->data[3] = (void *)(size_t) surface;
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,66,100)
// reordered frames // reordered frames
if (video_ctx->pkt) { if (video_ctx->pkt) {
frame->pkt_pts = video_ctx->pkt->pts; frame->pkt_pts = video_ctx->pkt->pts;
} else { } else {
frame->pkt_pts = AV_NOPTS_VALUE; frame->pkt_pts = AV_NOPTS_VALUE;
} }
#endif
return 0; return 0;
} }
//Debug(3, "codec: fallback to default get_buffer\n"); //Debug(3, "codec: fallback to default get_buffer\n");
@ -420,39 +379,22 @@ void CodecVideoDelDecoder(VideoDecoder * decoder)
** Open video decoder. ** Open video decoder.
** **
** @param decoder private video decoder ** @param decoder private video decoder
** @param codec_id video codec id ** @param name video codec name
** @param codec_id video codec id, used if name == NULL
*/ */
void CodecVideoOpen(VideoDecoder * decoder, int codec_id) void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
{ {
AVCodec *video_codec; AVCodec *video_codec;
const char *name;
Debug(3, "codec: using video codec ID %#06x (%s)\n", codec_id, Debug(3, "codec: using video codec %s or ID %#06x\n", name, codec_id);
avcodec_get_name(codec_id));
if (decoder->VideoCtx) { if (decoder->VideoCtx) {
Error(_("codec: missing close\n")); Error(_("codec: missing close\n"));
} }
#if 1
// FIXME: old vdpau API: should be updated to new API
name = NULL;
if (!strcasecmp(VideoGetDriverName(), "vdpau")) {
switch (codec_id) {
case AV_CODEC_ID_MPEG2VIDEO:
name = VideoHardwareDecoder < 0 ? "mpegvideo_vdpau" : NULL;
break;
case AV_CODEC_ID_H264:
name = VideoHardwareDecoder ? "h264_vdpau" : NULL;
break;
}
}
if (name && (video_codec = avcodec_find_decoder_by_name(name))) { if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
Debug(3, "codec: vdpau decoder found\n"); Debug(3, "codec: vdpau decoder found\n");
} else } else if (!(video_codec = avcodec_find_decoder(codec_id))) {
#endif
if (!(video_codec = avcodec_find_decoder(codec_id))) {
Fatal(_("codec: codec ID %#06x not found\n"), codec_id); Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
// FIXME: none fatal // FIXME: none fatal
} }
@ -491,8 +433,8 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
decoder->VideoCtx->opaque = decoder; // our structure decoder->VideoCtx->opaque = decoder; // our structure
Debug(3, "codec: video '%s'\n", decoder->VideoCodec->long_name); Debug(3, "codec: video '%s'\n", decoder->VideoCtx->codec_name);
if (codec_id == AV_CODEC_ID_H264) { if (codec_id == CODEC_ID_H264) {
// 2.53 Ghz CPU is too slow for this codec at 1080i // 2.53 Ghz CPU is too slow for this codec at 1080i
//decoder->VideoCtx->skip_loop_filter = AVDISCARD_ALL; //decoder->VideoCtx->skip_loop_filter = AVDISCARD_ALL;
//decoder->VideoCtx->skip_loop_filter = AVDISCARD_BIDIR; //decoder->VideoCtx->skip_loop_filter = AVDISCARD_BIDIR;
@ -534,7 +476,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
} else { } else {
decoder->VideoCtx->get_format = Codec_get_format; decoder->VideoCtx->get_format = Codec_get_format;
decoder->VideoCtx->hwaccel_context = decoder->VideoCtx->hwaccel_context =
VideoGetHwAccelContext(decoder->HwDecoder); VideoGetVaapiContext(decoder->HwDecoder);
} }
// our pixel format video hardware decoder hook // our pixel format video hardware decoder hook
@ -554,20 +496,11 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
// //
// Prepare frame buffer for decoder // Prepare frame buffer for decoder
// //
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
if (!(decoder->Frame = av_frame_alloc())) {
Fatal(_("codec: can't allocate video decoder frame buffer\n"));
}
#else
if (!(decoder->Frame = avcodec_alloc_frame())) { if (!(decoder->Frame = avcodec_alloc_frame())) {
Fatal(_("codec: can't allocate video decoder frame buffer\n")); Fatal(_("codec: can't allocate decoder frame\n"));
} }
#endif
// reset buggy ffmpeg/libav flag // reset buggy ffmpeg/libav flag
decoder->GetFormatDone = 0; decoder->GetFormatDone = 0;
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
decoder->FirstKeyFrame = 1;
#endif
} }
/** /**
@ -578,17 +511,12 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
void CodecVideoClose(VideoDecoder * video_decoder) void CodecVideoClose(VideoDecoder * video_decoder)
{ {
// FIXME: play buffered data // FIXME: play buffered data
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
av_frame_free(&video_decoder->Frame); // callee does checks
#else
av_freep(&video_decoder->Frame); av_freep(&video_decoder->Frame);
#endif
if (video_decoder->VideoCtx) { if (video_decoder->VideoCtx) {
pthread_mutex_lock(&CodecLockMutex); pthread_mutex_lock(&CodecLockMutex);
avcodec_close(video_decoder->VideoCtx); avcodec_close(video_decoder->VideoCtx);
av_freep(&video_decoder->VideoCtx);
pthread_mutex_unlock(&CodecLockMutex); pthread_mutex_unlock(&CodecLockMutex);
av_freep(&video_decoder->VideoCtx);
} }
} }
@ -659,22 +587,8 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
} }
if (got_frame) { // frame completed if (got_frame) { // frame completed
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
decoder->FirstKeyFrame++;
if (frame->key_frame) {
Debug(3, "codec: key frame after %d frames\n",
decoder->FirstKeyFrame);
decoder->FirstKeyFrame = 0;
}
} else {
//DisplayPts(video_ctx, frame);
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
}
#else
//DisplayPts(video_ctx, frame); //DisplayPts(video_ctx, frame);
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame); VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
#endif
} else { } else {
// some frames are needed for references, interlaced frames ... // some frames are needed for references, interlaced frames ...
// could happen with h264 dvb streams, just drop data. // could happen with h264 dvb streams, just drop data.
@ -703,11 +617,6 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
} }
} }
#endif #endif
// new AVFrame API
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
av_frame_unref(frame);
#endif
} }
/** /**
@ -748,22 +657,15 @@ struct _audio_decoder_
int HwSampleRate; ///< hw sample rate int HwSampleRate; ///< hw sample rate
int HwChannels; ///< hw channels int HwChannels; ///< hw channels
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1) #ifndef USE_SWRESAMPLE
AVFrame *Frame; ///< decoded audio frame buffer ReSampleContext *ReSample; ///< audio resampling context
#endif
#if !defined(USE_SWRESAMPLE) && !defined(USE_AVRESAMPLE)
ReSampleContext *ReSample; ///< old resampling context
#endif #endif
#ifdef USE_SWRESAMPLE #ifdef USE_SWRESAMPLE
#if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(0, 15, 100) #if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(0, 15, 100)
struct SwrContext *Resample; ///< ffmpeg software resample context struct SwrContext *Resample; ///< audio software resample context
#else #else
SwrContext *Resample; ///< ffmpeg software resample context SwrContext *Resample; ///< audio software resample context
#endif #endif
#endif
#ifdef USE_AVRESAMPLE
AVAudioResampleContext *Resample; ///< libav software resample context
#endif #endif
uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer uint16_t Spdif[24576 / 2]; ///< SPDIF output buffer
@ -778,7 +680,7 @@ struct _audio_decoder_
int DriftCorr; ///< audio drift correction value int DriftCorr; ///< audio drift correction value
int DriftFrac; ///< audio drift fraction for ac3 int DriftFrac; ///< audio drift fraction for ac3
#if !defined(USE_SWRESAMPLE) && !defined(USE_AVRESAMPLE) #ifndef USE_SWRESAMPLE
struct AVResampleContext *AvResample; ///< second audio resample context struct AVResampleContext *AvResample; ///< second audio resample context
#define MAX_CHANNELS 8 ///< max number of channels supported #define MAX_CHANNELS 8 ///< max number of channels supported
int16_t *Buffer[MAX_CHANNELS]; ///< deinterleave sample buffers int16_t *Buffer[MAX_CHANNELS]; ///< deinterleave sample buffers
@ -801,7 +703,7 @@ enum IEC61937
#ifdef USE_AUDIO_DRIFT_CORRECTION #ifdef USE_AUDIO_DRIFT_CORRECTION
#define CORRECT_PCM 1 ///< do PCM audio-drift correction #define CORRECT_PCM 1 ///< do PCM audio-drift correction
#define CORRECT_AC3 2 ///< do AC-3 audio-drift correction #define CORRECT_AC3 2 ///< do AC3 audio-drift correction
static char CodecAudioDrift; ///< flag: enable audio-drift correction static char CodecAudioDrift; ///< flag: enable audio-drift correction
#else #else
static const int CodecAudioDrift = 0; static const int CodecAudioDrift = 0;
@ -828,11 +730,6 @@ AudioDecoder *CodecAudioNewDecoder(void)
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) { if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
Fatal(_("codec: can't allocate audio decoder\n")); Fatal(_("codec: can't allocate audio decoder\n"));
} }
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
if (!(audio_decoder->Frame = av_frame_alloc())) {
Fatal(_("codec: can't allocate audio decoder frame buffer\n"));
}
#endif
return audio_decoder; return audio_decoder;
} }
@ -844,9 +741,6 @@ AudioDecoder *CodecAudioNewDecoder(void)
*/ */
void CodecAudioDelDecoder(AudioDecoder * decoder) void CodecAudioDelDecoder(AudioDecoder * decoder)
{ {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,28,1)
av_frame_free(&decoder->Frame); // callee does checks
#endif
free(decoder); free(decoder);
} }
@ -854,16 +748,19 @@ void CodecAudioDelDecoder(AudioDecoder * decoder)
** Open audio decoder. ** Open audio decoder.
** **
** @param audio_decoder private audio decoder ** @param audio_decoder private audio decoder
** @param codec_id audio codec id ** @param name audio codec name
** @param codec_id audio codec id, used if name == NULL
*/ */
void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id) void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name,
int codec_id)
{ {
AVCodec *audio_codec; AVCodec *audio_codec;
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id, Debug(3, "codec: using audio codec %s or ID %#06x\n", name, codec_id);
avcodec_get_name(codec_id));
if (!(audio_codec = avcodec_find_decoder(codec_id))) { if (name && (audio_codec = avcodec_find_decoder_by_name(name))) {
Debug(3, "codec: audio decoder '%s' found\n", name);
} else if (!(audio_codec = avcodec_find_decoder(codec_id))) {
Fatal(_("codec: codec ID %#06x not found\n"), codec_id); Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
// FIXME: errors aren't fatal // FIXME: errors aren't fatal
} }
@ -874,14 +771,14 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
} }
if (CodecDownmix) { if (CodecDownmix) {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,61,100) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,61,100) || FF_API_REQUEST_CHANNELS
audio_decoder->AudioCtx->request_channels = 2; audio_decoder->AudioCtx->request_channels = 2;
#endif #endif
audio_decoder->AudioCtx->request_channel_layout = audio_decoder->AudioCtx->request_channel_layout =
AV_CH_LAYOUT_STEREO_DOWNMIX; AV_CH_LAYOUT_STEREO_DOWNMIX;
} }
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,61,100) #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,61,100)
// this has no effect (with ffmpeg and libav) // this has no effect
// audio_decoder->AudioCtx->request_sample_fmt = AV_SAMPLE_FMT_S16; // audio_decoder->AudioCtx->request_sample_fmt = AV_SAMPLE_FMT_S16;
#endif #endif
pthread_mutex_lock(&CodecLockMutex); pthread_mutex_lock(&CodecLockMutex);
@ -908,7 +805,7 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
} }
#endif #endif
pthread_mutex_unlock(&CodecLockMutex); pthread_mutex_unlock(&CodecLockMutex);
Debug(3, "codec: audio '%s'\n", audio_decoder->AudioCodec->long_name); Debug(3, "codec: audio '%s'\n", audio_decoder->AudioCtx->codec_name);
if (audio_codec->capabilities & CODEC_CAP_TRUNCATED) { if (audio_codec->capabilities & CODEC_CAP_TRUNCATED) {
Debug(3, "codec: audio can use truncated packets\n"); Debug(3, "codec: audio can use truncated packets\n");
@ -930,7 +827,7 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
void CodecAudioClose(AudioDecoder * audio_decoder) void CodecAudioClose(AudioDecoder * audio_decoder)
{ {
// FIXME: output any buffered data // FIXME: output any buffered data
#if !defined(USE_SWRESAMPLE) && !defined(USE_AVRESAMPLE) #ifndef USE_SWRESAMPLE
if (audio_decoder->AvResample) { if (audio_decoder->AvResample) {
int ch; int ch;
@ -955,24 +852,19 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
if (audio_decoder->Resample) { if (audio_decoder->Resample) {
swr_free(&audio_decoder->Resample); swr_free(&audio_decoder->Resample);
} }
#endif
#ifdef USE_AVRESAMPLE
if (audio_decoder->Resample) {
avresample_free(&audio_decoder->Resample);
}
#endif #endif
if (audio_decoder->AudioCtx) { if (audio_decoder->AudioCtx) {
pthread_mutex_lock(&CodecLockMutex); pthread_mutex_lock(&CodecLockMutex);
avcodec_close(audio_decoder->AudioCtx); avcodec_close(audio_decoder->AudioCtx);
av_freep(&audio_decoder->AudioCtx);
pthread_mutex_unlock(&CodecLockMutex); pthread_mutex_unlock(&CodecLockMutex);
av_freep(&audio_decoder->AudioCtx);
} }
} }
/** /**
** Set audio drift correction. ** Set audio drift correction.
** **
** @param mask enable mask (PCM, AC-3) ** @param mask enable mask (PCM, AC3)
*/ */
void CodecSetAudioDrift(int mask) void CodecSetAudioDrift(int mask)
{ {
@ -985,7 +877,7 @@ void CodecSetAudioDrift(int mask)
/** /**
** Set audio pass-through. ** Set audio pass-through.
** **
** @param mask enable mask (PCM, AC-3, E-AC-3) ** @param mask enable mask (PCM, AC3, EAC3)
*/ */
void CodecSetAudioPassthrough(int mask) void CodecSetAudioPassthrough(int mask)
{ {
@ -1086,8 +978,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate,
audio_ctx->channels, CodecPassthrough & CodecPCM ? " PCM" : "", audio_ctx->channels, CodecPassthrough & CodecPCM ? " PCM" : "",
CodecPassthrough & CodecMPA ? " MPA" : "", CodecPassthrough & CodecMPA ? " MPA" : "",
CodecPassthrough & CodecAC3 ? " AC-3" : "", CodecPassthrough & CodecAC3 ? " AC3" : "",
CodecPassthrough & CodecEAC3 ? " E-AC-3" : "", CodecPassthrough & CodecEAC3 ? " EAC3" : "",
CodecPassthrough ? " pass-through" : ""); CodecPassthrough ? " pass-through" : "");
*passthrough = 0; *passthrough = 0;
@ -1098,11 +990,11 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
audio_decoder->Passthrough = CodecPassthrough; audio_decoder->Passthrough = CodecPassthrough;
// SPDIF/HDMI pass-through // SPDIF/HDMI pass-through
if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == CODEC_ID_AC3)
|| (CodecPassthrough & CodecEAC3 || (CodecPassthrough & CodecEAC3
&& audio_ctx->codec_id == AV_CODEC_ID_EAC3)) { && audio_ctx->codec_id == CODEC_ID_EAC3)) {
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) { if (audio_ctx->codec_id == CODEC_ID_EAC3) {
// E-AC-3 over HDMI some receivers need HBR // EAC3 over HDMI some receivers need HBR
audio_decoder->HwSampleRate *= 4; audio_decoder->HwSampleRate *= 4;
} }
audio_decoder->HwChannels = 2; audio_decoder->HwChannels = 2;
@ -1115,9 +1007,9 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
AudioSetup(&audio_decoder->HwSampleRate, AudioSetup(&audio_decoder->HwSampleRate,
&audio_decoder->HwChannels, *passthrough))) { &audio_decoder->HwChannels, *passthrough))) {
// try E-AC-3 none HBR // try EAC3 none HBR
audio_decoder->HwSampleRate /= 4; audio_decoder->HwSampleRate /= 4;
if (audio_ctx->codec_id != AV_CODEC_ID_EAC3 if (audio_ctx->codec_id != CODEC_ID_EAC3
|| (err = || (err =
AudioSetup(&audio_decoder->HwSampleRate, AudioSetup(&audio_decoder->HwSampleRate,
&audio_decoder->HwChannels, *passthrough))) { &audio_decoder->HwChannels, *passthrough))) {
@ -1152,7 +1044,7 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder,
audio_ctx = audio_decoder->AudioCtx; audio_ctx = audio_decoder->AudioCtx;
// SPDIF/HDMI passthrough // SPDIF/HDMI passthrough
if (CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) { if (CodecPassthrough & CodecAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
uint16_t *spdif; uint16_t *spdif;
int spdif_sz; int spdif_sz;
@ -1202,8 +1094,7 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder,
AudioEnqueue(spdif, spdif_sz); AudioEnqueue(spdif, spdif_sz);
return 1; return 1;
} }
if (CodecPassthrough & CodecEAC3 if (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == CODEC_ID_EAC3) {
&& audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
uint16_t *spdif; uint16_t *spdif;
int spdif_sz; int spdif_sz;
int repeat; int repeat;
@ -1256,7 +1147,7 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder,
return 0; return 0;
} }
#if !defined(USE_SWRESAMPLE) && !defined(USE_AVRESAMPLE) #ifndef USE_SWRESAMPLE
/** /**
** Set/update audio pts clock. ** Set/update audio pts clock.
@ -1332,9 +1223,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000); corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
// SPDIF/HDMI passthrough // SPDIF/HDMI passthrough
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3) if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) || audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
&& (!(CodecPassthrough & CodecEAC3) && (!(CodecPassthrough & CodecEAC3)
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) { || audio_decoder->AudioCtx->codec_id != CODEC_ID_EAC3)) {
audio_decoder->DriftCorr = -corr; audio_decoder->DriftCorr = -corr;
} }
@ -1658,7 +1549,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
#endif #endif
#if defined(USE_SWRESAMPLE) || defined(USE_AVRESAMPLE) #ifdef USE_SWRESAMPLE
/** /**
** Set/update audio pts clock. ** Set/update audio pts clock.
@ -1668,7 +1559,6 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
*/ */
static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts) static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
{ {
#ifdef USE_AUDIO_DRIFT_CORRECTION
struct timespec nowtime; struct timespec nowtime;
int64_t delay; int64_t delay;
int64_t tim_diff; int64_t tim_diff;
@ -1735,9 +1625,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000); corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
// SPDIF/HDMI passthrough // SPDIF/HDMI passthrough
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3) if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3) || audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
&& (!(CodecPassthrough & CodecEAC3) && (!(CodecPassthrough & CodecEAC3)
|| audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) { || audio_decoder->AudioCtx->codec_id != CODEC_ID_EAC3)) {
audio_decoder->DriftCorr = -corr; audio_decoder->DriftCorr = -corr;
} }
@ -1748,7 +1638,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
} }
} }
#ifdef USE_SWRESAMPLE
if (audio_decoder->Resample && audio_decoder->DriftCorr) { if (audio_decoder->Resample && audio_decoder->DriftCorr) {
int distance; int distance;
@ -1763,18 +1652,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
Debug(3, "codec/audio: swr_set_compensation failed\n"); Debug(3, "codec/audio: swr_set_compensation failed\n");
} }
} }
#endif
#ifdef USE_AVRESAMPLE
if (audio_decoder->Resample && audio_decoder->DriftCorr) {
int distance;
distance = (pts_diff * audio_decoder->HwSampleRate) / (900 * 1000);
if (avresample_set_compensation(audio_decoder->Resample,
audio_decoder->DriftCorr / 10, distance)) {
Debug(3, "codec/audio: swr_set_compensation failed\n");
}
}
#endif
if (1) { if (1) {
static int c; static int c;
@ -1783,9 +1660,6 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
audio_decoder->DriftCorr, drift * 1000 / 90, corr); audio_decoder->DriftCorr, drift * 1000 / 90, corr);
} }
} }
#else
AudioSetClock(pts);
#endif
} }
/** /**
@ -1817,7 +1691,6 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
} }
#endif #endif
#ifdef USE_SWRESAMPLE
audio_decoder->Resample = audio_decoder->Resample =
swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout,
AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate, AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate,
@ -1828,33 +1701,6 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
} else { } else {
Error(_("codec/audio: can't setup resample\n")); Error(_("codec/audio: can't setup resample\n"));
} }
#endif
#ifdef USE_AVRESAMPLE
if (!(audio_decoder->Resample = avresample_alloc_context())) {
Error(_("codec/audio: can't setup resample\n"));
return;
}
av_opt_set_int(audio_decoder->Resample, "in_channel_layout",
audio_ctx->channel_layout, 0);
av_opt_set_int(audio_decoder->Resample, "in_sample_fmt",
audio_ctx->sample_fmt, 0);
av_opt_set_int(audio_decoder->Resample, "in_sample_rate",
audio_ctx->sample_rate, 0);
av_opt_set_int(audio_decoder->Resample, "out_channel_layout",
audio_ctx->channel_layout, 0);
av_opt_set_int(audio_decoder->Resample, "out_sample_fmt",
AV_SAMPLE_FMT_S16, 0);
av_opt_set_int(audio_decoder->Resample, "out_sample_rate",
audio_decoder->HwSampleRate, 0);
if (avresample_open(audio_decoder->Resample)) {
avresample_free(&audio_decoder->Resample);
audio_decoder->Resample = NULL;
Error(_("codec/audio: can't open resample\n"));
return;
}
#endif
} }
/** /**
@ -1870,31 +1716,16 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
{ {
AVCodecContext *audio_ctx; AVCodecContext *audio_ctx;
AVFrame frame;
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,28,1)
AVFrame frame[1];
#else
AVFrame *frame;
#endif
int got_frame; int got_frame;
int n; int n;
audio_ctx = audio_decoder->AudioCtx; audio_ctx = audio_decoder->AudioCtx;
// FIXME: don't need to decode pass-through codecs // FIXME: don't need to decode pass-through codecs
frame.data[0] = NULL;
// new AVFrame API n = avcodec_decode_audio4(audio_ctx, &frame, &got_frame,
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,28,1)
avcodec_get_frame_defaults(frame);
#else
frame = audio_decoder->Frame;
av_frame_unref(frame);
#endif
got_frame = 0;
n = avcodec_decode_audio4(audio_ctx, frame, &got_frame,
(AVPacket *) avpkt); (AVPacket *) avpkt);
if (n != avpkt->size) { if (n != avpkt->size) {
if (n == AVERROR(EAGAIN)) { if (n == AVERROR(EAGAIN)) {
Error(_("codec/audio: latm\n")); Error(_("codec/audio: latm\n"));
@ -1936,7 +1767,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
data_sz = data_sz =
av_samples_get_buffer_size(&plane_sz, audio_ctx->channels, av_samples_get_buffer_size(&plane_sz, audio_ctx->channels,
frame->nb_samples, audio_ctx->sample_fmt, 1); frame.nb_samples, audio_ctx->sample_fmt, 1);
fprintf(stderr, "codec/audio: sample_fmt %s\n", fprintf(stderr, "codec/audio: sample_fmt %s\n",
av_get_sample_fmt_name(audio_ctx->sample_fmt)); av_get_sample_fmt_name(audio_ctx->sample_fmt));
av_get_channel_layout_string(strbuf, 32, audio_ctx->channels, av_get_channel_layout_string(strbuf, 32, audio_ctx->channels,
@ -1944,9 +1775,9 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
fprintf(stderr, "codec/audio: layout %s\n", strbuf); fprintf(stderr, "codec/audio: layout %s\n", strbuf);
fprintf(stderr, fprintf(stderr,
"codec/audio: channels %d samples %d plane %d data %d\n", "codec/audio: channels %d samples %d plane %d data %d\n",
audio_ctx->channels, frame->nb_samples, plane_sz, data_sz); audio_ctx->channels, frame.nb_samples, plane_sz, data_sz);
} }
#ifdef USE_SWRESAMPLE
if (audio_decoder->Resample) { if (audio_decoder->Resample) {
uint8_t outbuf[8192 * 2 * 8]; uint8_t outbuf[8192 * 2 * 8];
uint8_t *out[1]; uint8_t *out[1];
@ -1954,7 +1785,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
out[0] = outbuf; out[0] = outbuf;
n = swr_convert(audio_decoder->Resample, out, n = swr_convert(audio_decoder->Resample, out,
sizeof(outbuf) / (2 * audio_decoder->HwChannels), sizeof(outbuf) / (2 * audio_decoder->HwChannels),
(const uint8_t **)frame->extended_data, frame->nb_samples); (const uint8_t **)frame.extended_data, frame.nb_samples);
if (n > 0) { if (n > 0) {
if (!(audio_decoder->Passthrough & CodecPCM)) { if (!(audio_decoder->Passthrough & CodecPCM)) {
CodecReorderAudioFrame((int16_t *) outbuf, CodecReorderAudioFrame((int16_t *) outbuf,
@ -1965,30 +1796,6 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
} }
return; return;
} }
#endif
#ifdef USE_AVRESAMPLE
if (audio_decoder->Resample) {
uint8_t outbuf[8192 * 2 * 8];
uint8_t *out[1];
out[0] = outbuf;
n = avresample_convert(audio_decoder->Resample, out, 0,
sizeof(outbuf) / (2 * audio_decoder->HwChannels),
(uint8_t **) frame->extended_data, 0, frame->nb_samples);
// FIXME: set out_linesize, in_linesize correct
if (n > 0) {
if (!(audio_decoder->Passthrough & CodecPCM)) {
CodecReorderAudioFrame((int16_t *) outbuf,
n * 2 * audio_decoder->HwChannels,
audio_decoder->HwChannels);
}
AudioEnqueue(outbuf, n * 2 * audio_decoder->HwChannels);
}
return;
}
#endif
#ifdef DEBUG #ifdef DEBUG
// should be never reached // should be never reached
fprintf(stderr, "oops\n"); fprintf(stderr, "oops\n");

15
codec.h
View File

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

View File

@ -7,10 +7,10 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: VDR \n" "Project-Id-Version: VDR \n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2015-10-20 14:39+0200\n" "POT-Creation-Date: 2013-03-09 19:20+0100\n"
"PO-Revision-Date: blabla\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: blabla\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: blabla\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: german\n" "Language: german\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
@ -229,6 +229,9 @@ msgstr ""
msgid "audio: can't set channels %d sample-rate %dHz\n" msgid "audio: can't set channels %d sample-rate %dHz\n"
msgstr "" msgstr ""
msgid "audio: can't queue cancel play thread\n"
msgstr ""
msgid "audio: can't cancel play thread\n" msgid "audio: can't cancel play thread\n"
msgstr "" msgstr ""
@ -236,9 +239,6 @@ msgstr ""
msgid "audio: can't place %d samples in ring buffer\n" msgid "audio: can't place %d samples in ring buffer\n"
msgstr "" msgstr ""
msgid "audio: flush out of ring buffers\n"
msgstr ""
#, c-format #, c-format
msgid "audio: '%s' output module used\n" msgid "audio: '%s' output module used\n"
msgstr "" msgstr ""
@ -270,15 +270,12 @@ msgstr ""
msgid "codec: can't open video codec!\n" msgid "codec: can't open video codec!\n"
msgstr "" msgstr ""
msgid "codec: can't allocate video decoder frame buffer\n" msgid "codec: can't allocate decoder frame\n"
msgstr "" msgstr ""
msgid "codec: can't allocate audio decoder\n" msgid "codec: can't allocate audio decoder\n"
msgstr "" msgstr ""
msgid "codec: can't allocate audio decoder frame buffer\n"
msgstr ""
msgid "codec: can't allocate audio codec context\n" msgid "codec: can't allocate audio codec context\n"
msgstr "" msgstr ""
@ -309,9 +306,6 @@ msgstr ""
msgid "codec/audio: can't setup resample\n" msgid "codec/audio: can't setup resample\n"
msgstr "" msgstr ""
msgid "codec/audio: can't open resample\n"
msgstr ""
msgid "codec/audio: latm\n" msgid "codec/audio: latm\n"
msgstr "" msgstr ""
@ -390,10 +384,6 @@ msgstr ""
msgid "[softhddev] invalid PES video packet\n" msgid "[softhddev] invalid PES video packet\n"
msgstr "" msgstr ""
#, c-format
msgid "[softhddev] %d invalid PES video packet(s)\n"
msgstr ""
msgid "[softhddev] empty video packet\n" msgid "[softhddev] empty video packet\n"
msgstr "" msgstr ""
@ -489,9 +479,6 @@ msgstr "OSD Höhe"
msgid "Suspend" msgid "Suspend"
msgstr "Unterbrechen" msgstr "Unterbrechen"
msgid "Detach from main menu entry"
msgstr "Detach durch Hauptmenüeintrag"
msgid "Suspend closes video+audio" msgid "Suspend closes video+audio"
msgstr "Unterbrechen schließt Video+Audio" msgstr "Unterbrechen schließt Video+Audio"
@ -501,9 +488,6 @@ msgstr "Unterbrechen stoppt X11"
msgid "Video" msgid "Video"
msgstr "Video" msgstr "Video"
msgid "Enable Screensaver(DPMS) at black screen"
msgstr "Bildschirmschoner(DPMS) bei schwarzen Bild aktivieren"
msgid "Video background color (RGB)" msgid "Video background color (RGB)"
msgstr "Video Hintergrundfrabe (RGB)" msgstr "Video Hintergrundfrabe (RGB)"
@ -522,9 +506,6 @@ msgstr "Sanftanlauf A/V Sync"
msgid "Black during channel switch" msgid "Black during channel switch"
msgstr "Schwarz während Kanalwechsel" msgstr "Schwarz während Kanalwechsel"
msgid "Clear decoder on channel switch"
msgstr "Decoder bei Kanalwechsel leeren"
msgid "Brightness (-1000..1000) (vdpau)" msgid "Brightness (-1000..1000) (vdpau)"
msgstr "Helligkeit (-1000..1000) (vdpau)" msgstr "Helligkeit (-1000..1000) (vdpau)"
@ -606,11 +587,11 @@ msgstr ""
msgid " AC-3 pass-through" msgid " AC-3 pass-through"
msgstr "" msgstr ""
msgid " E-AC-3 pass-through" msgid " EAC-3 pass-through"
msgstr "" msgstr ""
msgid "Enable (E-)AC-3 (decoder) downmix" msgid "Enable (E)AC-3 (decoder) downmix"
msgstr "Aktiviere (E-)AC-3 (decoder) downmix" msgstr ""
msgid "Volume control" msgid "Volume control"
msgstr "Lautstärkesteuerung" msgstr "Lautstärkesteuerung"
@ -639,9 +620,6 @@ msgstr "Reduziere Steropegel (/1000)"
msgid "Audio buffer size (ms)" msgid "Audio buffer size (ms)"
msgstr "Audio Puffergröße (ms)" msgstr "Audio Puffergröße (ms)"
msgid "Enable automatic AES"
msgstr "Aktiviere automatiche AES"
msgid "Picture-In-Picture" msgid "Picture-In-Picture"
msgstr "Bild in Bild (PIP)" msgstr "Bild in Bild (PIP)"
@ -649,7 +627,7 @@ msgid "Pip X (%)"
msgstr "PIP X (%)" msgstr "PIP X (%)"
msgid "Pip Y (%)" msgid "Pip Y (%)"
msgstr "PIP Y (%)" msgstr "PIP X (%)"
msgid "Pip Width (%)" msgid "Pip Width (%)"
msgstr "PIP Breite (%)" msgstr "PIP Breite (%)"
@ -694,7 +672,7 @@ msgid "Alternative Video Height (%)"
msgstr "Alternative Videohöhe (%)" msgstr "Alternative Videohöhe (%)"
#, c-format #, c-format
msgid "[softhddev]pip: invalid PES packet %d\n" msgid "[softhddev]pip: invalid pes packet %d\n"
msgstr "" msgstr ""
msgid "[softhddev]pip: pes buffer too small\n" msgid "[softhddev]pip: pes buffer too small\n"
@ -706,9 +684,6 @@ msgstr ""
msgid "Channel not available!" msgid "Channel not available!"
msgstr "Kanal nicht verfügbar!" msgstr "Kanal nicht verfügbar!"
msgid "Detach SoftHdDevice"
msgstr ""
msgid "Suspend SoftHdDevice" msgid "Suspend SoftHdDevice"
msgstr "Unterbreche SoftHdDevice" msgstr "Unterbreche SoftHdDevice"
@ -756,12 +731,6 @@ msgstr ""
msgid "audio delay changed to %d" msgid "audio delay changed to %d"
msgstr "" msgstr ""
msgid "surround downmix enabled"
msgstr ""
msgid "surround downmix disabled"
msgstr ""
msgid "auto-crop disabled and freezed" msgid "auto-crop disabled and freezed"
msgstr "" msgstr ""
@ -926,9 +895,6 @@ msgstr ""
msgid "unsupported" msgid "unsupported"
msgstr "" msgstr ""
msgid "video/glx: glx error\n"
msgstr ""
#, c-format #, c-format
msgid "video/vaapi: unsupported pixel format %d\n" msgid "video/vaapi: unsupported pixel format %d\n"
msgstr "" msgstr ""
@ -1002,20 +968,14 @@ msgstr ""
msgid "video: output buffer full, dropping frame (%d/%d)\n" msgid "video: output buffer full, dropping frame (%d/%d)\n"
msgstr "" msgstr ""
#, c-format msgid "video/vaapi: can't create a surface\n"
msgid "video/vaapi: can't create a surface: %s\n"
msgstr "" msgstr ""
#, c-format #, c-format
msgid "video/vaapi: can't associate subpicture: %s\n" msgid "video/vaapi: vaDeriveImage failed %d\n"
msgstr "" msgstr ""
#, c-format msgid "video/vaapi: can't map the image!\n"
msgid "video/vaapi: can't create image: %s\n"
msgstr ""
#, c-format
msgid "video/vaapi: can't map the image: %s\n"
msgstr "" msgstr ""
msgid "video/vaapi: can't unmap the image!\n" msgid "video/vaapi: can't unmap the image!\n"
@ -1030,10 +990,6 @@ msgstr ""
msgid "video/vaapi: can't get source image\n" msgid "video/vaapi: can't get source image\n"
msgstr "" msgstr ""
#, c-format
msgid "video/vaapi: vaDeriveImage failed %d\n"
msgstr ""
#, c-format #, c-format
msgid "video/vaapi: can't put image: %d!\n" msgid "video/vaapi: can't put image: %d!\n"
msgstr "" msgstr ""
@ -1041,9 +997,6 @@ msgstr ""
msgid "video/vaapi: stream <-> surface size mismatch\n" msgid "video/vaapi: stream <-> surface size mismatch\n"
msgstr "" msgstr ""
msgid "video/vaapi: can't map the image!\n"
msgstr ""
#, c-format #, c-format
msgid "video/vaapi: can't put image err:%d!\n" msgid "video/vaapi: can't put image err:%d!\n"
msgstr "" msgstr ""
@ -1071,7 +1024,7 @@ msgstr ""
msgid "video/vaapi: can't find a supported subpicture format" msgid "video/vaapi: can't find a supported subpicture format"
msgstr "" msgstr ""
msgid "video/vaapi: supports unscaled osd\n" msgid "video/vaapi: vaapi supports unscaled osd\n"
msgstr "" msgstr ""
msgid "video/vaapi: can't create osd image\n" msgid "video/vaapi: can't create osd image\n"
@ -1312,9 +1265,6 @@ msgstr ""
msgid "video/vdpau: can't put video surface bits: %s\n" msgid "video/vdpau: can't put video surface bits: %s\n"
msgstr "" msgstr ""
msgid "video: get hwaccel context, not supported\n"
msgstr ""
#, c-format #, c-format
msgid "video/vdpau: can't render bitmap surface: %s\n" msgid "video/vdpau: can't render bitmap surface: %s\n"
msgstr "" msgstr ""
@ -1327,10 +1277,6 @@ msgstr ""
msgid "video/vdpau: can't render mixer: %s\n" msgid "video/vdpau: can't render mixer: %s\n"
msgstr "" msgstr ""
#, c-format
msgid "video/vdpau: can't query status: %s\n"
msgstr ""
#, c-format #, c-format
msgid "video/vdpau: can't block queue: %s\n" msgid "video/vdpau: can't block queue: %s\n"
msgstr "" msgstr ""
@ -1385,6 +1331,9 @@ msgstr ""
msgid "video: repeated pict %d found, but not handled\n" msgid "video: repeated pict %d found, but not handled\n"
msgstr "" msgstr ""
msgid "video/vaapi: get vaapi context, without vaapi enabled\n"
msgstr ""
#, c-format #, c-format
msgid "video/vdpau: decoder rendering failed: %s\n" msgid "video/vdpau: decoder rendering failed: %s\n"
msgstr "" msgstr ""
@ -1406,10 +1355,6 @@ msgstr ""
msgid "video: Can't connect to X11 server on '%s'\n" msgid "video: Can't connect to X11 server on '%s'\n"
msgstr "" msgstr ""
#, c-format
msgid "video: Can't initialize X11 thread support on '%s'\n"
msgstr ""
msgid "video: Can't convert XLIB display to XCB connection\n" msgid "video: Can't convert XLIB display to XCB connection\n"
msgstr "" msgstr ""

View File

@ -1,7 +1,7 @@
/// ///
/// @file ringbuffer.c @brief Ringbuffer module /// @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): /// Contributor(s):
/// ///
@ -30,7 +30,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "iatomic.h" #include <alsa/iatomic.h>
#include "ringbuffer.h" #include "ringbuffer.h"
/// ring buffer structure /// 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. /// @file softhddev.h @brief software HD device plugin header file.
/// ///
/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved. /// Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -25,8 +25,7 @@ extern "C"
{ {
#endif #endif
/// C callback feed key press /// C callback feed key press
extern void FeedKeyPress(const char *, const char *, int, int, extern void FeedKeyPress(const char *, const char *, int, int);
const char *);
/// C plugin get osd size and ascpect /// C plugin get osd size and ascpect
extern void GetOsdSize(int *, int *, double *); extern void GetOsdSize(int *, int *, double *);
@ -34,8 +33,7 @@ extern "C"
/// C plugin close osd /// C plugin close osd
extern void OsdClose(void); extern void OsdClose(void);
/// C plugin draw osd pixmap /// C plugin draw osd pixmap
extern void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
int);
/// C plugin play audio packet /// C plugin play audio packet
extern int PlayAudio(const uint8_t *, int, uint8_t); extern int PlayAudio(const uint8_t *, int, uint8_t);
@ -43,8 +41,6 @@ extern "C"
extern int PlayTsAudio(const uint8_t *, int); extern int PlayTsAudio(const uint8_t *, int);
/// C plugin set audio volume /// C plugin set audio volume
extern void SetVolumeDevice(int); extern void SetVolumeDevice(int);
/// C plugin reset channel id (restarts audio)
extern void ResetChannelId(void);
/// C plugin play video packet /// C plugin play video packet
extern int PlayVideo(const uint8_t *, int); extern int PlayVideo(const uint8_t *, int);

View File

@ -1,7 +1,7 @@
/// ///
/// @file softhddevice.cpp @brief A software HD device plugin for VDR. /// @file softhddevice.cpp @brief A software HD device plugin for VDR.
/// ///
/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved. /// Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -47,19 +47,12 @@ extern "C"
#include "codec.h" #include "codec.h"
} }
#if APIVERSNUM >= 20301
#define MURKS ->
#else
#define MURKS .
#define LOCK_CHANNELS_READ do { } while (0)
#endif
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// vdr-plugin version number. /// vdr-plugin version number.
/// Makefile extracts the version number for generating the file name /// Makefile extracts the version number for generating the file name
/// for the distribution archive. /// for the distribution archive.
static const char *const VERSION = "0.6.1rc1" static const char *const VERSION = "0.6.0"
#ifdef GIT_REV #ifdef GIT_REV
"-GIT" GIT_REV "-GIT" GIT_REV
#endif #endif
@ -86,7 +79,6 @@ static const char *const Resolution[RESOLUTIONS] = {
static char ConfigMakePrimary; ///< config primary wanted static char ConfigMakePrimary; ///< config primary wanted
static char ConfigHideMainMenuEntry; ///< config hide main menu entry static char ConfigHideMainMenuEntry; ///< config hide main menu entry
static char ConfigDetachFromMainMenu; ///< detach from main menu entry instead of suspend
static char ConfigSuspendClose; ///< suspend should close devices static char ConfigSuspendClose; ///< suspend should close devices
static char ConfigSuspendX11; ///< suspend should stop x11 static char ConfigSuspendX11; ///< suspend should stop x11
@ -99,7 +91,6 @@ static char ConfigVideoStudioLevels; ///< config use studio levels
static char ConfigVideo60HzMode; ///< config use 60Hz display mode static char ConfigVideo60HzMode; ///< config use 60Hz display mode
static char ConfigVideoSoftStartSync; ///< config use softstart sync static char ConfigVideoSoftStartSync; ///< config use softstart sync
static char ConfigVideoBlackPicture; ///< config enable black picture mode static char ConfigVideoBlackPicture; ///< config enable black picture mode
char ConfigVideoClearOnSwitch; ///< config enable Clear on channel switch
static int ConfigVideoBrightness; ///< config video brightness static int ConfigVideoBrightness; ///< config video brightness
static int ConfigVideoContrast = 1000; ///< config video contrast static int ConfigVideoContrast = 1000; ///< config video contrast
@ -147,7 +138,6 @@ static char ConfigAudioCompression; ///< config use volume compression
static int ConfigAudioMaxCompression; ///< config max volume compression static int ConfigAudioMaxCompression; ///< config max volume compression
static int ConfigAudioStereoDescent; ///< config reduce stereo loudness static int ConfigAudioStereoDescent; ///< config reduce stereo loudness
int ConfigAudioBufferTime; ///< config size ms of audio buffer int ConfigAudioBufferTime; ///< config size ms of audio buffer
static int ConfigAudioAutoAES; ///< config automatic AES handling
static char *ConfigX11Display; ///< config x11 display static char *ConfigX11Display; ///< config x11 display
static char *ConfigAudioDevice; ///< config audio stereo device static char *ConfigAudioDevice; ///< config audio stereo device
@ -172,17 +162,13 @@ static int ConfigPipAltVideoWidth; ///< config pip alt. video width in %
static int ConfigPipAltVideoHeight = 50; ///< config pip alt. video height in % static int ConfigPipAltVideoHeight = 50; ///< config pip alt. video height in %
#endif #endif
#ifdef USE_SCREENSAVER
static char ConfigEnableDPMSatBlackScreen; ///< Enable DPMS(Screensaver) while displaying black screen(radio)
#endif
static volatile int DoMakePrimary; ///< switch primary device to this static volatile int DoMakePrimary; ///< switch primary device to this
#define SUSPEND_EXTERNAL -1 ///< play external suspend mode #define SUSPEND_EXTERNAL -1 ///< play external suspend mode
#define NOT_SUSPENDED 0 ///< not suspend mode #define NOT_SUSPENDED 0 ///< not suspend mode
#define SUSPEND_NORMAL 1 ///< normal suspend mode #define SUSPEND_NORMAL 1 ///< normal suspend mode
#define SUSPEND_DETACHED 2 ///< detached suspend mode #define SUSPEND_DETACHED 2 ///< detached suspend mode
static signed char SuspendMode; ///< suspend mode static char SuspendMode; ///< suspend mode
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -225,10 +211,9 @@ class cSoftRemote:public cRemote
** @param key pressed/released key name ** @param key pressed/released key name
** @param repeat repeated key flag ** @param repeat repeated key flag
** @param release released key flag ** @param release released key flag
** @param letter x11 character string (system setting locale)
*/ */
extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat, extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
int release, const char *letter) int release)
{ {
cRemote *remote; cRemote *remote;
cSoftRemote *csoft; cSoftRemote *csoft;
@ -251,18 +236,9 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
csoft = new cSoftRemote(keymap); csoft = new cSoftRemote(keymap);
} }
//dsyslog("[softhddev]%s %s, %s, %s\n", __FUNCTION__, keymap, key, letter); //dsyslog("[softhddev]%s %s, %s\n", __FUNCTION__, keymap, key);
if (key[1]) { // no single character if (key[1]) { // no single character
if (!csoft->Put(key, repeat, release) && letter csoft->Put(key, repeat, release);
&& !cRemote::IsLearning()) {
cCharSetConv conv;
unsigned code;
code = Utf8CharGet(conv.Convert(letter));
if (code <= 0xFF) {
cRemote::Put(KBDKEY(code)); // feed it for edit mode
}
}
} else if (!csoft->Put(key, repeat, release)) { } else if (!csoft->Put(key, repeat, release)) {
cRemote::Put(KBDKEY(key[0])); // feed it for edit mode cRemote::Put(KBDKEY(key[0])); // feed it for edit mode
} }
@ -279,12 +255,10 @@ class cSoftOsd:public cOsd
{ {
public: public:
static volatile char Dirty; ///< flag force redraw everything static volatile char Dirty; ///< flag force redraw everything
int OsdLevel; ///< current osd level FIXME: remove int OsdLevel; ///< current osd level
cSoftOsd(int, int, uint); ///< osd constructor cSoftOsd(int, int, uint); ///< osd constructor
virtual ~ cSoftOsd(void); ///< osd destructor virtual ~ cSoftOsd(void); ///< osd destructor
/// set the sub-areas to the given areas
virtual eOsdError SetAreas(const tArea *, int);
virtual void Flush(void); ///< commits all data to the hardware virtual void Flush(void); ///< commits all data to the hardware
virtual void SetActive(bool); ///< sets OSD to be the active one virtual void SetActive(bool); ///< sets OSD to be the active one
}; };
@ -310,6 +284,11 @@ void cSoftOsd::SetActive(bool on)
} }
cOsd::SetActive(on); cOsd::SetActive(on);
// ignore sub-title if menu is open
if (OsdLevel >= OSD_LEVEL_SUBTITLES && IsOpen()) {
return;
}
if (on) { if (on) {
Dirty = 1; Dirty = 1;
// only flush here if there are already bitmaps // only flush here if there are already bitmaps
@ -341,6 +320,7 @@ cSoftOsd::cSoftOsd(int left, int top, uint level)
#endif #endif
OsdLevel = level; OsdLevel = level;
SetActive(true);
} }
/** /**
@ -371,31 +351,6 @@ cSoftOsd::~cSoftOsd(void)
#endif #endif
} }
/**
+* Set the sub-areas to the given areas
*/
eOsdError cSoftOsd::SetAreas(const tArea * areas, int n)
{
#ifdef OSD_DEBUG
dsyslog("[softhddev]%s: %d areas \n", __FUNCTION__, n);
#endif
// clear old OSD, when new areas are set
if (!IsTrueColor()) {
cBitmap *bitmap;
int i;
for (i = 0; (bitmap = GetBitmap(i)); i++) {
bitmap->Clean();
}
}
if (Active()) {
VideoOsdClear();
Dirty = 1;
}
return cOsd::SetAreas(areas, n);
}
/** /**
** Actually commits all data to the OSD hardware. ** Actually commits all data to the OSD hardware.
*/ */
@ -411,6 +366,10 @@ void cSoftOsd::Flush(void)
if (!Active()) { // this osd is not active if (!Active()) { // this osd is not active
return; return;
} }
// don't draw sub-title if menu is active
if (OsdLevel >= OSD_LEVEL_SUBTITLES && IsOpen()) {
return;
}
#ifdef USE_YAEPG #ifdef USE_YAEPG
// support yaepghd, video window // support yaepghd, video window
if (vidWin.bpp) { if (vidWin.bpp) {
@ -426,6 +385,17 @@ void cSoftOsd::Flush(void)
} }
#endif #endif
//
// VDR draws subtitle without clearing the old
//
if (OsdLevel >= OSD_LEVEL_SUBTITLES) {
VideoOsdClear();
cSoftOsd::Dirty = 1;
#ifdef OSD_DEBUG
dsyslog("[softhddev]%s: subtitle clear\n", __FUNCTION__);
#endif
}
if (!IsTrueColor()) { if (!IsTrueColor()) {
cBitmap *bitmap; cBitmap *bitmap;
int i; int i;
@ -442,8 +412,6 @@ void cSoftOsd::Flush(void)
// draw all bitmaps // draw all bitmaps
for (i = 0; (bitmap = GetBitmap(i)); ++i) { for (i = 0; (bitmap = GetBitmap(i)); ++i) {
uint8_t *argb; uint8_t *argb;
int xs;
int ys;
int x; int x;
int y; int y;
int w; int w;
@ -462,52 +430,22 @@ void cSoftOsd::Flush(void)
} else if (!bitmap->Dirty(x1, y1, x2, y2)) { } else if (!bitmap->Dirty(x1, y1, x2, y2)) {
continue; // nothing dirty continue continue; // nothing dirty continue
} }
// convert and upload only visible dirty areas // convert and upload only dirty areas
xs = bitmap->X0() + Left();
ys = bitmap->Y0() + Top();
// FIXME: negtative position bitmaps
w = x2 - x1 + 1; w = x2 - x1 + 1;
h = y2 - y1 + 1; h = y2 - y1 + 1;
// clip to screen
if (1) { // just for the case it makes trouble if (1) { // just for the case it makes trouble
int width; int width;
int height; int height;
double video_aspect; double video_aspect;
if (xs < 0) {
if (xs + x1 < 0) {
x1 -= xs + x1;
w += xs + x1;
if (w <= 0) {
continue;
}
}
xs = 0;
}
if (ys < 0) {
if (ys + y1 < 0) {
y1 -= ys + y1;
h += ys + y1;
if (h <= 0) {
continue;
}
}
ys = 0;
}
::GetOsdSize(&width, &height, &video_aspect); ::GetOsdSize(&width, &height, &video_aspect);
if (w > width - xs - x1) { if (w > width) {
w = width - xs - x1; w = width;
if (w <= 0) { x2 = x1 + width - 1;
continue;
}
x2 = x1 + w - 1;
} }
if (h > height - ys - y1) { if (h > height) {
h = height - ys - y1; h = height;
if (h <= 0) { y2 = y1 + height - 1;
continue;
}
y2 = y1 + h - 1;
} }
} }
#ifdef DEBUG #ifdef DEBUG
@ -525,99 +463,40 @@ void cSoftOsd::Flush(void)
} }
#ifdef OSD_DEBUG #ifdef OSD_DEBUG
dsyslog("[softhddev]%s: draw %dx%d%+d%+d bm\n", __FUNCTION__, w, h, dsyslog("[softhddev]%s: draw %dx%d%+d%+d bm\n", __FUNCTION__, w, h,
xs + x1, ys + y1); Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1);
#endif #endif
OsdDrawARGB(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1, OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
ys + y1); w, h, argb);
bitmap->Clean(); bitmap->Clean();
// FIXME: reuse argb // FIXME: reuse argb
free(argb); free(argb);
} }
Dirty = 0; cSoftOsd::Dirty = 0;
return; return;
} }
LOCK_PIXMAPS; LOCK_PIXMAPS;
while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) { while ((pm = RenderPixmaps())) {
int xp;
int yp;
int stride;
int x; int x;
int y; int y;
int w; int w;
int h; int h;
x = pm->ViewPort().X(); x = Left() + pm->ViewPort().X();
y = pm->ViewPort().Y(); y = Top() + pm->ViewPort().Y();
w = pm->ViewPort().Width(); w = pm->ViewPort().Width();
h = pm->ViewPort().Height(); h = pm->ViewPort().Height();
stride = w * sizeof(tColor);
// clip to osd
xp = 0;
if (x < 0) {
xp = -x;
w -= xp;
x = 0;
}
yp = 0;
if (y < 0) {
yp = -y;
h -= yp;
y = 0;
}
if (w > Width() - x) {
w = Width() - x;
}
if (h > Height() - y) {
h = Height() - y;
}
x += Left();
y += Top();
// clip to screen
if (1) { // just for the case it makes trouble
// and it can happen!
int width;
int height;
double video_aspect;
if (x < 0) {
w += x;
xp += -x;
x = 0;
}
if (y < 0) {
h += y;
yp += -y;
y = 0;
}
::GetOsdSize(&width, &height, &video_aspect);
if (w > width - x) {
w = width - x;
}
if (h > height - y) {
h = height - y;
}
}
#ifdef OSD_DEBUG #ifdef OSD_DEBUG
dsyslog("[softhddev]%s: draw %dx%d%+d%+d*%d -> %+d%+d %p\n", dsyslog("[softhddev]%s: draw %dx%d%+d%+d %p\n", __FUNCTION__, w, h, x,
__FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data()); y, pm->Data());
#endif #endif
OsdDrawARGB(xp, yp, w, h, stride, pm->Data(), x, y); OsdDrawARGB(x, y, w, h, pm->Data());
#if APIVERSNUM >= 20110
DestroyPixmap(pm);
#else
delete pm; delete pm;
#endif
} }
Dirty = 0; cSoftOsd::Dirty = 0;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -701,7 +580,6 @@ class cMenuSetupSoft:public cMenuSetupPage
int General; int General;
int MakePrimary; int MakePrimary;
int HideMainMenuEntry; int HideMainMenuEntry;
int DetachFromMainMenu;
int OsdSize; int OsdSize;
int OsdWidth; int OsdWidth;
int OsdHeight; int OsdHeight;
@ -717,7 +595,6 @@ class cMenuSetupSoft:public cMenuSetupPage
int _60HzMode; int _60HzMode;
int SoftStartSync; int SoftStartSync;
int BlackPicture; int BlackPicture;
int ClearOnSwitch;
int Brightness; int Brightness;
int Contrast; int Contrast;
@ -753,7 +630,6 @@ class cMenuSetupSoft:public cMenuSetupPage
int AudioMaxCompression; int AudioMaxCompression;
int AudioStereoDescent; int AudioStereoDescent;
int AudioBufferTime; int AudioBufferTime;
int AudioAutoAES;
#ifdef USE_PIP #ifdef USE_PIP
int Pip; int Pip;
@ -775,9 +651,6 @@ class cMenuSetupSoft:public cMenuSetupPage
int PipAltVideoHeight; int PipAltVideoHeight;
#endif #endif
#ifdef USE_SCREENSAVER
int EnableDPMSatBlackScreen;
#endif
/// @} /// @}
private: private:
inline cOsdItem * CollapsedItem(const char *, int &, const char * = NULL); inline cOsdItem * CollapsedItem(const char *, int &, const char * = NULL);
@ -884,8 +757,6 @@ void cMenuSetupSoft::Create(void)
// suspend // suspend
// //
Add(SeparatorItem(tr("Suspend"))); Add(SeparatorItem(tr("Suspend")));
Add(new cMenuEditBoolItem(tr("Detach from main menu entry"),
&DetachFromMainMenu, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Suspend closes video+audio"), Add(new cMenuEditBoolItem(tr("Suspend closes video+audio"),
&SuspendClose, trVDR("no"), trVDR("yes"))); &SuspendClose, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Suspend stops x11"), &SuspendX11, Add(new cMenuEditBoolItem(tr("Suspend stops x11"), &SuspendX11,
@ -896,11 +767,6 @@ void cMenuSetupSoft::Create(void)
// //
Add(CollapsedItem(tr("Video"), Video)); Add(CollapsedItem(tr("Video"), Video));
if (Video) { if (Video) {
#ifdef USE_SCREENSAVER
Add(new
cMenuEditBoolItem(tr("Enable Screensaver(DPMS) at black screen"),
&EnableDPMSatBlackScreen, trVDR("no"), trVDR("yes")));
#endif
Add(new cMenuEditStraItem(trVDR("4:3 video display format"), Add(new cMenuEditStraItem(trVDR("4:3 video display format"),
&Video4to3DisplayFormat, 3, video_display_formats_4_3)); &Video4to3DisplayFormat, 3, video_display_formats_4_3));
Add(new cMenuEditStraItem(trVDR("16:9+other video display format"), Add(new cMenuEditStraItem(trVDR("16:9+other video display format"),
@ -919,8 +785,6 @@ void cMenuSetupSoft::Create(void)
trVDR("no"), trVDR("yes"))); trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Black during channel switch"), Add(new cMenuEditBoolItem(tr("Black during channel switch"),
&BlackPicture, trVDR("no"), trVDR("yes"))); &BlackPicture, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Clear decoder on channel switch"),
&ClearOnSwitch, trVDR("no"), trVDR("yes")));
Add(new cMenuEditIntItem(tr("Brightness (-1000..1000) (vdpau)"), Add(new cMenuEditIntItem(tr("Brightness (-1000..1000) (vdpau)"),
&Brightness, -1000, 1000, tr("min"), tr("max"))); &Brightness, -1000, 1000, tr("min"), tr("max")));
@ -990,9 +854,9 @@ void cMenuSetupSoft::Create(void)
&AudioPassthroughPCM, trVDR("no"), trVDR("yes"))); &AudioPassthroughPCM, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("\040\040AC-3 pass-through"), Add(new cMenuEditBoolItem(tr("\040\040AC-3 pass-through"),
&AudioPassthroughAC3, trVDR("no"), trVDR("yes"))); &AudioPassthroughAC3, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("\040\040E-AC-3 pass-through"), Add(new cMenuEditBoolItem(tr("\040\040EAC-3 pass-through"),
&AudioPassthroughEAC3, trVDR("no"), trVDR("yes"))); &AudioPassthroughEAC3, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Enable (E-)AC-3 (decoder) downmix"), Add(new cMenuEditBoolItem(tr("Enable (E)AC-3 (decoder) downmix"),
&AudioDownmix, trVDR("no"), trVDR("yes"))); &AudioDownmix, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol, Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol,
tr("Hardware"), tr("Software"))); tr("Hardware"), tr("Software")));
@ -1008,8 +872,6 @@ void cMenuSetupSoft::Create(void)
&AudioStereoDescent, 0, 1000)); &AudioStereoDescent, 0, 1000));
Add(new cMenuEditIntItem(tr("Audio buffer size (ms)"), Add(new cMenuEditIntItem(tr("Audio buffer size (ms)"),
&AudioBufferTime, 0, 1000)); &AudioBufferTime, 0, 1000));
Add(new cMenuEditBoolItem(tr("Enable automatic AES"), &AudioAutoAES,
trVDR("no"), trVDR("yes")));
} }
#ifdef USE_PIP #ifdef USE_PIP
// //
@ -1115,7 +977,6 @@ cMenuSetupSoft::cMenuSetupSoft(void)
General = 0; General = 0;
MakePrimary = ConfigMakePrimary; MakePrimary = ConfigMakePrimary;
HideMainMenuEntry = ConfigHideMainMenuEntry; HideMainMenuEntry = ConfigHideMainMenuEntry;
DetachFromMainMenu = ConfigDetachFromMainMenu;
// //
// osd // osd
// //
@ -1149,7 +1010,6 @@ cMenuSetupSoft::cMenuSetupSoft(void)
_60HzMode = ConfigVideo60HzMode; _60HzMode = ConfigVideo60HzMode;
SoftStartSync = ConfigVideoSoftStartSync; SoftStartSync = ConfigVideoSoftStartSync;
BlackPicture = ConfigVideoBlackPicture; BlackPicture = ConfigVideoBlackPicture;
ClearOnSwitch = ConfigVideoClearOnSwitch;
Brightness = ConfigVideoBrightness; Brightness = ConfigVideoBrightness;
Contrast = ConfigVideoContrast; Contrast = ConfigVideoContrast;
@ -1193,7 +1053,6 @@ cMenuSetupSoft::cMenuSetupSoft(void)
AudioMaxCompression = ConfigAudioMaxCompression; AudioMaxCompression = ConfigAudioMaxCompression;
AudioStereoDescent = ConfigAudioStereoDescent; AudioStereoDescent = ConfigAudioStereoDescent;
AudioBufferTime = ConfigAudioBufferTime; AudioBufferTime = ConfigAudioBufferTime;
AudioAutoAES = ConfigAudioAutoAES;
#ifdef USE_PIP #ifdef USE_PIP
// //
@ -1217,11 +1076,6 @@ cMenuSetupSoft::cMenuSetupSoft(void)
PipAltVideoWidth = ConfigPipAltVideoWidth; PipAltVideoWidth = ConfigPipAltVideoWidth;
PipAltVideoHeight = ConfigPipAltVideoHeight; PipAltVideoHeight = ConfigPipAltVideoHeight;
#endif #endif
#ifdef USE_SCREENSAVER
EnableDPMSatBlackScreen = ConfigEnableDPMSatBlackScreen;
#endif
Create(); Create();
} }
@ -1235,8 +1089,6 @@ void cMenuSetupSoft::Store(void)
SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary); SetupStore("MakePrimary", ConfigMakePrimary = MakePrimary);
SetupStore("HideMainMenuEntry", ConfigHideMainMenuEntry = SetupStore("HideMainMenuEntry", ConfigHideMainMenuEntry =
HideMainMenuEntry); HideMainMenuEntry);
SetupStore("DetachFromMainMenu", ConfigDetachFromMainMenu =
DetachFromMainMenu);
switch (OsdSize) { switch (OsdSize) {
case 0: case 0:
OsdWidth = 0; OsdWidth = 0;
@ -1281,7 +1133,6 @@ void cMenuSetupSoft::Store(void)
VideoSetSoftStartSync(ConfigVideoSoftStartSync); VideoSetSoftStartSync(ConfigVideoSoftStartSync);
SetupStore("BlackPicture", ConfigVideoBlackPicture = BlackPicture); SetupStore("BlackPicture", ConfigVideoBlackPicture = BlackPicture);
VideoSetBlackPicture(ConfigVideoBlackPicture); VideoSetBlackPicture(ConfigVideoBlackPicture);
SetupStore("ClearOnSwitch", ConfigVideoClearOnSwitch = ClearOnSwitch);
SetupStore("Brightness", ConfigVideoBrightness = Brightness); SetupStore("Brightness", ConfigVideoBrightness = Brightness);
VideoSetBrightness(ConfigVideoBrightness); VideoSetBrightness(ConfigVideoBrightness);
@ -1336,12 +1187,6 @@ void cMenuSetupSoft::Store(void)
VideoSetAudioDelay(ConfigVideoAudioDelay); VideoSetAudioDelay(ConfigVideoAudioDelay);
SetupStore("AudioDrift", ConfigAudioDrift = AudioDrift); SetupStore("AudioDrift", ConfigAudioDrift = AudioDrift);
CodecSetAudioDrift(ConfigAudioDrift); CodecSetAudioDrift(ConfigAudioDrift);
// FIXME: can handle more audio state changes here
// downmix changed reset audio, to get change direct
if (ConfigAudioDownmix != AudioDownmix) {
ResetChannelId();
}
ConfigAudioPassthrough = (AudioPassthroughPCM ? CodecPCM : 0) ConfigAudioPassthrough = (AudioPassthroughPCM ? CodecPCM : 0)
| (AudioPassthroughAC3 ? CodecAC3 : 0) | (AudioPassthroughAC3 ? CodecAC3 : 0)
| (AudioPassthroughEAC3 ? CodecEAC3 : 0); | (AudioPassthroughEAC3 ? CodecEAC3 : 0);
@ -1369,8 +1214,6 @@ void cMenuSetupSoft::Store(void)
AudioStereoDescent); AudioStereoDescent);
AudioSetStereoDescent(ConfigAudioStereoDescent); AudioSetStereoDescent(ConfigAudioStereoDescent);
SetupStore("AudioBufferTime", ConfigAudioBufferTime = AudioBufferTime); SetupStore("AudioBufferTime", ConfigAudioBufferTime = AudioBufferTime);
SetupStore("AudioAutoAES", ConfigAudioAutoAES = AudioAutoAES);
AudioSetAutoAES(ConfigAudioAutoAES);
#ifdef USE_PIP #ifdef USE_PIP
SetupStore("pip.X", ConfigPipX = PipX); SetupStore("pip.X", ConfigPipX = PipX);
@ -1392,12 +1235,6 @@ void cMenuSetupSoft::Store(void)
SetupStore("pip.Alt.VideoHeight", ConfigPipAltVideoHeight = SetupStore("pip.Alt.VideoHeight", ConfigPipAltVideoHeight =
PipAltVideoHeight); PipAltVideoHeight);
#endif #endif
#ifdef USE_SCREENSAVER
SetupStore("EnableDPMSatBlackScreen", ConfigEnableDPMSatBlackScreen =
EnableDPMSatBlackScreen);
SetDPMSatBlackScreen(ConfigEnableDPMSatBlackScreen);
#endif
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -1513,11 +1350,7 @@ class cSoftReceiver:public cReceiver
{ {
protected: protected:
virtual void Activate(bool); virtual void Activate(bool);
#if APIVERSNUM >= 20301
virtual void Receive(const uchar *, int);
#else
virtual void Receive(uchar *, int); virtual void Receive(uchar *, int);
#endif
public: public:
cSoftReceiver(const cChannel *); ///< receiver constructor cSoftReceiver(const cChannel *); ///< receiver constructor
virtual ~ cSoftReceiver(); ///< receiver destructor virtual ~ cSoftReceiver(); ///< receiver destructor
@ -1610,12 +1443,12 @@ static void PipPesParse(const uint8_t * data, int size, int is_start)
if (is_start) { // start of pes packet if (is_start) { // start of pes packet
if (pes_index) { if (pes_index) {
if (0) { if (0) {
fprintf(stderr, "pip: PES packet %8d %02x%02x\n", pes_index, fprintf(stderr, "pip: pes packet %8d %02x%02x\n", pes_index,
pes_buf[2], pes_buf[3]); pes_buf[2], pes_buf[3]);
} }
if (pes_buf[0] || pes_buf[1] || pes_buf[2] != 0x01) { if (pes_buf[0] || pes_buf[1] || pes_buf[2] != 0x01) {
// FIXME: first should always fail // FIXME: first should always fail
esyslog(tr("[softhddev]pip: invalid PES packet %d\n"), esyslog(tr("[softhddev]pip: invalid pes packet %d\n"),
pes_index); pes_index);
} else { } else {
PipPlayVideo(pes_buf, pes_index); PipPlayVideo(pes_buf, pes_index);
@ -1651,11 +1484,7 @@ static void PipPesParse(const uint8_t * data, int size, int is_start)
** @param data ts packet ** @param data ts packet
** @param size size (#TS_PACKET_SIZE=188) of tes packet ** @param size size (#TS_PACKET_SIZE=188) of tes packet
*/ */
#if APIVERSNUM >= 20301
void cSoftReceiver::Receive(const uchar * data, int size)
#else
void cSoftReceiver::Receive(uchar * data, int size) void cSoftReceiver::Receive(uchar * data, int size)
#endif
{ {
const uint8_t *p; const uint8_t *p;
@ -1747,8 +1576,7 @@ static void NewPip(int channel_nr)
if (!channel_nr) { if (!channel_nr) {
channel_nr = cDevice::CurrentChannel(); channel_nr = cDevice::CurrentChannel();
} }
LOCK_CHANNELS_READ; if (channel_nr && (channel = Channels.GetByNumber(channel_nr))
if (channel_nr && (channel = Channels MURKS GetByNumber(channel_nr))
&& (device = cDevice::GetDevice(channel, 0, false, false))) { && (device = cDevice::GetDevice(channel, 0, false, false))) {
DelPip(); DelPip();
@ -1794,16 +1622,14 @@ static void PipNextAvailableChannel(int direction)
DelPip(); // disable PIP to free the device DelPip(); // disable PIP to free the device
LOCK_CHANNELS_READ;
while (channel) { while (channel) {
bool ndr; bool ndr;
cDevice *device; cDevice *device;
channel = direction > 0 ? Channels MURKS Next(channel) channel = direction > 0 ? Channels.Next(channel)
: Channels MURKS Prev(channel); : Channels.Prev(channel);
if (!channel && Setup.ChannelsWrap) { if (!channel && Setup.ChannelsWrap) {
channel = channel = direction > 0 ? Channels.First() : Channels.Last();
direction > 0 ? Channels MURKS First() : Channels MURKS Last();
} }
if (channel && !channel->GroupSep() if (channel && !channel->GroupSep()
&& (device = cDevice::GetDevice(channel, 0, false, true)) && (device = cDevice::GetDevice(channel, 0, false, true))
@ -1832,9 +1658,7 @@ static void SwapPipChannels(void)
NewPip(0); NewPip(0);
if (channel) { if (channel) {
LOCK_CHANNELS_READ; Channels.SwitchTo(channel->Number());
Channels MURKS SwitchTo(channel->Number());
} }
} }
@ -1922,12 +1746,7 @@ void cSoftHdMenu::Create(void)
Clear(); // clear the menu Clear(); // clear the menu
SetHasHotkeys(); SetHasHotkeys();
Add(new cOsdItem(hk(tr("Suspend SoftHdDevice")), osUser1));
if (ConfigDetachFromMainMenu) {
Add(new cOsdItem(hk(tr("Detach SoftHdDevice")), osUser1));
} else {
Add(new cOsdItem(hk(tr("Suspend SoftHdDevice")), osUser1));
}
#ifdef USE_PIP #ifdef USE_PIP
if (PipReceiver) { if (PipReceiver) {
Add(new cOsdItem(hk(tr("PIP toggle on/off: off")), osUser2)); Add(new cOsdItem(hk(tr("PIP toggle on/off: off")), osUser2));
@ -2023,17 +1842,6 @@ static void HandleHotkey(int code)
cString::sprintf(tr("audio delay changed to %d"), cString::sprintf(tr("audio delay changed to %d"),
ConfigVideoAudioDelay)); ConfigVideoAudioDelay));
break; break;
case 15:
ConfigAudioDownmix ^= 1;
fprintf(stderr, "toggle downmix\n");
CodecSetAudioDownmix(ConfigAudioDownmix);
if (ConfigAudioDownmix) {
Skins.QueueMessage(mtInfo, tr("surround downmix enabled"));
} else {
Skins.QueueMessage(mtInfo, tr("surround downmix disabled"));
}
ResetChannelId();
break;
case 20: // disable full screen case 20: // disable full screen
VideoSetFullscreen(0); VideoSetFullscreen(0);
@ -2108,7 +1916,6 @@ static void HandleHotkey(int code)
break; break;
case 108: case 108:
DelPip(); DelPip();
PipChannelNr = 0;
break; break;
#endif #endif
@ -2186,14 +1993,9 @@ eOSState cSoftHdMenu::ProcessKey(eKeys key)
if (SuspendMode == NOT_SUSPENDED && !cSoftHdControl::Player) { if (SuspendMode == NOT_SUSPENDED && !cSoftHdControl::Player) {
cControl::Launch(new cSoftHdControl); cControl::Launch(new cSoftHdControl);
cControl::Attach(); cControl::Attach();
if (ConfigDetachFromMainMenu) { Suspend(ConfigSuspendClose, ConfigSuspendClose,
Suspend(1, 1, 0); ConfigSuspendX11);
SuspendMode = SUSPEND_DETACHED; SuspendMode = SUSPEND_NORMAL;
} else {
Suspend(ConfigSuspendClose, ConfigSuspendClose,
ConfigSuspendX11);
SuspendMode = SUSPEND_NORMAL;
}
if (ShutdownHandler.GetUserInactiveTime()) { if (ShutdownHandler.GetUserInactiveTime()) {
dsyslog("[softhddev]%s: set user inactive\n", dsyslog("[softhddev]%s: set user inactive\n",
__FUNCTION__); __FUNCTION__);
@ -2219,7 +2021,6 @@ eOSState cSoftHdMenu::ProcessKey(eKeys key)
return osEnd; return osEnd;
case osUser8: case osUser8:
DelPip(); DelPip();
PipChannelNr = 0;
return osEnd; return osEnd;
#endif #endif
default: default:
@ -2242,11 +2043,7 @@ class cSoftHdDevice:public cDevice
virtual bool HasDecoder(void) const; virtual bool HasDecoder(void) const;
virtual bool CanReplay(void) const; virtual bool CanReplay(void) const;
virtual bool SetPlayMode(ePlayMode); virtual bool SetPlayMode(ePlayMode);
#if APIVERSNUM >= 20103
virtual void TrickSpeed(int, bool);
#else
virtual void TrickSpeed(int); virtual void TrickSpeed(int);
#endif
virtual void Clear(void); virtual void Clear(void);
virtual void Play(void); virtual void Play(void);
virtual void Freeze(void); virtual void Freeze(void);
@ -2393,7 +2190,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
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:
dsyslog("[softhddev] play mode external\n"); dsyslog("[softhddev] play mode external\n");
// FIXME: what if already suspended? // FIXME: what if already suspended?
@ -2434,23 +2231,13 @@ int64_t cSoftHdDevice::GetSTC(void)
** times. ** times.
** **
** @param speed trick speed ** @param speed trick speed
** @param forward flag forward direction
*/ */
#if APIVERSNUM >= 20103
void cSoftHdDevice::TrickSpeed(int speed, bool forward)
{
dsyslog("[softhddev]%s: %d %d\n", __FUNCTION__, speed, forward);
::TrickSpeed(speed);
}
#else
void cSoftHdDevice::TrickSpeed(int speed) void cSoftHdDevice::TrickSpeed(int speed)
{ {
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, speed); dsyslog("[softhddev]%s: %d\n", __FUNCTION__, speed);
::TrickSpeed(speed); ::TrickSpeed(speed);
} }
#endif
/** /**
** Clears all video and audio data from the device. ** Clears all video and audio data from the device.
@ -2725,9 +2512,6 @@ uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int width,
if (SuspendMode != NOT_SUSPENDED) { if (SuspendMode != NOT_SUSPENDED) {
return NULL; return NULL;
} }
if (quality < 0) { // caller should care, but fix it
quality = 95;
}
return::GrabImage(&size, jpeg, quality, width, height); return::GrabImage(&size, jpeg, quality, width, height);
} }
@ -2755,8 +2539,8 @@ cRect cSoftHdDevice::CanScaleVideo(const cRect & rect,
void cSoftHdDevice::ScaleVideo(const cRect & rect) void cSoftHdDevice::ScaleVideo(const cRect & rect)
{ {
#ifdef OSD_DEBUG #ifdef OSD_DEBUG
dsyslog("[softhddev]%s: %dx%d%+d%+d\n", __FUNCTION__, rect.Width(), dsyslog("[softhddev]%s: %dx%d%+d%+d\n", __FUNCTION__, VidWinRect.Width(),
rect.Height(), rect.X(), rect.Y()); VidWinRect.Height(), VidWinRect.X(), VidWinRect.Y());
#endif #endif
::ScaleVideo(rect.X(), rect.Y(), rect.Width(), rect.Height()); ::ScaleVideo(rect.X(), rect.Y(), rect.Width(), rect.Height());
} }
@ -3016,10 +2800,6 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
ConfigHideMainMenuEntry = atoi(value); ConfigHideMainMenuEntry = atoi(value);
return true; return true;
} }
if (!strcasecmp(name, "DetachFromMainMenu")) {
ConfigDetachFromMainMenu = atoi(value);
return true;
}
if (!strcasecmp(name, "Osd.Width")) { if (!strcasecmp(name, "Osd.Width")) {
ConfigOsdWidth = atoi(value); ConfigOsdWidth = atoi(value);
VideoSetOsdSize(ConfigOsdWidth, ConfigOsdHeight); VideoSetOsdSize(ConfigOsdWidth, ConfigOsdHeight);
@ -3069,10 +2849,6 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
VideoSetBlackPicture(ConfigVideoBlackPicture = atoi(value)); VideoSetBlackPicture(ConfigVideoBlackPicture = atoi(value));
return true; return true;
} }
if (!strcasecmp(name, "ClearOnSwitch")) {
ConfigVideoClearOnSwitch = atoi(value);
return true;
}
if (!strcasecmp(name, "Brightness")) { if (!strcasecmp(name, "Brightness")) {
VideoSetBrightness(ConfigVideoBrightness = atoi(value)); VideoSetBrightness(ConfigVideoBrightness = atoi(value));
return true; return true;
@ -3219,11 +2995,6 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
ConfigAudioBufferTime = atoi(value); ConfigAudioBufferTime = atoi(value);
return true; return true;
} }
if (!strcasecmp(name, "AudioAutoAES")) {
ConfigAudioAutoAES = atoi(value);
AudioSetAutoAES(ConfigAudioAutoAES);
return true;
}
#ifdef USE_PIP #ifdef USE_PIP
if (!strcasecmp(name, "pip.X")) { if (!strcasecmp(name, "pip.X")) {
ConfigPipX = atoi(value); ConfigPipX = atoi(value);
@ -3290,15 +3061,6 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
return true; return true;
} }
#endif #endif
#ifdef USE_SCREENSAVER
if (!strcasecmp(name, "EnableDPMSatBlackScreen")) {
ConfigEnableDPMSatBlackScreen = atoi(value);
SetDPMSatBlackScreen(ConfigEnableDPMSatBlackScreen);
return true;
}
#endif
return false; return false;
} }
@ -3418,7 +3180,7 @@ static const char *SVDRPHelpText[] = {
" 11: enable audio pass-through\n" " 11: enable audio pass-through\n"
" 12: toggle audio pass-through\n" " 12: toggle audio pass-through\n"
" 13: decrease audio delay by 10ms\n" " 13: decrease audio delay by 10ms\n"
" 14: increase audio delay by 10ms\n" " 15: toggle ac3 mixdown\n" " 14: increase audio delay by 10ms\n"
" 20: disable fullscreen\n\040 21: enable fullscreen\n" " 20: disable fullscreen\n\040 21: enable fullscreen\n"
" 22: toggle fullscreen\n" " 22: toggle fullscreen\n"
" 23: disable auto-crop\n\040 24: enable auto-crop\n" " 23: disable auto-crop\n\040 24: enable auto-crop\n"

View File

@ -1,7 +1,7 @@
/// ///
/// @file softhddevice.h @brief software HD device plugin header file. /// @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): /// Contributor(s):
/// ///

View File

@ -0,0 +1,74 @@
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
EAPI="4"
inherit eutils vdr-plugin-2
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 opengl debug"
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 )
"
src_prepare() {
vdr-plugin-2_src_prepare
}
src_compile() {
local myconf
myconf="-DHAVE_PTHREAD_NAME -DAV_INFO -DAV_INFO_TIME=15000"
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"
#vdr-plugin-2_src_compile
cd "${S}"
BUILD_TARGETS=${BUILD_TARGETS:-${VDRPLUGIN_MAKE_TARGET:-all}}
emake ${BUILD_PARAMS} CONFIG="${myconf}" \
${BUILD_TARGETS} \
LOCALEDIR="${TMP_LOCALE_DIR}" \
LIBDIR="${S}" \
TMPDIR="${T}" \
|| die "emake failed"
}
src_install() {
vdr-plugin-2_src_install
}

View File

@ -1,73 +1,65 @@
# Copyright 1999-2014 Gentoo Foundation # Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2 # Distributed under the terms of the GNU General Public License v2
# $Header: $ # $Header: $
EAPI="5" EAPI="5"
inherit vdr-plugin-2 git-2 inherit flag-o-matic toolchain-funcs vdr-plugin-2 eutils
RESTRICT="test" if [ "${PV}" = "9999" ]; then
inherit git-2
EGIT_REPO_URI="git://projects.vdr-developer.org/vdr-plugin-softhddevice.git"
KEYWORDS=""
else
SRC_URI="mirror://vdr-developerorg/889/${P}.tgz"
KEYWORDS="~amd64 ~x86"
fi
EGIT_REPO_URI="git://projects.vdr-developer.org/vdr-plugin-softhddevice.git" DESCRIPTION="Software and GPU emulated HD output device plugin for VDR"
KEYWORDS=""
DESCRIPTION="VDR Plugin: Software and GPU emulated HD output device"
HOMEPAGE="http://projects.vdr-developer.org/projects/show/plg-softhddevice" HOMEPAGE="http://projects.vdr-developer.org/projects/show/plg-softhddevice"
LICENSE="AGPL-3" LICENSE="AGPL-3"
SLOT="0" SLOT="0"
IUSE="alsa +debug opengl oss vaapi vdpau xscreensaver" IUSE="alsa oss vaapi vdpau yaepg xscreensaver debug"
RDEPEND=">=media-video/vdr-2 RDEPEND=">=media-video/vdr-1.7
>=virtual/ffmpeg-0.7[vdpau?,vaapi?]
x11-libs/libX11 x11-libs/libX11
>=x11-libs/libxcb-1.8 >=x11-libs/libxcb-1.8
x11-libs/xcb-util-wm x11-libs/xcb-util-wm
x11-libs/xcb-util-keysyms
x11-libs/xcb-util-renderutil
alsa? ( media-libs/alsa-lib ) alsa? ( media-libs/alsa-lib )
opengl? ( virtual/opengl ) vdpau? ( x11-libs/libvdpau )
vaapi? ( x11-libs/libva vaapi? ( x11-libs/libva )
virtual/ffmpeg[vaapi] ) alsa? ( media-libs/alsa-lib )
vdpau? ( x11-libs/libvdpau yaepg? ( >=media-video/vdr-1.7[yaepg] )"
virtual/ffmpeg[vdpau] )"
DEPEND="${RDEPEND} DEPEND="${RDEPEND}
x11-libs/xcb-util
sys-devel/gettext
virtual/pkgconfig virtual/pkgconfig
x11-libs/xcb-util" oss? ( sys-kernel/linux-headers )"
REQUIRED_USE="opengl? ( vaapi ) src_compile() {
|| ( vaapi vdpau ) local myconf
|| ( alsa oss )"
#VDR_CONFD_FILE="${FILESDIR}/confd-0.6.0" myconf+=" ALSA=$(usex alsa 1 0)"
#VDR_RCADDON_FILE="${FILESDIR}/rc-addon-0.6.0.sh" myconf+=" OSS=$(usex oss 1 0)"
myconf+=" VDPAU=$(usex vdpau 1 0)"
pkg_setup() { myconf+=" VAAPI=$(usex vaapi 1 0)"
vdr-plugin-2_pkg_setup myconf+=" SCREENSAVER=$(usex xscreensaver 1 0)"
if has_version ">=media-video/ffmpeg-0.8" ; then
append-cppflags -DHAVE_PTHREAD_NAME myconf+=" SWRESAMPLE=1"
use debug && append-cppflags -DDEBUG -DOSD_DEBUG
}
src_prepare() {
vdr-plugin-2_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)"
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 fi
append-cflags -DHAVE_PTHREAD_NAME -D_GNU_SOURCE
append-cxxflags -DHAVE_PTHREAD_NAME -D_GNU_SOURCE
tc-export CC CXX
BUILD_PARAMS="${myconf}"
vdr-plugin-2_src_compile
} }
src_install() { src_install() {
vdr-plugin-2_src_install vdr-plugin-2_src_install
nonfatal dodoc ChangeLog Todo dodoc ChangeLog README.txt
} }

1751
video.c

File diff suppressed because it is too large Load Diff

18
video.h
View File

@ -1,7 +1,7 @@
/// ///
/// @file video.h @brief Video module header file /// @file video.h @brief Video module header file
/// ///
/// Copyright (c) 2009 - 2015 by Johns. All Rights Reserved. /// Copyright (c) 2009 - 2013 by Johns. All Rights Reserved.
/// ///
/// Contributor(s): /// Contributor(s):
/// ///
@ -37,7 +37,7 @@ typedef struct __video_stream__ VideoStream;
// Variables // Variables
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
extern signed char VideoHardwareDecoder; ///< flag use hardware decoder extern char VideoHardwareDecoder; ///< flag use hardware decoder
extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
extern int VideoAudioDelay; ///< audio/video delay extern int VideoAudioDelay; ///< audio/video delay
extern char ConfigStartX11Server; ///< flag start the x11 server extern char ConfigStartX11Server; ///< flag start the x11 server
@ -67,8 +67,8 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *, extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
const AVFrame *); const AVFrame *);
/// Get hwaccel context for ffmpeg. /// Get ffmpeg vaapi context.
extern void *VideoGetHwAccelContext(VideoHwDecoder *); extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
#ifdef AVCODEC_VDPAU_H #ifdef AVCODEC_VDPAU_H
/// Draw vdpau render state. /// Draw vdpau render state.
@ -168,8 +168,7 @@ extern void VideoSetAutoCrop(int, int, int);
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, int, const uint8_t *, int, extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
int);
/// Get OSD size. /// Get OSD size.
extern void VideoGetOsdSize(int *, int *); extern void VideoGetOsdSize(int *, int *);
@ -222,10 +221,7 @@ extern int VideoDecodeInput(VideoStream *);
/// Get number of input buffers. /// Get number of input buffers.
extern int VideoGetBuffers(const VideoStream *); extern int VideoGetBuffers(const VideoStream *);
/// Set DPMS at Blackscreen switch /// Raise the frontend window
extern void SetDPMSatBlackScreen(int); extern int VideoRaiseWindow();
/// Raise the frontend window
extern int VideoRaiseWindow(void);
/// @} /// @}