mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
modules: add more docs and options to pipe-tunnel
This commit is contained in:
parent
af41d45e1a
commit
fe1652e843
1 changed files with 56 additions and 23 deletions
|
|
@ -59,11 +59,26 @@
|
|||
*
|
||||
* ## Module Options
|
||||
*
|
||||
* - `tunnel.mode`: the desired tunnel to create, must be `capture` or `playback`.
|
||||
* (Default `playback`)
|
||||
* - `tunnel.mode`: the desired tunnel to create. (Default `playback`)
|
||||
* - `pipe.filename`: the filename of the pipe.
|
||||
* - `stream.props`: Extra properties for the local stream.
|
||||
*
|
||||
* When `tunnel.mode` is `capture`, a capture stream on the default source is
|
||||
* created. Samples read from the pipe will be the contents of the captured source.
|
||||
*
|
||||
* When `tunnel.mode` is `sink`, a sink node is created. Samples read from the
|
||||
* pipe will be the samples played on the sink.
|
||||
*
|
||||
* When `tunnel.mode` is `playback`, a playback stream on the default sink is
|
||||
* created. Samples written to the pipe will be played on the sink.
|
||||
*
|
||||
* When `tunnel.mode` is `source`, a source node is created. Samples written to
|
||||
* the pipe will be made available to streams connected to the source.
|
||||
*
|
||||
* When `pipe.filename` is not given, a default fifo in `/tmp/fifo_input` or
|
||||
* `/tmp/fifo_output` will be created that can be written and read respectively,
|
||||
* depending on the selected `tunnel.mode`.
|
||||
*
|
||||
* ## General options
|
||||
*
|
||||
* Options with well-known behavior.
|
||||
|
|
@ -80,7 +95,10 @@
|
|||
* - \ref PW_KEY_MEDIA_CLASS
|
||||
* - \ref PW_KEY_NODE_TARGET to specify the remote name or id to link to
|
||||
*
|
||||
* ## Example configuration of a virtual pipe sink
|
||||
* When not otherwise specified, the pipe will accept or produce a
|
||||
* 16 bits, stereo, 48KHz sample stream.
|
||||
*
|
||||
* ## Example configuration of a pipe playback stream
|
||||
*
|
||||
*\code{.unparsed}
|
||||
* context.modules = [
|
||||
|
|
@ -118,8 +136,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
|||
"[ audio.rate=<sample rate> ] " \
|
||||
"[ audio.channels=<number of channels> ] " \
|
||||
"[ audio.position=<channel map> ] " \
|
||||
"[ tunnel.mode=capture|playback " \
|
||||
"pipe.filename=<filename> " \
|
||||
"[ tunnel.mode=capture|playback|sink|source " \
|
||||
"[ pipe.filename=<filename> ]" \
|
||||
"[ stream.props=<properties> ] "
|
||||
|
||||
|
||||
|
|
@ -135,6 +153,8 @@ struct impl {
|
|||
|
||||
#define MODE_PLAYBACK 0
|
||||
#define MODE_CAPTURE 1
|
||||
#define MODE_SINK 2
|
||||
#define MODE_SOURCE 3
|
||||
uint32_t mode;
|
||||
struct pw_properties *props;
|
||||
|
||||
|
|
@ -151,6 +171,7 @@ struct impl {
|
|||
int fd;
|
||||
|
||||
struct pw_properties *stream_props;
|
||||
enum pw_direction direction;
|
||||
struct pw_stream *stream;
|
||||
struct spa_hook stream_listener;
|
||||
struct spa_audio_info_raw info;
|
||||
|
|
@ -299,7 +320,7 @@ static int create_stream(struct impl *impl)
|
|||
if (impl->stream == NULL)
|
||||
return -errno;
|
||||
|
||||
if (impl->mode == MODE_CAPTURE) {
|
||||
if (impl->direction == PW_DIRECTION_OUTPUT) {
|
||||
pw_stream_add_listener(impl->stream,
|
||||
&impl->stream_listener,
|
||||
&capture_stream_events, impl);
|
||||
|
|
@ -315,7 +336,7 @@ static int create_stream(struct impl *impl)
|
|||
SPA_PARAM_EnumFormat, &impl->info);
|
||||
|
||||
if ((res = pw_stream_connect(impl->stream,
|
||||
impl->mode == MODE_CAPTURE ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT,
|
||||
impl->direction,
|
||||
PW_ID_ANY,
|
||||
PW_STREAM_FLAG_AUTOCONNECT |
|
||||
PW_STREAM_FLAG_MAP_BUFFERS |
|
||||
|
|
@ -334,7 +355,7 @@ static int create_fifo(struct impl *impl)
|
|||
int fd = -1, res;
|
||||
|
||||
if ((filename = pw_properties_get(impl->props, "pipe.filename")) == NULL)
|
||||
filename = impl->mode == MODE_CAPTURE ?
|
||||
filename = impl->direction == PW_DIRECTION_INPUT ?
|
||||
DEFAULT_CAPTURE_FILENAME :
|
||||
DEFAULT_PLAYBACK_FILENAME;
|
||||
|
||||
|
|
@ -372,6 +393,8 @@ static int create_fifo(struct impl *impl)
|
|||
pw_log_error("'%s' is not a FIFO.", filename);
|
||||
goto error;
|
||||
}
|
||||
pw_log_info("opened fifo '%s' for %s", filename,
|
||||
impl->direction == PW_DIRECTION_INPUT ? "writing" : "reading");
|
||||
impl->filename = strdup(filename);
|
||||
impl->unlink_fifo = do_unlink_fifo;
|
||||
impl->fd = fd;
|
||||
|
|
@ -556,7 +579,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
struct pw_context *context = pw_impl_module_get_context(module);
|
||||
struct pw_properties *props = NULL;
|
||||
struct impl *impl;
|
||||
const char *str;
|
||||
const char *str, *media_class = NULL;
|
||||
int res;
|
||||
|
||||
PW_LOG_TOPIC_INIT(mod_topic);
|
||||
|
|
@ -565,6 +588,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
if (impl == NULL)
|
||||
return -errno;
|
||||
|
||||
impl->fd = -1;
|
||||
|
||||
pw_log_debug("module %p: new %s", impl, args);
|
||||
|
||||
if (args == NULL)
|
||||
|
|
@ -588,25 +613,33 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
|||
impl->module = module;
|
||||
impl->context = context;
|
||||
|
||||
if ((str = pw_properties_get(props, "tunnel.mode")) != NULL) {
|
||||
if (spa_streq(str, "capture")) {
|
||||
impl->mode = MODE_CAPTURE;
|
||||
} else if (spa_streq(str, "playback")) {
|
||||
impl->mode = MODE_PLAYBACK;
|
||||
} else {
|
||||
pw_log_error("invalid tunnel.mode '%s'", str);
|
||||
res = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
if ((str = pw_properties_get(props, "tunnel.mode")) == NULL)
|
||||
str = "playback";
|
||||
|
||||
if (spa_streq(str, "capture")) {
|
||||
impl->mode = MODE_CAPTURE;
|
||||
impl->direction = PW_DIRECTION_INPUT;
|
||||
} else if (spa_streq(str, "playback")) {
|
||||
impl->mode = MODE_PLAYBACK;
|
||||
impl->direction = PW_DIRECTION_OUTPUT;
|
||||
}else if (spa_streq(str, "sink")) {
|
||||
impl->mode = MODE_SINK;
|
||||
impl->direction = PW_DIRECTION_INPUT;
|
||||
media_class = "Audio/Sink";
|
||||
} else if (spa_streq(str, "source")) {
|
||||
impl->mode = MODE_SOURCE;
|
||||
impl->direction = PW_DIRECTION_OUTPUT;
|
||||
media_class = "Audio/Source";
|
||||
} else {
|
||||
pw_log_error("invalid tunnel.mode '%s'", str);
|
||||
res = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL)
|
||||
pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
|
||||
|
||||
if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL)
|
||||
pw_properties_set(props, PW_KEY_MEDIA_CLASS,
|
||||
impl->mode == MODE_PLAYBACK ?
|
||||
"Audio/Sink" : "Audio/Source");
|
||||
pw_properties_set(props, PW_KEY_MEDIA_CLASS, media_class);
|
||||
|
||||
if ((str = pw_properties_get(props, "stream.props")) != NULL)
|
||||
pw_properties_update_string(impl->stream_props, str, strlen(str));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue