[pulseaudio-discuss] PA_CORE_HOOK_SINK_INPUT_PUT

Nick Thompson rextanka at comcast.net
Thu Jun 19 13:46:36 PDT 2008


Hi,

I've been looking at pulseaudio modules and am not seeing the behavior  
of the hook called by PA_CORE_HOOK_SINK_INPUT_PUT that I'd expect.   
I've enclosed some code at the end of this message that essentially  
calls pa_log when any one of the sink-input hooks are called.

I think, from Lennarts suggestions earlier on the list that put should  
be called once a sink-input is finalised, but before streaming takes  
place.  However what I'm seeing is different.  I'm using 0.9.8, we  
plan to move to 0.9.10 in the coming few weeks, but I did try this  
with 0.9.10 and saw similar behavior.

Here's what I'm seeing:  launch pulseaudio with logging

% pulseaudio --log-level=3

in pacmd load the module built from the attached code:

% pacmd
 >>> load-module module-test-sink-input
 >>>

Now play a .wav file with paplay

%  paplay ~/Sony\ CD-ROM\ Test\ Disk\ Type\ 3.0/Cantibile-Op-17.wav

If you look at the log file output, you can see that the put message  
is output after sink-input is created.  Now I'd expect the creation  
message to be output before my hook message in response to the put  
call being called, however what is unexpected is that the put call  
does not get called until after the file stops streaming.

I: module.c: Loaded "module-cli-protocol-unix" (index: #8; argument:  
"").
I: client.c: Created 0 "UNIX socket client"
E: > pa__init
E: this version compiled - Jun 19 2008 13:22:31
E: < pa__init
I: module.c: Loaded "module-test-sink-input" (index: #9; argument: "").
I: client.c: Created 1 "Native client (UNIX socket client)"
I: protocol-native.c: Got credentials: uid=1000 gid=1000 success=1
I: protocol-native.c: Enabled SHM for new connection
I: client.c: Client 1 changed name from "Native client (UNIX socket  
client)" to "paplay"
E: <  sink_input_new_hook
E: < sink_input_fixate_hook
I: sink-input.c: Created input 0 "/home/nick/Sony CD-ROM Test Disk  
Type 3.0/Cantibile-Op-17.wav" on usbAudio with sample spec s16le 2ch  
44100Hz and channel map front-left,front-right
E: < sink_input_put_hook
E: < sink_input_unlink_hook
I: sink-input.c: Freeing output 0 "/home/nick/Sony CD-ROM Test Disk  
Type 3.0/Cantibile-Op-17.wav"
I: client.c: Freed 1 "paplay"
I: protocol-native.c: connection died.

Should I expect put to be called on the sink input before the file is  
streamed to the output, or after?

Thanks

Nick






/*
  * pulse module for stream routing to log hook calls for sink-inputs
  * Nick Thompson
  * 6/19/08
  *
  */

#include <pulsecore/config.h>
#include <pulsecore/module.h>


/* user data for the pulseaudio module, store this in init so that
  * stuff we need can be accessed when we get callbacks
  */
struct userdata {

     /* cached references to pulse internals */
     pa_core *core;
     pa_module *module;

     /* slots for our sink input hook functions */
     pa_hook_slot *sink_input_new_hook_callback ;
     pa_hook_slot *sink_input_fixate_hook_callback ;
     pa_hook_slot *sink_input_put_hook_callback ;
     pa_hook_slot *sink_input_unlink_hook_callback ;
     pa_hook_slot *sink_input_unlink_post_hook_callback ;
     pa_hook_slot *sink_input_move_hook_callback ;
     pa_hook_slot *sink_input_move_post_callback ;
     pa_hook_slot *sink_input_name_changed_hook_callback ;
     pa_hook_slot *sink_input_state_changed_hook_callback ;
};


static pa_hook_result_t sink_input_new_hook(pa_core *c,
                                             pa_sink_input_new_data  
*data,
                                             struct userdata *u);

static pa_hook_result_t sink_input_fixate_hook(pa_core *c,
                                                pa_sink_input_new_data  
*data,
                                                struct userdata *u);

static pa_hook_result_t sink_input_put_hook(pa_core *c,
                                             pa_sink_input *data,
                                             struct userdata *u);

static pa_hook_result_t sink_input_unlink_hook(pa_core *c,
                                                pa_sink_input *data,
                                                struct userdata *u);

static pa_hook_result_t sink_input_unlink_post_hook(pa_core *c,
                                                     pa_sink_input  
*data,
                                                     struct userdata  
*u);

static pa_hook_result_t sink_input_move_hook(pa_core *c,
                                               
pa_sink_input_move_hook_data *data,
                                              struct userdata *u);

static pa_hook_result_t sink_input_move_post(pa_core *c,
                                              pa_sink_input *data,
                                              struct userdata *u);

static pa_hook_result_t sink_input_name_changed_hook(pa_core *c,
                                                      pa_sink_input  
*data,
                                                      struct userdata  
*u);

static pa_hook_result_t sink_input_state_changed_hook(pa_core *c,
                                                       pa_sink_input  
*data,
                                                       struct userdata  
*u);




PA_MODULE_AUTHOR("Nick Thompson") ;
PA_MODULE_DESCRIPTION("Sniffer for sink input hook callbacks") ;
PA_MODULE_VERSION(PACKAGE_VERSION) ;
PA_MODULE_USAGE("Usage TBD" ) ;




/* entry point for the module*/
int pa__init(pa_module* m)
{
     struct userdata *u = NULL;
     int i;

     pa_log("> pa__init");
     pa_log("this version compiled - %s %s",__DATE__,__TIME__);

     pa_assert(m);
     u = pa_xnew(struct userdata, 1);
     u->core = m->core;
     u->module = m;
     m->userdata = u;

     /* install hooks to allow us to maange an internal, to this module,
      * list of streams tied back to the originator sink of the stream
      * this will be used to implement the policy in place.
      */
     u->sink_input_new_hook_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_NEW],
                                              
(pa_hook_cb_t)sink_input_new_hook,
                                             u);


     u->sink_input_fixate_hook_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE],
                                                          
(pa_hook_cb_t)sink_input_fixate_hook,
                                                         u);


     u->sink_input_put_hook_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_PUT],
                                                       
(pa_hook_cb_t)sink_input_put_hook,
                                                      u);


     u->sink_input_unlink_hook_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK],
                                                          
(pa_hook_cb_t)sink_input_unlink_hook,
                                                         u);


     u->sink_input_unlink_post_hook_callback = pa_hook_connect(&u- 
 >core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST],
                                                               
(pa_hook_cb_t)sink_input_unlink_post_hook,
                                                              u);


     u->sink_input_move_hook_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_MOVE],
                                                        
(pa_hook_cb_t)sink_input_move_hook,
                                                       u);


     u->sink_input_move_post_callback = pa_hook_connect(&u->core- 
 >hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST],
                                                        
(pa_hook_cb_t)sink_input_move_post,
                                                       u);


     u->sink_input_name_changed_hook_callback = pa_hook_connect(&u- 
 >core->hooks[PA_CORE_HOOK_SINK_INPUT_NAME_CHANGED],
                                                                
(pa_hook_cb_t)sink_input_name_changed_hook,
                                                               u);


     u->sink_input_state_changed_hook_callback = pa_hook_connect(&u- 
 >core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED],
                                                                 
(pa_hook_cb_t)sink_input_state_changed_hook,
                                                                u);



     pa_log("< pa__init");
     return 0;

fail:
     pa_log("< pa__init");
     return -1;
}

static pa_hook_result_t sink_input_new_hook(pa_core *c,
                                             pa_sink_input_new_data  
*data,
                                             struct userdata *u){
     pa_log("<  sink_input_new_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_fixate_hook(pa_core *c,
                                                pa_sink_input_new_data  
*data,
                                                struct userdata *u){
     pa_log("< sink_input_fixate_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_put_hook(pa_core *c,
                                             pa_sink_input *data,
                                             struct userdata *u){
     pa_log("< sink_input_put_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_unlink_hook(pa_core *c,
                                                pa_sink_input *data,
                                                struct userdata *u){
     pa_log("< sink_input_unlink_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_unlink_post_hook(pa_core *c,
                                                     pa_sink_input  
*data,
                                                     struct userdata  
*u){
     pa_log("< sink_input_unlink_post_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_move_hook(pa_core *c,
                                               
pa_sink_input_move_hook_data *data,
                                              struct userdata *u){
     pa_log("< sink_input_move_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_move_post(pa_core *c,
                                              pa_sink_input *data,
                                              struct userdata *u){
     pa_log("< sink_input_move_post");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_name_changed_hook(pa_core *c,
                                                      pa_sink_input  
*data,
                                                      struct userdata  
*u){
     pa_log("< sink_input_name_changed_hook");
     return PA_HOOK_OK;
}

static pa_hook_result_t sink_input_state_changed_hook(pa_core *c,
                                                       pa_sink_input  
*data,
                                                       struct userdata  
*u){
     pa_log("< sink_input_state_changed_hook");
     return PA_HOOK_OK;
}



/* exit and cleanup */
void pa__done(pa_module *m) {
     struct userdata *u ;


     pa_log("> pa__done");
     pa_assert(m) ;

     if (!(u = m->userdata))
         return;

     if(u->sink_input_new_hook_callback )
         pa_hook_slot_free(u->sink_input_new_hook_callback) ;
     if(u->sink_input_fixate_hook_callback )
         pa_hook_slot_free(u->sink_input_fixate_hook_callback) ;
     if(u->sink_input_put_hook_callback )
         pa_hook_slot_free(u->sink_input_put_hook_callback) ;
     if(u->sink_input_unlink_hook_callback )
         pa_hook_slot_free(u->sink_input_unlink_hook_callback) ;
     if(u->sink_input_unlink_post_hook_callback )
         pa_hook_slot_free(u->sink_input_unlink_post_hook_callback) ;
     if(u->sink_input_move_hook_callback )
         pa_hook_slot_free(u->sink_input_move_hook_callback) ;
     if(u->sink_input_move_post_callback )
         pa_hook_slot_free(u->sink_input_move_post_callback) ;
     if(u->sink_input_name_changed_hook_callback )
         pa_hook_slot_free(u->sink_input_name_changed_hook_callback) ;
     if(u->sink_input_state_changed_hook_callback )
         pa_hook_slot_free(u->sink_input_state_changed_hook_callback) ;


     pa_xfree(u);
     pa_log("< pa__done");
}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20080619/f1efd995/attachment.htm>


More information about the pulseaudio-discuss mailing list