summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--README.txt4
-rw-r--r--audio.c79
-rw-r--r--audio.h3
-rw-r--r--codec.c35
-rw-r--r--softhddev.c10
6 files changed, 105 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index f8f44af..e570655 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
+User Morone
+Data: Sun Jan 22 16:43:23 CET 2012
+
+ Use different alsa devices for AC3/pass-through and pcm.
+
User johns
-Data:
+Data: Sun Jan 22 11:12:57 CET 2012
Add dummy player and control for suspend mode.
Buffertime compile time configurable in ms.
diff --git a/README.txt b/README.txt
index d4cfb5e..6b9cab2 100644
--- a/README.txt
+++ b/README.txt
@@ -79,6 +79,8 @@ Setup: environment
only if alsa is configured
ALSA_DEVICE=default
alsa PCM device name
+ ALSA_AC3_DEVICE=
+ alsa AC3/pass-though device name
ALSA_MIXER=default
alsa control device name
ALSA_MIXER_CHANNEL=PCM
@@ -128,6 +130,8 @@ Setup: /etc/vdr/setup.conf
softhddevice.AudioPassthrough = 0
0 = none, 1 = AC-3
+ for AC-3 the pass-through device is used.
+
softhddevice.AutoCrop.Interval = 0
0 disables auto-crop
n each 'n' frames auto-crop is checked.
diff --git a/audio.c b/audio.c
index 5ec0827..77f95a5 100644
--- a/audio.c
+++ b/audio.c
@@ -112,7 +112,7 @@ typedef struct _audio_module_
int (*FreeBytes) (void); ///< number of bytes free in buffer
uint64_t(*GetDelay) (void); ///< get current audio delay
void (*SetVolume) (int); ///< set output volume
- int (*Setup) (int *, int *); ///< setup channels, samplerate
+ int (*Setup) (int *, int *, int); ///< setup channels, samplerate
void (*Init) (void); ///< initialize audio output module
void (*Exit) (void); ///< cleanup audio output module
} AudioModule;
@@ -128,6 +128,7 @@ static const char *AudioModuleName; ///< which audio module to use
/// Selected audio module.
static const AudioModule *AudioUsedModule = &NoopModule;
static const char *AudioPCMDevice; ///< alsa/OSS PCM device name
+static const char *AudioAC3Device; ///< alsa/OSS AC3 device name
static const char *AudioMixerDevice; ///< alsa/OSS mixer device name
static const char *AudioMixerChannel; ///< alsa/OSS mixer channel name
static volatile char AudioRunning; ///< thread running / stopped
@@ -696,18 +697,24 @@ static void AlsaThreadFlushBuffers(void)
/**
** Open alsa pcm device.
+**
+** @param use_ac3 use ac3/pass-through device
*/
-static snd_pcm_t *AlsaOpenPCM(void)
+static snd_pcm_t *AlsaOpenPCM(int use_ac3)
{
const char *device;
snd_pcm_t *handle;
int err;
- if (!(device = AudioPCMDevice)) {
- if (!(device = getenv("ALSA_DEVICE"))) {
- device = "default";
- }
+ // &&|| hell
+ if (!(use_ac3 && ((device = AudioAC3Device)
+ || (device = getenv("ALSA_PASSTHROUGH_DEVICE"))))
+ && !(device = AudioPCMDevice) && !(device = getenv("ALSA_DEVICE"))) {
+ device = "default";
}
+ Debug(3, "audio/alsa: &&|| hell '%s'\n", device);
+
+ // open none blocking; if device is already used, we don't want wait
if ((err =
snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK)) < 0) {
@@ -734,7 +741,7 @@ static void AlsaInitPCM(void)
int err;
snd_pcm_uframes_t buffer_size;
- if (!(handle = AlsaOpenPCM())) {
+ if (!(handle = AlsaOpenPCM(0))) {
return;
}
@@ -878,6 +885,7 @@ static uint64_t AlsaGetDelay(void)
**
** @param freq sample frequency
** @param channels number of channels
+** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@@ -885,7 +893,7 @@ static uint64_t AlsaGetDelay(void)
**
** @todo audio changes must be queued and done when the buffer is empty
*/
-static int AlsaSetup(int *freq, int *channels)
+static int AlsaSetup(int *freq, int *channels, int use_ac3)
{
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
@@ -904,7 +912,7 @@ static int AlsaSetup(int *freq, int *channels)
handle = AlsaPCMHandle;
AlsaPCMHandle = NULL;
snd_pcm_close(handle);
- if (!(handle = AlsaOpenPCM())) {
+ if (!(handle = AlsaOpenPCM(use_ac3))) {
return -1;
}
AlsaPCMHandle = handle;
@@ -1584,6 +1592,7 @@ static uint64_t OssGetDelay(void)
**
** @param freq sample frequency
** @param channels number of channels
+** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@@ -1591,7 +1600,8 @@ static uint64_t OssGetDelay(void)
**
** @todo audio changes must be queued and done when the buffer is empty
*/
-static int OssSetup(int *freq, int *channels)
+static int OssSetup(int *freq, int *channels, __attribute__ ((unused))
+ int use_ac3)
{
int ret;
int tmp;
@@ -1690,6 +1700,8 @@ static int OssSetup(int *freq, int *channels)
/**
** Initialize OSS audio output module.
+**
+** @param use_ac3 use ac3/pass-through device
*/
static void OssInit(void)
{
@@ -1790,7 +1802,8 @@ static void NoopSetVolume( __attribute__ ((unused))
*/
static int NoopSetup( __attribute__ ((unused))
int *channels, __attribute__ ((unused))
- int *freq)
+ int *freq, __attribute__ ((unused))
+ int use_ac3)
{
return -1;
}
@@ -2040,6 +2053,7 @@ void AudioSetVolume(int volume)
**
** @param freq sample frequency
** @param channels number of channels
+** @param use_ac3 use ac3/pass-through device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@@ -2047,9 +2061,10 @@ void AudioSetVolume(int volume)
**
** @todo audio changes must be queued and done when the buffer is empty
*/
-int AudioSetup(int *freq, int *channels)
+int AudioSetup(int *freq, int *channels, int use_ac3)
{
- Debug(3, "audio: channels %d frequency %d hz\n", *channels, *freq);
+ Debug(3, "audio: channels %d frequency %d hz %s\n", *channels, *freq,
+ use_ac3 ? "ac3" : "pcm");
// invalid parameter
if (!freq || !channels || !*freq || !*channels) {
@@ -2059,9 +2074,9 @@ int AudioSetup(int *freq, int *channels)
}
#ifdef USE_AUDIORING
// FIXME: need to store possible combination and report this
- return AudioRingAdd(*freq, *channels);
+ return AudioRingAdd(*freq, *channels, use_ac3);
#endif
- return AudioUsedModule->Setup(freq, channels);
+ return AudioUsedModule->Setup(freq, channels, use_ac3);
}
/**
@@ -2073,16 +2088,38 @@ int AudioSetup(int *freq, int *channels)
*/
void AudioSetDevice(const char *device)
{
- AudioModuleName = "alsa"; // detect alsa/OSS
- if (!device[0]) {
- AudioModuleName = "noop";
- } else if (device[0] == '/') {
- AudioModuleName = "oss";
+ if (!AudioModuleName) {
+ AudioModuleName = "alsa"; // detect alsa/OSS
+ if (!device[0]) {
+ AudioModuleName = "noop";
+ } else if (device[0] == '/') {
+ AudioModuleName = "oss";
+ }
}
AudioPCMDevice = device;
}
/**
+** Set pass-through audio device.
+**
+** @param device name of pass-through device (fe. "hw:0,1")
+**
+** @note this is currently usable with alsa only.
+*/
+void AudioSetDeviceAC3(const char *device)
+{
+ if (!AudioModuleName) {
+ AudioModuleName = "alsa"; // detect alsa/OSS
+ if (!device[0]) {
+ AudioModuleName = "noop";
+ } else if (device[0] == '/') {
+ AudioModuleName = "oss";
+ }
+ }
+ AudioAC3Device = device;
+}
+
+/**
** Initialize audio output module.
**
** @todo FIXME: make audio output module selectable.
@@ -2125,7 +2162,7 @@ void AudioInit(void)
AudioUsedModule->Init();
freq = 48000;
chan = 2;
- if (AudioSetup(&freq, &chan)) { // set default parameters
+ if (AudioSetup(&freq, &chan, 0)) { // set default parameters
Error(_("audio: can't do initial setup\n"));
}
#ifdef USE_AUDIO_THREAD
diff --git a/audio.h b/audio.h
index f031c7d..2a4c45f 100644
--- a/audio.h
+++ b/audio.h
@@ -37,12 +37,13 @@ extern uint64_t AudioGetDelay(void); ///< get current audio delay
extern void AudioSetClock(int64_t); ///< set audio clock base
extern int64_t AudioGetClock(); ///< get current audio clock
extern void AudioSetVolume(int); ///< set volume
-extern int AudioSetup(int *, int *); ///< setup audio output
+extern int AudioSetup(int *, int *, int); ///< setup audio output
//extern void AudioPlay(void); ///< play audio
//extern void AudioPause(void); ///< pause audio
extern void AudioSetDevice(const char *); ///< set PCM audio device
+extern void AudioSetDeviceAC3(const char *); ///< set Passthrough device
extern void AudioInit(void); ///< setup audio module
extern void AudioExit(void); ///< cleanup and exit audio module
diff --git a/codec.c b/codec.c
index 158b1eb..fb373d5 100644
--- a/codec.c
+++ b/codec.c
@@ -320,14 +320,14 @@ static void Codec_draw_horiz_band(AVCodecContext * video_ctx,
**
** @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 *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;
@@ -335,6 +335,16 @@ VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder * hw_decoder)
}
/**
+** Deallocate a video decoder context.
+**
+** @param decoder private video decoder
+*/
+void CodecVideoDelDecoder(VideoDecoder * decoder)
+{
+ free(decoder);
+}
+
+/**
** Open video decoder.
**
** @param decoder private video decoder
@@ -613,22 +623,30 @@ static char CodecPassthroughAC3; ///< pass ac3 through
/**
** Allocate a new audio decoder context.
**
-** @param hw_decoder video hardware decoder
-**
-** @returns private decoder pointer for audio/video decoder.
+** @returns private decoder pointer for audio decoder.
*/
AudioDecoder *CodecAudioNewDecoder(void)
{
AudioDecoder *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;
}
/**
+** Deallocate an audio decoder context.
+**
+** @param decoder private audio decoder
+*/
+void CodecAudioDelDecoder(AudioDecoder * decoder)
+{
+ free(decoder);
+}
+
+/**
** Open audio decoder.
**
** @param audio_decoder private audio decoder
@@ -794,6 +812,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
if (audio_decoder->SampleRate != audio_ctx->sample_rate
|| audio_decoder->Channels != audio_ctx->channels) {
int err;
+ int isAC3;
if (audio_decoder->ReSample) {
audio_resample_close(audio_decoder->ReSample);
@@ -807,16 +826,18 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
// SPDIF/HDMI passthrough
if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
audio_decoder->HwChannels = 2;
+ isAC3 = 1;
} else
#endif
{
audio_decoder->HwChannels = audio_ctx->channels;
+ isAC3 = 0;
}
// channels not support?
if ((err =
AudioSetup(&audio_decoder->HwSampleRate,
- &audio_decoder->HwChannels))) {
+ &audio_decoder->HwChannels, isAC3))) {
Debug(3, "codec/audio: resample %dHz *%d -> %dHz *%d\n",
audio_ctx->sample_rate, audio_ctx->channels,
audio_decoder->HwSampleRate,
diff --git a/softhddev.c b/softhddev.c
index 80abe9a..b1e29cf 100644
--- a/softhddev.c
+++ b/softhddev.c
@@ -989,6 +989,7 @@ static char ConfigStartX11Server; ///< flag start the x11 server
const char *CommandLineHelp(void)
{
return " -a device\taudio device (fe. alsa: hw:0,0 oss: /dev/dsp)\n"
+ " -p device\taudio device (alsa only) for pass-through (hw:0,1)\n"
" -d display\tdisplay of x11 server (fe. :0.0)\n"
" -f\t\tstart with fullscreen window (only with window manager)\n"
" -g geometry\tx11 window geometry wxh+x+y\n"
@@ -1007,10 +1008,13 @@ int ProcessArgs(int argc, char *const argv[])
// Parse arguments.
//
for (;;) {
- switch (getopt(argc, argv, "-a:d:fg:x")) {
+ switch (getopt(argc, argv, "-a:p:d:fg:x")) {
case 'a': // audio device
AudioSetDevice(optarg);
continue;
+ case 'p': // pass-through audio device
+ AudioSetDeviceAC3(optarg);
+ continue;
case 'd': // x11 display name
X11DisplayName = optarg;
continue;
@@ -1154,12 +1158,12 @@ void SoftHdDeviceExit(void)
if (MyVideoDecoder) {
CodecVideoClose(MyVideoDecoder);
- // FIXME: CodecDelVideoDecoder(MyVideoDecoder);
+ CodecVideoDelDecoder(MyVideoDecoder);
MyVideoDecoder = NULL;
}
if (MyAudioDecoder) {
CodecAudioClose(MyAudioDecoder);
- // FIXME: CodecDelAudioDecoder(MyAudioDecoder);
+ CodecAudioDelDecoder(MyAudioDecoder);
MyAudioDecoder = NULL;
}