From d240aa367ed308fdfbc1f5c6419ef4b1281fd1df Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 9 Nov 2013 01:27:10 +0100 Subject: ao_alsa: redo the way parameters are added in the spdif case Using spdif with alsa requires adding magic parameters to the device name, and the existing code tried to deal with the situation when the user wanted to add parameters too. Rewrite this code, in particular remove the duplicated parameter string as preparation for the next commit. The new code is a bit stricter, e.g. it doesn't skip spaces before and after '{' and '}'. (Just don't add spaces.) --- audio/out/ao_alsa.c | 62 +++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 38 deletions(-) (limited to 'audio') diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 1f7dc71d3d..05f9e89803 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -304,51 +304,38 @@ static const char *select_chmap(struct ao *ao) return "default"; } -static int try_open_device(struct ao *ao, const char *device, int open_mode, - int try_ac3) +static int try_open_device(struct ao *ao, const char *device, int open_mode) { struct priv *p = ao->priv; - int err, len; - char *ac3_device, *args; - if (try_ac3) { + if (AF_FORMAT_IS_IEC61937(ao->format)) { + void *tmp = talloc_new(NULL); /* to set the non-audio bit, use AES0=6 */ - len = strlen(device); - ac3_device = malloc(len + 7 + 1); - if (!ac3_device) - return -ENOMEM; - strcpy(ac3_device, device); - args = strchr(ac3_device, ':'); - if (!args) { + char *params = "AES0=6"; + const char *ac3_device = device; + int len = strlen(device); + char *end = strchr(device, ':'); + if (!end) { /* no existing parameters: add it behind device name */ - strcat(ac3_device, ":AES0=6"); + ac3_device = talloc_asprintf(tmp, "%s:%s", device, params); + } else if (end[1] == '\0') { + /* ":" but no parameters */ + ac3_device = talloc_asprintf(tmp, "%s%s", device, params); + } else if (end[1] == '{' && device[len - 1] == '}') { + /* parameters in config syntax: add it inside the { } block */ + ac3_device = talloc_asprintf(tmp, "%.*s %s}", len - 1, device, params); } else { - do { - ++args; - } while (isspace(*args)); - if (*args == '\0') { - /* ":" but no parameters */ - strcat(ac3_device, "AES0=6"); - } else if (*args != '{') { - /* a simple list of parameters: add it at the end of the list */ - strcat(ac3_device, ",AES0=6"); - } else { - /* parameters in config syntax: add it inside the { } block */ - do { - --len; - } while (len > 0 && isspace(ac3_device[len])); - if (ac3_device[len] == '}') - strcpy(ac3_device + len, " AES0=6}"); - } + /* a simple list of parameters: add it at the end of the list */ + ac3_device = talloc_asprintf(tmp, "%s,%s", device, params); } - err = snd_pcm_open - (&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, open_mode); - free(ac3_device); + int err = snd_pcm_open + (&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, open_mode); + talloc_free(tmp); if (!err) return 0; } - return snd_pcm_open - (&p->alsa, device, SND_PCM_STREAM_PLAYBACK, open_mode); + + return snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, open_mode); } /* @@ -400,14 +387,13 @@ static int init(struct ao *ao) snd_lib_error_set_handler(alsa_error_handler); int open_mode = p->cfg_block ? 0 : SND_PCM_NONBLOCK; - int isac3 = AF_FORMAT_IS_IEC61937(ao->format); //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC - err = try_open_device(ao, device, open_mode, isac3); + err = try_open_device(ao, device, open_mode); if (err < 0) { if (err != -EBUSY && !p->cfg_block) { MP_WARN(ao, "Open in nonblock-mode " "failed, trying to open in block-mode.\n"); - err = try_open_device(ao, device, 0, isac3); + err = try_open_device(ao, device, 0); } CHECK_ALSA_ERROR("Playback open error"); } -- cgit v1.2.3