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
|
||||
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 AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
||||
char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
handle = AlsaPCMHandle;
|
||||
// FIXME: need lock
|
||||
AlsaPCMHandle = NULL; // other threads should check handle
|
||||
snd_pcm_close(handle);
|
||||
if (AudioAlsaCloseOpenDelay) {
|
||||
usleep(50 * 1000); // 50ms delay for alsa recovery
|
||||
}
|
||||
// FIXME: can use multiple retries
|
||||
if (!(handle = AlsaOpenPCM(passthrough))) {
|
||||
return -1;
|
||||
}
|
||||
@ -2043,25 +2049,27 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
int read;
|
||||
int flush;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
// look if there is a flush command in the queue
|
||||
flush = 0;
|
||||
filled = atomic_read(&AudioRingFilled);
|
||||
read = AudioRingRead;
|
||||
while (filled--) {
|
||||
i = filled;
|
||||
while (i--) {
|
||||
read = (read + 1) % AUDIO_RING_MAX;
|
||||
if (AudioRing[read].FlushBuffers) {
|
||||
AudioRing[read].FlushBuffers = 0;
|
||||
AudioRingRead = read;
|
||||
atomic_set(&AudioRingFilled, filled);
|
||||
// handle all flush in queue
|
||||
flush = 1;
|
||||
flush = filled - i;
|
||||
}
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
Debug(3, "audio: flush\n");
|
||||
Debug(3, "audio: flush %d ring buffer(s)\n", flush);
|
||||
AudioUsedModule->FlushBuffers();
|
||||
atomic_sub(flush, &AudioRingFilled);
|
||||
if (AudioNextRing()) {
|
||||
Debug(3, "audio: break after flush\n");
|
||||
break;
|
||||
@ -2421,8 +2429,23 @@ void AudioFlushBuffers(void)
|
||||
int old;
|
||||
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;
|
||||
// FIXME: check ring buffer overflow
|
||||
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
|
||||
AudioRing[AudioRingWrite].FlushBuffers = 1;
|
||||
AudioRing[AudioRingWrite].Passthrough = AudioRing[old].Passthrough;
|
||||
@ -2439,12 +2462,13 @@ void AudioFlushBuffers(void)
|
||||
|
||||
atomic_inc(&AudioRingFilled);
|
||||
|
||||
// FIXME: wait for flush complete?
|
||||
// FIXME: wait for flush complete needed?
|
||||
for (i = 0; i < 24 * 2; ++i) {
|
||||
if (!AudioRunning) { // wakeup thread to flush buffers
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
}
|
||||
// FIXME: waiting on zero isn't correct, but currently works
|
||||
if (!atomic_read(&AudioRingFilled)) {
|
||||
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 AudioAlsaNoCloseOpen; ///< disable alsa close/open fix
|
||||
extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix
|
||||
|
||||
/// @}
|
||||
|
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: VDR \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"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -239,6 +239,9 @@ msgstr ""
|
||||
msgid "audio: can't place %d samples in ring buffer\n"
|
||||
msgstr ""
|
||||
|
||||
msgid "audio: flush out of ring buffers\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "audio: '%s' output module used\n"
|
||||
msgstr ""
|
||||
|
@ -2888,6 +2888,8 @@ const char *CommandLineHelp(void)
|
||||
"\tstill-hw-decoder\tenable hardware 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-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"
|
||||
" -D\t\tstart in detached mode\n";
|
||||
}
|
||||
@ -2964,6 +2966,10 @@ int ProcessArgs(int argc, char *const argv[])
|
||||
ConfigStillDecoder = 1;
|
||||
} else if (!strcasecmp("alsa-driver-broken", optarg)) {
|
||||
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)) {
|
||||
VideoIgnoreRepeatPict = 1;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user