summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2014-01-29 10:07:07 +0100
committerJohns <johns98@gmx.net>2014-01-29 10:07:07 +0100
commit340e10a0eb66eff59581371d3bfcebb602da8046 (patch)
tree8274ad333300eef5b735d30e444dbc6136a38c67
parenta45b9a3abe63ac2e3d196c0283692d1f92afe232 (diff)
downloadvdr-plugin-softhddevice-340e10a0eb66eff59581371d3bfcebb602da8046.tar.gz
vdr-plugin-softhddevice-340e10a0eb66eff59581371d3bfcebb602da8046.tar.bz2
Add Workaround for alsa blocking audio device.
-rw-r--r--ChangeLog6
-rw-r--r--audio.c38
-rw-r--r--audio.h2
-rw-r--r--po/de_DE.po5
-rw-r--r--softhddev.c6
5 files changed, 49 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 972b633..f71f899 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/audio.c b/audio.c
index 6ad2907..78463fb 100644
--- a/audio.c
+++ b/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;
}
diff --git a/audio.h b/audio.h
index 4a0ac51..30fefae 100644
--- a/audio.h
+++ b/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
/// @}
diff --git a/po/de_DE.po b/po/de_DE.po
index 7edfebb..1f3d0a1 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -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 ""
diff --git a/softhddev.c b/softhddev.c
index 2631df7..b88290e 100644
--- a/softhddev.c
+++ b/softhddev.c
@@ -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 {