size_t libvlc_renderer_discoverer_list_get( libvlc_instance_t *p_inst, libvlc_rd_description_t ***ppp_services ) { assert( p_inst != NULL && ppp_services != NULL ); /* Fetch all rd names, and longnames */ char **ppsz_names, **ppsz_longnames; int i_ret = vlc_rd_get_names( p_inst->p_libvlc_int, &ppsz_names, &ppsz_longnames ); if( i_ret != VLC_SUCCESS ) { *ppp_services = NULL; return 0; } /* Count the number of sd matching our category (i_cat/i_core_cat) */ size_t i_nb_services = 0; char **ppsz_name = ppsz_names; for( ; *ppsz_name != NULL; ppsz_name++ ) i_nb_services++; libvlc_rd_description_t **pp_services = NULL, *p_services = NULL; if( i_nb_services > 0 ) { /* Double alloc here, so that the caller iterates through pointers of * struct instead of structs. This allows us to modify the struct * without breaking the API. */ pp_services = malloc( i_nb_services * sizeof(libvlc_rd_description_t *) ); p_services = malloc( i_nb_services * sizeof(libvlc_rd_description_t) ); if( pp_services == NULL || p_services == NULL ) { free( pp_services ); free( p_services ); pp_services = NULL; p_services = NULL; i_nb_services = 0; /* Even if alloc fails, the next loop must be run in order to free * names returned by vlc_sd_GetNames */ } } /* Fill output pp_services or free unused name, longname */ char **ppsz_longname = ppsz_longnames; unsigned int i_service_idx = 0; libvlc_rd_description_t *p_service = p_services; for( ppsz_name = ppsz_names; *ppsz_name != NULL; ppsz_name++, ppsz_longname++ ) { if( pp_services != NULL ) { p_service->psz_name = *ppsz_name; p_service->psz_longname = *ppsz_longname; pp_services[i_service_idx++] = p_service++; } else { free( *ppsz_name ); free( *ppsz_longname ); } } free( ppsz_names ); free( ppsz_longnames ); *ppp_services = pp_services; return i_nb_services; }
void RendererDialog::setVisible(bool visible) { QVLCDialog::setVisible(visible); if (visible) { /* SD subnodes */ char **ppsz_longnames; char **ppsz_names; if( vlc_rd_get_names( THEPL, &ppsz_names, &ppsz_longnames ) != VLC_SUCCESS ) return; char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames; for( ; *ppsz_name; ppsz_name++, ppsz_longname++ ) { /* TODO launch all discovery services for renderers */ msg_Dbg( p_intf, "starting renderer discovery service %s", *ppsz_longname ); if ( p_rd == NULL ) { p_rd = vlc_rd_new( VLC_OBJECT(p_intf), *ppsz_name ); if( !p_rd ) msg_Err( p_intf, "Could not start renderer discovery services" ); } break; } free( ppsz_names ); free( ppsz_longnames ); if ( p_rd != NULL ) { int row = -1; char *psz_renderer = var_InheritString( THEPL, "sout" ); if ( psz_renderer != NULL ) { for ( row = 0 ; row < ui.receiversListWidget->count(); row++ ) { RendererItem *rowItem = reinterpret_cast<RendererItem*>( ui.receiversListWidget->item( row ) ); if ( rowItem->isItemSout( psz_renderer, false ) ) break; } if ( row == ui.receiversListWidget->count() ) row = -1; free( psz_renderer ); } ui.receiversListWidget->setCurrentRow( row ); if ( !b_rd_started ) { vlc_event_manager_t *em = vlc_rd_event_manager( p_rd ); vlc_event_attach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this ); vlc_event_attach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this ); b_rd_started = vlc_rd_start( p_rd ) == VLC_SUCCESS; if ( !b_rd_started ) { vlc_event_detach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this); vlc_event_detach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this); } } } } else { if ( p_rd != NULL ) { if ( b_rd_started ) { vlc_event_manager_t *em = vlc_rd_event_manager( p_rd ); vlc_event_detach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this); vlc_event_detach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this); vlc_rd_stop( p_rd ); b_rd_started = false; } } ui.receiversListWidget->clear(); } }