mplayer-1.0rc1-fix-alsa-output.patch 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. --- a/libao2/ao_alsa.c
  2. +++ b/libao2/ao_alsa.c
  3. @@ -263,48 +263,49 @@ static int str_maxlen(strarg_t *str) {
  4. return 1;
  5. }
  6. -/* change a PCM definition for correct AC-3 playback */
  7. -static void set_non_audio(snd_config_t *root, const char *name_with_args)
  8. +static int try_open_device(const char *device, int open_mode, int try_ac3)
  9. {
  10. - char *name, *colon, *old_value_str;
  11. - snd_config_t *config, *args, *aes0, *old_def, *def;
  12. - int value, err;
  13. -
  14. - /* strip the parameters from the PCM name */
  15. - if ((name = strdup(name_with_args)) != NULL) {
  16. - if ((colon = strchr(name, ':')) != NULL)
  17. - *colon = '\0';
  18. - /* search the PCM definition that we'll later use */
  19. - if (snd_config_search_alias_hooks(root, strchr(name, '.') ? NULL : "pcm",
  20. - name, &config) >= 0) {
  21. - /* does this definition have an "AES0" parameter? */
  22. - if (snd_config_search(config, "@args", &args) >= 0 &&
  23. - snd_config_search(args, "AES0", &aes0) >= 0) {
  24. - /* read the old default value */
  25. - value = IEC958_AES0_CON_NOT_COPYRIGHT |
  26. - IEC958_AES0_CON_EMPHASIS_NONE;
  27. - if (snd_config_search(aes0, "default", &old_def) >= 0) {
  28. - /* don't use snd_config_get_integer() because alsa-lib <= 1.0.12
  29. - * parses hex numbers as strings */
  30. - if (snd_config_get_ascii(old_def, &old_value_str) >= 0) {
  31. - sscanf(old_value_str, "%i", &value);
  32. - free(old_value_str);
  33. - }
  34. - } else
  35. - old_def = NULL;
  36. - /* set the non-audio bit */
  37. - value |= IEC958_AES0_NONAUDIO;
  38. - /* set the new default value */
  39. - if (snd_config_imake_integer(&def, "default", value) >= 0) {
  40. - if (old_def)
  41. - snd_config_substitute(old_def, def);
  42. - else
  43. - snd_config_add(aes0, def);
  44. - }
  45. + int err, len;
  46. + char *ac3_device, *args;
  47. +
  48. + if (try_ac3) {
  49. + /* to set the non-audio bit, use AES0=6 */
  50. + len = strlen(device);
  51. + ac3_device = malloc(len + 7 + 1);
  52. + if (!ac3_device)
  53. + return -ENOMEM;
  54. + strcpy(ac3_device, device);
  55. + args = strchr(ac3_device, ':');
  56. + if (!args) {
  57. + /* no existing parameters: add it behind device name */
  58. + strcat(ac3_device, ":AES0=6");
  59. + } else {
  60. + do
  61. + ++args;
  62. + while (isspace(*args));
  63. + if (*args == '\0') {
  64. + /* ":" but no parameters */
  65. + strcat(ac3_device, "AES0=6");
  66. + } else if (*args != '{') {
  67. + /* a simple list of parameters: add it at the end of the list */
  68. + strcat(ac3_device, ",AES0=6");
  69. + } else {
  70. + /* parameters in config syntax: add it inside the { } block */
  71. + do
  72. + --len;
  73. + while (len > 0 && isspace(ac3_device[len]));
  74. + if (ac3_device[len] == '}')
  75. + strcpy(ac3_device + len, " AES0=6}");
  76. }
  77. }
  78. - free(name);
  79. + err = snd_pcm_open(&alsa_handler, ac3_device, SND_PCM_STREAM_PLAYBACK,
  80. + open_mode);
  81. + free(ac3_device);
  82. }
  83. + if (!try_ac3 || err < 0)
  84. + err = snd_pcm_open(&alsa_handler, device, SND_PCM_STREAM_PLAYBACK,
  85. + open_mode);
  86. + return err;
  87. }
  88. /*
  89. @@ -316,7 +317,6 @@ static int init(int rate_hz, int channel
  90. int err;
  91. int block;
  92. strarg_t device;
  93. - snd_config_t *my_config;
  94. snd_pcm_uframes_t bufsize;
  95. snd_pcm_uframes_t boundary;
  96. opt_t subopts[] = {
  97. @@ -496,24 +496,12 @@ static int init(int rate_hz, int channel
  98. }
  99. if (!alsa_handler) {
  100. - if ((err = snd_config_update()) < 0) {
  101. - mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: cannot read ALSA configuration: %s\n", snd_strerror(err));
  102. - return 0;
  103. - }
  104. - if ((err = snd_config_copy(&my_config, snd_config)) < 0) {
  105. - mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: cannot copy configuration: %s\n", snd_strerror(err));
  106. - return 0;
  107. - }
  108. - if (format == AF_FORMAT_AC3)
  109. - set_non_audio(my_config, alsa_device);
  110. //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
  111. - if ((err = snd_pcm_open_lconf(&alsa_handler, alsa_device,
  112. - SND_PCM_STREAM_PLAYBACK, open_mode, my_config)) < 0)
  113. + if ((err = try_open_device(alsa_device, open_mode, format == AF_FORMAT_AC3)) < 0)
  114. {
  115. if (err != -EBUSY && ao_noblock) {
  116. mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: open in nonblock-mode failed, trying to open in block-mode\n");
  117. - if ((err = snd_pcm_open_lconf(&alsa_handler, alsa_device,
  118. - SND_PCM_STREAM_PLAYBACK, 0, my_config)) < 0) {
  119. + if ((err = try_open_device(alsa_device, 0, format == AF_FORMAT_AC3)) < 0) {
  120. mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: playback open error: %s\n", snd_strerror(err));
  121. return(0);
  122. }
  123. @@ -522,12 +510,11 @@ static int init(int rate_hz, int channel
  124. return(0);
  125. }
  126. }
  127. - snd_config_delete(my_config);
  128. if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) {
  129. mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: error set block-mode %s\n", snd_strerror(err));
  130. } else {
  131. - mp_msg(MSGT_AO,MSGL_V,"alsa-init: pcm opend in blocking mode\n");
  132. + mp_msg(MSGT_AO,MSGL_V,"alsa-init: pcm opened in blocking mode\n");
  133. }
  134. snd_pcm_hw_params_alloca(&alsa_hwparams);
  135. @@ -879,8 +866,8 @@ static int get_space(void)
  136. }
  137. ret = snd_pcm_status_get_avail(status) * bytes_per_sample;
  138. - if (ret > MAX_OUTBURST)
  139. - ret = MAX_OUTBURST;
  140. + if (ret > ao_data.buffersize) // Buffer underrun?
  141. + ret = ao_data.buffersize;
  142. return(ret);
  143. }