Mercurial > mplayer.hg
changeset 22166:68dceb30bbcf
When setting the non-audio bit for hwac3 output, just try to set the
AES0 parameter in the device name instead of poking around inside ALSA's
configuration structures. This means that the non-audio bit will be set
even if the user-specified device name tries to clear it.
author | cladisch |
---|---|
date | Fri, 09 Feb 2007 19:49:31 +0000 |
parents | 78ebc8dc4533 |
children | 8eddcfb3d4f9 |
files | ChangeLog help/help_mp-en.h libao2/ao_alsa.c |
diffstat | 3 files changed, 45 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Feb 09 19:47:20 2007 +0000 +++ b/ChangeLog Fri Feb 09 19:49:31 2007 +0000 @@ -47,6 +47,10 @@ Ports: * further Intel Mac fixes + Drivers: + * ALSA audio output now sets the non-audio bit for AC3 passthrough even + if the user-specified default device name tries to clear it + Others: * libdvdcss updated to Subversion HEAD, now same as upstream version * libmpdvdkit split into libdvdread and libdvdcss
--- a/help/help_mp-en.h Fri Feb 09 19:47:20 2007 +0000 +++ b/help/help_mp-en.h Fri Feb 09 19:49:31 2007 +0000 @@ -1203,8 +1203,6 @@ "[AO_ALSA] device=<device-name>\n"\ "[AO_ALSA] Sets device (change , to . and : to =)\n" #define MSGTR_AO_ALSA_ChannelsNotSupported "[AO_ALSA] %d channels are not supported.\n" -#define MSGTR_AO_ALSA_CannotReadAlsaConfiguration "[AO_ALSA] Cannot read ALSA configuration: %s\n" -#define MSGTR_AO_ALSA_CannotCopyConfiguration "[AO_ALSA] Cannot copy configuration: %s\n" #define MSGTR_AO_ALSA_OpenInNonblockModeFailed "[AO_ALSA] Open in nonblock-mode failed, trying to open in block-mode.\n" #define MSGTR_AO_ALSA_PlaybackOpenError "[AO_ALSA] Playback open error: %s\n" #define MSGTR_AO_ALSA_ErrorSetBlockMode "[AL_ALSA] Error setting block-mode %s.\n"
--- a/libao2/ao_alsa.c Fri Feb 09 19:47:20 2007 +0000 +++ b/libao2/ao_alsa.c Fri Feb 09 19:49:31 2007 +0000 @@ -16,6 +16,7 @@ #include <sys/time.h> #include <stdlib.h> #include <stdarg.h> +#include <ctype.h> #include <math.h> #include <string.h> @@ -257,48 +258,49 @@ 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; + int err, len; + char *ac3_device, *args; - /* 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); - } + 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; } /* @@ -310,7 +312,6 @@ 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[] = { @@ -490,24 +491,12 @@ } if (!alsa_handler) { - if ((err = snd_config_update()) < 0) { - mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_CannotReadAlsaConfiguration, snd_strerror(err)); - return 0; - } - if ((err = snd_config_copy(&my_config, snd_config)) < 0) { - mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_CannotCopyConfiguration, 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,MSGTR_AO_ALSA_OpenInNonblockModeFailed); - 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,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err)); return(0); } @@ -516,7 +505,6 @@ return(0); } } - snd_config_delete(my_config); if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSetBlockMode, snd_strerror(err));