]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/pulse.c
pulse: require Xlib
[vlc] / modules / audio_output / pulse.c
index bacd55ca2343ebe32be8f12aef1e09732acc31d3..f36ec0949e6233c87e43b29ca842b05005535873 100644 (file)
 #include <vlc_plugin.h>
 
 #include <vlc_aout.h>
+#include <vlc_cpu.h>
 
 #include <pulse/pulseaudio.h>
+#ifdef HAVE_X11_XLIB_H
+# include <X11/Xlib.h>
+#endif
 
 #include <assert.h>
 
@@ -95,15 +99,14 @@ static void uninit(aout_instance_t *p_aout);
  * Module descriptor
  *****************************************************************************/
 vlc_module_begin ()
-    set_shortname( "Pulse Audio" )
+    set_shortname( "PulseAudio" )
     set_description( N_("Pulseaudio audio output") )
-    set_capability( "audio output", 40 )
+    set_capability( "audio output", 160 )
     set_category( CAT_AUDIO )
     set_subcategory( SUBCAT_AUDIO_AOUT )
     add_shortcut( "pulseaudio" )
     add_shortcut( "pa" )
     set_callbacks( Open, Close )
-    linked_with_a_crap_library_which_uses_atexit()
 vlc_module_end ()
 
 /*****************************************************************************
@@ -118,6 +121,12 @@ static int Open ( vlc_object_t *p_this )
     struct pa_buffer_attr a;
     struct pa_channel_map map;
 
+#ifdef X_DISPLAY_MISSING
+# error Xlib required due to PulseAudio bug 799!
+#else
+    if( !XInitThreads() )
+        return VLC_EGENERIC;
+#endif
     /* Allocate structures */
     p_aout->output.p_sys = p_sys = calloc( 1, sizeof( aout_sys_t ) );
     if( p_sys == NULL )
@@ -165,11 +174,19 @@ static int Open ( vlc_object_t *p_this )
     }
 
     /* Add a quick command line info message */
-    msg_Info(p_aout, "No. of Audio Channels: %d", ss.channels);
+    msg_Dbg(p_aout, "%d audio channels", ss.channels);
 
     ss.rate = p_aout->output.output.i_rate;
-    ss.format = PA_SAMPLE_FLOAT32NE;
-    p_aout->output.output.i_format = VLC_CODEC_FL32;
+    if (HAVE_FPU)
+    {
+        ss.format = PA_SAMPLE_FLOAT32NE;
+        p_aout->output.output.i_format = VLC_CODEC_FL32;
+    }
+    else
+    {
+        ss.format = PA_SAMPLE_S16NE;
+        p_aout->output.output.i_format = VLC_CODEC_S16N;
+    }
 
     if (!pa_sample_spec_valid(&ss)) {
         msg_Err(p_aout,"Invalid sample spec");
@@ -181,7 +198,7 @@ static int Open ( vlc_object_t *p_this )
      */
     a.tlength = pa_bytes_per_second(&ss)/5;
     a.maxlength = a.tlength * 2;
-    a.prebuf = a.tlength;
+    a.prebuf = a.tlength / 2;
     a.minreq = a.tlength / 10;
 
     /* Buffer size is 20mS */
@@ -224,7 +241,7 @@ static int Open ( vlc_object_t *p_this )
     pa_threaded_mainloop_wait(p_sys->mainloop);
 
     if (pa_context_get_state(p_sys->context) != PA_CONTEXT_READY) {
-        msg_Err(p_aout, "Failed to connect to server: %s", pa_strerror(pa_context_errno(p_sys->context)));
+        msg_Dbg(p_aout, "Failed to connect to server: %s", pa_strerror(pa_context_errno(p_sys->context)));
         goto unlock_and_fail;
     }
 
@@ -288,7 +305,7 @@ unlock_and_fail:
     if (p_sys->mainloop)
         pa_threaded_mainloop_unlock(p_sys->mainloop);
 fail:
-    msg_Err(p_aout, "Pulse initialization failed");
+    msg_Dbg(p_aout, "Pulse initialization failed");
     uninit(p_aout);
     return VLC_EGENERIC;
 }
@@ -329,11 +346,16 @@ static void Close ( vlc_object_t *p_this )
     msg_Dbg(p_aout, "Pulse Close");
 
     if(p_sys->stream){
-        pa_operation *o;
         pa_threaded_mainloop_lock(p_sys->mainloop);
         pa_stream_set_write_callback(p_sys->stream, NULL, NULL);
 
-        if((o = pa_stream_drain(p_sys->stream, success_cb, p_aout))){
+/* I didn't find any explanation why we need to do pa_stream_drain on close
+ * as we don't really care if we lose 20ms buffer in this point anyway?
+ * And disabling this speeds up closing pulseaudio quite a lot (atleast for me).
+ */
+#if 0
+        pa_operation *o = pa_stream_drain(p_sys->stream, success_cb, p_aout);
+        if(o){
             while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
                 CHECK_DEAD_GOTO(fail);
                 pa_threaded_mainloop_wait(p_sys->mainloop);
@@ -343,7 +365,7 @@ static void Close ( vlc_object_t *p_this )
 
             pa_operation_unref(o);
         }
-
+#endif
         pa_threaded_mainloop_unlock(p_sys->mainloop);
     }
     uninit(p_aout);
@@ -424,6 +446,7 @@ static void stream_state_cb(pa_stream *s, void * userdata) {
 }
 
 static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
+    VLC_UNUSED( s );
     aout_instance_t *p_aout = (aout_instance_t *)userdata;
     struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys;
     mtime_t next_date;
@@ -458,9 +481,9 @@ static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
 
         if ( p_buffer != NULL )
         {
-            PULSE_DEBUG( "Pulse stream request write buffer %d", p_buffer->i_nb_bytes);
-            pa_stream_write(p_sys->stream, p_buffer->p_buffer, p_buffer->i_nb_bytes, NULL, 0, PA_SEEK_RELATIVE);
-            length -= p_buffer->i_nb_bytes;
+            PULSE_DEBUG( "Pulse stream request write buffer %d", p_buffer->i_buffer);
+            pa_stream_write(p_sys->stream, p_buffer->p_buffer, p_buffer->i_buffer, NULL, 0, PA_SEEK_RELATIVE);
+            length -= p_buffer->i_buffer;
             aout_BufferFree( p_buffer );
         }
         else
@@ -477,6 +500,7 @@ static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
 }
 
 static void stream_latency_update_cb(pa_stream *s, void *userdata) {
+    VLC_UNUSED( s );
     aout_instance_t *p_aout = (aout_instance_t *)userdata;
     struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys;
 
@@ -489,6 +513,7 @@ static void stream_latency_update_cb(pa_stream *s, void *userdata) {
 
 static void success_cb(pa_stream *s, int sucess, void *userdata)
 {
+    VLC_UNUSED( s );
     aout_instance_t *p_aout = (aout_instance_t *)userdata;
     struct aout_sys_t * p_sys = (struct aout_sys_t *) p_aout->output.p_sys;