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

View file

@ -3,9 +3,9 @@ load-module libpipewire-module-protocol-native
load-module libpipewire-module-suspend-on-idle
load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
load-module libpipewire-module-spa-monitor v4l2/libspa-v4l2 v4l2-monitor v4l2
#load-module libpipewire-module-spa-node videotestsrc/libspa-videotestsrc videotestsrc videotestsrc media.class=Video/Source Spa:POD:Object:Props:patternType=Spa:POD:Object:Props:patternType:snow
#load-module libpipewire-module-spa-node videotestsrc/libspa-videotestsrc videotestsrc videotestsrc Spa:POD:Object:Props:patternType=Spa:POD:Object:Props:patternType:snow
load-module libpipewire-module-autolink
#load-module libpipewire-module-mixer
load-module libpipewire-module-client-node
load-module libpipewire-module-flatpak
load-module libpipewire-module-jack
#load-module libpipewire-module-jack

View file

@ -29,8 +29,6 @@
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
#include <pipewire/module.h>
#include <pipewire/node-factory.h>
#define M_PI_M2 ( M_PI + M_PI )
@ -312,9 +310,6 @@ static int impl_node_process_output(struct spa_node *node)
int16_t *dst;
struct spa_port_io *io = d->io;
if (io->status == SPA_RESULT_HAVE_BUFFER)
return SPA_RESULT_HAVE_BUFFER;
if (io->buffer_id < d->n_buffers) {
reuse_buffer(d, io->buffer_id);
io->buffer_id = SPA_ID_INVALID;

View file

@ -29,7 +29,6 @@
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
#include <pipewire/module.h>
#include <pipewire/node-factory.h>
struct data {
@ -42,19 +41,33 @@ struct data {
struct spa_hook remote_listener;
struct pw_node *node;
const char *library;
const char *factory;
const char *path;
};
static void make_node(struct data *data)
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");
props = pw_properties_new("spa.library.name", "v4l2/libspa-v4l2",
"spa.factory.name", "v4l2-source", NULL);
data->node = pw_node_factory_create_node(factory, NULL, "v4l2-source", props);
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)
@ -69,7 +82,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
case PW_REMOTE_STATE_CONNECTED:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
make_node(data);
if (make_node(data) < 0) {
pw_log_error("can't make node");
pw_main_loop_quit(data->loop);
}
break;
default:
@ -96,6 +112,13 @@ int main(int argc, char *argv[])
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);
@ -103,6 +126,10 @@ int main(int argc, char *argv[])
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);
@ -114,7 +141,6 @@ int main(int argc, char *argv[])
pw_main_loop_run(data.loop);
pw_remote_destroy(data.remote);
if (data.node)
pw_node_destroy(data.node);
pw_core_destroy(data.core);

View file

@ -3,17 +3,18 @@ executable('video-src',
install: false,
dependencies : [pipewire_dep],
)
executable('export-v4l2',
'export-v4l2.c',
install: false,
dependencies : [pipewire_dep],
)
executable('export-source',
'export-source.c',
install: false,
dependencies : [pipewire_dep, libm],
)
executable('export-spa',
'export-spa.c',
install: false,
dependencies : [pipewire_dep, libm],
)
if sdl_dep.found()
executable('video-play',
'video-play.c',

View file

@ -198,7 +198,7 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info, uint
GstCaps *caps = NULL;
GstStructure *props;
const gchar *klass = NULL;
struct spa_dict_item *item;
const struct spa_dict_item *item;
GstPipeWireDeviceType type;
int i;
struct pw_type *t = self->type;

View file

@ -96,7 +96,6 @@ static void add_item(struct pw_spa_monitor *this, struct spa_monitor_item *item)
pw_properties_set(props, key, val);
}
}
pw_properties_set(props, "media.class", klass);
support = pw_core_get_support(impl->core, &n_support);

View file

@ -103,20 +103,6 @@ pw_spa_node_new(struct pw_core *core,
struct pw_node *this;
struct impl *impl;
if (node->info) {
uint32_t i;
if (properties == NULL)
properties = pw_properties_new(NULL, NULL);
if (properties == NULL)
return NULL;
for (i = 0; i < node->info->n_items; i++)
pw_properties_set(properties,
node->info->items[i].key,
node->info->items[i].value);
}
this = pw_node_new(core, owner, parent, name, properties, sizeof(struct impl) + user_data_size);
if (this == NULL)
return NULL;

View file

@ -76,19 +76,20 @@ const char *pw_link_state_as_string(enum pw_link_state state)
static void pw_spa_dict_destroy(struct spa_dict *dict)
{
struct spa_dict_item *item;
const struct spa_dict_item *item;
spa_dict_for_each(item, dict) {
free((void *) item->key);
free((void *) item->value);
}
free(dict->items);
free((void*)dict->items);
free(dict);
}
static struct spa_dict *pw_spa_dict_copy(struct spa_dict *dict)
{
struct spa_dict *copy;
struct spa_dict_item *items;
uint32_t i;
if (dict == NULL)
@ -97,14 +98,14 @@ static struct spa_dict *pw_spa_dict_copy(struct spa_dict *dict)
copy = calloc(1, sizeof(struct spa_dict));
if (copy == NULL)
goto no_mem;
copy->items = calloc(dict->n_items, sizeof(struct spa_dict_item));
copy->items = items = calloc(dict->n_items, sizeof(struct spa_dict_item));
if (copy->items == NULL)
goto no_items;
copy->n_items = dict->n_items;
for (i = 0; i < dict->n_items; i++) {
copy->items[i].key = strdup(dict->items[i].key);
copy->items[i].value = strdup(dict->items[i].value);
items[i].key = strdup(dict->items[i].key);
items[i].value = strdup(dict->items[i].value);
}
return copy;

View file

@ -610,7 +610,7 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
data_sizes, data_strides,
&this->buffer_mem);
pw_log_debug("link %p: allocating %d input buffers %p %zd %zd", this,
pw_log_debug("link %p: allocating %d buffers %p %zd %zd", this,
this->n_buffers, this->buffers, minsize, stride);
}

View file

@ -500,6 +500,14 @@ void pw_node_set_implementation(struct pw_node *node,
node->node = spa_node;
spa_node_set_callbacks(node->node, &node_callbacks, node);
spa_graph_node_set_implementation(&node->rt.node, spa_node);
if (spa_node->info) {
uint32_t i;
for (i = 0; i < spa_node->info->n_items; i++)
pw_properties_set(node->properties,
spa_node->info->items[i].key,
spa_node->info->items[i].value);
}
}
struct spa_node *pw_node_get_implementation(struct pw_node *node)

View file

@ -54,7 +54,7 @@ struct proxy_data {
static void print_properties(struct spa_dict *props, char mark)
{
struct spa_dict_item *item;
const struct spa_dict_item *item;
printf("%c\tproperties:\n", mark);
if (props == NULL || props->n_items == 0) {