Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
bd55fe88
Commit
bd55fe88
authored
Oct 08, 2011
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add service discovery for PulseAudio input
parent
933ddbeb
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
262 additions
and
0 deletions
+262
-0
modules/LIST
modules/LIST
+1
-0
modules/services_discovery/Modules.am
modules/services_discovery/Modules.am
+10
-0
modules/services_discovery/pulse.c
modules/services_discovery/pulse.c
+250
-0
po/POTFILES.in
po/POTFILES.in
+1
-0
No files found.
modules/LIST
View file @
bd55fe88
...
@@ -257,6 +257,7 @@ $Id$
...
@@ -257,6 +257,7 @@ $Id$
* ps: input module for MPEG PS decapsulation
* ps: input module for MPEG PS decapsulation
* psychedelic: Psychedelic video filter
* psychedelic: Psychedelic video filter
* pulse: PulseAudio audio output
* pulse: PulseAudio audio output
* pulselist: PulseAudio audio input services discovery
* pulsesrc: PulseAudio audio input
* pulsesrc: PulseAudio audio input
* puzzle: puzzle video filter
* puzzle: puzzle video filter
* pva: PVA demuxer
* pva: PVA demuxer
...
...
modules/services_discovery/Modules.am
View file @
bd55fe88
...
@@ -5,6 +5,16 @@ SOURCES_podcast = podcast.c
...
@@ -5,6 +5,16 @@ SOURCES_podcast = podcast.c
SOURCES_mtp = mtp.c
SOURCES_mtp = mtp.c
SOURCES_mediadirs = mediadirs.c
SOURCES_mediadirs = mediadirs.c
libpulselist_plugin_la_SOURCES = \
../audio_output/vlcpulse.c ../audio_output/vlcpulse.h \
pulse.c
libpulselist_plugin_la_CFLAGS = $(AM_CFLAGS) $(PULSE_CFLAGS)
libpulselist_plugin_la_LIBADD = $(AM_LIBADD) $(PULSE_LIBS)
lubpulselist_plugin_la_DEPENDENCIES =
if HAVE_PULSE
libvlc_LTLIBRARIES += libpulselist_plugin.la
endif
libudev_plugin_la_SOURCES = udev.c
libudev_plugin_la_SOURCES = udev.c
libudev_plugin_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS)
libudev_plugin_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS)
libudev_plugin_la_LIBADD = $(AM_LIBADD) $(UDEV_LIBS)
libudev_plugin_la_LIBADD = $(AM_LIBADD) $(UDEV_LIBS)
...
...
modules/services_discovery/pulse.c
0 → 100644
View file @
bd55fe88
/**
* @file pulse.c
* @brief List of PulseAudio sources for VLC media player
*/
/*****************************************************************************
* Copyright © 2011 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <search.h>
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_services_discovery.h>
#include <pulse/pulseaudio.h>
#include "../audio_output/vlcpulse.h"
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
VLC_SD_PROBE_HELPER
(
"pulse"
,
"Audio capture"
,
SD_CAT_DEVICES
);
vlc_module_begin
()
set_shortname
(
N_
(
"Video capture"
))
set_description
(
N_
(
"Video capture (Video4Linux)"
))
set_category
(
CAT_PLAYLIST
)
set_subcategory
(
SUBCAT_PLAYLIST_SD
)
set_capability
(
"services_discovery"
,
0
)
set_callbacks
(
Open
,
Close
)
add_shortcut
(
"pulse"
,
"pa"
,
"pulseaudio"
,
"audio"
)
VLC_SD_PROBE_SUBMODULE
vlc_module_end
()
struct
services_discovery_sys_t
{
void
*
root
;
pa_context
*
context
;
pa_threaded_mainloop
*
mainloop
;
};
static
void
SourceCallback
(
pa_context
*
,
const
pa_source_info
*
,
int
,
void
*
);
static
void
ContextCallback
(
pa_context
*
,
pa_subscription_event_type_t
,
uint32_t
,
void
*
);
static
int
Open
(
vlc_object_t
*
obj
)
{
services_discovery_t
*
sd
=
(
services_discovery_t
*
)
obj
;
pa_operation
*
op
;
pa_context
*
ctx
;
services_discovery_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
unlikely
(
sys
==
NULL
))
return
VLC_ENOMEM
;
ctx
=
vlc_pa_connect
(
obj
,
&
sys
->
mainloop
);
if
(
ctx
==
NULL
)
{
free
(
sys
);
return
VLC_EGENERIC
;
}
sd
->
p_sys
=
sys
;
sys
->
context
=
ctx
;
sys
->
root
=
NULL
;
/* Subscribe for source events */
const
pa_subscription_mask_t
mask
=
PA_SUBSCRIPTION_MASK_SOURCE
;
pa_threaded_mainloop_lock
(
sys
->
mainloop
);
pa_context_set_subscribe_callback
(
ctx
,
ContextCallback
,
sd
);
op
=
pa_context_subscribe
(
ctx
,
mask
,
NULL
,
NULL
);
if
(
likely
(
op
!=
NULL
))
pa_operation_unref
(
op
);
/* Enumerate existing sources */
op
=
pa_context_get_source_info_list
(
ctx
,
SourceCallback
,
sd
);
if
(
likely
(
op
!=
NULL
))
{
//while (pa_operation_get_state (op) == PA_OPERATION_RUNNING)
// pa_threaded_mainloop_wait (sys->mainloop);
pa_operation_unref
(
op
);
}
pa_threaded_mainloop_unlock
(
sys
->
mainloop
);
return
VLC_SUCCESS
;
/*
error:
pa_threaded_mainloop_unlock (sys->mainloop);
vlc_pa_disconnect (obj, ctx, sys->mainloop);
free (sys);
return VLC_EGENERIC;*/
}
struct
device
{
uint32_t
index
;
input_item_t
*
item
;
services_discovery_t
*
sd
;
};
static
void
DestroySource
(
void
*
data
)
{
struct
device
*
d
=
data
;
if
(
d
->
sd
)
services_discovery_RemoveItem
(
d
->
sd
,
d
->
item
);
vlc_gc_decref
(
d
->
item
);
free
(
d
);
}
/**
* Compares two devices (to support binary search).
*/
static
int
cmpsrc
(
const
void
*
a
,
const
void
*
b
)
{
const
uint32_t
*
pa
=
a
,
*
pb
=
b
;
uint32_t
idxa
=
*
pa
,
idxb
=
*
pb
;
return
(
idxa
!=
idxb
)
?
((
idxa
<
idxb
)
?
-
1
:
+
1
)
:
0
;
}
/**
* Adds a source.
*/
static
int
AddSource
(
services_discovery_t
*
sd
,
const
pa_source_info
*
info
)
{
services_discovery_sys_t
*
sys
=
sd
->
p_sys
;
msg_Dbg
(
sd
,
"adding %s (%s)"
,
info
->
name
,
info
->
description
);
char
*
mrl
;
if
(
unlikely
(
asprintf
(
&
mrl
,
"pulse://%s"
,
info
->
name
)
==
-
1
))
return
-
1
;
input_item_t
*
item
=
input_item_NewWithType
(
mrl
,
info
->
description
,
0
,
NULL
,
0
,
-
1
,
ITEM_TYPE_CARD
);
free
(
mrl
);
if
(
unlikely
(
item
==
NULL
))
return
-
1
;
struct
device
*
d
=
malloc
(
sizeof
(
*
d
));
if
(
unlikely
(
d
==
NULL
))
{
vlc_gc_decref
(
item
);
return
-
1
;
}
d
->
index
=
info
->
index
;
d
->
item
=
item
;
d
->
sd
=
NULL
;
struct
device
**
dp
=
tsearch
(
d
,
&
sys
->
root
,
cmpsrc
);
if
(
dp
==
NULL
)
/* Out-of-memory */
{
DestroySource
(
d
);
return
-
1
;
}
if
(
*
dp
!=
d
)
/* Replace existing source */
{
DestroySource
(
*
dp
);
*
dp
=
d
;
}
char
*
card
;
if
(
info
->
card
==
PA_INVALID_INDEX
||
unlikely
(
asprintf
(
&
card
,
N_
(
"Card %"
PRIu32
),
info
->
card
)
==
-
1
))
card
=
NULL
;
services_discovery_AddItem
(
sd
,
item
,
(
card
!=
NULL
)
?
card
:
N_
(
"Generic"
));
d
->
sd
=
sd
;
free
(
card
);
return
0
;
}
static
void
SourceCallback
(
pa_context
*
ctx
,
const
pa_source_info
*
i
,
int
eol
,
void
*
userdata
)
{
services_discovery_t
*
sd
=
userdata
;
if
(
eol
)
return
;
AddSource
(
sd
,
i
);
(
void
)
ctx
;
}
/**
* Removes a source (if present) by index.
*/
static
void
RemoveSource
(
services_discovery_t
*
sd
,
uint32_t
idx
)
{
services_discovery_sys_t
*
sys
=
sd
->
p_sys
;
struct
device
**
dp
=
tfind
(
&
idx
,
&
sys
->
root
,
cmpsrc
);
if
(
dp
==
NULL
)
return
;
struct
device
*
d
=
*
dp
;
tdelete
(
d
,
&
sys
->
root
,
cmpsrc
);
DestroySource
(
d
);
}
static
void
ContextCallback
(
pa_context
*
ctx
,
pa_subscription_event_type_t
type
,
uint32_t
idx
,
void
*
userdata
)
{
services_discovery_t
*
sd
=
userdata
;
pa_operation
*
op
;
assert
((
type
&
PA_SUBSCRIPTION_EVENT_FACILITY_MASK
)
==
PA_SUBSCRIPTION_EVENT_SOURCE
);
switch
(
type
&
PA_SUBSCRIPTION_EVENT_TYPE_MASK
)
{
case
PA_SUBSCRIPTION_EVENT_NEW
:
case
PA_SUBSCRIPTION_EVENT_CHANGE
:
op
=
pa_context_get_source_info_by_index
(
ctx
,
idx
,
SourceCallback
,
sd
);
if
(
likely
(
op
!=
NULL
))
pa_operation_unref
(
op
);
break
;
case
PA_SUBSCRIPTION_EVENT_REMOVE
:
RemoveSource
(
sd
,
idx
);
break
;
}
}
static
void
Close
(
vlc_object_t
*
obj
)
{
services_discovery_t
*
sd
=
(
services_discovery_t
*
)
obj
;
services_discovery_sys_t
*
sys
=
sd
->
p_sys
;
vlc_pa_disconnect
(
obj
,
sys
->
context
,
sys
->
mainloop
);
tdestroy
(
sys
->
root
,
DestroySource
);
free
(
sys
);
}
po/POTFILES.in
View file @
bd55fe88
...
@@ -971,6 +971,7 @@ modules/services_discovery/bonjour.c
...
@@ -971,6 +971,7 @@ modules/services_discovery/bonjour.c
modules/services_discovery/mediadirs.c
modules/services_discovery/mediadirs.c
modules/services_discovery/mtp.c
modules/services_discovery/mtp.c
modules/services_discovery/podcast.c
modules/services_discovery/podcast.c
modules/services_discovery/pulse.c
modules/services_discovery/sap.c
modules/services_discovery/sap.c
modules/services_discovery/udev.c
modules/services_discovery/udev.c
modules/services_discovery/upnp.cpp
modules/services_discovery/upnp.cpp
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment