diff options
author | Johns <johns98@gmx.net> | 2014-01-29 10:07:07 +0100 |
---|---|---|
committer | Johns <johns98@gmx.net> | 2014-01-29 10:07:07 +0100 |
commit | 340e10a0eb66eff59581371d3bfcebb602da8046 (patch) | |
tree | 8274ad333300eef5b735d30e444dbc6136a38c67 | |
parent | a45b9a3abe63ac2e3d196c0283692d1f92afe232 (diff) | |
download | vdr-plugin-softhddevice-340e10a0eb66eff59581371d3bfcebb602da8046.tar.gz vdr-plugin-softhddevice-340e10a0eb66eff59581371d3bfcebb602da8046.tar.bz2 |
Add Workaround for alsa blocking audio device.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | audio.c | 38 | ||||
-rw-r--r-- | audio.h | 2 | ||||
-rw-r--r-- | po/de_DE.po | 5 | ||||
-rw-r--r-- | softhddev.c | 6 |
5 files changed, 49 insertions, 8 deletions
@@ -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 @@ -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; } @@ -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 { |