@@ -388,6 +388,52 @@ static void link_node_to_sink(struct obs_pw_audio_capture_app *pwac, struct targ
388388/** The app capture sink is created when there
389389 * is info about the system's default sink.
390390 * See the on_metadata and on_default_sink callbacks */
391+ static void destroy_sink_links (struct obs_pw_audio_capture_app * pwac )
392+ {
393+ obs_pw_audio_proxy_list_clear (& pwac -> sink .links );
394+ }
395+
396+ static void connect_targets (struct obs_pw_audio_capture_app * pwac )
397+ {
398+ if (!pwac -> sink .proxy ) {
399+ return ;
400+ }
401+
402+ destroy_sink_links (pwac );
403+
404+ if (pwac -> selections .num == 0 ) {
405+ return ;
406+ }
407+
408+ struct obs_pw_audio_proxy_list_iter iter ;
409+ obs_pw_audio_proxy_list_iter_init (& iter , & pwac -> nodes );
410+
411+ struct target_node * node ;
412+ while (obs_pw_audio_proxy_list_iter_next (& iter , (void * * )& node )) {
413+ if (node_is_targeted (pwac , node )) {
414+ link_node_to_sink (pwac , node );
415+ }
416+ }
417+ }
418+
419+ static void finalize_capture_sink (struct obs_pw_audio_capture_app * pwac )
420+ {
421+ if (!pwac -> sink .proxy || pwac -> sink .id == SPA_ID_INVALID || pwac -> sink .serial == SPA_ID_INVALID ||
422+ pwac -> sink .ports .num != pwac -> sink .channels ) {
423+ return ;
424+ }
425+
426+ blog (LOG_DEBUG , "[pipewire-audio] App capture sink ready" );
427+
428+ connect_targets (pwac );
429+
430+ pwac -> sink .autoconnect_targets = true;
431+
432+ if (obs_pw_audio_stream_connect (& pwac -> pw .audio , pwac -> sink .id , pwac -> sink .serial , pwac -> sink .channels ) < 0 ) {
433+ blog (LOG_WARNING , "[pipewire-audio] Error connecting stream %p to app capture sink %u" ,
434+ pwac -> pw .audio .stream , pwac -> sink .id );
435+ }
436+ }
391437
392438static void on_sink_proxy_bound_cb (void * data , uint32_t global_id )
393439{
@@ -444,40 +490,16 @@ static const struct pw_proxy_events sink_proxy_events = {
444490
445491static void register_capture_sink_port (struct obs_pw_audio_capture_app * pwac , uint32_t global_id , const char * channel )
446492{
493+ blog (LOG_DEBUG , "[pipewire-audio] Registering app capture sink port %u" , global_id );
494+
447495 struct capture_sink_port * port = da_push_back_new (pwac -> sink .ports );
448496 port -> channel = bstrdup (channel );
449497 port -> id = global_id ;
450- }
451498
452- static void destroy_sink_links (struct obs_pw_audio_capture_app * pwac )
453- {
454- obs_pw_audio_proxy_list_clear (& pwac -> sink .links );
499+ finalize_capture_sink (pwac );
455500}
456501
457- static void connect_targets (struct obs_pw_audio_capture_app * pwac )
458- {
459- if (!pwac -> sink .proxy ) {
460- return ;
461- }
462-
463- destroy_sink_links (pwac );
464-
465- if (pwac -> selections .num == 0 ) {
466- return ;
467- }
468-
469- struct obs_pw_audio_proxy_list_iter iter ;
470- obs_pw_audio_proxy_list_iter_init (& iter , & pwac -> nodes );
471-
472- struct target_node * node ;
473- while (obs_pw_audio_proxy_list_iter_next (& iter , (void * * )& node )) {
474- if (node_is_targeted (pwac , node )) {
475- link_node_to_sink (pwac , node );
476- }
477- }
478- }
479-
480- static bool make_capture_sink (struct obs_pw_audio_capture_app * pwac , uint32_t channels , const char * position )
502+ static void make_capture_sink (struct obs_pw_audio_capture_app * pwac , uint32_t channels , const char * position )
481503{
482504 /* HACK: In order to hide the app capture sink from PulseAudio applications, for example to prevent them from intentionally outputting
483505 * to it, or to not fill up desktop audio control menus with sinks, the media class is set to Audio/Sink/Internal.
@@ -502,7 +524,7 @@ static bool make_capture_sink(struct obs_pw_audio_capture_app *pwac, uint32_t ch
502524
503525 if (!pwac -> sink .proxy ) {
504526 blog (LOG_WARNING , "[pipewire-audio] Failed to create app capture sink" );
505- return false ;
527+ return ;
506528 }
507529
508530 pwac -> sink .channels = channels ;
@@ -513,30 +535,7 @@ static bool make_capture_sink(struct obs_pw_audio_capture_app *pwac, uint32_t ch
513535
514536 pw_proxy_add_listener (pwac -> sink .proxy , & pwac -> sink .proxy_listener , & sink_proxy_events , pwac );
515537
516- while (pwac -> sink .id == SPA_ID_INVALID || pwac -> sink .serial == SPA_ID_INVALID ||
517- pwac -> sink .ports .num != channels ) {
518- /* Iterate until the sink is bound and all the ports are registered */
519- pw_loop_iterate (pw_thread_loop_get_loop (pwac -> pw .thread_loop ), -1 );
520- }
521-
522- if (pwac -> sink .serial == 0 ) {
523- pw_proxy_destroy (pwac -> sink .proxy );
524- return false;
525- }
526-
527- blog (LOG_INFO , "[pipewire-audio] Created app capture sink %u with %u channels and position %s" , pwac -> sink .id ,
528- channels , position );
529-
530- connect_targets (pwac );
531-
532- pwac -> sink .autoconnect_targets = true;
533-
534- if (obs_pw_audio_stream_connect (& pwac -> pw .audio , pwac -> sink .id , pwac -> sink .serial , channels ) < 0 ) {
535- blog (LOG_WARNING , "[pipewire-audio] Error connecting stream %p to app capture sink %u" ,
536- pwac -> pw .audio .stream , pwac -> sink .id );
537- }
538-
539- return true;
538+ blog (LOG_DEBUG , "[pipewire-audio] Created app capture sink" );
540539}
541540
542541static void destroy_capture_sink (struct obs_pw_audio_capture_app * pwac )
@@ -692,6 +691,7 @@ static void on_global_cb(void *data, uint32_t id, uint32_t permissions, const ch
692691 pwac -> sink .serial = 0 ;
693692 } else {
694693 pwac -> sink .serial = strtoul (ser , NULL , 10 );
694+ finalize_capture_sink (pwac );
695695 }
696696 }
697697
0 commit comments