Add more generic export-spa example

Replace the v4l2 example with a more generic version that can add
any spa node to a remote graph
Make the dictionary items const
Add some info to nodes and factories. Add the node info to the node
properties. We can then set the media.class directly on the node,
instead of letting the monitor set it.
Debug node info in spa-inspect.
Do async operation on the audiotestsrc and videotestsrc differently.
This commit is contained in:
Wim Taymans 2017-09-07 19:55:22 +02:00
parent 21cd5a2918
commit dc85a79786
19 changed files with 190 additions and 92 deletions

150
src/examples/export-spa.c Normal file
View file

@ -0,0 +1,150 @@
/* PipeWire
* Copyright (C) 2017 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
#include <pipewire/node-factory.h>
struct data {
struct pw_main_loop *loop;
struct pw_core *core;
struct pw_type *t;
struct pw_remote *remote;
struct spa_hook remote_listener;
struct pw_node *node;
const char *library;
const char *factory;
const char *path;
};
static int make_node(struct data *data)
{
struct pw_node_factory *factory;
struct pw_properties *props;
factory = pw_core_find_node_factory(data->core, "spa-node-factory");
if (factory == NULL)
return -1;
props = pw_properties_new("spa.library.name", data->library,
"spa.factory.name", data->factory, NULL);
if (data->path) {
pw_properties_set(props, "pipewire.autoconnect", "1");
pw_properties_set(props, "pipewire.target.node", data->path);
}
data->node = pw_node_factory_create_node(factory, NULL, data->factory, props);
pw_remote_export(data->remote, data->node);
return 0;
}
static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error)
{
struct data *data = _data;
switch (state) {
case PW_REMOTE_STATE_ERROR:
printf("remote error: %s\n", error);
pw_main_loop_quit(data->loop);
break;
case PW_REMOTE_STATE_CONNECTED:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
if (make_node(data) < 0) {
pw_log_error("can't make node");
pw_main_loop_quit(data->loop);
}
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;
}
}
static const struct pw_remote_events remote_events = {
PW_VERSION_REMOTE_EVENTS,
.state_changed = on_state_changed,
};
static void do_quit(void *data, int signal_number)
{
struct data *d = data;
pw_main_loop_quit(d->loop);
}
int main(int argc, char *argv[])
{
struct data data = { 0, };
struct pw_loop *l;
pw_init(&argc, &argv);
if (argc < 3) {
fprintf(stderr, "usage: %s <library> <factory> [path]\n\n"
"\texample: %s v4l2/libspa-v4l2 v4l2-source\n\n",
argv[0], argv[0]);
return -1;
}
data.loop = pw_main_loop_new(NULL);
l = pw_main_loop_get_loop(data.loop);
pw_loop_add_signal(l, SIGINT, do_quit, &data);
pw_loop_add_signal(l, SIGTERM, do_quit, &data);
data.core = pw_core_new(l, NULL);
data.t = pw_core_get_type(data.core);
data.remote = pw_remote_new(data.core, NULL);
data.library = argv[1];
data.factory = argv[2];
if (argc > 3)
data.path = argv[3];
pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL);
spa_debug_set_type_map(data.t->map);
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
pw_remote_connect(data.remote);
pw_main_loop_run(data.loop);
if (data.node)
pw_node_destroy(data.node);
pw_core_destroy(data.core);
pw_main_loop_destroy(data.loop);
return 0;
}