mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 17:16:51 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
583b6f246e | ||
|
|
e6ce7832ba | ||
|
|
696bb8e934 | ||
|
|
3bb7782d40 | ||
|
|
b5162bae5c | ||
|
|
d486fb2ca1 | ||
|
|
73d65968ae | ||
|
|
3be69730f0 | ||
|
|
6f1c4d6ef6 | ||
|
|
6aa8601f7d | ||
|
|
0f62a521f4 | ||
|
|
57af986367 | ||
|
|
a2311748ca | ||
|
|
2c5a14ae4a | ||
|
|
ed1e16dccf | ||
|
|
da9886e9f1 | ||
|
|
32527f832e | ||
|
|
57bbd02c57 | ||
|
|
940849d03f | ||
|
|
c112b850d8 | ||
|
|
752ee356fa | ||
|
|
43e70b6a3f | ||
|
|
541754a619 | ||
|
|
3772b2160c | ||
|
|
465c68d839 | ||
| aca508114b | |||
|
|
49ae1c7211 | ||
|
|
0cf110da81 | ||
|
|
8d5ff6f6fb | ||
|
|
5456164dce | ||
|
|
6dd7c2680a | ||
|
|
3b5c1adef2 | ||
|
|
47d840bbff | ||
|
|
207871fd9b | ||
|
|
ebe0beb400 | ||
|
|
93ddd26a4a | ||
|
|
e30e1e5aad | ||
|
|
d26c34f34f | ||
| 24a8c7f763 | |||
|
|
3e39ffd5e0 | ||
|
|
53f22a2ed2 | ||
|
|
44ca71fedb | ||
|
|
8039e8ae04 | ||
|
|
79e78bf235 | ||
|
|
c9ef8b759a | ||
|
|
80db7c6656 | ||
|
|
3ba18d8720 | ||
|
|
2ffcb874bb | ||
|
|
5b765f02bd | ||
|
|
2c52955ac0 | ||
|
|
09d8588588 | ||
|
|
71f786711b | ||
|
|
deea34eb5e | ||
|
|
1f14af6590 | ||
|
|
aeae505bd4 |
53
ChangeLog
53
ChangeLog
@@ -1,3 +1,56 @@
|
|||||||
|
User johns
|
||||||
|
Date: Tue Jul 3 16:35:46 CEST 2012
|
||||||
|
|
||||||
|
Release Version 0.5.1
|
||||||
|
Add commandline support to disable hardware decoder.
|
||||||
|
Display frame statistics in plugin menu.
|
||||||
|
Fix bug: 100% CPU use during playback.
|
||||||
|
Fix bug: audio use 100% CPU during pause.
|
||||||
|
Guard audio skip against old PTS values.
|
||||||
|
Improved audio skip, after channel switch.
|
||||||
|
Setup add preview of collapsed tree.
|
||||||
|
Fix bug: dvd plugin times out.
|
||||||
|
Makes OSD size configurable.
|
||||||
|
Support display with non-square pixels.
|
||||||
|
Initial ADTS (AAC+) support.
|
||||||
|
Fix bug #959: log flooded with service messages.
|
||||||
|
|
||||||
|
User durchflieger
|
||||||
|
Date: Mon Apr 30 14:46:51 CEST 2012
|
||||||
|
|
||||||
|
Adds VDR DFAtmo Plugin support.
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Mon Apr 30 13:56:26 CEST 2012
|
||||||
|
|
||||||
|
Fix bug: don't normalize or compress pass-through samples.
|
||||||
|
Make audio ring buffer size a multiple of 3,5,7,8.
|
||||||
|
Add reset ring buffer support.
|
||||||
|
Fix bug: alloca wrong size for audio buffer.
|
||||||
|
Handle jump in stream like stream start.
|
||||||
|
Always compile audio drift correction.
|
||||||
|
Add audio drift correction configuration to the setup.
|
||||||
|
|
||||||
|
User mini73
|
||||||
|
Date: Fri Apr 20 16:51:14 CEST 2012
|
||||||
|
|
||||||
|
Add support for svdr command "stat".
|
||||||
|
|
||||||
|
User johns
|
||||||
|
Date: Fri Apr 20 16:05:40 CEST 2012
|
||||||
|
|
||||||
|
Made showing black picture configurable.
|
||||||
|
Show black picture, if no video stream is available.
|
||||||
|
Setup split into foldable sections.
|
||||||
|
Adds show cursor on pointer move and hide after 200ms.
|
||||||
|
Adds Hot-key support for auto-crop enable/disable/toggle.
|
||||||
|
Adds detached start mode.
|
||||||
|
Fix bug: VDPAU looses preemption callback.
|
||||||
|
Fix bug: X11 server keeps sending USR1 signals, which confuses suspend.
|
||||||
|
Show message for hot-keys.
|
||||||
|
Fix bug: playback errors with old PES recordings.
|
||||||
|
Adds Hot-key support for 4:3 zoom modes.
|
||||||
|
|
||||||
User johns
|
User johns
|
||||||
Date: Sat Apr 7 20:21:16 CEST 2012
|
Date: Sat Apr 7 20:21:16 CEST 2012
|
||||||
|
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -19,8 +19,6 @@ 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 += -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 += -DAV_INFO -DAV_INFO_TIME=3000 # debug a/v sync
|
||||||
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
|
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
|
||||||
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
|
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
|
||||||
@@ -47,7 +45,7 @@ TMPDIR ?= /tmp
|
|||||||
|
|
||||||
### Make sure that necessary options are included:
|
### Make sure that necessary options are included:
|
||||||
|
|
||||||
include $(VDRDIR)/Make.global
|
-include $(VDRDIR)/Make.global
|
||||||
|
|
||||||
### Allow user defined options to overwrite defaults:
|
### Allow user defined options to overwrite defaults:
|
||||||
|
|
||||||
|
|||||||
55
README.txt
55
README.txt
@@ -26,19 +26,19 @@ A software and GPU emulated HD output device plugin for VDR.
|
|||||||
o Audio FFMpeg / Alsa / Digital
|
o Audio FFMpeg / Alsa / Digital
|
||||||
o Audio FFMpeg / OSS / Analog
|
o Audio FFMpeg / OSS / Analog
|
||||||
o HDMI/SPDIF pass-through
|
o HDMI/SPDIF pass-through
|
||||||
|
o Software volume, compression, normalize and channel resample
|
||||||
o YaepgHD support
|
o YaepgHD support
|
||||||
o Software deinterlacer Bob (VA-API only)
|
o Software deinterlacer Bob (VA-API only)
|
||||||
o Autocrop
|
o Autocrop
|
||||||
o Grab image (VDPAU only)
|
o Grab image (VDPAU only)
|
||||||
o Suspend
|
o Suspend
|
||||||
o Letterbox, Stretch and Center cut-out video display modes
|
o Letterbox, Stretch and Center cut-out video display modes
|
||||||
|
o atmo light support with plugin http://github.com/durchflieger/DFAtmo
|
||||||
|
|
||||||
o planned: Video decoder VA-API Branch: vaapi-ext/staging
|
o planned: Video decoder VA-API Branch: vaapi-ext/staging
|
||||||
o planned: Video output XvBA / Opengl / Xv
|
o planned: Video output XvBA / Opengl / Xv
|
||||||
o planned: VA-API grab image
|
o planned: VA-API grab image
|
||||||
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
|
||||||
o 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.
|
||||||
|
|
||||||
@@ -108,12 +108,17 @@ Setup: /etc/vdr/setup.conf
|
|||||||
------
|
------
|
||||||
Following is supported:
|
Following is supported:
|
||||||
|
|
||||||
softhddevice.MakePrimary = 1
|
softhddevice.MakePrimary = 0
|
||||||
0 = no change, 1 make softhddevice primary at start
|
0 = no change, 1 make softhddevice primary at start
|
||||||
|
|
||||||
softhddevice.HideMainMenuEntry = 0
|
softhddevice.HideMainMenuEntry = 0
|
||||||
0 = show softhddevice main menu entry, 1 = hide entry
|
0 = show softhddevice main menu entry, 1 = hide entry
|
||||||
|
|
||||||
|
softhddevice.Osd.Width = 0
|
||||||
|
0 = auto (=display, unscaled) n = fixed osd size scaled for display
|
||||||
|
softhddevice.Osd.Height = 0
|
||||||
|
0 = auto (=display, unscaled) n = fixed osd size scaled for display
|
||||||
|
|
||||||
<res> of the next parameters is 576i, 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
|
||||||
@@ -157,6 +162,29 @@ Setup: /etc/vdr/setup.conf
|
|||||||
0 = none, 1 = downmix
|
0 = none, 1 = downmix
|
||||||
downmix AC-3 to stero.
|
downmix AC-3 to stero.
|
||||||
|
|
||||||
|
softhddevice.AudioSoftvol = 0
|
||||||
|
0 = off, use hardware volume control
|
||||||
|
1 = on, use software volume control
|
||||||
|
|
||||||
|
softhddevice.AudioNormalize = 0
|
||||||
|
0 = off, 1 = enable audio normalize
|
||||||
|
|
||||||
|
softhddevice.AudioMaxNormalize = 0
|
||||||
|
maximal volume factor/1000 of the normalize filter
|
||||||
|
|
||||||
|
softhddevice.AudioCompression = 0
|
||||||
|
0 = off, 1 = enable audio compression
|
||||||
|
|
||||||
|
softhddevice.AudioMaxCompression = 0
|
||||||
|
maximal volume factor/1000 of the compression filter
|
||||||
|
|
||||||
|
softhddevice.AudioStereoDescent = 0
|
||||||
|
reduce volume level (/1000) for stereo sources
|
||||||
|
|
||||||
|
softhddevice.AudioBufferTime = 0
|
||||||
|
0 = default (336 ms)
|
||||||
|
1 - 1000 = size of the buffer in ms
|
||||||
|
|
||||||
softhddevice.AutoCrop.Interval = 0
|
softhddevice.AutoCrop.Interval = 0
|
||||||
0 disables auto-crop
|
0 disables auto-crop
|
||||||
n each 'n' frames auto-crop is checked.
|
n each 'n' frames auto-crop is checked.
|
||||||
@@ -196,6 +224,10 @@ Setup: /etc/vdr/setup.conf
|
|||||||
0 disable soft start of audio/video sync
|
0 disable soft start of audio/video sync
|
||||||
1 enable soft start of audio/video sync
|
1 enable soft start of audio/video sync
|
||||||
|
|
||||||
|
softhddevice.BlackPicture = 0
|
||||||
|
0 disable black picture during channel switch
|
||||||
|
1 enable black picture during channel switch
|
||||||
|
|
||||||
VideoDisplayFormat = ?
|
VideoDisplayFormat = ?
|
||||||
0 pan and scan
|
0 pan and scan
|
||||||
1 letter box
|
1 letter box
|
||||||
@@ -248,6 +280,18 @@ Keymacros:
|
|||||||
@softhddevice Blue 1 0 disable pass-through
|
@softhddevice Blue 1 0 disable pass-through
|
||||||
@softhddevice Blue 1 1 enable pass-through
|
@softhddevice Blue 1 1 enable pass-through
|
||||||
@softhddevice Blue 1 2 toggle pass-through
|
@softhddevice Blue 1 2 toggle pass-through
|
||||||
|
@softhddevice Blue 1 3 decrease audio delay by 10ms
|
||||||
|
@softhddevice Blue 1 4 increase audio delay by 10ms
|
||||||
|
@softhddevice Blue 2 0 disable fullscreen
|
||||||
|
@softhddevice Blue 2 1 enable fullscreen
|
||||||
|
@softhddevice Blue 2 2 toggle fullscreen
|
||||||
|
@softhddevice Blue 2 3 disable auto-crop
|
||||||
|
@softhddevice Blue 2 4 enable auto-crop
|
||||||
|
@softhddevice Blue 2 5 toggle auto-crop
|
||||||
|
@softhddevice Blue 3 0 stretch 4:3 to 16:9
|
||||||
|
@softhddevice Blue 3 1 letter box 4:3 in 16:9
|
||||||
|
@softhddevice Blue 3 2 center cut-out 4:3 to 16:9
|
||||||
|
@softhddevice Blue 3 9 rotate 4:3 to 16:9 zoom mode
|
||||||
|
|
||||||
Running:
|
Running:
|
||||||
--------
|
--------
|
||||||
@@ -259,6 +303,11 @@ Warning:
|
|||||||
--------
|
--------
|
||||||
libav is not supported, expect many bugs with it.
|
libav is not supported, expect many bugs with it.
|
||||||
|
|
||||||
|
Known Bugs:
|
||||||
|
-----------
|
||||||
|
VA-API doesn't v-sync 1080i streams
|
||||||
|
vdr-image not working
|
||||||
|
|
||||||
Requires:
|
Requires:
|
||||||
---------
|
---------
|
||||||
media-video/ffmpeg (version >=0.7)
|
media-video/ffmpeg (version >=0.7)
|
||||||
|
|||||||
9
Todo
9
Todo
@@ -37,6 +37,8 @@ video:
|
|||||||
radio no need to wait on video buffers
|
radio no need to wait on video buffers
|
||||||
starting with radio and own X11 server, shows no video
|
starting with radio and own X11 server, shows no video
|
||||||
some low-bandwidth tv channels have hiccups.
|
some low-bandwidth tv channels have hiccups.
|
||||||
|
check start with 24Hz display rate
|
||||||
|
crash with ffmpeg without vaapi and vdpau.
|
||||||
|
|
||||||
vdpau:
|
vdpau:
|
||||||
software decoder path not working
|
software decoder path not working
|
||||||
@@ -73,10 +75,8 @@ x11:
|
|||||||
support embedded mode
|
support embedded mode
|
||||||
|
|
||||||
audio:
|
audio:
|
||||||
Combine alsa+oss ringbuffer code.
|
|
||||||
Make alsa thread/polled and oss thread/polled output module runtime
|
Make alsa thread/polled and oss thread/polled output module runtime
|
||||||
selectable.
|
selectable.
|
||||||
software volume support (could be done with asound.conf)
|
|
||||||
Mute should do a real mute and not only set volume to zero.
|
Mute should do a real mute and not only set volume to zero.
|
||||||
Starting suspended and muted, didn't register the mute.
|
Starting suspended and muted, didn't register the mute.
|
||||||
Relaxed audio sync checks at end of packet and already in sync
|
Relaxed audio sync checks at end of packet and already in sync
|
||||||
@@ -84,12 +84,10 @@ audio:
|
|||||||
only wait for video start, if video is running.
|
only wait for video start, if video is running.
|
||||||
Not primary device, don't use and block audio/video.
|
Not primary device, don't use and block audio/video.
|
||||||
multiple open of audio device, reduce them.
|
multiple open of audio device, reduce them.
|
||||||
|
Not all channel conversions are written (f.e. 2->3 ... 5->6 ...)
|
||||||
|
|
||||||
audio/alsa:
|
audio/alsa:
|
||||||
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
|
|
||||||
ffmpeg didn't support resample of 5 to 2 channels
|
|
||||||
|
|
||||||
audio/oss:
|
audio/oss:
|
||||||
alsa oss emulation mixer "pcm" not working
|
alsa oss emulation mixer "pcm" not working
|
||||||
@@ -124,7 +122,6 @@ future features (not planed for 1.0 - 1.5)
|
|||||||
video out with opengl
|
video out with opengl
|
||||||
video out with xvba
|
video out with xvba
|
||||||
software decoder for xv / opengl
|
software decoder for xv / opengl
|
||||||
atmolight support
|
|
||||||
multistream handling
|
multistream handling
|
||||||
pip support
|
pip support
|
||||||
save and use auto-crop with channel zapping
|
save and use auto-crop with channel zapping
|
||||||
|
|||||||
4
audio.h
4
audio.h
@@ -42,6 +42,10 @@ extern void AudioPlay(void); ///< play audio
|
|||||||
extern void AudioPause(void); ///< pause audio
|
extern void AudioPause(void); ///< pause audio
|
||||||
|
|
||||||
extern void AudioSetBufferTime(int); ///< set audio buffer time
|
extern void AudioSetBufferTime(int); ///< set audio buffer time
|
||||||
|
extern void AudioSetSoftvol(int); ///< enable/disable softvol
|
||||||
|
extern void AudioSetNormalize(int, int); ///< set normalize parameters
|
||||||
|
extern void AudioSetCompression(int, int); ///< set compression parameters
|
||||||
|
extern void AudioSetStereoDescent(int); ///< set stereo loudness descent
|
||||||
|
|
||||||
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
||||||
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
||||||
|
|||||||
67
codec.c
67
codec.c
@@ -33,7 +33,9 @@
|
|||||||
/// compile with passthrough support (stable, ac3 only)
|
/// compile with passthrough support (stable, ac3 only)
|
||||||
#define USE_PASSTHROUGH
|
#define USE_PASSTHROUGH
|
||||||
/// compile audio drift correction support (experimental)
|
/// compile audio drift correction support (experimental)
|
||||||
#define noUSE_AUDIO_DRIFT_CORRECTION
|
#define USE_AUDIO_DRIFT_CORRECTION
|
||||||
|
/// compile AC3 audio drift correction support (experimental)
|
||||||
|
#define USE_AC3_DRIFT_CORRECTION
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -583,7 +585,9 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
|||||||
*/
|
*/
|
||||||
void CodecVideoFlushBuffers(VideoDecoder * decoder)
|
void CodecVideoFlushBuffers(VideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
avcodec_flush_buffers(decoder->VideoCtx);
|
if (decoder->VideoCtx) {
|
||||||
|
avcodec_flush_buffers(decoder->VideoCtx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -631,6 +635,11 @@ struct _audio_decoder_
|
|||||||
int RemainCount; ///< number of remaining samples
|
int RemainCount; ///< number of remaining samples
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
|
static char CodecAudioDrift; ///< flag: enable audio-drift correction
|
||||||
|
#else
|
||||||
|
static const int CodecAudioDrift = 0;
|
||||||
|
#endif
|
||||||
#ifdef USE_PASSTHROUGH
|
#ifdef USE_PASSTHROUGH
|
||||||
//static char CodecPassthroughPCM; ///< pass pcm through (unsupported)
|
//static char CodecPassthroughPCM; ///< pass pcm through (unsupported)
|
||||||
static char CodecPassthroughAC3; ///< pass ac3 through
|
static char CodecPassthroughAC3; ///< pass ac3 through
|
||||||
@@ -773,8 +782,23 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Set audio drift correction.
|
||||||
|
**
|
||||||
|
** @param mask enable mask (PCM, AC3)
|
||||||
|
*/
|
||||||
|
void CodecSetAudioDrift(int mask)
|
||||||
|
{
|
||||||
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
|
CodecAudioDrift = mask & 3;
|
||||||
|
#endif
|
||||||
|
(void)mask;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Set audio pass-through.
|
** Set audio pass-through.
|
||||||
|
**
|
||||||
|
** @param mask enable mask (PCM, AC3)
|
||||||
*/
|
*/
|
||||||
void CodecSetAudioPassthrough(int mask)
|
void CodecSetAudioPassthrough(int mask)
|
||||||
{
|
{
|
||||||
@@ -791,6 +815,10 @@ void CodecSetAudioPassthrough(int mask)
|
|||||||
*/
|
*/
|
||||||
void CodecSetAudioDownmix(int onoff)
|
void CodecSetAudioDownmix(int onoff)
|
||||||
{
|
{
|
||||||
|
if (onoff == -1) {
|
||||||
|
CodecDownmix ^= 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
CodecDownmix = onoff;
|
CodecDownmix = onoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,7 +910,7 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
audio_decoder->LastDelay = delay;
|
audio_decoder->LastDelay = delay;
|
||||||
audio_decoder->Drift = 0;
|
audio_decoder->Drift = 0;
|
||||||
audio_decoder->DriftFrac = 0;
|
audio_decoder->DriftFrac = 0;
|
||||||
Debug(3, "codec/audio: inital delay %zd ms\n", delay / 90);
|
Debug(3, "codec/audio: inital delay %" PRId64 "ms\n", delay / 90);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// collect over some time
|
// collect over some time
|
||||||
@@ -906,9 +934,10 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
audio_decoder->LastDelay = delay;
|
audio_decoder->LastDelay = delay;
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
Debug(3, "codec/audio: interval P:%5zdms T:%5zdms D:%4zdms %f %d\n",
|
Debug(3,
|
||||||
pts_diff / 90, tim_diff / (1000 * 1000), delay / 90, drift / 90.0,
|
"codec/audio: interval P:%5zdms T:%5" PRId64 "ms D:%4" PRId64
|
||||||
audio_decoder->DriftCorr);
|
"ms %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 :(((
|
// underruns and av_resample have the same time :(((
|
||||||
if (abs(drift) > 10 * 90) {
|
if (abs(drift) > 10 * 90) {
|
||||||
@@ -916,17 +945,17 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
Debug(3, "codec/audio: drift(%6d) %3dms reset\n",
|
Debug(3, "codec/audio: drift(%6d) %3dms reset\n",
|
||||||
audio_decoder->DriftCorr, drift / 90);
|
audio_decoder->DriftCorr, drift / 90);
|
||||||
audio_decoder->LastDelay = 0;
|
audio_decoder->LastDelay = 0;
|
||||||
|
#ifdef DEBUG
|
||||||
|
corr = 0; // keep gcc happy
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
drift += audio_decoder->Drift;
|
drift += audio_decoder->Drift;
|
||||||
audio_decoder->Drift = drift;
|
audio_decoder->Drift = drift;
|
||||||
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
|
||||||
#if defined(USE_PASSTHROUGH) && !defined(USE_AC3_DRIFT_CORRECTION)
|
|
||||||
// SPDIF/HDMI passthrough
|
// SPDIF/HDMI passthrough
|
||||||
if (!CodecPassthroughAC3
|
if ((CodecAudioDrift & 2) && (!CodecPassthroughAC3
|
||||||
|| audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
|
|| audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)) {
|
||||||
#endif
|
|
||||||
{
|
|
||||||
audio_decoder->DriftCorr = -corr;
|
audio_decoder->DriftCorr = -corr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,8 +978,14 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
av_resample_compensate(audio_decoder->AvResample,
|
av_resample_compensate(audio_decoder->AvResample,
|
||||||
audio_decoder->DriftCorr / 10, distance);
|
audio_decoder->DriftCorr / 10, distance);
|
||||||
}
|
}
|
||||||
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n", audio_decoder->DriftCorr,
|
if (1) {
|
||||||
drift * 1000 / 90, corr);
|
static int c;
|
||||||
|
|
||||||
|
if (!(c++ % 10)) {
|
||||||
|
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n",
|
||||||
|
audio_decoder->DriftCorr, drift * 1000 / 90, corr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1025,7 +1060,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
}
|
}
|
||||||
// prepare audio drift resample
|
// prepare audio drift resample
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
if (!isAC3) {
|
if ((CodecAudioDrift & 1) && !isAC3) {
|
||||||
if (audio_decoder->AvResample) {
|
if (audio_decoder->AvResample) {
|
||||||
Error(_("codec/audio: overwrite resample\n"));
|
Error(_("codec/audio: overwrite resample\n"));
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1091,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder)
|
|||||||
void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count)
|
void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count)
|
||||||
{
|
{
|
||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
if (audio_decoder->AvResample) {
|
if ((CodecAudioDrift & 1) && audio_decoder->AvResample) {
|
||||||
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)));
|
||||||
int16_t buftmp[MAX_CHANNELS][(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4];
|
int16_t buftmp[MAX_CHANNELS][(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4];
|
||||||
@@ -1211,7 +1246,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
buf_sz = 6144;
|
buf_sz = 6144;
|
||||||
|
|
||||||
#ifdef USE_AC3_DRIFT_CORRECTION
|
#ifdef USE_AC3_DRIFT_CORRECTION
|
||||||
if (1) {
|
if (CodecAudioDrift & 2) {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
x = (audio_decoder->DriftFrac +
|
x = (audio_decoder->DriftFrac +
|
||||||
|
|||||||
10
codec.h
10
codec.h
@@ -67,8 +67,14 @@ 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.
|
/// Set audio drift correction.
|
||||||
extern void CodecAudioDecodeOld(AudioDecoder *, const AVPacket *);
|
extern void CodecSetAudioDrift(int);
|
||||||
|
|
||||||
|
/// Set audio pass-through.
|
||||||
|
extern void CodecSetAudioPassthrough(int);
|
||||||
|
|
||||||
|
/// Set audio downmix.
|
||||||
|
extern void CodecSetAudioDownmix(int);
|
||||||
|
|
||||||
/// Decode an audio packet.
|
/// Decode an audio packet.
|
||||||
extern void CodecAudioDecode(AudioDecoder *, const AVPacket *);
|
extern void CodecAudioDecode(AudioDecoder *, const AVPacket *);
|
||||||
|
|||||||
20
ringbuffer.c
20
ringbuffer.c
@@ -48,6 +48,18 @@ struct _ring_buffer_
|
|||||||
atomic_t Filled; ///< how many of the buffer is used
|
atomic_t Filled; ///< how many of the buffer is used
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Reset ring buffer pointers.
|
||||||
|
**
|
||||||
|
** @param rb Ring buffer to reset read/write pointers.
|
||||||
|
*/
|
||||||
|
void RingBufferReset(RingBuffer * rb)
|
||||||
|
{
|
||||||
|
rb->ReadPointer = rb->Buffer;
|
||||||
|
rb->WritePointer = rb->Buffer;
|
||||||
|
atomic_set(&rb->Filled, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Allocate a new ring buffer.
|
** Allocate a new ring buffer.
|
||||||
**
|
**
|
||||||
@@ -69,10 +81,8 @@ RingBuffer *RingBufferNew(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rb->Size = size;
|
rb->Size = size;
|
||||||
rb->ReadPointer = rb->Buffer;
|
|
||||||
rb->WritePointer = rb->Buffer;
|
|
||||||
rb->BufferEnd = rb->Buffer + size;
|
rb->BufferEnd = rb->Buffer + size;
|
||||||
atomic_set(&rb->Filled, 0);
|
RingBufferReset(rb);
|
||||||
|
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
@@ -89,7 +99,7 @@ void RingBufferDel(RingBuffer * rb)
|
|||||||
/**
|
/**
|
||||||
** Advance write pointer in ring buffer.
|
** Advance write pointer in ring buffer.
|
||||||
**
|
**
|
||||||
** @param rb Ring buffer to adance write pointer.
|
** @param rb Ring buffer to advance write pointer.
|
||||||
** @param cnt Number of bytes to be adavanced.
|
** @param cnt Number of bytes to be adavanced.
|
||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
@@ -198,7 +208,7 @@ size_t RingBufferGetWritePointer(RingBuffer * rb, void **wp)
|
|||||||
/**
|
/**
|
||||||
** Advance read pointer in ring buffer.
|
** Advance read pointer in ring buffer.
|
||||||
**
|
**
|
||||||
** @param rb Ring buffer to adance read pointer.
|
** @param rb Ring buffer to advance read pointer.
|
||||||
** @param cnt Number of bytes to be advanced.
|
** @param cnt Number of bytes to be advanced.
|
||||||
**
|
**
|
||||||
** @returns Number of bytes that could be advanced in ring buffer.
|
** @returns Number of bytes that could be advanced in ring buffer.
|
||||||
|
|||||||
@@ -23,13 +23,16 @@
|
|||||||
/// @addtogroup Ringbuffer
|
/// @addtogroup Ringbuffer
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
///< ring buffer typedef
|
/// ring buffer typedef
|
||||||
typedef struct _ring_buffer_ RingBuffer;
|
typedef struct _ring_buffer_ RingBuffer;
|
||||||
|
|
||||||
///< create new ring buffer
|
/// reset ring buffer pointers
|
||||||
|
extern void RingBufferReset(RingBuffer *);
|
||||||
|
|
||||||
|
/// create new ring buffer
|
||||||
extern RingBuffer *RingBufferNew(size_t);
|
extern RingBuffer *RingBufferNew(size_t);
|
||||||
|
|
||||||
///< free ring buffer
|
/// free ring buffer
|
||||||
extern void RingBufferDel(RingBuffer *);
|
extern void RingBufferDel(RingBuffer *);
|
||||||
|
|
||||||
/// write into ring buffer
|
/// write into ring buffer
|
||||||
|
|||||||
241
softhddev.c
241
softhddev.c
@@ -61,6 +61,7 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
|
|||||||
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int ConfigAudioBufferTime; ///< config size ms of audio buffer
|
||||||
static char ConfigStartSuspended; ///< flag to start in suspend mode
|
static char ConfigStartSuspended; ///< flag to start in suspend mode
|
||||||
static char ConfigFullscreen; ///< fullscreen modus
|
static char ConfigFullscreen; ///< fullscreen modus
|
||||||
static char ConfigStartX11Server; ///< flag start the x11 server
|
static char ConfigStartX11Server; ///< flag start the x11 server
|
||||||
@@ -347,8 +348,8 @@ static int Ac3Check(const uint8_t * data, int size)
|
|||||||
frmsizcod = data[4] & 0x3F; // invalid is checked by fast
|
frmsizcod = data[4] & 0x3F; // invalid is checked by fast
|
||||||
frame_size = Ac3FrameSizeTable[frmsizcod][fscod] * 2;
|
frame_size = Ac3FrameSizeTable[frmsizcod][fscod] * 2;
|
||||||
|
|
||||||
if (frame_size + 2 > size) {
|
if (frame_size + 5 > size) {
|
||||||
return -frame_size - 2;
|
return -frame_size - 5;
|
||||||
}
|
}
|
||||||
// check if after this frame a new AC-3 frame starts
|
// check if after this frame a new AC-3 frame starts
|
||||||
if (FastAc3Check(data + frame_size)) {
|
if (FastAc3Check(data + frame_size)) {
|
||||||
@@ -358,6 +359,71 @@ static int Ac3Check(const uint8_t * data, int size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Fast check for ADTS Audio Data Transport Stream.
|
||||||
|
///
|
||||||
|
/// 7/9 bytes 0xFFFxxxxxxxxxxx(xxxx) ADTS audio
|
||||||
|
///
|
||||||
|
static inline int FastAdtsCheck(const uint8_t * p)
|
||||||
|
{
|
||||||
|
if (p[0] != 0xFF) { // 12bit sync
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((p[1] & 0xF6) != 0xF0) { // sync + layer must be 0
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((p[2] & 0x3C) == 0x3C) { // sampling frequency index != 15
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Check for ADTS Audio Data Transport Stream.
|
||||||
|
///
|
||||||
|
/// 0xFFF already checked.
|
||||||
|
///
|
||||||
|
/// @param data incomplete PES packet
|
||||||
|
/// @param size number of bytes
|
||||||
|
///
|
||||||
|
/// @retval <0 possible ADTS audio, but need more data
|
||||||
|
/// @retval 0 no valid ADTS audio
|
||||||
|
/// @retval >0 valid AC-3 audio
|
||||||
|
///
|
||||||
|
/// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP
|
||||||
|
/// (QQQQQQQQ QQQQQQQ)
|
||||||
|
///
|
||||||
|
/// o A*12 syncword 0xFFF
|
||||||
|
/// o B*1 MPEG Version: 0 for MPEG-4, 1 for MPEG-2
|
||||||
|
/// o C*2 layer: always 0
|
||||||
|
/// o ..
|
||||||
|
/// o F*4 sampling frequency index (15 is invalid)
|
||||||
|
/// o ..
|
||||||
|
/// o M*13 frame length
|
||||||
|
///
|
||||||
|
static int AdtsCheck(const uint8_t * data, int size)
|
||||||
|
{
|
||||||
|
int frame_size;
|
||||||
|
|
||||||
|
if (size < 6) {
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_size = (data[3] & 0x03) << 11;
|
||||||
|
frame_size |= (data[4] & 0xFF) << 3;
|
||||||
|
frame_size |= (data[5] & 0xE0) >> 5;
|
||||||
|
|
||||||
|
if (frame_size + 3 > size) {
|
||||||
|
return -frame_size - 3;
|
||||||
|
}
|
||||||
|
// check if after this frame a new ADTS frame starts
|
||||||
|
if (FastAdtsCheck(data + frame_size)) {
|
||||||
|
return frame_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_TS_AUDIO
|
#ifndef NO_TS_AUDIO
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -540,11 +606,13 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
|||||||
unsigned codec_id;
|
unsigned codec_id;
|
||||||
|
|
||||||
// 4 bytes 0xFFExxxxx Mpeg audio
|
// 4 bytes 0xFFExxxxx Mpeg audio
|
||||||
// 3 bytes 0x56Exxx AAC LATM audio
|
|
||||||
// 5 bytes 0x0B77xxxxxx AC3 audio
|
// 5 bytes 0x0B77xxxxxx AC3 audio
|
||||||
|
// 3 bytes 0x56Exxx AAC LATM audio
|
||||||
|
// 7/9 bytes 0xFFFxxxxxxxxxxx ADTS audio
|
||||||
// PCM audio can't be found
|
// PCM audio can't be found
|
||||||
|
// FIXME: simple+faster detection, if codec already known
|
||||||
r = 0;
|
r = 0;
|
||||||
if (FastMpegCheck(q)) {
|
if (!r && FastMpegCheck(q)) {
|
||||||
r = MpegCheck(q, n);
|
r = MpegCheck(q, n);
|
||||||
codec_id = CODEC_ID_MP2;
|
codec_id = CODEC_ID_MP2;
|
||||||
}
|
}
|
||||||
@@ -556,6 +624,10 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
|||||||
r = LatmCheck(q, n);
|
r = LatmCheck(q, n);
|
||||||
codec_id = CODEC_ID_AAC_LATM;
|
codec_id = CODEC_ID_AAC_LATM;
|
||||||
}
|
}
|
||||||
|
if (!r && FastAdtsCheck(q)) {
|
||||||
|
r = AdtsCheck(q, n);
|
||||||
|
codec_id = CODEC_ID_AAC;
|
||||||
|
}
|
||||||
if (r < 0) { // need more bytes
|
if (r < 0) { // need more bytes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -583,6 +655,12 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
|||||||
//pesdx->State = PES_MPEG_DECODE;
|
//pesdx->State = PES_MPEG_DECODE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (AudioCodecID != CODEC_ID_NONE) {
|
||||||
|
// shouldn't happen after we have a vaild codec
|
||||||
|
// detected
|
||||||
|
Debug(4, "pesdemux: skip @%d %02x\n", pesdx->Skip,
|
||||||
|
q[0]);
|
||||||
|
}
|
||||||
// try next byte
|
// try next byte
|
||||||
++pesdx->Skip;
|
++pesdx->Skip;
|
||||||
++q;
|
++q;
|
||||||
@@ -802,7 +880,9 @@ static int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size)
|
|||||||
|
|
||||||
p = data;
|
p = data;
|
||||||
while (size >= TS_PACKET_SIZE) {
|
while (size >= TS_PACKET_SIZE) {
|
||||||
|
#ifdef DEBUG
|
||||||
int pid;
|
int pid;
|
||||||
|
#endif
|
||||||
int payload;
|
int payload;
|
||||||
|
|
||||||
if (p[0] != TS_PACKET_SYNC) {
|
if (p[0] != TS_PACKET_SYNC) {
|
||||||
@@ -816,11 +896,11 @@ static int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size)
|
|||||||
// FIXME: kill all buffers
|
// FIXME: kill all buffers
|
||||||
goto next_packet;
|
goto next_packet;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
pid = (p[1] & 0x1F) << 8 | p[2];
|
pid = (p[1] & 0x1F) << 8 | p[2];
|
||||||
Debug(4, "tsdemux: PID: %#04x%s%s\n", pid, p[1] & 0x40 ? " start" : "",
|
Debug(4, "tsdemux: PID: %#04x%s%s\n", pid, p[1] & 0x40 ? " start" : "",
|
||||||
p[3] & 0x10 ? " payload" : "");
|
p[3] & 0x10 ? " payload" : "");
|
||||||
|
#endif
|
||||||
// skip adaptation field
|
// skip adaptation field
|
||||||
switch (p[3] & 0x30) { // adaption field
|
switch (p[3] & 0x30) { // adaption field
|
||||||
case 0x00: // reserved
|
case 0x00: // reserved
|
||||||
@@ -887,7 +967,8 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
if (NewAudioStream) {
|
if (NewAudioStream) {
|
||||||
// this clears the audio ringbuffer indirect, open and setup does it
|
// this clears the audio ringbuffer indirect, open and setup does it
|
||||||
CodecAudioClose(MyAudioDecoder);
|
CodecAudioClose(MyAudioDecoder);
|
||||||
AudioSetBufferTime(0);
|
AudioFlushBuffers();
|
||||||
|
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||||
AudioCodecID = CODEC_ID_NONE;
|
AudioCodecID = CODEC_ID_NONE;
|
||||||
AudioChannelID = -1;
|
AudioChannelID = -1;
|
||||||
NewAudioStream = 0;
|
NewAudioStream = 0;
|
||||||
@@ -972,6 +1053,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
samplerate = samplerates[p[5] >> 4];
|
samplerate = samplerates[p[5] >> 4];
|
||||||
channels = (p[5] & 0x7) + 1;
|
channels = (p[5] & 0x7) + 1;
|
||||||
|
|
||||||
|
// FIXME: ConfigAudioBufferTime + x
|
||||||
AudioSetBufferTime(400);
|
AudioSetBufferTime(400);
|
||||||
AudioSetup(&samplerate, &channels, 0);
|
AudioSetup(&samplerate, &channels, 0);
|
||||||
if (samplerate != samplerates[p[5] >> 4]) {
|
if (samplerate != samplerates[p[5] >> 4]) {
|
||||||
@@ -1002,6 +1084,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
p += 4;
|
p += 4;
|
||||||
n -= 4; // skip track header
|
n -= 4; // skip track header
|
||||||
if (AudioCodecID == CODEC_ID_NONE) {
|
if (AudioCodecID == CODEC_ID_NONE) {
|
||||||
|
// FIXME: ConfigAudioBufferTime + x
|
||||||
AudioSetBufferTime(400);
|
AudioSetBufferTime(400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,6 +1101,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
// 4 bytes 0xFFExxxxx Mpeg audio
|
// 4 bytes 0xFFExxxxx Mpeg audio
|
||||||
// 3 bytes 0x56Exxx AAC LATM audio
|
// 3 bytes 0x56Exxx AAC LATM audio
|
||||||
// 5 bytes 0x0B77xxxxxx AC3 audio
|
// 5 bytes 0x0B77xxxxxx AC3 audio
|
||||||
|
// 7/9 bytes 0xFFFxxxxxxxxxxx ADTS audio
|
||||||
// PCM audio can't be found
|
// PCM audio can't be found
|
||||||
r = 0;
|
r = 0;
|
||||||
codec_id = CODEC_ID_NONE; // keep compiler happy
|
codec_id = CODEC_ID_NONE; // keep compiler happy
|
||||||
@@ -1038,6 +1122,10 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
if (id != 0xbd && !r && FastAdtsCheck(p)) {
|
||||||
|
r = AdtsCheck(p, n);
|
||||||
|
codec_id = CODEC_ID_AAC;
|
||||||
|
}
|
||||||
if (r < 0) { // need more bytes
|
if (r < 0) { // need more bytes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1100,8 +1188,9 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
if (NewAudioStream) {
|
if (NewAudioStream) {
|
||||||
// this clears the audio ringbuffer indirect, open and setup does it
|
// this clears the audio ringbuffer indirect, open and setup does it
|
||||||
CodecAudioClose(MyAudioDecoder);
|
CodecAudioClose(MyAudioDecoder);
|
||||||
|
AudioFlushBuffers();
|
||||||
// max time between audio packets 200ms + 24ms hw buffer
|
// max time between audio packets 200ms + 24ms hw buffer
|
||||||
AudioSetBufferTime(264);
|
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||||
AudioCodecID = CODEC_ID_NONE;
|
AudioCodecID = CODEC_ID_NONE;
|
||||||
AudioChannelID = -1;
|
AudioChannelID = -1;
|
||||||
NewAudioStream = 0;
|
NewAudioStream = 0;
|
||||||
@@ -1128,7 +1217,7 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
*/
|
*/
|
||||||
void SetVolumeDevice(int volume)
|
void SetVolumeDevice(int volume)
|
||||||
{
|
{
|
||||||
AudioSetVolume((volume * 100) / 255);
|
AudioSetVolume((volume * 1000) / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1347,6 +1436,29 @@ void FixPacketForFFMpeg(VideoDecoder * MyVideoDecoder, AVPacket * avpkt)
|
|||||||
CodecVideoDecode(MyVideoDecoder, tmp);
|
CodecVideoDecode(MyVideoDecoder, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Poll PES packet ringbuffer.
|
||||||
|
**
|
||||||
|
** Called if video frame buffers are full.
|
||||||
|
*/
|
||||||
|
int VideoPollInput(void)
|
||||||
|
{
|
||||||
|
if (VideoClearBuffers) {
|
||||||
|
atomic_set(&VideoPacketsFilled, 0);
|
||||||
|
VideoPacketRead = VideoPacketWrite;
|
||||||
|
if (MyVideoDecoder) {
|
||||||
|
CodecVideoFlushBuffers(MyVideoDecoder);
|
||||||
|
VideoResetStart(MyHwDecoder);
|
||||||
|
}
|
||||||
|
VideoClearBuffers = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!atomic_read(&VideoPacketsFilled)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Decode from PES packet ringbuffer.
|
** Decode from PES packet ringbuffer.
|
||||||
**
|
**
|
||||||
@@ -1354,25 +1466,27 @@ void FixPacketForFFMpeg(VideoDecoder * MyVideoDecoder, AVPacket * avpkt)
|
|||||||
** @retval 1 stream paused
|
** @retval 1 stream paused
|
||||||
** @retval -1 empty stream
|
** @retval -1 empty stream
|
||||||
*/
|
*/
|
||||||
int VideoDecode(void)
|
int VideoDecodeInput(void)
|
||||||
{
|
{
|
||||||
int filled;
|
int filled;
|
||||||
AVPacket *avpkt;
|
AVPacket *avpkt;
|
||||||
int saved_size;
|
int saved_size;
|
||||||
static int last_codec_id = CODEC_ID_NONE;
|
static int last_codec_id = CODEC_ID_NONE;
|
||||||
|
|
||||||
if (StreamFreezed) { // stream freezed
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (VideoClearBuffers) {
|
if (VideoClearBuffers) {
|
||||||
atomic_set(&VideoPacketsFilled, 0);
|
atomic_set(&VideoPacketsFilled, 0);
|
||||||
VideoPacketRead = VideoPacketWrite;
|
VideoPacketRead = VideoPacketWrite;
|
||||||
if (MyVideoDecoder) {
|
if (MyVideoDecoder) {
|
||||||
CodecVideoFlushBuffers(MyVideoDecoder);
|
CodecVideoFlushBuffers(MyVideoDecoder);
|
||||||
|
VideoResetStart(MyHwDecoder);
|
||||||
}
|
}
|
||||||
VideoClearBuffers = 0;
|
VideoClearBuffers = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (StreamFreezed) { // stream freezed
|
||||||
|
// clear is called during freezed
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
filled = atomic_read(&VideoPacketsFilled);
|
filled = atomic_read(&VideoPacketsFilled);
|
||||||
if (!filled) {
|
if (!filled) {
|
||||||
@@ -1438,33 +1552,6 @@ int VideoDecode(void)
|
|||||||
avpkt->size = avpkt->stream_index;
|
avpkt->size = avpkt->stream_index;
|
||||||
avpkt->stream_index = 0;
|
avpkt->stream_index = 0;
|
||||||
|
|
||||||
if (0) {
|
|
||||||
static int done;
|
|
||||||
|
|
||||||
if (done < 2) {
|
|
||||||
int fildes;
|
|
||||||
int who_designed_this_is____;
|
|
||||||
|
|
||||||
if (done == 0)
|
|
||||||
fildes =
|
|
||||||
open("frame0.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
|
||||||
else if (done == 1)
|
|
||||||
fildes =
|
|
||||||
open("frame1.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
|
||||||
else
|
|
||||||
fildes =
|
|
||||||
open("frame2.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
|
||||||
done++;
|
|
||||||
who_designed_this_is____ = write(fildes, avpkt->data, avpkt->size);
|
|
||||||
close(fildes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ClosingVideoStream) { // closing don't sync
|
|
||||||
avpkt->pts = AV_NOPTS_VALUE;
|
|
||||||
avpkt->dts = AV_NOPTS_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_codec_id == CODEC_ID_MPEG2VIDEO) {
|
if (last_codec_id == CODEC_ID_MPEG2VIDEO) {
|
||||||
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
||||||
} else {
|
} else {
|
||||||
@@ -1638,8 +1725,6 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
VideoNextPacket(CODEC_ID_NONE);
|
VideoNextPacket(CODEC_ID_NONE);
|
||||||
VideoCodecID = CODEC_ID_NONE;
|
VideoCodecID = CODEC_ID_NONE;
|
||||||
// clear clock until new stream starts
|
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
ClosingVideoStream = 1;
|
ClosingVideoStream = 1;
|
||||||
NewVideoStream = 0;
|
NewVideoStream = 0;
|
||||||
}
|
}
|
||||||
@@ -1732,8 +1817,8 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
Debug(3, "softhddev/video: invalid mpeg2 video packet\n");
|
Debug(3, "softhddev/video: invalid mpeg2 video packet\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// SKIP PES header
|
// SKIP PES header, begin of start code
|
||||||
VideoEnqueue(pts, check - 2, l + 2);
|
VideoEnqueue(pts, check - z, l + z);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
// this happens when vdr sends incomplete packets
|
// this happens when vdr sends incomplete packets
|
||||||
@@ -1856,6 +1941,9 @@ int SetPlayMode(int play_mode)
|
|||||||
if (MyVideoDecoder) { // tell video parser we have new stream
|
if (MyVideoDecoder) { // tell video parser we have new stream
|
||||||
if (VideoCodecID != CODEC_ID_NONE) {
|
if (VideoCodecID != CODEC_ID_NONE) {
|
||||||
NewVideoStream = 1;
|
NewVideoStream = 1;
|
||||||
|
// tell hw decoder we are closing stream
|
||||||
|
VideoSetClosing(MyHwDecoder);
|
||||||
|
VideoResetStart(MyHwDecoder);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
VideoSwitch = GetMsTicks();
|
VideoSwitch = GetMsTicks();
|
||||||
#endif
|
#endif
|
||||||
@@ -1871,11 +1959,9 @@ int SetPlayMode(int play_mode)
|
|||||||
break;
|
break;
|
||||||
case 2: // audio only
|
case 2: // audio only
|
||||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
break;
|
break;
|
||||||
case 3: // audio only, black screen
|
case 3: // audio only, black screen
|
||||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
break;
|
break;
|
||||||
case 4: // video only
|
case 4: // video only
|
||||||
break;
|
break;
|
||||||
@@ -1927,16 +2013,21 @@ void Clear(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
VideoResetPacket(); // terminate work
|
VideoResetPacket(); // terminate work
|
||||||
|
//closing not reset:
|
||||||
|
//VideoSetClosing(MyHwDecoder);
|
||||||
|
VideoResetStart(MyHwDecoder);
|
||||||
VideoClearBuffers = 1;
|
VideoClearBuffers = 1;
|
||||||
AudioFlushBuffers();
|
AudioFlushBuffers();
|
||||||
//NewAudioStream = 1;
|
//NewAudioStream = 1;
|
||||||
// FIXME: audio avcodec_flush_buffers, video is done by VideoClearBuffers
|
// FIXME: audio avcodec_flush_buffers, video is done by VideoClearBuffers
|
||||||
|
|
||||||
// wait for empty buffers
|
// wait for empty buffers
|
||||||
|
// FIXME: without softstart sync VideoDecode isn't called.
|
||||||
for (i = 0; VideoClearBuffers && i < 20; ++i) {
|
for (i = 0; VideoClearBuffers && i < 20; ++i) {
|
||||||
usleep(1 * 1000);
|
usleep(1 * 1000);
|
||||||
}
|
}
|
||||||
Debug(3, "[softhddev]%s: buffers %d\n", __FUNCTION__, VideoGetBuffers());
|
Debug(3, "[softhddev]%s: %dms buffers %d\n", __FUNCTION__, i,
|
||||||
|
VideoGetBuffers());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2090,10 +2181,15 @@ int Poll(int timeout)
|
|||||||
#else
|
#else
|
||||||
int full;
|
int full;
|
||||||
int t;
|
int t;
|
||||||
|
int used;
|
||||||
|
int filled;
|
||||||
|
|
||||||
// one buffer is full
|
used = AudioUsedBytes();
|
||||||
full = AudioFreeBytes() >= AUDIO_MIN_BUFFER_FREE
|
filled = atomic_read(&VideoPacketsFilled);
|
||||||
|| atomic_read(&VideoPacketsFilled) < VIDEO_PACKET_MAX - 3;
|
// soft limit + hard limit
|
||||||
|
full = (used > AUDIO_MIN_BUFFER_FREE && filled > 3)
|
||||||
|
|| AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE
|
||||||
|
|| filled >= VIDEO_PACKET_MAX - 3;
|
||||||
|
|
||||||
if (!full || !timeout) {
|
if (!full || !timeout) {
|
||||||
return !full;
|
return !full;
|
||||||
@@ -2198,7 +2294,8 @@ const char *CommandLineHelp(void)
|
|||||||
"\tno-hw-decoder\t\tdisable hw decoder, use software decoder only\n"
|
"\tno-hw-decoder\t\tdisable hw decoder, use software decoder only\n"
|
||||||
"\tno-mpeg-hw-decoder\tdisable hw decoder for mpeg only\n"
|
"\tno-mpeg-hw-decoder\tdisable hw decoder for mpeg only\n"
|
||||||
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
||||||
"\tignore-repeat-pict\tdisable repeat pict message\n";
|
"\tignore-repeat-pict\tdisable repeat pict message\n"
|
||||||
|
" -D\t\tstart in detached mode\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2213,7 +2310,7 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
// Parse arguments.
|
// Parse arguments.
|
||||||
//
|
//
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (getopt(argc, argv, "-a:c:d:fg:p:sv:w:x")) {
|
switch (getopt(argc, argv, "-a:c:d:fg:p:sv:w:xD")) {
|
||||||
case 'a': // audio device for pcm
|
case 'a': // audio device for pcm
|
||||||
AudioSetDevice(optarg);
|
AudioSetDevice(optarg);
|
||||||
continue;
|
continue;
|
||||||
@@ -2250,9 +2347,14 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
case 's': // start in suspend mode
|
case 's': // start in suspend mode
|
||||||
ConfigStartSuspended = 1;
|
ConfigStartSuspended = 1;
|
||||||
continue;
|
continue;
|
||||||
|
case 'D': // start in detached mode
|
||||||
|
ConfigStartSuspended = -1;
|
||||||
|
continue;
|
||||||
case 'w': // workarounds
|
case 'w': // workarounds
|
||||||
if (!strcasecmp("no-hw-decoder", optarg)) {
|
if (!strcasecmp("no-hw-decoder", optarg)) {
|
||||||
|
VideoHardwareDecoder = 0;
|
||||||
} else if (!strcasecmp("no-mpeg-hw-decoder", optarg)) {
|
} else if (!strcasecmp("no-mpeg-hw-decoder", optarg)) {
|
||||||
|
VideoHardwareDecoder = 1;
|
||||||
} else if (!strcasecmp("alsa-driver-broken", optarg)) {
|
} else if (!strcasecmp("alsa-driver-broken", optarg)) {
|
||||||
AudioAlsaDriverBroken = 1;
|
AudioAlsaDriverBroken = 1;
|
||||||
} else if (!strcasecmp("ignore-repeat-pict", optarg)) {
|
} else if (!strcasecmp("ignore-repeat-pict", optarg)) {
|
||||||
@@ -2333,6 +2435,8 @@ static void StartXServer(void)
|
|||||||
argn = 1;
|
argn = 1;
|
||||||
if (X11DisplayName) { // append display name
|
if (X11DisplayName) { // append display name
|
||||||
args[argn++] = X11DisplayName;
|
args[argn++] = X11DisplayName;
|
||||||
|
// export display for childs
|
||||||
|
setenv("DISPLAY", X11DisplayName, 1);
|
||||||
}
|
}
|
||||||
// split X server arguments string into words
|
// split X server arguments string into words
|
||||||
if ((sval = X11ServerArguments)) {
|
if ((sval = X11ServerArguments)) {
|
||||||
@@ -2370,10 +2474,12 @@ static void StartXServer(void)
|
|||||||
}
|
}
|
||||||
// child
|
// child
|
||||||
signal(SIGUSR1, SIG_IGN); // ignore to force answer
|
signal(SIGUSR1, SIG_IGN); // ignore to force answer
|
||||||
|
//setpgid(0,getpid());
|
||||||
// start the X server
|
// start the X server
|
||||||
execvp(args[0], (char *const *)args);
|
execvp(args[0], (char *const *)args);
|
||||||
|
|
||||||
Error(_("x-setup: Failed to start X server '%s'\n"), args[0]);
|
Error(_("x-setup: Failed to start X server '%s'\n"), args[0]);
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2436,6 +2542,10 @@ void SoftHdDeviceExit(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
** Prepare plugin.
|
** Prepare plugin.
|
||||||
|
**
|
||||||
|
** @retval 0 normal start
|
||||||
|
** @retval 1 suspended start
|
||||||
|
** @retval -1 detached start
|
||||||
*/
|
*/
|
||||||
int Start(void)
|
int Start(void)
|
||||||
{
|
{
|
||||||
@@ -2465,9 +2575,11 @@ int Start(void)
|
|||||||
#ifndef NO_TS_AUDIO
|
#ifndef NO_TS_AUDIO
|
||||||
PesInit(PesDemuxAudio);
|
PesInit(PesDemuxAudio);
|
||||||
#endif
|
#endif
|
||||||
Info(_("[softhddev] ready%s\n"), ConfigStartSuspended ? " suspended" : "");
|
Info(_("[softhddev] ready%s\n"),
|
||||||
|
ConfigStartSuspended ? ConfigStartSuspended ==
|
||||||
|
-1 ? "detached" : " suspended" : "");
|
||||||
|
|
||||||
return !ConfigStartSuspended;
|
return ConfigStartSuspended;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2495,6 +2607,8 @@ void Housekeeping(void)
|
|||||||
void MainThreadHook(void)
|
void MainThreadHook(void)
|
||||||
{
|
{
|
||||||
if (Usr1Signal) { // x11 server ready
|
if (Usr1Signal) { // x11 server ready
|
||||||
|
// FIYME: x11 server keeps sending sigusr1 signals
|
||||||
|
signal(SIGUSR1, SIG_IGN); // ignore further signals
|
||||||
Usr1Signal = 0;
|
Usr1Signal = 0;
|
||||||
StartVideo();
|
StartVideo();
|
||||||
VideoDisplayWakeup();
|
VideoDisplayWakeup();
|
||||||
@@ -2577,3 +2691,22 @@ void Resume(void)
|
|||||||
|
|
||||||
pthread_mutex_unlock(&SuspendLockMutex);
|
pthread_mutex_unlock(&SuspendLockMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Get decoder statistics.
|
||||||
|
**
|
||||||
|
** @param[out] missed missed frames
|
||||||
|
** @param[out] duped duped frames
|
||||||
|
** @param[out] dropped dropped frames
|
||||||
|
** @param[out] count number of decoded frames
|
||||||
|
*/
|
||||||
|
void GetStats(int *missed, int *duped, int *dropped, int *counter)
|
||||||
|
{
|
||||||
|
*missed = 0;
|
||||||
|
*duped = 0;
|
||||||
|
*dropped = 0;
|
||||||
|
*counter = 0;
|
||||||
|
if (MyHwDecoder) {
|
||||||
|
VideoGetStats(MyHwDecoder, missed, duped, dropped, counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ extern "C"
|
|||||||
extern void Suspend(int, int, int);
|
extern void Suspend(int, int, int);
|
||||||
/// Resume plugin
|
/// Resume plugin
|
||||||
extern void Resume(void);
|
extern void Resume(void);
|
||||||
|
|
||||||
|
/// Get decoder statistics
|
||||||
|
extern void GetStats(int *, int *, int *, int *);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
792
softhddevice.cpp
792
softhddevice.cpp
File diff suppressed because it is too large
Load Diff
44
softhddevice_service.h
Normal file
44
softhddevice_service.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
///
|
||||||
|
/// @file softhddev_service.h @brief software HD device service header file.
|
||||||
|
///
|
||||||
|
/// Copyright (c) 2012 by durchflieger. All Rights Reserved.
|
||||||
|
///
|
||||||
|
/// Contributor(s):
|
||||||
|
///
|
||||||
|
/// License: AGPLv3
|
||||||
|
///
|
||||||
|
/// This program is free software: you can redistribute it and/or modify
|
||||||
|
/// it under the terms of the GNU Affero General Public License as
|
||||||
|
/// published by the Free Software Foundation, either version 3 of the
|
||||||
|
/// License.
|
||||||
|
///
|
||||||
|
/// This program is distributed in the hope that it will be useful,
|
||||||
|
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/// GNU Affero General Public License for more details.
|
||||||
|
///
|
||||||
|
/// $Id$
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ATMO_GRAB_SERVICE "SoftHDDevice-AtmoGrabService-v1.0"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{ GRAB_IMG_RGBA_FORMAT_B8G8R8A8 };
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int structSize;
|
||||||
|
|
||||||
|
// request data
|
||||||
|
int analyseSize;
|
||||||
|
int clippedOverscan;
|
||||||
|
|
||||||
|
// reply data
|
||||||
|
int imgType;
|
||||||
|
int imgSize;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
void *img;
|
||||||
|
} SoftHDDevice_AtmoGrabService_v1_0_t;
|
||||||
23
video.h
23
video.h
@@ -34,6 +34,7 @@ typedef struct _video_hw_decoder_ VideoHwDecoder;
|
|||||||
// Variables
|
// Variables
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern char VideoHardwareDecoder; ///< flag use hardware decoder
|
||||||
extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
extern char VideoIgnoreRepeatPict; ///< disable repeat pict warning
|
||||||
extern int VideoAudioDelay; ///< audio/video delay
|
extern int VideoAudioDelay; ///< audio/video delay
|
||||||
|
|
||||||
@@ -90,6 +91,9 @@ extern void VideoSet60HzMode(int);
|
|||||||
/// Set soft start audio/video sync.
|
/// Set soft start audio/video sync.
|
||||||
extern void VideoSetSoftStartSync(int);
|
extern void VideoSetSoftStartSync(int);
|
||||||
|
|
||||||
|
/// Set show black picture during channel switch.
|
||||||
|
extern void VideoSetBlackPicture(int);
|
||||||
|
|
||||||
/// Set video output position.
|
/// Set video output position.
|
||||||
extern void VideoSetOutputPosition(int, int, int, int);
|
extern void VideoSetOutputPosition(int, int, int, int);
|
||||||
|
|
||||||
@@ -147,26 +151,41 @@ extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
|
|||||||
/// Get OSD size.
|
/// Get OSD size.
|
||||||
extern void VideoGetOsdSize(int *, int *);
|
extern void VideoGetOsdSize(int *, int *);
|
||||||
|
|
||||||
|
/// Set OSD size.
|
||||||
|
extern void VideoSetOsdSize(int, int);
|
||||||
|
|
||||||
/// Set video clock.
|
/// Set video clock.
|
||||||
extern void VideoSetClock(VideoHwDecoder *, int64_t);
|
extern void VideoSetClock(VideoHwDecoder *, int64_t);
|
||||||
|
|
||||||
/// Get video clock.
|
/// Get video clock.
|
||||||
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
||||||
|
|
||||||
|
/// Set closing flag.
|
||||||
|
extern void VideoSetClosing(VideoHwDecoder *);
|
||||||
|
|
||||||
|
/// Reset start of frame counter
|
||||||
|
extern void VideoResetStart(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Set trick play speed.
|
/// Set trick play speed.
|
||||||
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
||||||
|
|
||||||
/// Grab screen.
|
/// Grab screen.
|
||||||
extern uint8_t *VideoGrab(int *, int *, int *, int);
|
extern uint8_t *VideoGrab(int *, int *, int *, int);
|
||||||
|
|
||||||
|
/// Grab screen raw.
|
||||||
|
extern uint8_t *VideoGrabService(int *, int *, int *);
|
||||||
|
|
||||||
|
/// Get decoder statistics.
|
||||||
|
extern void VideoGetStats(VideoHwDecoder *, 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.
|
||||||
|
|
||||||
extern void VideoInit(const char *); ///< Setup video module.
|
extern void VideoInit(const char *); ///< Setup video module.
|
||||||
extern void VideoExit(void); ///< Cleanup and exit video module.
|
extern void VideoExit(void); ///< Cleanup and exit video module.
|
||||||
|
|
||||||
extern void VideoFlushInput(void); ///< Flush video input buffers.
|
extern int VideoPollInput(void); ///< Poll video input buffers.
|
||||||
extern int VideoDecode(void); ///< Decode video input buffers.
|
extern int VideoDecodeInput(void); ///< Decode video input buffers.
|
||||||
extern int VideoGetBuffers(void); ///< Get number of input buffers.
|
extern int VideoGetBuffers(void); ///< Get number of input buffers.
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
Reference in New Issue
Block a user