mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
185 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e10e62dcf7 | ||
|
|
2a1793c98e | ||
|
|
30d4586448 | ||
|
|
aa4debc9c8 | ||
| ac2e10a308 | |||
|
|
c986d285ea | ||
|
|
8612044b9b | ||
|
|
c19b86411a | ||
|
|
9165052d5e | ||
|
|
413983a666 | ||
|
|
f86fa4edd7 | ||
|
|
7f8110557f | ||
|
|
c9b344a3fd | ||
|
|
b41f934c37 | ||
|
|
6058f3da56 | ||
| 689d75b808 | |||
|
|
bd4503f30b | ||
|
|
24ba8175a3 | ||
|
|
fe24cbb182 | ||
|
|
6eff8fa818 | ||
|
|
552a994db3 | ||
|
|
d24f19bc2d | ||
|
|
7b570c507c | ||
|
|
09ba3e2993 | ||
|
|
d0f825f831 | ||
|
|
47d2896468 | ||
|
|
f59425ac57 | ||
|
|
1acdeee913 | ||
|
|
c2938c7ef3 | ||
|
|
d65fe88c83 | ||
|
|
7d3f4f4434 | ||
|
|
acc35fe30c | ||
|
|
ee5804fed7 | ||
|
|
1cbaddf75c | ||
|
|
226760490b | ||
|
|
7931909e28 | ||
|
|
129c139ed7 | ||
|
|
340816d763 | ||
|
|
d6c6818ecf | ||
|
|
181a0bb372 | ||
|
|
f2d4163899 | ||
|
|
4cc98d7937 | ||
|
|
3812fa8d38 | ||
|
|
da5c5cd5fd | ||
|
|
74a62e3649 | ||
|
|
7e1a42f7ed | ||
|
|
dda9011abc | ||
|
|
de79e9211f | ||
|
|
b0d9f41020 | ||
|
|
4d1a516c80 | ||
|
|
995f1286bd | ||
|
|
fd0ae12f24 | ||
|
|
db258a0fbd | ||
|
|
0df8e8a5fc | ||
|
|
6a28064dce | ||
|
|
b5e9077c74 | ||
|
|
3b4ace14cf | ||
|
|
5aa868c296 | ||
|
|
43b48224b5 | ||
|
|
144f22314f | ||
|
|
51eb720265 | ||
|
|
e977007dd3 | ||
|
|
769f00b4f6 | ||
|
|
aa426cd8b2 | ||
|
|
b2cab00599 | ||
|
|
b54d62ef35 | ||
|
|
9b68248a3e | ||
|
|
762959fbb4 | ||
|
|
07b426f2b5 | ||
|
|
668a6ec277 | ||
|
|
82f61de117 | ||
|
|
67e571f02b | ||
|
|
c17af0e958 | ||
|
|
2561214c3e | ||
|
|
7382bd60ff | ||
|
|
73b93f1aba | ||
|
|
0243b1c8a7 | ||
|
|
6ce760ccd8 | ||
|
|
2f869884ba | ||
|
|
5d8dea1b6b | ||
|
|
1f232db5b4 | ||
|
|
c4ad13c53f | ||
|
|
98f73f2199 | ||
|
|
89ca44206c | ||
|
|
5c9b85b69b | ||
|
|
09cfab3856 | ||
|
|
30e903d90a | ||
|
|
852d367225 | ||
|
|
a7f0cf6d6f | ||
|
|
346953d209 | ||
|
|
97af9c6de2 | ||
|
|
8dd95dab5e | ||
|
|
6775173e4f | ||
|
|
9170fcf485 | ||
|
|
919428cb80 | ||
|
|
4331692ee5 | ||
|
|
5aa826bdb0 | ||
|
|
6736db082e | ||
|
|
807b4df381 | ||
| 56edfd4f54 | |||
|
|
0a1a258d2a | ||
|
|
09a0880d07 | ||
|
|
a98a4adc7e | ||
|
|
f872f54e2a | ||
| 33c638d538 | |||
|
|
0a2a221fa9 | ||
|
|
24a065e5de | ||
|
|
6df970ca9e | ||
|
|
616cd9e133 | ||
|
|
a91533f6d1 | ||
|
|
baa4500a2c | ||
|
|
f28a737a9a | ||
|
|
19cec561ba | ||
|
|
d8f63adaad | ||
|
|
8c16466d31 | ||
|
|
ced54a5cf1 | ||
|
|
08246b5ac3 | ||
|
|
c3a1de8c7b | ||
|
|
918170d00b | ||
|
|
bc50f37c4d | ||
|
|
09cf1f5c85 | ||
|
|
947f6b312e | ||
|
|
99728258f1 | ||
|
|
c972f8c4dd | ||
|
|
7d38dff5bf | ||
|
|
8db8b68edd | ||
|
|
00cafd18ed | ||
|
|
ab4e89132e | ||
|
|
3585f1df19 | ||
|
|
e258c35537 | ||
|
|
91dbe46786 | ||
|
|
a7389111ff | ||
|
|
27e9a88e2f | ||
|
|
33e9c71aea | ||
|
|
bd84e3f3b9 | ||
|
|
364cc04736 | ||
| ec4a899bb8 | |||
|
|
dab31e2367 | ||
|
|
e613ff1f7e | ||
|
|
1886b745e5 | ||
|
|
422c378a5e | ||
|
|
eed708b9ea | ||
|
|
60a7c36fa6 | ||
|
|
4d74ed1bfc | ||
|
|
c3b924a239 | ||
|
|
f8d198636b | ||
|
|
bcf6ecabc1 | ||
|
|
9063b4e3ff | ||
|
|
e3681812bd | ||
|
|
9d14522121 | ||
| 2dff69dc14 | |||
|
|
5668fa22d2 | ||
|
|
c7cebe1aeb | ||
|
|
037f582bad | ||
|
|
6ca4d3c44f | ||
|
|
2ac2eb39c6 | ||
|
|
217545542d | ||
|
|
5f43803236 | ||
|
|
993d831190 | ||
|
|
1969b2a0a7 | ||
|
|
0fad02285d | ||
|
|
9546233175 | ||
|
|
98d2e0f728 | ||
| 970493fb23 | |||
|
|
329dbc5f07 | ||
|
|
bc8a13e1ef | ||
|
|
bd7e6143c7 | ||
|
|
fa27a1c73a | ||
|
|
e32857a27a | ||
|
|
5ba88bb822 | ||
|
|
0422b6aa5a | ||
|
|
eb024558de | ||
|
|
1593d5dd83 | ||
|
|
09f62307d4 | ||
|
|
87f7aa63cc | ||
|
|
b1ce88923e | ||
|
|
c6e66e0787 | ||
|
|
19d4eeed82 | ||
|
|
9f668c4750 | ||
|
|
e419742a40 | ||
|
|
2cacdc6c90 | ||
|
|
6efe558f78 | ||
|
|
80100299f3 | ||
|
|
5509d768ac | ||
|
|
c0d0a4ae7c |
222
ChangeLog
222
ChangeLog
@@ -1,4 +1,226 @@
|
|||||||
User johns
|
User johns
|
||||||
|
Date: Sat Apr 7 20:21:16 CEST 2012
|
||||||
|
|
||||||
|
Release Version 0.5.0
|
||||||
|
Change audio/video delay with hot-key.
|
||||||
|
Enable/disable/toggle fullscreen with hot-key (Feature #930).
|
||||||
|
|
||||||
|
User: CafeDelMar
|
||||||
|
Date: Thu Apr 5 22:44:06 CEST 2012
|
||||||
|
|
||||||
|
Cutting pixels are now configured for each resolution.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Thu Apr 5 15:47:59 CEST 2012
|
||||||
|
|
||||||
|
Buffer less video and audio.
|
||||||
|
Fix 100% cpu use, with mp3 plugin.
|
||||||
|
Audio/Video sync rewrite, trick-speed support moved to video.
|
||||||
|
Faster VdpauBlackSurface version.
|
||||||
|
Fix bug: VideoSetPts wrong position for multi frame packets.
|
||||||
|
|
||||||
|
User: CafeDelMar
|
||||||
|
Date: Mon Mar 26 20:45:54 CEST 2012
|
||||||
|
|
||||||
|
Add VideoSkipPixels support.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Fri Mar 23 18:43:20 CET 2012
|
||||||
|
|
||||||
|
Add optional argument (display) to ATTA svdrp commmand.
|
||||||
|
Wakeup display to show OSD for remote learning mode.
|
||||||
|
Support switching the primary device with svdrp.
|
||||||
|
Disable and reenable screen saver and DPMS.
|
||||||
|
Video source code cleanup.
|
||||||
|
Fix fast backward with some h264 streams.
|
||||||
|
Make soft start sync setup menu configurable.
|
||||||
|
Fix bug: StillPicture NAL end of sequence is 10 and not 0x10.
|
||||||
|
Fix bug: AudioEnqueue crash without sound card.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Sun Mar 4 22:35:36 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.9
|
||||||
|
Experimental ac3 audio drift correction support.
|
||||||
|
Removes LPCM detection from TS parser.
|
||||||
|
Rewrote video/audio start code.
|
||||||
|
Add support for attach/detach plugin.
|
||||||
|
OSS needs bigger audio buffers.
|
||||||
|
Improved audio drift correction support.
|
||||||
|
Experimental audio drift correction support.
|
||||||
|
Add SVDRP HOTK command support.
|
||||||
|
Increased audio buffer time for PES packets.
|
||||||
|
Support configuration and set of video background.
|
||||||
|
Survive lost X11 display.
|
||||||
|
Fix bug: 100% cpu use with plugins like mp3.
|
||||||
|
Wakeup display thread on channel switch, osd can now be shown without
|
||||||
|
video.
|
||||||
|
Makes 60Hz display mode configurable with setup.conf.
|
||||||
|
Support downmix of AC-3 to stero.
|
||||||
|
New audio PES packet parser.
|
||||||
|
Fix bug: Grabbing a JPG image fails while suspended.
|
||||||
|
Add support for hot keys.
|
||||||
|
Add support to use characters input in edit mode.
|
||||||
|
Adds trick speed support.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Thu Feb 16 09:59:14 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.8
|
||||||
|
Fix bug: wrong start of video packet.
|
||||||
|
VDPAU: Enables inverse telecine configuration.
|
||||||
|
Find AC3 (Dolby Digital) inside PES packet.
|
||||||
|
Fix bug: audio increments invalid audio PTS.
|
||||||
|
Fix bug: dvd plugin not working.
|
||||||
|
Fix bug: used frame-> instead of video_ctx-> for old libav/ffmpeg.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Mon Feb 13 23:20:26 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.7
|
||||||
|
|
||||||
|
User FireFly
|
||||||
|
Date: Mon Feb 13 20:14:11 CET 2012
|
||||||
|
|
||||||
|
Fix bug: unscaled jpeg includes PNG header.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Mon Feb 13 14:58:26 CET 2012
|
||||||
|
|
||||||
|
VDPAU: Studio levels could be configured in the setup menu.
|
||||||
|
Window size defaults to fullscreen, if no geometry is given.
|
||||||
|
|
||||||
|
User m.Rcu
|
||||||
|
Date: Sun Feb 12 20:28:22 CET 2012
|
||||||
|
|
||||||
|
Jpeg screengrab use VDR RgbToJpeg function.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Sun Feb 12 20:14:43 CET 2012
|
||||||
|
|
||||||
|
Add play/pause audio support.
|
||||||
|
Fix bug: audible glitch when switching AC-3 pass-through <-> none.
|
||||||
|
Fix bug: mpeg stills not displayed.
|
||||||
|
Detect audio stream type only after stream switch.
|
||||||
|
Detect more h264 streams with leading zeros.
|
||||||
|
VDPAU: support for studio levels added.
|
||||||
|
Add support for skip chroma deinterlace to software deinterlacer.
|
||||||
|
Type of software deinterlacer now configurable from setup menu.
|
||||||
|
Mixer channel could be set through command line option.
|
||||||
|
Fix bug: LFE moved to wrong position.
|
||||||
|
Guard suspend/resume against multiple calls.
|
||||||
|
Add support for AAC LATM audio streams.
|
||||||
|
Fix bug: alsa and ffmpeg use different channel layout.
|
||||||
|
Support more LPCM sample rates and number of channels.
|
||||||
|
Quick&dirty support for mpeg LPCM streams.
|
||||||
|
Workaround for text2skin undrawn OSD areas.
|
||||||
|
Detect dvb LPCM stream and ignore it.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Thu Feb 2 23:29:35 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.6
|
||||||
|
Warn only on the first duplicated frame in sequence.
|
||||||
|
Increase audio buffer, if bigger audio delay is used.
|
||||||
|
Makes SkipLines configure in setup menu.
|
||||||
|
Auto-crop only enabled with normal 4:3 display mode.
|
||||||
|
Vaapi updates OSD when cropping changes.
|
||||||
|
Add A-V info output and compile time option.
|
||||||
|
Fix bug: VA-API intel software decoder broken by aspect commit.
|
||||||
|
Add support for 4:3 output modes.
|
||||||
|
Quicker auto-crop after channel switch.
|
||||||
|
Add auto-crop support for Intel VA-API backend.
|
||||||
|
Fix bug: Auto-Crop logo skip didn't use displayed width.
|
||||||
|
Workaround for mpeg2 FFMpeg + VA-API + Intel GPU hung.
|
||||||
|
Fix bug: Missing vaSyncSurface and vaDestroyImage.
|
||||||
|
Fix bug: Only black picture with VA-API hw decoder.
|
||||||
|
|
||||||
|
User HelAu
|
||||||
|
Date: Mon Jan 30 16:54:47 CET 2012
|
||||||
|
|
||||||
|
Add support to start the plugin in suspended mode.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Mon Jan 30 15:58:21 CET 2012
|
||||||
|
|
||||||
|
Finished rewrite of video code, to support output modules.
|
||||||
|
Add aspect change support to software decoder path.
|
||||||
|
Repair software decoder with vaapi vdpau backend.
|
||||||
|
Add workaround for Intel VA-API MPEG GPU hung.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Sat Jan 28 13:32:12 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.5
|
||||||
|
Add configurable skip lines at video top and bottom.
|
||||||
|
Add auto-crop tolerance configuration.
|
||||||
|
Reduces audio latency, increases audio buffer time.
|
||||||
|
Made video_test working again.
|
||||||
|
Disabled VA-API Intel vaAssociateSubpicture workaround.
|
||||||
|
Fix bug: Must release lock for VideoPollEvent.
|
||||||
|
Allow faster video and audio sync.
|
||||||
|
Fix bug: Software decoder use vaPutImage with intel backend.
|
||||||
|
Fix bug: Artefacts are shown after mpeg2 channel switch.
|
||||||
|
Fix bug: VideoReleaseSurface called after VideoExit.
|
||||||
|
Support external players.
|
||||||
|
Add VDPAU display preemption support.
|
||||||
|
|
||||||
|
User m.Rcu
|
||||||
|
Date: Tue Jan 24 22:38:30 CET 2012
|
||||||
|
|
||||||
|
Add support for grab jpeg image.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Tue Jan 24 22:25:33 CET 2012
|
||||||
|
|
||||||
|
Fix bug: VaapiOsdExit doesn't deassociate osd surface.
|
||||||
|
Fix bug: First OSD can show random pixels.
|
||||||
|
Wait for X11 exit and kill it, if not.
|
||||||
|
Fix still picture handling.
|
||||||
|
Fix for dead-lock in VdpauExit.
|
||||||
|
Workaround for dead-lock in VdpauExit.
|
||||||
|
VDPAU: Add very primitive software scaler for grab image.
|
||||||
|
VA-API: Add auto-crop support.
|
||||||
|
Suspend can close/open X11 window, connection and audio device.
|
||||||
|
|
||||||
|
User Morone
|
||||||
|
Date: Sun Jan 22 16:43:23 CET 2012
|
||||||
|
|
||||||
|
Use different alsa devices for AC3/pass-through and pcm.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Sun Jan 22 11:12:57 CET 2012
|
||||||
|
|
||||||
|
Add dummy player and control for suspend mode.
|
||||||
|
Buffertime compile time configurable in ms.
|
||||||
|
|
||||||
|
Date: Sat Jan 21 15:49:16 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.4.0
|
||||||
|
VDPAU: Add grab image support.
|
||||||
|
VDPAU: Add auto-crop support.
|
||||||
|
VDPAU: Changed OSD alpha calculation.
|
||||||
|
Fix bug: Used VideoSharpen for denoise settings.
|
||||||
|
Instant update deinterlace/... configuration changes.
|
||||||
|
Fix bug: AudioExit called without AudioInit crash.
|
||||||
|
|
||||||
|
Date: Thu Jan 19 15:58:40 CET 2012
|
||||||
|
|
||||||
|
Release Version 0.3.5
|
||||||
|
OSD improvements:
|
||||||
|
Use OSD size equal to video window.
|
||||||
|
Update only dirty area(s) of OSD.
|
||||||
|
Show/mix only used area of OSD.
|
||||||
|
Fix bug: vpdau use previous resolution for deint, ...
|
||||||
|
Fix software deinterlace with VA-API.
|
||||||
|
Fix bug: transposed digits 567 should be 576.
|
||||||
|
Audio module cleanup:
|
||||||
|
Alsa + OSS can be included/build at the same time.
|
||||||
|
Alsa or OSS can be runtime selected with -a.
|
||||||
|
Add audio thread support to OSS module.
|
||||||
|
Add polled audio support to alsa module.
|
||||||
|
Removed some debug source code.
|
||||||
|
|
||||||
Date: Sun Jan 15 16:56:04 CET 2012
|
Date: Sun Jan 15 16:56:04 CET 2012
|
||||||
|
|
||||||
Release Version 0.3.1
|
Release Version 0.3.1
|
||||||
|
|||||||
24
Makefile
24
Makefile
@@ -14,23 +14,30 @@ PLUGIN = softhddevice
|
|||||||
### The version number of this plugin (taken from the main source file):
|
### 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')
|
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)
|
### Configuration (edit this for your needs)
|
||||||
|
|
||||||
CONFIG := #-DDEBUG
|
CONFIG := #-DDEBUG
|
||||||
#CONFIG += -DHAVE_PTHREAD_NAME
|
#CONFIG += -DUSE_AUDIO_DRIFT_CORRECTION # build new audio drift code
|
||||||
|
#CONFIG += -DUSE_AC3_DRIFT_CORRECTION # build new ac-3 drift code
|
||||||
|
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # debug a/v sync
|
||||||
|
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
|
||||||
|
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
|
||||||
|
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
|
||||||
CONFIG += $(shell pkg-config --exists vdpau && echo "-DUSE_VDPAU")
|
CONFIG += $(shell pkg-config --exists vdpau && echo "-DUSE_VDPAU")
|
||||||
CONFIG += $(shell pkg-config --exists libva && echo "-DUSE_VAAPI")
|
CONFIG += $(shell pkg-config --exists libva && echo "-DUSE_VAAPI")
|
||||||
CONFIG += $(shell pkg-config --exists alsa && echo "-DUSE_ALSA")
|
CONFIG += $(shell pkg-config --exists alsa && echo "-DUSE_ALSA")
|
||||||
#CONFIG += -DUSE_OSS
|
CONFIG += -DUSE_OSS
|
||||||
|
|
||||||
### The C++ compiler and options:
|
### The C++ compiler and options:
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CXX ?= g++
|
CXX ?= g++
|
||||||
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
CFLAGS ?= -g -O2 -W -Wall -Wextra -Winit-self \
|
||||||
-Wdeclaration-after-statement
|
-Wdeclaration-after-statement \
|
||||||
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Woverloaded-virtual
|
-ftree-vectorize -msse3 -flax-vector-conversions
|
||||||
|
CXXFLAGS ?= -g -O2 -W -Wall -Wextra -Werror=overloaded-virtual
|
||||||
|
|
||||||
### The directory environment:
|
### The directory environment:
|
||||||
|
|
||||||
@@ -59,10 +66,11 @@ PACKAGE = vdr-$(ARCHIVE)
|
|||||||
|
|
||||||
INCLUDES += -I$(VDRDIR)/include
|
INCLUDES += -I$(VDRDIR)/include
|
||||||
|
|
||||||
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
|
DEFINES += $(CONFIG) -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' \
|
||||||
|
$(if $(GIT_REV), -DGIT_REV='"$(GIT_REV)"')
|
||||||
|
|
||||||
_CFLAGS = $(DEFINES) $(INCLUDES) \
|
_CFLAGS = $(DEFINES) $(INCLUDES) \
|
||||||
$(shell pkg-config --cflags libavcodec libavformat) \
|
$(shell pkg-config --cflags libavcodec) \
|
||||||
`pkg-config --cflags x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
`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`\
|
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||||
`pkg-config --cflags gl glu` \
|
`pkg-config --cflags gl glu` \
|
||||||
@@ -78,7 +86,7 @@ override CXXFLAGS += $(_CFLAGS)
|
|||||||
override CFLAGS += $(_CFLAGS)
|
override CFLAGS += $(_CFLAGS)
|
||||||
|
|
||||||
LIBS += -lrt \
|
LIBS += -lrt \
|
||||||
$(shell pkg-config --libs libavcodec libavformat) \
|
$(shell pkg-config --libs libavcodec) \
|
||||||
`pkg-config --libs x11 x11-xcb xcb xcb-xv xcb-shm xcb-dpms xcb-atom\
|
`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`\
|
xcb-screensaver xcb-randr xcb-glx xcb-icccm xcb-keysyms`\
|
||||||
`pkg-config --libs gl glu` \
|
`pkg-config --libs gl glu` \
|
||||||
@@ -169,6 +177,6 @@ indent:
|
|||||||
indent $$i; unexpand -a $$i > $$i.up; mv $$i.up $$i; \
|
indent $$i; unexpand -a $$i > $$i.up; mv $$i.up $$i; \
|
||||||
done
|
done
|
||||||
|
|
||||||
video_test: video.c
|
video_test: video.c Makefile
|
||||||
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
|
$(CC) -DVIDEO_TEST -DVERSION='"$(VERSION)"' $(CFLAGS) $(LDFLAGS) $< $(LIBS) \
|
||||||
-o $@
|
-o $@
|
||||||
|
|||||||
144
README.txt
144
README.txt
@@ -20,21 +20,25 @@ $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 VA-API/VA-API (with intel, nvidia and amd backend supported)
|
o Video decoder CPU / VA-API / VDPAU
|
||||||
o Video CPU/VA-API
|
o Video output VA-API / VDPAU
|
||||||
o Video VDPAU/VDPAU
|
o Audio FFMpeg / Alsa / Analog
|
||||||
o Video CPU/VDPAU
|
o Audio FFMpeg / Alsa / Digital
|
||||||
o planned: Video VA-API/Opengl
|
o Audio FFMpeg / OSS / Analog
|
||||||
o planned: Video VDPAU/Opengl
|
o HDMI/SPDIF pass-through
|
||||||
o planned: Video CPU/Xv
|
o YaepgHD support
|
||||||
o planned: Video CPU/Opengl
|
o Software deinterlacer Bob (VA-API only)
|
||||||
o planned: Software Deinterlacer
|
o Autocrop
|
||||||
o planned: Video XvBA/XvBA
|
o Grab image (VDPAU only)
|
||||||
o Audio FFMpeg/Alsa/Analog
|
o Suspend
|
||||||
o Audio FFMpeg/Alsa/Digital
|
o Letterbox, Stretch and Center cut-out video display modes
|
||||||
o Audio FFMpeg/OSS/Analog
|
|
||||||
o Alsa HDMI/SPDIF Passthrough
|
o planned: Video decoder VA-API Branch: vaapi-ext/staging
|
||||||
o planned: OSS HDMI/SPDIF Passthrough
|
o planned: Video output XvBA / Opengl / Xv
|
||||||
|
o planned: VA-API grab image
|
||||||
|
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
||||||
|
o planned: software volume, software channel resample
|
||||||
|
o planned: atmo light support
|
||||||
|
|
||||||
To compile you must have the 'requires' installed.
|
To compile you must have the 'requires' installed.
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ Install:
|
|||||||
http://projects.vdr-developer.org/projects/plg-softhddevice/files
|
http://projects.vdr-developer.org/projects/plg-softhddevice/files
|
||||||
|
|
||||||
tar vxf vdr-softhddevice-*.tar.bz2
|
tar vxf vdr-softhddevice-*.tar.bz2
|
||||||
cd vdr-softhddevice
|
cd softhddevice-*
|
||||||
make VDRDIR=<path-to-your-vdr-files> LIBDIR=.
|
make VDRDIR=<path-to-your-vdr-files> LIBDIR=.
|
||||||
|
|
||||||
You can edit Makefile to enable/disable VDPAU / VA-API / Alsa / OSS
|
You can edit Makefile to enable/disable VDPAU / VA-API / Alsa / OSS
|
||||||
@@ -73,16 +77,28 @@ Setup: environment
|
|||||||
|
|
||||||
DISPLAY=:0.0
|
DISPLAY=:0.0
|
||||||
x11 display name
|
x11 display name
|
||||||
|
NO_HW=1
|
||||||
|
if set don't use the hardware decoders
|
||||||
|
NO_MPEG_HW=1
|
||||||
|
if set don't use the hardware decoder for mpeg1/2
|
||||||
|
STUDIO_LEVELS=1
|
||||||
|
if set use studio levels with vdpau (deprecated use setup)
|
||||||
|
|
||||||
only if alsa is configured
|
only if alsa is configured
|
||||||
ALSA_DEVICE=default
|
ALSA_DEVICE=default
|
||||||
alsa PCM device name
|
alsa PCM device name
|
||||||
|
ALSA_AC3_DEVICE=
|
||||||
|
alsa AC3/pass-though device name
|
||||||
ALSA_MIXER=default
|
ALSA_MIXER=default
|
||||||
alsa control device name
|
alsa control device name
|
||||||
ALSA_MIXER_CHANNEL=PCM
|
ALSA_MIXER_CHANNEL=PCM
|
||||||
alsa control channel name
|
alsa control channel name
|
||||||
|
|
||||||
only if oss is configured
|
only if oss is configured
|
||||||
OSS_AUDIODEV=/dev/dsp
|
OSS_AUDIODEV=/dev/dsp
|
||||||
oss dsp device name
|
oss dsp device name
|
||||||
|
OSS_AC3_AUDIODEV=
|
||||||
|
oss AC3/pass-though 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
|
||||||
@@ -98,7 +114,7 @@ Setup: /etc/vdr/setup.conf
|
|||||||
softhddevice.HideMainMenuEntry = 0
|
softhddevice.HideMainMenuEntry = 0
|
||||||
0 = show softhddevice main menu entry, 1 = hide entry
|
0 = show softhddevice main menu entry, 1 = hide entry
|
||||||
|
|
||||||
<res> of the next parameters is 567i, 720p, 1080i_fake or 1080i.
|
<res> of the next parameters is 576i, 720p, 1080i_fake or 1080i.
|
||||||
1080i_fake is 1280x1080 or 1440x1080
|
1080i_fake is 1280x1080 or 1440x1080
|
||||||
1080i is "real" 1920x1080
|
1080i is "real" 1920x1080
|
||||||
|
|
||||||
@@ -112,6 +128,9 @@ Setup: /etc/vdr/setup.conf
|
|||||||
softhddevice.<res>.SkipChromaDeinterlace = 0
|
softhddevice.<res>.SkipChromaDeinterlace = 0
|
||||||
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
0 = disabled, 1 = enabled (for slower cards, poor qualit<69>t)
|
||||||
|
|
||||||
|
softhddevice.<res>.InverseTelecine = 0
|
||||||
|
0 = disabled, 1 = enabled
|
||||||
|
|
||||||
softhddevice.<res>.Denoise = 0
|
softhddevice.<res>.Denoise = 0
|
||||||
0 .. 1000 noise reduction level (0 off, 1000 max)
|
0 .. 1000 noise reduction level (0 off, 1000 max)
|
||||||
|
|
||||||
@@ -119,12 +138,69 @@ Setup: /etc/vdr/setup.conf
|
|||||||
-1000 .. 1000 noise reduction level (0 off, -1000 max blur,
|
-1000 .. 1000 noise reduction level (0 off, -1000 max blur,
|
||||||
1000 max sharp)
|
1000 max sharp)
|
||||||
|
|
||||||
|
softhddevice.<res>.CutTopBottom = 0
|
||||||
|
Cut 'n' pixels at at top and bottom of the video picture.
|
||||||
|
|
||||||
|
softhddevice.<res>.CutLeftRight = 0
|
||||||
|
Cut 'n' pixels at at left and right of the video picture.
|
||||||
|
|
||||||
softhddevice.AudioDelay = 0
|
softhddevice.AudioDelay = 0
|
||||||
+n or -n ms
|
+n or -n ms
|
||||||
|
delay audio or delay video
|
||||||
|
|
||||||
softhddevice.AudioPassthrough = 0
|
softhddevice.AudioPassthrough = 0
|
||||||
0 = none, 1 = AC-3
|
0 = none, 1 = AC-3
|
||||||
|
|
||||||
|
for AC-3 the pass-through device is used.
|
||||||
|
|
||||||
|
softhddevice.AudioDownmix = 0
|
||||||
|
0 = none, 1 = downmix
|
||||||
|
downmix AC-3 to stero.
|
||||||
|
|
||||||
|
softhddevice.AutoCrop.Interval = 0
|
||||||
|
0 disables auto-crop
|
||||||
|
n each 'n' frames auto-crop is checked.
|
||||||
|
|
||||||
|
softhddevice.AutoCrop.Delay = 0
|
||||||
|
if auto-crop is over 'n' intervals the same, the cropping is
|
||||||
|
used.
|
||||||
|
|
||||||
|
softhddevice.AutoCrop.Tolerance = 0
|
||||||
|
if detected crop area is too small, cut max 'n' pixels at top and
|
||||||
|
bottom.
|
||||||
|
|
||||||
|
softhddevice.Background = 0
|
||||||
|
32bit RGBA background color
|
||||||
|
(Red * 16777216 + Green * 65536 + Blue * 256 + Alpha)
|
||||||
|
or hex RRGGBBAA
|
||||||
|
grey 127 * 16777216 + 127 * 65536 + 127 * 256 => 2139062016
|
||||||
|
in the setup menu this is entered as (24bit RGB and 8bit Alpha)
|
||||||
|
(Red * 65536 + Green * 256 + Blue)
|
||||||
|
|
||||||
|
softhddevice.StudioLevels = 0
|
||||||
|
0 use PC levels (0-255) with vdpau.
|
||||||
|
1 use studio levels (16-235) with vdpau.
|
||||||
|
|
||||||
|
softhddevice.Suspend.Close = 0
|
||||||
|
1 suspend closes x11 window, connection and audio device.
|
||||||
|
(use svdrpsend plug softhddevice RESU to resume, if you have no lirc)
|
||||||
|
|
||||||
|
softhddevice.Suspend.X11 = 0
|
||||||
|
1 suspend stops X11 server (not working yet)
|
||||||
|
|
||||||
|
softhddevice.60HzMode = 0
|
||||||
|
0 disable 60Hz display mode
|
||||||
|
1 enable 60Hz display mode
|
||||||
|
|
||||||
|
softhddevice.SoftStartSync = 0
|
||||||
|
0 disable soft start of audio/video sync
|
||||||
|
1 enable soft start of audio/video sync
|
||||||
|
|
||||||
|
VideoDisplayFormat = ?
|
||||||
|
0 pan and scan
|
||||||
|
1 letter box
|
||||||
|
2 center cut-out
|
||||||
|
|
||||||
Setup: /etc/vdr/remote.conf
|
Setup: /etc/vdr/remote.conf
|
||||||
------
|
------
|
||||||
|
|
||||||
@@ -144,7 +220,34 @@ Setup: /etc/vdr/remote.conf
|
|||||||
Commandline:
|
Commandline:
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Use vdr -h to see the command line arguments support by the plugin.
|
Use vdr -h to see the command line arguments supported by the plugin.
|
||||||
|
|
||||||
|
-a audio_device
|
||||||
|
|
||||||
|
Selects audio output module and device.
|
||||||
|
"" to disable audio output
|
||||||
|
/... to use oss audio module (if compiled with oss
|
||||||
|
support)
|
||||||
|
other to use alsa audio module (if compiled with alsa
|
||||||
|
support)
|
||||||
|
|
||||||
|
SVDRP:
|
||||||
|
------
|
||||||
|
|
||||||
|
Use 'svdrpsend.pl plug softhddevice HELP'
|
||||||
|
or 'svdrpsend plug softhddevice HELP' to see the SVDRP commands help
|
||||||
|
and which are supported by the plugin.
|
||||||
|
|
||||||
|
Keymacros:
|
||||||
|
----------
|
||||||
|
|
||||||
|
See keymacros.conf how to setup the macros.
|
||||||
|
|
||||||
|
This are the supported key sequences:
|
||||||
|
|
||||||
|
@softhddevice Blue 1 0 disable pass-through
|
||||||
|
@softhddevice Blue 1 1 enable pass-through
|
||||||
|
@softhddevice Blue 1 2 toggle pass-through
|
||||||
|
|
||||||
Running:
|
Running:
|
||||||
--------
|
--------
|
||||||
@@ -182,6 +285,11 @@ Requires:
|
|||||||
x11-libs/xvba-video
|
x11-libs/xvba-video
|
||||||
XVBA Backend for Video Acceleration (VA) API
|
XVBA Backend for Video Acceleration (VA) API
|
||||||
http://www.freedesktop.org/wiki/Software/vaapi
|
http://www.freedesktop.org/wiki/Software/vaapi
|
||||||
|
|
||||||
|
x11-libs/libvdpau
|
||||||
|
VDPAU wrapper and trace libraries
|
||||||
|
http://www.freedesktop.org/wiki/Software/VDPAU
|
||||||
|
|
||||||
x11-libs/libxcb,
|
x11-libs/libxcb,
|
||||||
X C-language Bindings library
|
X C-language Bindings library
|
||||||
http://xcb.freedesktop.org
|
http://xcb.freedesktop.org
|
||||||
|
|||||||
98
Todo
98
Todo
@@ -19,71 +19,92 @@ GNU Affero General Public License for more details.
|
|||||||
$Id: $
|
$Id: $
|
||||||
|
|
||||||
missing:
|
missing:
|
||||||
software deinterlace
|
more software deinterlace (yadif, ...)
|
||||||
auto crop
|
more software decoder with software deinterlace
|
||||||
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
suspend output / energie saver: stop and restart X11
|
||||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
suspend plugin didn't restore full-screen (is this wanted?)
|
||||||
suspend output / energie saver: stop audio, stop video, configurable
|
|
||||||
Option deinterlace off / deinterlace force!
|
Option deinterlace off / deinterlace force!
|
||||||
Make output drivers better moduluar.
|
ColorSpace aren't configurable with the gui.
|
||||||
|
works for me: restart vdr not working, when started x11 was killed.
|
||||||
|
|
||||||
|
video:
|
||||||
|
subtitle not cleared
|
||||||
|
subtitle could be asyncron
|
||||||
|
grab image with hardware and better scaling support
|
||||||
|
yaepghd changed position is lost on channel switch
|
||||||
|
pause (live tv) has sometime problems with SAT1 HD Pro7 HD
|
||||||
|
radio show black background
|
||||||
|
radio no need to wait on video buffers
|
||||||
|
starting with radio and own X11 server, shows no video
|
||||||
|
some low-bandwidth tv channels have hiccups.
|
||||||
|
|
||||||
vdpau:
|
vdpau:
|
||||||
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
software decoder path not working
|
||||||
1080i with temporal spatial too slow with my GT 520 on some channels
|
|
||||||
SkipChromaDeinterlace improves performance
|
|
||||||
Improve OSD handling, show only what is used. Big OSD costs performance
|
|
||||||
VdpPreemptionCallback handling
|
|
||||||
hard channel switch
|
|
||||||
suspendoutput didn't show logo or black picture.
|
|
||||||
|
|
||||||
libva:
|
libva:
|
||||||
hard channel switch
|
|
||||||
yaepghd (VaapiSetOutputPosition) support
|
yaepghd (VaapiSetOutputPosition) support
|
||||||
|
can associate only displayed part of osd
|
||||||
|
grab image for va-api
|
||||||
|
remove stderr output of libva init
|
||||||
|
still many: (workaround export NO_MPEG_HW=1)
|
||||||
|
[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
|
||||||
|
[drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ...
|
||||||
|
|
||||||
|
libva: branch vaapi-ext / staging
|
||||||
|
add support for vaapi-ext / staging
|
||||||
|
|
||||||
libva-intel-driver:
|
libva-intel-driver:
|
||||||
intel still has hangups most with 1080i
|
deinterlace only supported with vaapi-ext
|
||||||
1080i does no v-sync (workaround written)
|
1080i does no v-sync (sometimes correct working with vaapi-ext)
|
||||||
osd has sometimes wrong size (workaround written)
|
OSD has sometimes wrong size (workaround written)
|
||||||
|
sometimes software decoder deinterlace isn't working and 1080i channels
|
||||||
|
show artefacts
|
||||||
|
|
||||||
libva-vdpau-driver:
|
libva-vdpau-driver:
|
||||||
G210 osd update too slow (needs hardware problem workaround)
|
G210/GT520 OSD update too slow (needs hardware problem workaround)
|
||||||
OSD update is too slow
|
|
||||||
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
||||||
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
||||||
|
OSD still has some problems with auto-crop and 4:3 zoom.
|
||||||
|
|
||||||
libva-xvba-driver:
|
libva-xvba-driver:
|
||||||
|
|
||||||
x11:
|
x11:
|
||||||
disable screensaver
|
skip multiple configure-notify, handle only the last one.
|
||||||
|
support embedded mode
|
||||||
|
|
||||||
|
audio:
|
||||||
|
Combine alsa+oss ringbuffer code.
|
||||||
|
Make alsa thread/polled and oss thread/polled output module runtime
|
||||||
|
selectable.
|
||||||
|
software volume support (could be done with asound.conf)
|
||||||
|
Mute should do a real mute and not only set volume to zero.
|
||||||
|
Starting suspended and muted, didn't register the mute.
|
||||||
|
Relaxed audio sync checks at end of packet and already in sync
|
||||||
|
samplerate problem resume/suspend.
|
||||||
|
only wait for video start, if video is running.
|
||||||
|
Not primary device, don't use and block audio/video.
|
||||||
|
multiple open of audio device, reduce them.
|
||||||
|
|
||||||
audio/alsa:
|
audio/alsa:
|
||||||
done? video/audio asyncron
|
|
||||||
random crashes in av_parser_parse2, when switching channels
|
|
||||||
sometimes alsa hangs
|
|
||||||
fixed? snd_pcm_state: Assertion `pcm' failed. while switching channels
|
|
||||||
(thread problem)
|
|
||||||
|
|
||||||
better downmix of >2 channels on 2 channel hardware
|
better downmix of >2 channels on 2 channel hardware
|
||||||
remix support of unsupported sample rates
|
remix support of unsupported sample rates
|
||||||
libav supports only resample of mono to 2 channels
|
libav supports only resample of mono to 2 channels
|
||||||
ffmpeg didn't support resample of 5 to 2 channels
|
ffmpeg didn't support resample of 5 to 2 channels
|
||||||
CodecAudioOpen can fail "can't open audio codec" and does Fatal exit.
|
|
||||||
|
|
||||||
audio:
|
|
||||||
write TS -> PES parser, which feeds audio before the next start packet
|
|
||||||
|
|
||||||
audio/oss:
|
audio/oss:
|
||||||
alsa oss emulation mixer "pcm" not working
|
alsa oss emulation mixer "pcm" not working
|
||||||
|
oss4 mixer channel not working
|
||||||
ring buffer overflow with alsa oss emulation
|
ring buffer overflow with alsa oss emulation
|
||||||
|
|
||||||
HDMI/SPDIF Passthrough:
|
HDMI/SPDIF Passthrough:
|
||||||
only AC-3 written
|
only AC-3 written
|
||||||
Channels are wrong setup, if changing setting during operation.
|
|
||||||
split pcm and ac-3 out into two devices
|
|
||||||
|
|
||||||
playback of recording
|
playback of recording
|
||||||
pause is not reset, when replay exit
|
pause is not reset, when replay exit (fixed?)
|
||||||
replay/pause need 100% cpu
|
replay/pause need 100% cpu (fixed?)
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
mp3 plugin needs 100% cpu (bad ::Poll)
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
Setup of decoder type.
|
Setup of decoder type.
|
||||||
@@ -92,7 +113,10 @@ setup:
|
|||||||
Setup 4:3 zoom type
|
Setup 4:3 zoom type
|
||||||
Some setup parameters are not used until restart.
|
Some setup parameters are not used until restart.
|
||||||
Can a notice be added to the setup menu?
|
Can a notice be added to the setup menu?
|
||||||
576i, 720p, fake 1080i, 1080i
|
|
||||||
|
unsorted:
|
||||||
|
stoping vdr while plugin is suspended opens and closes a window.
|
||||||
|
svdrp prim: support plugin names for device numbers.
|
||||||
|
|
||||||
future features (not planed for 1.0 - 1.5)
|
future features (not planed for 1.0 - 1.5)
|
||||||
|
|
||||||
@@ -102,5 +126,7 @@ future features (not planed for 1.0 - 1.5)
|
|||||||
software decoder for xv / opengl
|
software decoder for xv / opengl
|
||||||
atmolight support
|
atmolight support
|
||||||
multistream handling
|
multistream handling
|
||||||
|
pip support
|
||||||
|
save and use auto-crop with channel zapping
|
||||||
|
|
||||||
upmix stereo to AC-3
|
upmix stereo to AC-3 (supported by alsa plugin)
|
||||||
|
|||||||
27
audio.h
27
audio.h
@@ -30,22 +30,29 @@
|
|||||||
extern void AudioEnqueue(const void *, int); ///< buffer audio samples
|
extern void AudioEnqueue(const void *, int); ///< buffer audio samples
|
||||||
extern void AudioFlushBuffers(void); ///< flush audio buffers
|
extern void AudioFlushBuffers(void); ///< flush audio buffers
|
||||||
extern void AudioPoller(void); ///< poll audio events/handling
|
extern void AudioPoller(void); ///< poll audio events/handling
|
||||||
|
|
||||||
extern int AudioFreeBytes(void); ///< free bytes in audio output
|
extern int AudioFreeBytes(void); ///< free bytes in audio output
|
||||||
|
extern int AudioUsedBytes(void); ///< used bytes in audio output
|
||||||
//extern int AudioUsedBytes(void); ///< used bytes in audio output
|
extern int64_t AudioGetDelay(void); ///< get current audio delay
|
||||||
extern void AudioSetClock(int64_t); ///< set audio clock base
|
extern void AudioSetClock(int64_t); ///< set audio clock base
|
||||||
extern int64_t AudioGetClock(); ///< get current audio clock
|
extern int64_t AudioGetClock(); ///< get current audio clock
|
||||||
extern uint64_t AudioGetDelay(void); ///< get current audio delay
|
|
||||||
|
|
||||||
extern int AudioSetup(int *, int *); ///< setup audio output
|
|
||||||
|
|
||||||
//extern void AudioPlay(void); ///< play audio
|
|
||||||
//extern void AudioPause(void); ///< pause audio
|
|
||||||
extern void AudioSetVolume(int); ///< set volume
|
extern void AudioSetVolume(int); ///< set volume
|
||||||
|
extern int AudioSetup(int *, int *, int); ///< setup audio output
|
||||||
|
|
||||||
extern void AudioSetDevice(const char *); ///< set alsa PCM audio device
|
extern void AudioPlay(void); ///< play audio
|
||||||
|
extern void AudioPause(void); ///< pause audio
|
||||||
|
|
||||||
|
extern void AudioSetBufferTime(int); ///< set audio buffer time
|
||||||
|
|
||||||
|
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
||||||
|
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
||||||
|
extern void AudioSetChannel(const char *); ///< set mixer channel
|
||||||
extern void AudioInit(void); ///< setup audio module
|
extern void AudioInit(void); ///< setup audio module
|
||||||
extern void AudioExit(void); ///< cleanup and exit audio module
|
extern void AudioExit(void); ///< cleanup and exit audio module
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Variables
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
733
codec.c
733
codec.c
@@ -30,13 +30,10 @@
|
|||||||
/// many bugs and incompatiblity in it. Don't use this shit.
|
/// many bugs and incompatiblity in it. Don't use this shit.
|
||||||
///
|
///
|
||||||
|
|
||||||
/**
|
/// compile with passthrough support (stable, ac3 only)
|
||||||
** use av_parser to support insane dvb audio streams.
|
|
||||||
*/
|
|
||||||
#define USE_AVPARSER
|
|
||||||
|
|
||||||
/// compile with passthrough support (experimental)
|
|
||||||
#define USE_PASSTHROUGH
|
#define USE_PASSTHROUGH
|
||||||
|
/// compile audio drift correction support (experimental)
|
||||||
|
#define noUSE_AUDIO_DRIFT_CORRECTION
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -320,20 +317,30 @@ static void Codec_draw_horiz_band(AVCodecContext * video_ctx,
|
|||||||
**
|
**
|
||||||
** @param hw_decoder video hardware decoder
|
** @param hw_decoder video hardware decoder
|
||||||
**
|
**
|
||||||
** @returns private decoder pointer for audio/video decoder.
|
** @returns private decoder pointer for video decoder.
|
||||||
*/
|
*/
|
||||||
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
|
||||||
{
|
{
|
||||||
VideoDecoder *decoder;
|
VideoDecoder *decoder;
|
||||||
|
|
||||||
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
if (!(decoder = calloc(1, sizeof(*decoder)))) {
|
||||||
Fatal(_("codec: Can't allocate vodeo decoder\n"));
|
Fatal(_("codec: can't allocate vodeo decoder\n"));
|
||||||
}
|
}
|
||||||
decoder->HwDecoder = hw_decoder;
|
decoder->HwDecoder = hw_decoder;
|
||||||
|
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Deallocate a video decoder context.
|
||||||
|
**
|
||||||
|
** @param decoder private video decoder
|
||||||
|
*/
|
||||||
|
void CodecVideoDelDecoder(VideoDecoder * decoder)
|
||||||
|
{
|
||||||
|
free(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Open video decoder.
|
** Open video decoder.
|
||||||
**
|
**
|
||||||
@@ -345,8 +352,11 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
|
|||||||
{
|
{
|
||||||
AVCodec *video_codec;
|
AVCodec *video_codec;
|
||||||
|
|
||||||
Debug(3, "codec: using codec %s or ID %#04x\n", name, codec_id);
|
Debug(3, "codec: using video codec %s or ID %#06x\n", name, codec_id);
|
||||||
|
|
||||||
|
if (decoder->VideoCtx) {
|
||||||
|
Error(_("codec: missing close\n"));
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// ffmpeg compatibility hack
|
// ffmpeg compatibility hack
|
||||||
//
|
//
|
||||||
@@ -367,7 +377,7 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
|
|||||||
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 if (!(video_codec = avcodec_find_decoder(codec_id))) {
|
} else if (!(video_codec = avcodec_find_decoder(codec_id))) {
|
||||||
Fatal(_("codec: codec ID %#04x not found\n"), codec_id);
|
Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
|
||||||
// FIXME: none fatal
|
// FIXME: none fatal
|
||||||
}
|
}
|
||||||
decoder->VideoCodec = video_codec;
|
decoder->VideoCodec = video_codec;
|
||||||
@@ -548,13 +558,18 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
video_ctx->frame_number, used);
|
video_ctx->frame_number, used);
|
||||||
}
|
}
|
||||||
if (used != pkt->size) {
|
if (used != pkt->size) {
|
||||||
if (used >= 0) {
|
// ffmpeg 0.8.7 dislikes our seq_end_h264 and enters endless loop here
|
||||||
|
if (used == 0 && pkt->size == 5 && pkt->data[4] == 0x0A) {
|
||||||
|
Warning("codec: ffmpeg 0.8.x workaround used\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (used >= 0 && used < pkt->size) {
|
||||||
// some tv channels, produce this
|
// some tv channels, produce this
|
||||||
Debug(4,
|
Debug(4,
|
||||||
"codec: ooops didn't use complete video packet used %d of %d\n",
|
"codec: ooops didn't use complete video packet used %d of %d\n",
|
||||||
used, pkt->size);
|
used, pkt->size);
|
||||||
pkt->data += used;
|
|
||||||
pkt->size -= used;
|
pkt->size -= used;
|
||||||
|
pkt->data += used;
|
||||||
goto next_part;
|
goto next_part;
|
||||||
}
|
}
|
||||||
Debug(3, "codec: bad frame %d\n", used);
|
Debug(3, "codec: bad frame %d\n", used);
|
||||||
@@ -590,8 +605,7 @@ struct _audio_decoder_
|
|||||||
AVCodec *AudioCodec; ///< audio codec
|
AVCodec *AudioCodec; ///< audio codec
|
||||||
AVCodecContext *AudioCtx; ///< audio codec context
|
AVCodecContext *AudioCtx; ///< audio codec context
|
||||||
|
|
||||||
/// audio parser to support insane dvb streaks
|
int PassthroughAC3; ///< current ac-3 pass-through
|
||||||
AVCodecParserContext *AudioParser;
|
|
||||||
int SampleRate; ///< current stream sample rate
|
int SampleRate; ///< current stream sample rate
|
||||||
int Channels; ///< current stream channels
|
int Channels; ///< current stream channels
|
||||||
|
|
||||||
@@ -600,6 +614,21 @@ struct _audio_decoder_
|
|||||||
|
|
||||||
ReSampleContext *ReSample; ///< audio resampling context
|
ReSampleContext *ReSample; ///< audio resampling context
|
||||||
|
|
||||||
|
int64_t LastDelay; ///< last delay
|
||||||
|
struct timespec LastTime; ///< last time
|
||||||
|
int64_t LastPTS; ///< last PTS
|
||||||
|
|
||||||
|
int Drift; ///< accumulated audio drift
|
||||||
|
int DriftCorr; ///< audio drift correction value
|
||||||
|
int DriftFrac; ///< audio drift fraction for ac3
|
||||||
|
|
||||||
|
struct AVResampleContext *AvResample; ///< second audio resample context
|
||||||
|
#define MAX_CHANNELS 8 ///< max number of channels supported
|
||||||
|
int16_t *Buffer[MAX_CHANNELS]; ///< deinterleave sample buffers
|
||||||
|
int BufferSize; ///< size of sample buffer
|
||||||
|
int16_t *Remain[MAX_CHANNELS]; ///< filter remaining samples
|
||||||
|
int RemainSize; ///< size of remain buffer
|
||||||
|
int RemainCount; ///< number of remaining samples
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
@@ -608,26 +637,38 @@ static char CodecPassthroughAC3; ///< pass ac3 through
|
|||||||
|
|
||||||
//static char CodecPassthroughDTS; ///< pass dts through (unsupported)
|
//static char CodecPassthroughDTS; ///< pass dts through (unsupported)
|
||||||
//static char CodecPassthroughMPA; ///< pass mpa through (unsupported)
|
//static char CodecPassthroughMPA; ///< pass mpa through (unsupported)
|
||||||
|
#else
|
||||||
|
|
||||||
|
static const int CodecPassthroughAC3 = 0;
|
||||||
#endif
|
#endif
|
||||||
|
static char CodecDownmix; ///< enable ac-3 downmix
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Allocate a new audio decoder context.
|
** Allocate a new audio decoder context.
|
||||||
**
|
**
|
||||||
** @param hw_decoder video hardware decoder
|
** @returns private decoder pointer for audio decoder.
|
||||||
**
|
|
||||||
** @returns private decoder pointer for audio/video decoder.
|
|
||||||
*/
|
*/
|
||||||
AudioDecoder *CodecAudioNewDecoder(void)
|
AudioDecoder *CodecAudioNewDecoder(void)
|
||||||
{
|
{
|
||||||
AudioDecoder *audio_decoder;
|
AudioDecoder *audio_decoder;
|
||||||
|
|
||||||
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
||||||
Fatal(_("codec: Can't allocate audio decoder\n"));
|
Fatal(_("codec: can't allocate audio decoder\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return audio_decoder;
|
return audio_decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Deallocate an audio decoder context.
|
||||||
|
**
|
||||||
|
** @param decoder private audio decoder
|
||||||
|
*/
|
||||||
|
void CodecAudioDelDecoder(AudioDecoder * decoder)
|
||||||
|
{
|
||||||
|
free(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Open audio decoder.
|
** Open audio decoder.
|
||||||
**
|
**
|
||||||
@@ -640,10 +681,12 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name,
|
|||||||
{
|
{
|
||||||
AVCodec *audio_codec;
|
AVCodec *audio_codec;
|
||||||
|
|
||||||
|
Debug(3, "codec: using audio codec %s or ID %#06x\n", name, codec_id);
|
||||||
|
|
||||||
if (name && (audio_codec = avcodec_find_decoder_by_name(name))) {
|
if (name && (audio_codec = avcodec_find_decoder_by_name(name))) {
|
||||||
Debug(3, "codec: audio decoder '%s' found\n", name);
|
Debug(3, "codec: audio decoder '%s' found\n", name);
|
||||||
} else if (!(audio_codec = avcodec_find_decoder(codec_id))) {
|
} else if (!(audio_codec = avcodec_find_decoder(codec_id))) {
|
||||||
Fatal(_("codec: codec ID %#04x 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
|
||||||
}
|
}
|
||||||
audio_decoder->AudioCodec = audio_codec;
|
audio_decoder->AudioCodec = audio_codec;
|
||||||
@@ -651,6 +694,12 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name,
|
|||||||
if (!(audio_decoder->AudioCtx = avcodec_alloc_context3(audio_codec))) {
|
if (!(audio_decoder->AudioCtx = avcodec_alloc_context3(audio_codec))) {
|
||||||
Fatal(_("codec: can't allocate audio codec context\n"));
|
Fatal(_("codec: can't allocate audio codec context\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CodecDownmix) {
|
||||||
|
audio_decoder->AudioCtx->request_channels = 2;
|
||||||
|
audio_decoder->AudioCtx->request_channel_layout =
|
||||||
|
AV_CH_LAYOUT_STEREO_DOWNMIX;
|
||||||
|
}
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
// open codec
|
// open codec
|
||||||
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,5,0)
|
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(53,5,0)
|
||||||
@@ -659,27 +708,34 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name,
|
|||||||
Fatal(_("codec: can't open audio codec\n"));
|
Fatal(_("codec: can't open audio codec\n"));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (avcodec_open2(audio_decoder->AudioCtx, audio_codec, NULL) < 0) {
|
if (1) {
|
||||||
|
AVDictionary *av_dict;
|
||||||
|
|
||||||
|
av_dict = NULL;
|
||||||
|
// FIXME: import settings
|
||||||
|
//av_dict_set(&av_dict, "dmix_mode", "0", 0);
|
||||||
|
//av_dict_set(&av_dict, "ltrt_cmixlev", "1.414", 0);
|
||||||
|
//av_dict_set(&av_dict, "loro_cmixlev", "1.414", 0);
|
||||||
|
if (avcodec_open2(audio_decoder->AudioCtx, audio_codec, &av_dict) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't open audio codec\n"));
|
Fatal(_("codec: can't open audio codec\n"));
|
||||||
}
|
}
|
||||||
|
av_dict_free(&av_dict);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Debug(3, "codec: audio '%s'\n", audio_decoder->AudioCtx->codec_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");
|
||||||
// we do not send complete frames
|
// we send only complete frames
|
||||||
audio_decoder->AudioCtx->flags |= CODEC_FLAG_TRUNCATED;
|
// audio_decoder->AudioCtx->flags |= CODEC_FLAG_TRUNCATED;
|
||||||
}
|
|
||||||
if (!(audio_decoder->AudioParser =
|
|
||||||
av_parser_init(audio_decoder->AudioCtx->codec_id))) {
|
|
||||||
Fatal(_("codec: can't init audio parser\n"));
|
|
||||||
}
|
}
|
||||||
audio_decoder->SampleRate = 0;
|
audio_decoder->SampleRate = 0;
|
||||||
audio_decoder->Channels = 0;
|
audio_decoder->Channels = 0;
|
||||||
audio_decoder->HwSampleRate = 0;
|
audio_decoder->HwSampleRate = 0;
|
||||||
audio_decoder->HwChannels = 0;
|
audio_decoder->HwChannels = 0;
|
||||||
|
audio_decoder->LastDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -690,14 +746,25 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name,
|
|||||||
void CodecAudioClose(AudioDecoder * audio_decoder)
|
void CodecAudioClose(AudioDecoder * audio_decoder)
|
||||||
{
|
{
|
||||||
// FIXME: output any buffered data
|
// FIXME: output any buffered data
|
||||||
|
if (audio_decoder->AvResample) {
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
av_resample_close(audio_decoder->AvResample);
|
||||||
|
audio_decoder->AvResample = NULL;
|
||||||
|
audio_decoder->RemainCount = 0;
|
||||||
|
audio_decoder->BufferSize = 0;
|
||||||
|
audio_decoder->RemainSize = 0;
|
||||||
|
for (ch = 0; ch < MAX_CHANNELS; ++ch) {
|
||||||
|
free(audio_decoder->Buffer[ch]);
|
||||||
|
audio_decoder->Buffer[ch] = NULL;
|
||||||
|
free(audio_decoder->Remain[ch]);
|
||||||
|
audio_decoder->Remain[ch] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (audio_decoder->ReSample) {
|
if (audio_decoder->ReSample) {
|
||||||
audio_resample_close(audio_decoder->ReSample);
|
audio_resample_close(audio_decoder->ReSample);
|
||||||
audio_decoder->ReSample = NULL;
|
audio_decoder->ReSample = NULL;
|
||||||
}
|
}
|
||||||
if (audio_decoder->AudioParser) {
|
|
||||||
av_parser_close(audio_decoder->AudioParser);
|
|
||||||
audio_decoder->AudioParser = NULL;
|
|
||||||
}
|
|
||||||
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);
|
||||||
@@ -714,11 +781,350 @@ void CodecSetAudioPassthrough(int mask)
|
|||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
CodecPassthroughAC3 = mask & 1 ? 1 : 0;
|
CodecPassthroughAC3 = mask & 1 ? 1 : 0;
|
||||||
#endif
|
#endif
|
||||||
// FIXME: must update audio decoder (nr. of channels wrong)
|
|
||||||
(void)mask;
|
(void)mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_AVPARSER
|
/**
|
||||||
|
** Set audio downmix.
|
||||||
|
**
|
||||||
|
** @param onoff enable/disable downmix.
|
||||||
|
*/
|
||||||
|
void CodecSetAudioDownmix(int onoff)
|
||||||
|
{
|
||||||
|
CodecDownmix = onoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Reorder audio frame.
|
||||||
|
**
|
||||||
|
** ffmpeg L R C Ls Rs -> alsa L R Ls Rs C
|
||||||
|
** ffmpeg L R C LFE Ls Rs -> alsa L R Ls Rs C LFE
|
||||||
|
** ffmpeg L R C LFE Ls Rs Rl Rr -> alsa L R Ls Rs C LFE Rl Rr
|
||||||
|
**
|
||||||
|
** @param buf[IN,OUT] sample buffer
|
||||||
|
** @param size size of sample buffer in bytes
|
||||||
|
** @param channels number of channels interleaved in sample buffer
|
||||||
|
*/
|
||||||
|
static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int c;
|
||||||
|
int ls;
|
||||||
|
int rs;
|
||||||
|
int lfe;
|
||||||
|
|
||||||
|
switch (channels) {
|
||||||
|
case 5:
|
||||||
|
size /= 2;
|
||||||
|
for (i = 0; i < size; i += 5) {
|
||||||
|
c = buf[i + 2];
|
||||||
|
ls = buf[i + 3];
|
||||||
|
rs = buf[i + 4];
|
||||||
|
buf[i + 2] = ls;
|
||||||
|
buf[i + 3] = rs;
|
||||||
|
buf[i + 4] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
size /= 2;
|
||||||
|
for (i = 0; i < size; i += 6) {
|
||||||
|
c = buf[i + 2];
|
||||||
|
lfe = buf[i + 3];
|
||||||
|
ls = buf[i + 4];
|
||||||
|
rs = buf[i + 5];
|
||||||
|
buf[i + 2] = ls;
|
||||||
|
buf[i + 3] = rs;
|
||||||
|
buf[i + 4] = c;
|
||||||
|
buf[i + 5] = lfe;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
size /= 2;
|
||||||
|
for (i = 0; i < size; i += 8) {
|
||||||
|
c = buf[i + 2];
|
||||||
|
lfe = buf[i + 3];
|
||||||
|
ls = buf[i + 4];
|
||||||
|
rs = buf[i + 5];
|
||||||
|
buf[i + 2] = ls;
|
||||||
|
buf[i + 3] = rs;
|
||||||
|
buf[i + 4] = c;
|
||||||
|
buf[i + 5] = lfe;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Set/update audio pts clock.
|
||||||
|
**
|
||||||
|
** @param audio_decoder audio decoder data
|
||||||
|
** @param pts presentation timestamp
|
||||||
|
*/
|
||||||
|
static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
||||||
|
{
|
||||||
|
struct timespec nowtime;
|
||||||
|
int64_t delay;
|
||||||
|
int64_t tim_diff;
|
||||||
|
int64_t pts_diff;
|
||||||
|
int drift;
|
||||||
|
int corr;
|
||||||
|
|
||||||
|
AudioSetClock(pts);
|
||||||
|
|
||||||
|
delay = AudioGetDelay();
|
||||||
|
if (!delay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clock_gettime(CLOCK_REALTIME, &nowtime);
|
||||||
|
if (!audio_decoder->LastDelay) {
|
||||||
|
audio_decoder->LastTime = nowtime;
|
||||||
|
audio_decoder->LastPTS = pts;
|
||||||
|
audio_decoder->LastDelay = delay;
|
||||||
|
audio_decoder->Drift = 0;
|
||||||
|
audio_decoder->DriftFrac = 0;
|
||||||
|
Debug(3, "codec/audio: inital delay %zd ms\n", delay / 90);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// collect over some time
|
||||||
|
pts_diff = pts - audio_decoder->LastPTS;
|
||||||
|
if (pts_diff < 10 * 1000 * 90) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tim_diff = (nowtime.tv_sec - audio_decoder->LastTime.tv_sec)
|
||||||
|
* 1000 * 1000 * 1000 + (nowtime.tv_nsec -
|
||||||
|
audio_decoder->LastTime.tv_nsec);
|
||||||
|
|
||||||
|
drift =
|
||||||
|
(tim_diff * 90) / (1000 * 1000) - pts_diff + delay -
|
||||||
|
audio_decoder->LastDelay;
|
||||||
|
|
||||||
|
// adjust rounding error
|
||||||
|
nowtime.tv_nsec -= nowtime.tv_nsec % (1000 * 1000 / 90);
|
||||||
|
audio_decoder->LastTime = nowtime;
|
||||||
|
audio_decoder->LastPTS = pts;
|
||||||
|
audio_decoder->LastDelay = delay;
|
||||||
|
|
||||||
|
if (0) {
|
||||||
|
Debug(3, "codec/audio: interval P:%5zdms T:%5zdms D:%4zdms %f %d\n",
|
||||||
|
pts_diff / 90, tim_diff / (1000 * 1000), delay / 90, drift / 90.0,
|
||||||
|
audio_decoder->DriftCorr);
|
||||||
|
}
|
||||||
|
// underruns and av_resample have the same time :(((
|
||||||
|
if (abs(drift) > 10 * 90) {
|
||||||
|
// drift too big, pts changed?
|
||||||
|
Debug(3, "codec/audio: drift(%6d) %3dms reset\n",
|
||||||
|
audio_decoder->DriftCorr, drift / 90);
|
||||||
|
audio_decoder->LastDelay = 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
drift += audio_decoder->Drift;
|
||||||
|
audio_decoder->Drift = drift;
|
||||||
|
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
||||||
|
#if defined(USE_PASSTHROUGH) && !defined(USE_AC3_DRIFT_CORRECTION)
|
||||||
|
// SPDIF/HDMI passthrough
|
||||||
|
if (!CodecPassthroughAC3
|
||||||
|
|| audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
audio_decoder->DriftCorr = -corr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audio_decoder->DriftCorr < -20000) { // limit correction
|
||||||
|
audio_decoder->DriftCorr = -20000;
|
||||||
|
} else if (audio_decoder->DriftCorr > 20000) {
|
||||||
|
audio_decoder->DriftCorr = 20000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME: this works with libav 0.8, and only with >10ms with ffmpeg 0.10
|
||||||
|
if (audio_decoder->AvResample && audio_decoder->DriftCorr) {
|
||||||
|
int distance;
|
||||||
|
|
||||||
|
// try workaround for buggy ffmpeg 0.10
|
||||||
|
if (abs(audio_decoder->DriftCorr) < 2000) {
|
||||||
|
distance = (pts_diff * audio_decoder->HwSampleRate) / (900 * 1000);
|
||||||
|
} else {
|
||||||
|
distance = (pts_diff * audio_decoder->HwSampleRate) / (90 * 1000);
|
||||||
|
}
|
||||||
|
av_resample_compensate(audio_decoder->AvResample,
|
||||||
|
audio_decoder->DriftCorr / 10, distance);
|
||||||
|
}
|
||||||
|
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n", audio_decoder->DriftCorr,
|
||||||
|
drift * 1000 / 90, corr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Handle audio format changes.
|
||||||
|
**
|
||||||
|
** @param audio_decoder audio decoder data
|
||||||
|
*/
|
||||||
|
static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
||||||
|
{
|
||||||
|
const AVCodecContext *audio_ctx;
|
||||||
|
int err;
|
||||||
|
int isAC3;
|
||||||
|
|
||||||
|
// FIXME: use swr_convert from swresample (only in ffmpeg!)
|
||||||
|
if (audio_decoder->ReSample) {
|
||||||
|
audio_resample_close(audio_decoder->ReSample);
|
||||||
|
audio_decoder->ReSample = NULL;
|
||||||
|
}
|
||||||
|
if (audio_decoder->AvResample) {
|
||||||
|
av_resample_close(audio_decoder->AvResample);
|
||||||
|
audio_decoder->AvResample = NULL;
|
||||||
|
audio_decoder->RemainCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
|
Debug(3, "codec/audio: format change %dHz %d channels %s\n",
|
||||||
|
audio_ctx->sample_rate, audio_ctx->channels,
|
||||||
|
CodecPassthroughAC3 ? "pass-through" : "");
|
||||||
|
|
||||||
|
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
||||||
|
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
||||||
|
audio_decoder->Channels = audio_ctx->channels;
|
||||||
|
audio_decoder->PassthroughAC3 = CodecPassthroughAC3;
|
||||||
|
|
||||||
|
// SPDIF/HDMI passthrough
|
||||||
|
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
|
||||||
|
audio_decoder->HwChannels = 2;
|
||||||
|
isAC3 = 1;
|
||||||
|
} else {
|
||||||
|
audio_decoder->HwChannels = audio_ctx->channels;
|
||||||
|
isAC3 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// channels not support?
|
||||||
|
if ((err =
|
||||||
|
AudioSetup(&audio_decoder->HwSampleRate,
|
||||||
|
&audio_decoder->HwChannels, isAC3))) {
|
||||||
|
Debug(3, "codec/audio: resample %dHz *%d -> %dHz *%d\n",
|
||||||
|
audio_ctx->sample_rate, audio_ctx->channels,
|
||||||
|
audio_decoder->HwSampleRate, audio_decoder->HwChannels);
|
||||||
|
|
||||||
|
if (err == 1) {
|
||||||
|
audio_decoder->ReSample =
|
||||||
|
av_audio_resample_init(audio_decoder->HwChannels,
|
||||||
|
audio_ctx->channels, audio_decoder->HwSampleRate,
|
||||||
|
audio_ctx->sample_rate, audio_ctx->sample_fmt,
|
||||||
|
audio_ctx->sample_fmt, 16, 10, 0, 0.8);
|
||||||
|
// libav-0.8_pre didn't support 6 -> 2 channels
|
||||||
|
if (!audio_decoder->ReSample) {
|
||||||
|
Error(_("codec/audio: resample setup error\n"));
|
||||||
|
audio_decoder->HwChannels = 0;
|
||||||
|
audio_decoder->HwSampleRate = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Debug(3, "codec/audio: audio setup error\n");
|
||||||
|
// FIXME: handle errors
|
||||||
|
audio_decoder->HwChannels = 0;
|
||||||
|
audio_decoder->HwSampleRate = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prepare audio drift resample
|
||||||
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
|
if (!isAC3) {
|
||||||
|
if (audio_decoder->AvResample) {
|
||||||
|
Error(_("codec/audio: overwrite resample\n"));
|
||||||
|
}
|
||||||
|
audio_decoder->AvResample =
|
||||||
|
av_resample_init(audio_decoder->HwSampleRate,
|
||||||
|
audio_decoder->HwSampleRate, 16, 10, 0, 0.8);
|
||||||
|
if (!audio_decoder->AvResample) {
|
||||||
|
Error(_("codec/audio: AvResample setup error\n"));
|
||||||
|
} else {
|
||||||
|
// reset drift to some default value
|
||||||
|
audio_decoder->DriftCorr /= 2;
|
||||||
|
audio_decoder->DriftFrac = 0;
|
||||||
|
av_resample_compensate(audio_decoder->AvResample,
|
||||||
|
audio_decoder->DriftCorr / 10,
|
||||||
|
10 * audio_decoder->HwSampleRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Codec enqueue audio samples.
|
||||||
|
**
|
||||||
|
** @param audio_decoder audio decoder data
|
||||||
|
** @param data samples data
|
||||||
|
** @param count number of bytes in sample data
|
||||||
|
*/
|
||||||
|
void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count)
|
||||||
|
{
|
||||||
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
|
if (audio_decoder->AvResample) {
|
||||||
|
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||||
|
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
||||||
|
int16_t buftmp[MAX_CHANNELS][(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4];
|
||||||
|
int consumed;
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
int ch;
|
||||||
|
int bytes_n;
|
||||||
|
|
||||||
|
bytes_n = count / audio_decoder->HwChannels;
|
||||||
|
// resize sample buffer, if needed
|
||||||
|
if (audio_decoder->RemainCount + bytes_n > audio_decoder->BufferSize) {
|
||||||
|
audio_decoder->BufferSize = audio_decoder->RemainCount + bytes_n;
|
||||||
|
for (ch = 0; ch < MAX_CHANNELS; ++ch) {
|
||||||
|
audio_decoder->Buffer[ch] =
|
||||||
|
realloc(audio_decoder->Buffer[ch],
|
||||||
|
audio_decoder->BufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy remaining bytes into sample buffer
|
||||||
|
for (ch = 0; ch < audio_decoder->HwChannels; ++ch) {
|
||||||
|
memcpy(audio_decoder->Buffer[ch], audio_decoder->Remain[ch],
|
||||||
|
audio_decoder->RemainCount);
|
||||||
|
}
|
||||||
|
// deinterleave samples into sample buffer
|
||||||
|
for (i = 0; i < bytes_n / 2; i++) {
|
||||||
|
for (ch = 0; ch < audio_decoder->HwChannels; ++ch) {
|
||||||
|
audio_decoder->Buffer[ch][audio_decoder->RemainCount / 2 + i]
|
||||||
|
= data[i * audio_decoder->HwChannels + ch];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_n += audio_decoder->RemainSize;
|
||||||
|
n = 0; // keep gcc lucky
|
||||||
|
// resample the sample buffer into tmp buffer
|
||||||
|
for (ch = 0; ch < audio_decoder->HwChannels; ++ch) {
|
||||||
|
n = av_resample(audio_decoder->AvResample, buftmp[ch],
|
||||||
|
audio_decoder->Buffer[ch], &consumed, bytes_n / 2,
|
||||||
|
sizeof(buftmp[ch]) / 2, ch == audio_decoder->HwChannels - 1);
|
||||||
|
// fixme remaining channels
|
||||||
|
if (bytes_n - consumed * 2 > audio_decoder->RemainSize) {
|
||||||
|
audio_decoder->RemainSize = bytes_n - consumed * 2;
|
||||||
|
}
|
||||||
|
audio_decoder->Remain[ch] =
|
||||||
|
realloc(audio_decoder->Remain[ch], audio_decoder->RemainSize);
|
||||||
|
memcpy(audio_decoder->Remain[ch],
|
||||||
|
audio_decoder->Buffer[ch] + consumed,
|
||||||
|
audio_decoder->RemainSize);
|
||||||
|
audio_decoder->RemainCount = audio_decoder->RemainSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interleave samples from sample buffer
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
for (ch = 0; ch < audio_decoder->HwChannels; ++ch) {
|
||||||
|
buf[i * audio_decoder->HwChannels + ch] = buftmp[ch][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n *= 2;
|
||||||
|
|
||||||
|
n *= audio_decoder->HwChannels;
|
||||||
|
CodecReorderAudioFrame(buf, n, audio_decoder->HwChannels);
|
||||||
|
AudioEnqueue(buf, n);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CodecReorderAudioFrame(data, count, audio_decoder->HwChannels);
|
||||||
|
AudioEnqueue(data, count);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Decode an audio packet.
|
** Decode an audio packet.
|
||||||
@@ -732,116 +1138,42 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
{
|
{
|
||||||
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
||||||
|
int buf_sz;
|
||||||
|
int l;
|
||||||
AVCodecContext *audio_ctx;
|
AVCodecContext *audio_ctx;
|
||||||
int index;
|
|
||||||
|
|
||||||
//#define spkt avpkt
|
|
||||||
#if 1 // didn't fix crash in av_parser_parse2
|
|
||||||
AVPacket spkt[1];
|
|
||||||
|
|
||||||
// av_new_packet reserves FF_INPUT_BUFFER_PADDING_SIZE and clears it
|
|
||||||
if (av_new_packet(spkt, avpkt->size)) {
|
|
||||||
Error(_("codec: out of memory\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(spkt->data, avpkt->data, avpkt->size);
|
|
||||||
spkt->pts = avpkt->pts;
|
|
||||||
spkt->dts = avpkt->dts;
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!audio_decoder->AudioParser) {
|
|
||||||
Fatal(_("codec: internal error parser freeded while running\n"));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
audio_ctx = audio_decoder->AudioCtx;
|
audio_ctx = audio_decoder->AudioCtx;
|
||||||
index = 0;
|
|
||||||
while (spkt->size > index) {
|
|
||||||
int n;
|
|
||||||
int l;
|
|
||||||
AVPacket dpkt[1];
|
|
||||||
|
|
||||||
av_init_packet(dpkt);
|
|
||||||
n = av_parser_parse2(audio_decoder->AudioParser, audio_ctx,
|
|
||||||
&dpkt->data, &dpkt->size, spkt->data + index, spkt->size - index,
|
|
||||||
!index ? (uint64_t) spkt->pts : AV_NOPTS_VALUE,
|
|
||||||
!index ? (uint64_t) spkt->dts : AV_NOPTS_VALUE, -1);
|
|
||||||
|
|
||||||
// FIXME: make this a function for both #ifdef cases
|
|
||||||
if (dpkt->size) {
|
|
||||||
int buf_sz;
|
|
||||||
|
|
||||||
dpkt->pts = audio_decoder->AudioParser->pts;
|
|
||||||
dpkt->dts = audio_decoder->AudioParser->dts;
|
|
||||||
buf_sz = sizeof(buf);
|
buf_sz = sizeof(buf);
|
||||||
l = avcodec_decode_audio3(audio_ctx, buf, &buf_sz, dpkt);
|
l = avcodec_decode_audio3(audio_ctx, buf, &buf_sz, (AVPacket *) avpkt);
|
||||||
|
if (avpkt->size != l) {
|
||||||
|
if (l == AVERROR(EAGAIN)) {
|
||||||
|
Error(_("codec: latm\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (l < 0) { // no audio frame could be decompressed
|
if (l < 0) { // no audio frame could be decompressed
|
||||||
Error(_("codec: error audio data at %d\n"), index);
|
Error(_("codec: error audio data\n"));
|
||||||
break;
|
return;
|
||||||
|
}
|
||||||
|
Error(_("codec: error more than one frame data\n"));
|
||||||
}
|
}
|
||||||
#ifdef notyetFF_API_OLD_DECODE_AUDIO
|
#ifdef notyetFF_API_OLD_DECODE_AUDIO
|
||||||
// FIXME: ffmpeg git comeing
|
// FIXME: ffmpeg git comeing
|
||||||
int got_frame;
|
int got_frame;
|
||||||
|
|
||||||
avcodec_decode_audio4(audio_ctx, frame, &got_frame, dpkt);
|
avcodec_decode_audio4(audio_ctx, frame, &got_frame, avpkt);
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
// Update audio clock
|
|
||||||
if ((uint64_t) dpkt->pts != AV_NOPTS_VALUE) {
|
// update audio clock
|
||||||
AudioSetClock(dpkt->pts);
|
if (avpkt->pts != (int64_t) AV_NOPTS_VALUE) {
|
||||||
|
CodecAudioSetClock(audio_decoder, avpkt->pts);
|
||||||
}
|
}
|
||||||
// FIXME: must first play remainings bytes, than change and play new.
|
// FIXME: must first play remainings bytes, than change and play new.
|
||||||
if (audio_decoder->SampleRate != audio_ctx->sample_rate
|
if (audio_decoder->PassthroughAC3 != CodecPassthroughAC3
|
||||||
|
|| audio_decoder->SampleRate != audio_ctx->sample_rate
|
||||||
|| audio_decoder->Channels != audio_ctx->channels) {
|
|| audio_decoder->Channels != audio_ctx->channels) {
|
||||||
int err;
|
CodecAudioUpdateFormat(audio_decoder);
|
||||||
|
|
||||||
if (audio_decoder->ReSample) {
|
|
||||||
audio_resample_close(audio_decoder->ReSample);
|
|
||||||
audio_decoder->ReSample = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_decoder->SampleRate = audio_ctx->sample_rate;
|
|
||||||
audio_decoder->HwSampleRate = audio_ctx->sample_rate;
|
|
||||||
audio_decoder->Channels = audio_ctx->channels;
|
|
||||||
#ifdef USE_PASSTHROUGH
|
|
||||||
// SPDIF/HDMI passthrough
|
|
||||||
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
|
|
||||||
audio_decoder->HwChannels = 2;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
audio_decoder->HwChannels = audio_ctx->channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
// channels not support?
|
|
||||||
if ((err =
|
|
||||||
AudioSetup(&audio_decoder->HwSampleRate,
|
|
||||||
&audio_decoder->HwChannels))) {
|
|
||||||
Debug(3, "codec/audio: resample %dHz *%d -> %dHz *%d\n",
|
|
||||||
audio_ctx->sample_rate, audio_ctx->channels,
|
|
||||||
audio_decoder->HwSampleRate,
|
|
||||||
audio_decoder->HwChannels);
|
|
||||||
|
|
||||||
if (err == 1) {
|
|
||||||
audio_decoder->ReSample =
|
|
||||||
av_audio_resample_init(audio_decoder->HwChannels,
|
|
||||||
audio_ctx->channels, audio_decoder->HwSampleRate,
|
|
||||||
audio_ctx->sample_rate, audio_ctx->sample_fmt,
|
|
||||||
audio_ctx->sample_fmt, 16, 10, 0, 0.8);
|
|
||||||
// libav-0.8_pre didn't support 6 -> 2 channels
|
|
||||||
if (!audio_decoder->ReSample) {
|
|
||||||
Error(_("codec/audio: resample setup error\n"));
|
|
||||||
audio_decoder->HwChannels = 0;
|
|
||||||
audio_decoder->HwSampleRate = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Debug(3, "codec/audio: audio setup error\n");
|
|
||||||
// FIXME: handle errors
|
|
||||||
audio_decoder->HwChannels = 0;
|
|
||||||
audio_decoder->HwSampleRate = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_decoder->HwSampleRate && audio_decoder->HwChannels) {
|
if (audio_decoder->HwSampleRate && audio_decoder->HwChannels) {
|
||||||
@@ -854,8 +1186,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
|
|
||||||
// FIXME: libav-0.7.2 crash here
|
// FIXME: libav-0.7.2 crash here
|
||||||
outlen =
|
outlen =
|
||||||
audio_resample(audio_decoder->ReSample, outbuf, buf,
|
audio_resample(audio_decoder->ReSample, outbuf, buf, buf_sz);
|
||||||
buf_sz);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (outlen != buf_sz) {
|
if (outlen != buf_sz) {
|
||||||
Debug(3, "codec/audio: possible fixed ffmpeg\n");
|
Debug(3, "codec/audio: possible fixed ffmpeg\n");
|
||||||
@@ -869,30 +1200,52 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
audio_decoder->HwChannels *
|
audio_decoder->HwChannels *
|
||||||
av_get_bytes_per_sample(audio_ctx->sample_fmt);
|
av_get_bytes_per_sample(audio_ctx->sample_fmt);
|
||||||
Debug(4, "codec/audio: %d -> %d\n", buf_sz, outlen);
|
Debug(4, "codec/audio: %d -> %d\n", buf_sz, outlen);
|
||||||
AudioEnqueue(outbuf, outlen);
|
CodecAudioEnqueue(audio_decoder, outbuf, outlen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
// SPDIF/HDMI passthrough
|
// SPDIF/HDMI passthrough
|
||||||
if (CodecPassthroughAC3
|
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
|
||||||
&& audio_ctx->codec_id == CODEC_ID_AC3) {
|
|
||||||
// build SPDIF header and append A52 audio to it
|
// build SPDIF header and append A52 audio to it
|
||||||
// dpkt is the original data
|
// avpkt is the original data
|
||||||
buf_sz = 6144;
|
buf_sz = 6144;
|
||||||
if (buf_sz < dpkt->size + 8) {
|
|
||||||
|
#ifdef USE_AC3_DRIFT_CORRECTION
|
||||||
|
if (1) {
|
||||||
|
int x;
|
||||||
|
|
||||||
|
x = (audio_decoder->DriftFrac +
|
||||||
|
(audio_decoder->DriftCorr * buf_sz)) / (10 *
|
||||||
|
audio_decoder->HwSampleRate * 100);
|
||||||
|
audio_decoder->DriftFrac =
|
||||||
|
(audio_decoder->DriftFrac +
|
||||||
|
(audio_decoder->DriftCorr * buf_sz)) % (10 *
|
||||||
|
audio_decoder->HwSampleRate * 100);
|
||||||
|
x *= audio_decoder->HwChannels * 4;
|
||||||
|
if (x < -64) { // limit correction
|
||||||
|
x = -64;
|
||||||
|
} else if (x > 64) {
|
||||||
|
x = 64;
|
||||||
|
}
|
||||||
|
buf_sz += x;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (buf_sz < avpkt->size + 8) {
|
||||||
Error(_
|
Error(_
|
||||||
("codec/audio: decoded data smaller than encoded\n"));
|
("codec/audio: decoded data smaller than encoded\n"));
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
// copy original data for output
|
// copy original data for output
|
||||||
// FIXME: not 100% sure, if endian is correct
|
// FIXME: not 100% sure, if endian is correct
|
||||||
buf[0] = htole16(0xF872); // iec 61937 sync word
|
buf[0] = htole16(0xF872); // iec 61937 sync word
|
||||||
buf[1] = htole16(0x4E1F);
|
buf[1] = htole16(0x4E1F);
|
||||||
buf[2] = htole16(0x01 | (dpkt->data[5] & 0x07) << 8);
|
buf[2] = htole16(0x01 | (avpkt->data[5] & 0x07) << 8);
|
||||||
buf[3] = htole16(dpkt->size * 8);
|
buf[3] = htole16(avpkt->size * 8);
|
||||||
swab(dpkt->data, buf + 4, dpkt->size);
|
swab(avpkt->data, buf + 4, avpkt->size);
|
||||||
memset(buf + 4 + dpkt->size / 2, 0,
|
memset(buf + 4 + avpkt->size / 2, 0, buf_sz - 8 - avpkt->size);
|
||||||
buf_sz - 8 - dpkt->size);
|
// don't play with the ac-3 samples
|
||||||
|
AudioEnqueue(buf, buf_sz);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
//
|
//
|
||||||
@@ -907,7 +1260,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
buf[2] = 0x1F;
|
buf[2] = 0x1F;
|
||||||
buf[3] = 0x4E;
|
buf[3] = 0x4E;
|
||||||
buf[4] = 0x00;
|
buf[4] = 0x00;
|
||||||
switch (dpkt->size) {
|
switch (avpkt->size) {
|
||||||
case 512:
|
case 512:
|
||||||
buf[5] = 0x0B;
|
buf[5] = 0x0B;
|
||||||
break;
|
break;
|
||||||
@@ -923,15 +1276,14 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
buf[5] = 0x00;
|
buf[5] = 0x00;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf[6] = (dpkt->size * 8);
|
buf[6] = (avpkt->size * 8);
|
||||||
buf[7] = (dpkt->size * 8) >> 8;
|
buf[7] = (avpkt->size * 8) >> 8;
|
||||||
//buf[8] = 0x0B;
|
//buf[8] = 0x0B;
|
||||||
//buf[9] = 0x77;
|
//buf[9] = 0x77;
|
||||||
//printf("%x %x\n", dpkt->data[0],dpkt->data[1]);
|
//printf("%x %x\n", avpkt->data[0],avpkt->data[1]);
|
||||||
// swab?
|
// swab?
|
||||||
memcpy(buf + 8, dpkt->data, dpkt->size);
|
memcpy(buf + 8, avpkt->data, avpkt->size);
|
||||||
memset(buf + 8 + dpkt->size, 0,
|
memset(buf + 8 + avpkt->size, 0, buf_sz - 8 - avpkt->size);
|
||||||
buf_sz - 8 - dpkt->size);
|
|
||||||
} else if (1) {
|
} else if (1) {
|
||||||
// FIXME: need to detect mp2
|
// FIXME: need to detect mp2
|
||||||
// FIXME: mp2 passthrough
|
// FIXME: mp2 passthrough
|
||||||
@@ -947,97 +1299,11 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
// True HD?
|
// True HD?
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
AudioEnqueue(buf, buf_sz);
|
CodecAudioEnqueue(audio_decoder, buf, buf_sz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpkt->size > l) {
|
|
||||||
Error(_("codec: error more than one frame data\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// or av_free_packet, make no difference here
|
|
||||||
av_destruct_packet(spkt);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/**
|
|
||||||
** Decode an audio packet.
|
|
||||||
**
|
|
||||||
** PTS must be handled self.
|
|
||||||
**
|
|
||||||
** @param audio_decoder audio decoder data
|
|
||||||
** @param avpkt audio packet
|
|
||||||
*/
|
|
||||||
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|
||||||
{
|
|
||||||
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
|
||||||
AVCodecContext *audio_ctx;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
//#define spkt avpkt
|
|
||||||
#if 1
|
|
||||||
AVPacket spkt[1];
|
|
||||||
|
|
||||||
// av_new_packet reserves FF_INPUT_BUFFER_PADDING_SIZE and clears it
|
|
||||||
if (av_new_packet(spkt, avpkt->size)) {
|
|
||||||
Error(_("codec: out of memory\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(spkt->data, avpkt->data, avpkt->size);
|
|
||||||
spkt->pts = avpkt->pts;
|
|
||||||
spkt->dts = avpkt->dts;
|
|
||||||
#endif
|
|
||||||
audio_ctx = audio_decoder->AudioCtx;
|
|
||||||
index = 0;
|
|
||||||
while (spkt->size > index) {
|
|
||||||
int n;
|
|
||||||
int buf_sz;
|
|
||||||
AVPacket dpkt[1];
|
|
||||||
|
|
||||||
av_init_packet(dpkt);
|
|
||||||
dpkt->data = spkt->data + index;
|
|
||||||
dpkt->size = spkt->size - index;
|
|
||||||
|
|
||||||
buf_sz = sizeof(buf);
|
|
||||||
n = avcodec_decode_audio3(audio_ctx, buf, &buf_sz, dpkt);
|
|
||||||
if (n < 0) { // no audio frame could be decompressed
|
|
||||||
Error(_("codec: error audio data at %d\n"), index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
Debug(4, "codec/audio: -> %d\n", buf_sz);
|
|
||||||
if ((unsigned)buf_sz > sizeof(buf)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef notyetFF_API_OLD_DECODE_AUDIO
|
|
||||||
// FIXME: ffmpeg git comeing
|
|
||||||
int got_frame;
|
|
||||||
|
|
||||||
avcodec_decode_audio4(audio_ctx, frame, &got_frame, dpkt);
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
// FIXME: see above, old code removed
|
|
||||||
|
|
||||||
index += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// or av_free_packet, make no difference here
|
|
||||||
av_destruct_packet(spkt);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Flush the audio decoder.
|
** Flush the audio decoder.
|
||||||
**
|
**
|
||||||
@@ -1045,7 +1311,6 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
*/
|
*/
|
||||||
void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
void CodecAudioFlushBuffers(AudioDecoder * decoder)
|
||||||
{
|
{
|
||||||
// FIXME: reset audio parser
|
|
||||||
avcodec_flush_buffers(decoder->AudioCtx);
|
avcodec_flush_buffers(decoder->AudioCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
codec.h
9
codec.h
@@ -40,6 +40,9 @@ typedef struct _audio_decoder_ AudioDecoder;
|
|||||||
/// Allocate a new video decoder context.
|
/// Allocate a new video decoder context.
|
||||||
extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
|
extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *);
|
||||||
|
|
||||||
|
/// Deallocate a video decoder context.
|
||||||
|
extern void CodecVideoDelDecoder(VideoDecoder *);
|
||||||
|
|
||||||
/// Open video codec.
|
/// Open video codec.
|
||||||
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
|
extern void CodecVideoOpen(VideoDecoder *, const char *, int);
|
||||||
|
|
||||||
@@ -55,12 +58,18 @@ extern void CodecVideoFlushBuffers(VideoDecoder *);
|
|||||||
/// Allocate a new audio decoder context.
|
/// Allocate a new audio decoder context.
|
||||||
extern AudioDecoder *CodecAudioNewDecoder(void);
|
extern AudioDecoder *CodecAudioNewDecoder(void);
|
||||||
|
|
||||||
|
/// Deallocate an audio decoder context.
|
||||||
|
extern void CodecAudioDelDecoder(AudioDecoder *);
|
||||||
|
|
||||||
/// Open audio codec.
|
/// Open audio codec.
|
||||||
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
|
extern void CodecAudioOpen(AudioDecoder *, const char *, int);
|
||||||
|
|
||||||
/// Close audio codec.
|
/// Close audio codec.
|
||||||
extern void CodecAudioClose(AudioDecoder *);
|
extern void CodecAudioClose(AudioDecoder *);
|
||||||
|
|
||||||
|
/// Decode an audio packet.
|
||||||
|
extern void CodecAudioDecodeOld(AudioDecoder *, const AVPacket *);
|
||||||
|
|
||||||
/// Decode an audio packet.
|
/// Decode an audio packet.
|
||||||
extern void CodecAudioDecode(AudioDecoder *, const AVPacket *);
|
extern void CodecAudioDecode(AudioDecoder *, const AVPacket *);
|
||||||
|
|
||||||
|
|||||||
27
misc.h
27
misc.h
@@ -86,7 +86,7 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
/**
|
/**
|
||||||
** Show fatal error.
|
** Show fatal error.
|
||||||
*/
|
*/
|
||||||
#define Fatal(fmt...) do { Error(fmt); exit(-1); } while (0)
|
#define Fatal(fmt...) do { Error(fmt); abort(); } while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Show warning.
|
** Show warning.
|
||||||
@@ -107,6 +107,31 @@ static inline void Syslog(const int level, const char *format, ...)
|
|||||||
#define Debug(level, fmt...) /* disabled */
|
#define Debug(level, fmt...) /* disabled */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AV_NOPTS_VALUE
|
||||||
|
#define AV_NOPTS_VALUE INT64_C(0x8000000000000000)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Nice time-stamp string.
|
||||||
|
**
|
||||||
|
** @param ts dvb time stamp
|
||||||
|
*/
|
||||||
|
static inline const char *Timestamp2String(int64_t ts)
|
||||||
|
{
|
||||||
|
static char buf[4][16];
|
||||||
|
static int idx;
|
||||||
|
|
||||||
|
if (ts == (int64_t) AV_NOPTS_VALUE) {
|
||||||
|
return "--:--:--.---";
|
||||||
|
}
|
||||||
|
idx = (idx + 1) % 3;
|
||||||
|
snprintf(buf[idx], sizeof(buf[idx]), "%2d:%02d:%02d.%03d",
|
||||||
|
(int)(ts / (90 * 3600000)), (int)((ts / (90 * 60000)) % 60),
|
||||||
|
(int)((ts / (90 * 1000)) % 60), (int)((ts / 90) % 1000));
|
||||||
|
|
||||||
|
return buf[idx];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Get ticks in ms.
|
** Get ticks in ms.
|
||||||
**
|
**
|
||||||
|
|||||||
1925
softhddev.c
1925
softhddev.c
File diff suppressed because it is too large
Load Diff
20
softhddev.h
20
softhddev.h
@@ -37,8 +37,8 @@ extern "C"
|
|||||||
|
|
||||||
/// 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);
|
||||||
/// C plugin mute audio
|
/// C plugin play TS audio packet
|
||||||
extern void Mute(void);
|
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);
|
||||||
|
|
||||||
@@ -46,15 +46,23 @@ extern "C"
|
|||||||
extern int PlayVideo(const uint8_t *, int);
|
extern int PlayVideo(const uint8_t *, int);
|
||||||
/// C plugin play TS video packet
|
/// C plugin play TS video packet
|
||||||
extern void PlayTsVideo(const uint8_t *, int);
|
extern void PlayTsVideo(const uint8_t *, int);
|
||||||
|
/// C plugin grab an image
|
||||||
|
extern uint8_t *GrabImage(int *, int, int, int, int);
|
||||||
|
|
||||||
/// C plugin set play mode
|
/// C plugin set play mode
|
||||||
extern void SetPlayMode(void);
|
extern int SetPlayMode(int);
|
||||||
|
/// C plugin get current system time counter
|
||||||
|
extern int64_t GetSTC(void);
|
||||||
|
/// C plugin set trick speed
|
||||||
|
extern void TrickSpeed(int);
|
||||||
/// C plugin clears all video and audio data from the device
|
/// C plugin clears all video and audio data from the device
|
||||||
extern void Clear(void);
|
extern void Clear(void);
|
||||||
/// C plugin sets the device into play mode
|
/// C plugin sets the device into play mode
|
||||||
extern void Play(void);
|
extern void Play(void);
|
||||||
/// C plugin sets the device into "freeze frame" mode
|
/// C plugin sets the device into "freeze frame" mode
|
||||||
extern void Freeze(void);
|
extern void Freeze(void);
|
||||||
|
/// C plugin mute audio
|
||||||
|
extern void Mute(void);
|
||||||
/// C plugin display I-frame as a still picture.
|
/// C plugin display I-frame as a still picture.
|
||||||
extern void StillPicture(const uint8_t *, int);
|
extern void StillPicture(const uint8_t *, int);
|
||||||
/// C plugin poll if ready
|
/// C plugin poll if ready
|
||||||
@@ -70,14 +78,16 @@ extern "C"
|
|||||||
/// C plugin exit + cleanup
|
/// C plugin exit + cleanup
|
||||||
extern void SoftHdDeviceExit(void);
|
extern void SoftHdDeviceExit(void);
|
||||||
/// C plugin start code
|
/// C plugin start code
|
||||||
extern void Start(void);
|
extern int Start(void);
|
||||||
/// C plugin stop code
|
/// C plugin stop code
|
||||||
extern void Stop(void);
|
extern void Stop(void);
|
||||||
|
/// C plugin house keeping
|
||||||
|
extern void Housekeeping(void);
|
||||||
/// C plugin main thread hook
|
/// C plugin main thread hook
|
||||||
extern void MainThreadHook(void);
|
extern void MainThreadHook(void);
|
||||||
|
|
||||||
/// Suspend plugin
|
/// Suspend plugin
|
||||||
extern void Suspend(void);
|
extern void Suspend(int, int, int);
|
||||||
/// Resume plugin
|
/// Resume plugin
|
||||||
extern void Resume(void);
|
extern void Resume(void);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
1146
softhddevice.cpp
1146
softhddevice.cpp
File diff suppressed because it is too large
Load Diff
@@ -21,24 +21,26 @@ SRC_URI=""
|
|||||||
LICENSE="AGPL-3"
|
LICENSE="AGPL-3"
|
||||||
SLOT="0"
|
SLOT="0"
|
||||||
KEYWORDS="~x86 ~amd64"
|
KEYWORDS="~x86 ~amd64"
|
||||||
IUSE="vaapi vdpau alsa oss yaepg"
|
IUSE="vaapi vdpau alsa oss yaepg opengl jpeg"
|
||||||
|
|
||||||
DEPEND=">=x11-libs/libxcb-1.7
|
DEPEND=">=x11-libs/libxcb-1.8
|
||||||
x11-libs/xcb-util
|
x11-libs/xcb-util
|
||||||
x11-libs/xcb-util-wm
|
x11-libs/xcb-util-wm
|
||||||
x11-libs/xcb-util-wm
|
|
||||||
x11-libs/xcb-util-keysyms
|
x11-libs/xcb-util-keysyms
|
||||||
x11-libs/xcb-util-renderutil
|
x11-libs/xcb-util-renderutil
|
||||||
x11-libs/libX11
|
x11-libs/libX11
|
||||||
>=media-video/ffmpeg-0.7
|
opengl? ( virtual/opengl )
|
||||||
|
>=virtual/ffmpeg-0.7
|
||||||
sys-devel/gettext
|
sys-devel/gettext
|
||||||
sys-devel/make
|
sys-devel/make
|
||||||
dev-util/pkgconfig
|
dev-util/pkgconfig
|
||||||
yaepg? ( >=media-video/vdr-1.7[yaepg] )
|
yaepg? ( >=media-video/vdr-1.7.23[yaepg] )
|
||||||
!yaepg? ( >=media-video/vdr-1.7 )
|
!yaepg? ( >=media-video/vdr-1.7.23 )
|
||||||
vdpau? ( x11-libs/libvdpau )
|
vdpau? ( x11-libs/libvdpau )
|
||||||
vaapi? ( x11-libs/libva )
|
vaapi? ( x11-libs/libva )
|
||||||
alsa? ( media-libs/alsa-lib )
|
alsa? ( media-libs/alsa-lib )
|
||||||
|
oss? ( sys-kernel/linux-headers )
|
||||||
|
jpeg? ( virtual/jpeg )
|
||||||
"
|
"
|
||||||
|
|
||||||
src_prepare() {
|
src_prepare() {
|
||||||
@@ -48,11 +50,12 @@ src_prepare() {
|
|||||||
src_compile() {
|
src_compile() {
|
||||||
local myconf
|
local myconf
|
||||||
|
|
||||||
myconf=""
|
myconf="-DHAVE_PTHREAD_NAME"
|
||||||
use vdpau && myconf="${myconf} -DUSE_VDPAU"
|
use vdpau && myconf="${myconf} -DUSE_VDPAU"
|
||||||
use vaapi && myconf="${myconf} -DUSE_VAAPI"
|
use vaapi && myconf="${myconf} -DUSE_VAAPI"
|
||||||
use alsa && myconf="${myconf} -DUSE_ALSA"
|
use alsa && myconf="${myconf} -DUSE_ALSA"
|
||||||
use oss && myconf="${myconf} -DUSE_OSS"
|
use oss && myconf="${myconf} -DUSE_OSS"
|
||||||
|
use jpeg && myconf="${myconf} -DUSE_JPEG"
|
||||||
|
|
||||||
emake all CC="$(tc-getCC)" CFLAGS="${CFLAGS}" \
|
emake all CC="$(tc-getCC)" CFLAGS="${CFLAGS}" \
|
||||||
LDFLAGS="${LDFLAGS}" CONFIG="${myconf}" LIBDIR="." || die
|
LDFLAGS="${LDFLAGS}" CONFIG="${myconf}" LIBDIR="." || die
|
||||||
@@ -61,10 +64,11 @@ src_compile() {
|
|||||||
src_install() {
|
src_install() {
|
||||||
vdr-plugin_src_install
|
vdr-plugin_src_install
|
||||||
|
|
||||||
dodir /etc/vdr/plugins || die
|
dodoc README.txt
|
||||||
|
|
||||||
insinto /etc/vdr/plugins
|
#dodir /etc/vdr/plugins || die
|
||||||
fowners -R vdr:vdr /etc/vdr || die
|
#insinto /etc/vdr/plugins
|
||||||
|
#fowners -R vdr:vdr /etc/vdr || die
|
||||||
|
|
||||||
#insinto /etc/conf.d
|
#insinto /etc/conf.d
|
||||||
#doins vdr.softhddevice
|
#doins vdr.softhddevice
|
||||||
|
|||||||
69
video.h
69
video.h
@@ -30,6 +30,13 @@
|
|||||||
/// Video hardware decoder typedef
|
/// Video hardware decoder typedef
|
||||||
typedef struct _video_hw_decoder_ VideoHwDecoder;
|
typedef struct _video_hw_decoder_ VideoHwDecoder;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Variables
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
||||||
|
extern int VideoAudioDelay; ///< audio/video delay
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Prototypes
|
// Prototypes
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -37,6 +44,9 @@ typedef struct _video_hw_decoder_ VideoHwDecoder;
|
|||||||
/// Allocate new video hardware decoder.
|
/// Allocate new video hardware decoder.
|
||||||
extern VideoHwDecoder *VideoNewHwDecoder(void);
|
extern VideoHwDecoder *VideoNewHwDecoder(void);
|
||||||
|
|
||||||
|
/// Deallocate video hardware decoder.
|
||||||
|
extern void VideoDelHwDecoder(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Get and allocate a video hardware surface.
|
/// Get and allocate a video hardware surface.
|
||||||
extern unsigned VideoGetSurface(VideoHwDecoder *);
|
extern unsigned VideoGetSurface(VideoHwDecoder *);
|
||||||
|
|
||||||
@@ -44,16 +54,17 @@ extern unsigned VideoGetSurface(VideoHwDecoder *);
|
|||||||
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
||||||
|
|
||||||
#ifdef LIBAVCODEC_VERSION
|
#ifdef LIBAVCODEC_VERSION
|
||||||
/// Render a ffmpeg frame.
|
|
||||||
extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *);
|
|
||||||
|
|
||||||
/// Get ffmpeg vaapi context.
|
|
||||||
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
|
||||||
|
|
||||||
/// Callback to negotiate the PixelFormat.
|
/// Callback to negotiate the PixelFormat.
|
||||||
extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
||||||
const enum PixelFormat *);
|
const enum PixelFormat *);
|
||||||
|
|
||||||
|
/// Render a ffmpeg frame.
|
||||||
|
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
|
||||||
|
const AVFrame *);
|
||||||
|
|
||||||
|
/// Get ffmpeg vaapi context.
|
||||||
|
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
|
||||||
|
|
||||||
#ifdef AVCODEC_VDPAU_H
|
#ifdef AVCODEC_VDPAU_H
|
||||||
/// Draw vdpau render state.
|
/// Draw vdpau render state.
|
||||||
extern void VideoDrawRenderState(VideoHwDecoder *,
|
extern void VideoDrawRenderState(VideoHwDecoder *,
|
||||||
@@ -67,15 +78,27 @@ extern void VideoPollEvent(void);
|
|||||||
/// Wakeup display handler.
|
/// Wakeup display handler.
|
||||||
extern void VideoDisplayWakeup(void);
|
extern void VideoDisplayWakeup(void);
|
||||||
|
|
||||||
|
/// Set video device.
|
||||||
|
extern void VideoSetDevice(const char *);
|
||||||
|
|
||||||
/// Set video geometry.
|
/// Set video geometry.
|
||||||
extern int VideoSetGeometry(const char *);
|
extern int VideoSetGeometry(const char *);
|
||||||
|
|
||||||
|
/// Set 60Hz display mode.
|
||||||
|
extern void VideoSet60HzMode(int);
|
||||||
|
|
||||||
|
/// Set soft start audio/video sync.
|
||||||
|
extern void VideoSetSoftStartSync(int);
|
||||||
|
|
||||||
/// Set video output position.
|
/// Set video output position.
|
||||||
extern void VideoSetOutputPosition(int, int, int, int);
|
extern void VideoSetOutputPosition(int, int, int, int);
|
||||||
|
|
||||||
/// Set video mode.
|
/// Set video mode.
|
||||||
extern void VideoSetVideoMode(int, int, int, int);
|
extern void VideoSetVideoMode(int, int, int, int);
|
||||||
|
|
||||||
|
/// Set display format.
|
||||||
|
extern void VideoSetDisplayFormat(int);
|
||||||
|
|
||||||
/// Set video fullscreen mode.
|
/// Set video fullscreen mode.
|
||||||
extern void VideoSetFullscreen(int);
|
extern void VideoSetFullscreen(int);
|
||||||
|
|
||||||
@@ -85,6 +108,9 @@ extern void VideoSetDeinterlace(int[]);
|
|||||||
/// Set skip chroma deinterlace.
|
/// Set skip chroma deinterlace.
|
||||||
extern void VideoSetSkipChromaDeinterlace(int[]);
|
extern void VideoSetSkipChromaDeinterlace(int[]);
|
||||||
|
|
||||||
|
/// Set inverse telecine.
|
||||||
|
extern void VideoSetInverseTelecine(int[]);
|
||||||
|
|
||||||
/// Set scaling.
|
/// Set scaling.
|
||||||
extern void VideoSetScaling(int[]);
|
extern void VideoSetScaling(int[]);
|
||||||
|
|
||||||
@@ -94,16 +120,44 @@ extern void VideoSetDenoise(int[]);
|
|||||||
/// Set sharpen.
|
/// Set sharpen.
|
||||||
extern void VideoSetSharpen(int[]);
|
extern void VideoSetSharpen(int[]);
|
||||||
|
|
||||||
|
/// Set cut top and bottom.
|
||||||
|
extern void VideoSetCutTopBottom(int[]);
|
||||||
|
|
||||||
|
/// Set cut left and right.
|
||||||
|
extern void VideoSetCutLeftRight(int[]);
|
||||||
|
|
||||||
|
/// Set studio levels.
|
||||||
|
extern void VideoSetStudioLevels(int);
|
||||||
|
|
||||||
|
/// Set background.
|
||||||
|
extern void VideoSetBackground(uint32_t);
|
||||||
|
|
||||||
/// Set audio delay.
|
/// Set audio delay.
|
||||||
extern void VideoSetAudioDelay(int);
|
extern void VideoSetAudioDelay(int);
|
||||||
|
|
||||||
|
/// Set auto-crop parameters.
|
||||||
|
extern void VideoSetAutoCrop(int, int, int);
|
||||||
|
|
||||||
/// Clear OSD.
|
/// Clear OSD.
|
||||||
extern void VideoOsdClear(void);
|
extern void VideoOsdClear(void);
|
||||||
|
|
||||||
/// Draw an OSD ARGB image.
|
/// Draw an OSD ARGB image.
|
||||||
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
||||||
|
|
||||||
extern int64_t VideoGetClock(void); ///< Get video clock.
|
/// Get OSD size.
|
||||||
|
extern void VideoGetOsdSize(int *, int *);
|
||||||
|
|
||||||
|
/// Set video clock.
|
||||||
|
extern void VideoSetClock(VideoHwDecoder *, int64_t);
|
||||||
|
|
||||||
|
/// Get video clock.
|
||||||
|
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
||||||
|
|
||||||
|
/// Set trick play speed.
|
||||||
|
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
||||||
|
|
||||||
|
/// Grab screen.
|
||||||
|
extern uint8_t *VideoGrab(int *, int *, int *, int);
|
||||||
|
|
||||||
extern void VideoOsdInit(void); ///< Setup osd.
|
extern void VideoOsdInit(void); ///< Setup osd.
|
||||||
extern void VideoOsdExit(void); ///< Cleanup osd.
|
extern void VideoOsdExit(void); ///< Cleanup osd.
|
||||||
@@ -113,5 +167,6 @@ extern void VideoExit(void); ///< Cleanup and exit video module.
|
|||||||
|
|
||||||
extern void VideoFlushInput(void); ///< Flush video input buffers.
|
extern void VideoFlushInput(void); ///< Flush video input buffers.
|
||||||
extern int VideoDecode(void); ///< Decode video input buffers.
|
extern int VideoDecode(void); ///< Decode video input buffers.
|
||||||
|
extern int VideoGetBuffers(void); ///< Get number of input buffers.
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
Reference in New Issue
Block a user