mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Add Workaround for alsa blocking audio device.
This commit is contained in:
parent
a45b9a3abe
commit
340e10a0eb
@ -1,3 +1,9 @@
|
|||||||
|
User johns
|
||||||
|
Date:
|
||||||
|
|
||||||
|
Add Workaround for alsa blocking audio device.
|
||||||
|
Improves thread handling for audio flush and close.
|
||||||
|
|
||||||
User mini73
|
User mini73
|
||||||
Date: Fri Jan 24 11:30:49 CET 2014
|
Date: Fri Jan 24 11:30:49 CET 2014
|
||||||
|
|
||||||
|
38
audio.c
38
audio.c
@ -123,6 +123,8 @@ static const AudioModule NoopModule; ///< forward definition of noop module
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
char AudioAlsaDriverBroken; ///< disable broken driver message
|
char AudioAlsaDriverBroken; ///< disable broken driver message
|
||||||
|
char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
||||||
|
char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
||||||
|
|
||||||
static const char *AudioModuleName; ///< which audio module to use
|
static const char *AudioModuleName; ///< which audio module to use
|
||||||
|
|
||||||
@ -1189,13 +1191,17 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
|
|||||||
// FIXME: if open fails for fe. pass-through, we never recover
|
// FIXME: if open fails for fe. pass-through, we never recover
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (1) { // close+open to fix HDMI no sound bug
|
if (!AudioAlsaNoCloseOpen) { // close+open to fix HDMI no sound bug
|
||||||
snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
|
|
||||||
handle = AlsaPCMHandle;
|
handle = AlsaPCMHandle;
|
||||||
// FIXME: need lock
|
// FIXME: need lock
|
||||||
AlsaPCMHandle = NULL; // other threads should check handle
|
AlsaPCMHandle = NULL; // other threads should check handle
|
||||||
snd_pcm_close(handle);
|
snd_pcm_close(handle);
|
||||||
|
if (AudioAlsaCloseOpenDelay) {
|
||||||
|
usleep(50 * 1000); // 50ms delay for alsa recovery
|
||||||
|
}
|
||||||
|
// FIXME: can use multiple retries
|
||||||
if (!(handle = AlsaOpenPCM(passthrough))) {
|
if (!(handle = AlsaOpenPCM(passthrough))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2043,25 +2049,27 @@ static void *AudioPlayHandlerThread(void *dummy)
|
|||||||
int read;
|
int read;
|
||||||
int flush;
|
int flush;
|
||||||
int err;
|
int err;
|
||||||
|
int i;
|
||||||
|
|
||||||
// look if there is a flush command in the queue
|
// look if there is a flush command in the queue
|
||||||
flush = 0;
|
flush = 0;
|
||||||
filled = atomic_read(&AudioRingFilled);
|
filled = atomic_read(&AudioRingFilled);
|
||||||
read = AudioRingRead;
|
read = AudioRingRead;
|
||||||
while (filled--) {
|
i = filled;
|
||||||
|
while (i--) {
|
||||||
read = (read + 1) % AUDIO_RING_MAX;
|
read = (read + 1) % AUDIO_RING_MAX;
|
||||||
if (AudioRing[read].FlushBuffers) {
|
if (AudioRing[read].FlushBuffers) {
|
||||||
AudioRing[read].FlushBuffers = 0;
|
AudioRing[read].FlushBuffers = 0;
|
||||||
AudioRingRead = read;
|
AudioRingRead = read;
|
||||||
atomic_set(&AudioRingFilled, filled);
|
|
||||||
// handle all flush in queue
|
// handle all flush in queue
|
||||||
flush = 1;
|
flush = filled - i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
Debug(3, "audio: flush\n");
|
Debug(3, "audio: flush %d ring buffer(s)\n", flush);
|
||||||
AudioUsedModule->FlushBuffers();
|
AudioUsedModule->FlushBuffers();
|
||||||
|
atomic_sub(flush, &AudioRingFilled);
|
||||||
if (AudioNextRing()) {
|
if (AudioNextRing()) {
|
||||||
Debug(3, "audio: break after flush\n");
|
Debug(3, "audio: break after flush\n");
|
||||||
break;
|
break;
|
||||||
@ -2421,8 +2429,23 @@ void AudioFlushBuffers(void)
|
|||||||
int old;
|
int old;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (atomic_read(&AudioRingFilled) >= AUDIO_RING_MAX) {
|
||||||
|
// wait for space in ring buffer, should never happen
|
||||||
|
for (i = 0; i < 24 * 2; ++i) {
|
||||||
|
if (atomic_read(&AudioRingFilled) < AUDIO_RING_MAX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Debug(3, "audio: flush out of ring buffers\n");
|
||||||
|
usleep(1 * 1000); // avoid hot polling
|
||||||
|
}
|
||||||
|
if (atomic_read(&AudioRingFilled) >= AUDIO_RING_MAX) {
|
||||||
|
// FIXME: We can set the flush flag in the last wrote ring buffer
|
||||||
|
Error(_("audio: flush out of ring buffers\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
old = AudioRingWrite;
|
old = AudioRingWrite;
|
||||||
// FIXME: check ring buffer overflow
|
|
||||||
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
|
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
|
||||||
AudioRing[AudioRingWrite].FlushBuffers = 1;
|
AudioRing[AudioRingWrite].FlushBuffers = 1;
|
||||||
AudioRing[AudioRingWrite].Passthrough = AudioRing[old].Passthrough;
|
AudioRing[AudioRingWrite].Passthrough = AudioRing[old].Passthrough;
|
||||||
@ -2439,12 +2462,13 @@ void AudioFlushBuffers(void)
|
|||||||
|
|
||||||
atomic_inc(&AudioRingFilled);
|
atomic_inc(&AudioRingFilled);
|
||||||
|
|
||||||
// FIXME: wait for flush complete?
|
// FIXME: wait for flush complete needed?
|
||||||
for (i = 0; i < 24 * 2; ++i) {
|
for (i = 0; i < 24 * 2; ++i) {
|
||||||
if (!AudioRunning) { // wakeup thread to flush buffers
|
if (!AudioRunning) { // wakeup thread to flush buffers
|
||||||
AudioRunning = 1;
|
AudioRunning = 1;
|
||||||
pthread_cond_signal(&AudioStartCond);
|
pthread_cond_signal(&AudioStartCond);
|
||||||
}
|
}
|
||||||
|
// FIXME: waiting on zero isn't correct, but currently works
|
||||||
if (!atomic_read(&AudioRingFilled)) {
|
if (!atomic_read(&AudioRingFilled)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
2
audio.h
2
audio.h
@ -60,5 +60,7 @@ extern void AudioExit(void); ///< cleanup and exit audio module
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
extern char AudioAlsaDriverBroken; ///< disable broken driver message
|
||||||
|
extern char AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
||||||
|
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: VDR \n"
|
"Project-Id-Version: VDR \n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2013-10-06 22:20+0200\n"
|
"POT-Creation-Date: 2013-12-05 12:15+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -239,6 +239,9 @@ msgstr ""
|
|||||||
msgid "audio: can't place %d samples in ring buffer\n"
|
msgid "audio: can't place %d samples in ring buffer\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "audio: flush out of ring buffers\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "audio: '%s' output module used\n"
|
msgid "audio: '%s' output module used\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2888,6 +2888,8 @@ const char *CommandLineHelp(void)
|
|||||||
"\tstill-hw-decoder\tenable hardware decoder for still-pictures\n"
|
"\tstill-hw-decoder\tenable hardware decoder for still-pictures\n"
|
||||||
"\tstill-h264-hw-decoder\tenable h264 hw decoder for still-pictures\n"
|
"\tstill-h264-hw-decoder\tenable h264 hw decoder for still-pictures\n"
|
||||||
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
"\talsa-driver-broken\tdisable broken alsa driver message\n"
|
||||||
|
"-talsa-no-close-open\tdisable close open to fix alsa no sound bug\n"
|
||||||
|
"-talsa-close-open-delay\tenable close open delay to fix no sound bug\n"
|
||||||
"\tignore-repeat-pict\tdisable repeat pict message\n"
|
"\tignore-repeat-pict\tdisable repeat pict message\n"
|
||||||
" -D\t\tstart in detached mode\n";
|
" -D\t\tstart in detached mode\n";
|
||||||
}
|
}
|
||||||
@ -2964,6 +2966,10 @@ int ProcessArgs(int argc, char *const argv[])
|
|||||||
ConfigStillDecoder = 1;
|
ConfigStillDecoder = 1;
|
||||||
} else if (!strcasecmp("alsa-driver-broken", optarg)) {
|
} else if (!strcasecmp("alsa-driver-broken", optarg)) {
|
||||||
AudioAlsaDriverBroken = 1;
|
AudioAlsaDriverBroken = 1;
|
||||||
|
} else if (!strcasecmp("alsa-no-close-open", optarg)) {
|
||||||
|
AudioAlsaNoCloseOpen = 1;
|
||||||
|
} else if (!strcasecmp("alsa-close-open-delay", optarg)) {
|
||||||
|
AudioAlsaCloseOpenDelay = 1;
|
||||||
} else if (!strcasecmp("ignore-repeat-pict", optarg)) {
|
} else if (!strcasecmp("ignore-repeat-pict", optarg)) {
|
||||||
VideoIgnoreRepeatPict = 1;
|
VideoIgnoreRepeatPict = 1;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user