123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- --- 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);
- }
-
|