summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-09 01:27:10 +0100
committerwm4 <wm4@nowhere>2013-11-09 01:30:00 +0100
commitd240aa367ed308fdfbc1f5c6419ef4b1281fd1df (patch)
tree923fdaa4772d14e483717532f903d81fb3140aa0 /audio
parentebc4ccbbfaa41a54d27cd7717434c5e3f5050cf0 (diff)
downloadmpv-d240aa367ed308fdfbc1f5c6419ef4b1281fd1df.tar.bz2
mpv-d240aa367ed308fdfbc1f5c6419ef4b1281fd1df.tar.xz
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.)
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_alsa.c62
1 files changed, 24 insertions, 38 deletions
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");
}