| --- a/libao2/ao_alsa.c |
| +++ b/libao2/ao_alsa.c |
| @@ -263,48 +263,49 @@ static int str_maxlen(strarg_t *str) { |
| return 1; |
| } |
| |
| -/* change a PCM definition for correct AC-3 playback */ |
| -static void set_non_audio(snd_config_t *root, const char *name_with_args) |
| +static int try_open_device(const char *device, int open_mode, int try_ac3) |
| { |
| - char *name, *colon, *old_value_str; |
| - snd_config_t *config, *args, *aes0, *old_def, *def; |
| - int value, err; |
| - |
| - /* strip the parameters from the PCM name */ |
| - if ((name = strdup(name_with_args)) != NULL) { |
| - if ((colon = strchr(name, ':')) != NULL) |
| - *colon = '\0'; |
| - /* search the PCM definition that we'll later use */ |
| - if (snd_config_search_alias_hooks(root, strchr(name, '.') ? NULL : "pcm", |
| - name, &config) >= 0) { |
| - /* does this definition have an "AES0" parameter? */ |
| - if (snd_config_search(config, "@args", &args) >= 0 && |
| - snd_config_search(args, "AES0", &aes0) >= 0) { |
| - /* read the old default value */ |
| - value = IEC958_AES0_CON_NOT_COPYRIGHT | |
| - IEC958_AES0_CON_EMPHASIS_NONE; |
| - if (snd_config_search(aes0, "default", &old_def) >= 0) { |
| - /* don't use snd_config_get_integer() because alsa-lib <= 1.0.12 |
| - * parses hex numbers as strings */ |
| - if (snd_config_get_ascii(old_def, &old_value_str) >= 0) { |
| - sscanf(old_value_str, "%i", &value); |
| - free(old_value_str); |
| - } |
| - } else |
| - old_def = NULL; |
| - /* set the non-audio bit */ |
| - value |= IEC958_AES0_NONAUDIO; |
| - /* set the new default value */ |
| - if (snd_config_imake_integer(&def, "default", value) >= 0) { |
| - if (old_def) |
| - snd_config_substitute(old_def, def); |
| - else |
| - snd_config_add(aes0, def); |
| - } |
| + int err, len; |
| + char *ac3_device, *args; |
| + |
| + if (try_ac3) { |
| + /* 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) { |
| + /* no existing parameters: add it behind device name */ |
| + strcat(ac3_device, ":AES0=6"); |
| + } 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}"); |
| } |
| } |
| - free(name); |
| + err = snd_pcm_open(&alsa_handler, ac3_device, SND_PCM_STREAM_PLAYBACK, |
| + open_mode); |
| + free(ac3_device); |
| } |
| + if (!try_ac3 || err < 0) |
| + err = snd_pcm_open(&alsa_handler, device, SND_PCM_STREAM_PLAYBACK, |
| + open_mode); |
| + return err; |
| } |
| |
| /* |
| @@ -316,7 +317,6 @@ static int init(int rate_hz, int channel |
| int err; |
| int block; |
| strarg_t device; |
| - snd_config_t *my_config; |
| snd_pcm_uframes_t bufsize; |
| snd_pcm_uframes_t boundary; |
| opt_t subopts[] = { |
| @@ -496,24 +496,12 @@ static int init(int rate_hz, int channel |
| } |
| |
| if (!alsa_handler) { |
| - if ((err = snd_config_update()) < 0) { |
| - mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: cannot read ALSA configuration: %s\n", snd_strerror(err)); |
| - return 0; |
| - } |
| - if ((err = snd_config_copy(&my_config, snd_config)) < 0) { |
| - mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: cannot copy configuration: %s\n", snd_strerror(err)); |
| - return 0; |
| - } |
| - if (format == AF_FORMAT_AC3) |
| - set_non_audio(my_config, alsa_device); |
| //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC |
| - if ((err = snd_pcm_open_lconf(&alsa_handler, alsa_device, |
| - SND_PCM_STREAM_PLAYBACK, open_mode, my_config)) < 0) |
| + if ((err = try_open_device(alsa_device, open_mode, format == AF_FORMAT_AC3)) < 0) |
| { |
| if (err != -EBUSY && ao_noblock) { |
| mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: open in nonblock-mode failed, trying to open in block-mode\n"); |
| - if ((err = snd_pcm_open_lconf(&alsa_handler, alsa_device, |
| - SND_PCM_STREAM_PLAYBACK, 0, my_config)) < 0) { |
| + if ((err = try_open_device(alsa_device, 0, format == AF_FORMAT_AC3)) < 0) { |
| mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: playback open error: %s\n", snd_strerror(err)); |
| return(0); |
| } |
| @@ -522,12 +510,11 @@ static int init(int rate_hz, int channel |
| return(0); |
| } |
| } |
| - snd_config_delete(my_config); |
| |
| if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) { |
| mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: error set block-mode %s\n", snd_strerror(err)); |
| } else { |
| - mp_msg(MSGT_AO,MSGL_V,"alsa-init: pcm opend in blocking mode\n"); |
| + mp_msg(MSGT_AO,MSGL_V,"alsa-init: pcm opened in blocking mode\n"); |
| } |
| |
| snd_pcm_hw_params_alloca(&alsa_hwparams); |
| @@ -879,8 +866,8 @@ static int get_space(void) |
| } |
| |
| ret = snd_pcm_status_get_avail(status) * bytes_per_sample; |
| - if (ret > MAX_OUTBURST) |
| - ret = MAX_OUTBURST; |
| + if (ret > ao_data.buffersize) // Buffer underrun? |
| + ret = ao_data.buffersize; |
| return(ret); |
| } |
| |