Bug#580113: [mplayer] No audio output to pulse

Reinhard Tartler siretart at tauware.de
Tue May 4 15:36:34 UTC 2010


On Tue, May 04, 2010 at 08:40:58 (CEST), Adam wrote:

> AO: [pulse] 48000Hz 2ch s16be (2 bytes per sample)
> Assertion 'channels > 0' failed at pulse/volume.c:76, function pa_cvolume_set(). Aborting.

This assertion doesn't look like it comes from mplayer, but rather from
libpulse. In fact, after having a quick look in the source, the
assertion triggered is in this function from the pulseaudio source:

,----
| pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
|     int i;
| 
|     pa_assert(a);
|     pa_assert(channels > 0);
|     pa_assert(channels <= PA_CHANNELS_MAX);
| 
|     a->channels = (uint8_t) channels;
| 
|     for (i = 0; i < a->channels; i++)
|         a->values[i] = v;
| 
|     return a;
| }
`----

okay, after having had a quick look at the mplayer source, it seems that
there are some upstream patches that should be considered for
backporting:

------------------------------------------------------------------------
r30060 | reimar | 2009-12-18 21:22:39 +0100 (Fri, 18 Dec 2009) | 2 lines

Get rid of global volume variable, it is only used for temporary values.

Index: ao_pulse.c
===================================================================
--- ao_pulse.c	(revision 29160)
+++ ao_pulse.c	(revision 30060)
@@ -49,9 +49,6 @@
 /** Main event loop object */
 static struct pa_threaded_mainloop *mainloop;
 
-/** A temporary variable to store the current volume */
-static pa_cvolume volume;
-
 static int broken_pause;
 
 LIBAO_EXTERN(pulse)
@@ -144,6 +141,7 @@
     char *host = NULL;
     char *sink = NULL;
     char *version = pa_get_library_version();
+    struct pa_cvolume volume;
 
     if (ao_subdevice) {
         devarg = strdup(ao_subdevice);
@@ -350,13 +348,14 @@
  * pa_context_get_sink_input_info() operation completes. Saves the
  * volume field of the specified structure to the global variable volume. */
 static void info_func(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
+    struct pa_cvolume *volume = userdata;
     if (is_last < 0) {
         GENERIC_ERR_MSG(context, "Failed to get sink input info");
         return;
     }
     if (!i)
         return;
-    volume = i->volume;
+    *volume = i->volume;
     pa_threaded_mainloop_signal(mainloop, 0);
 }
 
@@ -365,8 +364,9 @@
         case AOCONTROL_GET_VOLUME: {
             ao_control_vol_t *vol = arg;
             uint32_t devidx = pa_stream_get_index(stream);
+            struct pa_cvolume volume;
             pa_threaded_mainloop_lock(mainloop);
-            if (!waitop(pa_context_get_sink_input_info(context, devidx, info_func, NULL))) {
+            if (!waitop(pa_context_get_sink_input_info(context, devidx, info_func, &volume))) {
                 GENERIC_ERR_MSG(context, "pa_stream_get_sink_input_info() failed");
                 return CONTROL_ERROR;
             }
@@ -384,7 +384,9 @@
         case AOCONTROL_SET_VOLUME: {
             const ao_control_vol_t *vol = arg;
             pa_operation *o;
+            struct pa_cvolume volume;
 
+            pa_cvolume_reset(&volume, ao_data.channels);
             if (volume.channels != 2)
                 pa_cvolume_set(&volume, volume.channels, (pa_volume_t)vol->left*PA_VOLUME_NORM/100);
             else {


------------------------------------------------------------------------
r30061 | reimar | 2009-12-18 21:26:28 +0100 (Fri, 18 Dec 2009) | 4 lines

Allow pulseaudio to restore the previous volume on init instead of forcing to
full volume.
The old behaviour can be restored by using -volume 100.


Index: ao_pulse.c
===================================================================
--- ao_pulse.c	(revision 30060)
+++ ao_pulse.c	(revision 30061)
@@ -141,7 +141,6 @@
     char *host = NULL;
     char *sink = NULL;
     char *version = pa_get_library_version();
-    struct pa_cvolume volume;
 
     if (ao_subdevice) {
         devarg = strdup(ao_subdevice);
@@ -187,8 +186,6 @@
     pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA);
     ao_data.bps = pa_bytes_per_second(&ss);
 
-    pa_cvolume_reset(&volume, ss.channels);
-
     if (!(mainloop = pa_threaded_mainloop_new())) {
         mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Failed to allocate main loop\n");
         goto fail;
@@ -222,7 +219,7 @@
     pa_stream_set_write_callback(stream, stream_request_cb, NULL);
     pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, NULL);
 
-    if (pa_stream_connect_playback(stream, sink, NULL, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, &volume, NULL) < 0)
+    if (pa_stream_connect_playback(stream, sink, NULL, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL) < 0)
         goto unlock_and_fail;
 
     /* Wait until the stream is ready */


Can anyone who is affected by this please test these patches against
mplayer? I'm pretty confident that they should fix the symptom.


-- 
Gruesse/greetings,
Reinhard Tartler, KeyID 945348A4





More information about the pkg-multimedia-maintainers mailing list