diff --git a/spa/include/spa/dict.h b/spa/include/spa/dict.h index ac36d5d8e..a9b8c9e82 100644 --- a/spa/include/spa/dict.h +++ b/spa/include/spa/dict.h @@ -38,7 +38,7 @@ struct spa_dict_item { struct spa_dict { uint32_t n_items; - struct spa_dict_item *items; + const struct spa_dict_item *items; }; #define SPA_DICT_INIT(n_items,items) { n_items, items } @@ -48,10 +48,10 @@ struct spa_dict { (item) < &(dict)->items[(dict)->n_items]; \ (item)++) -static inline struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict *dict, - const char *key) +static inline const struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict *dict, + const char *key) { - struct spa_dict_item *item; + const struct spa_dict_item *item; spa_dict_for_each(item, dict) { if (!strcmp(item->key, key)) return item; @@ -61,7 +61,7 @@ static inline struct spa_dict_item *spa_dict_lookup_item(const struct spa_dict * static inline const char *spa_dict_lookup(const struct spa_dict *dict, const char *key) { - struct spa_dict_item *item = spa_dict_lookup_item(dict, key); + const struct spa_dict_item *item = spa_dict_lookup_item(dict, key); return item ? item->value : NULL; } diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index 8042d45f7..8dbe136d0 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -32,7 +32,7 @@ #define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) static const char default_device[] = "hw:0"; -static const uint32_t default_min_latency = 64; +static const uint32_t default_min_latency = 128; static void reset_props(struct props *props) { @@ -446,7 +446,7 @@ impl_node_port_use_buffers(struct spa_node *node, for (i = 0; i < n_buffers; i++) { struct buffer *b = &this->buffers[i]; - uint32_t type = buffers[i]->datas[0].type; + uint32_t type; b->outbuf = buffers[i]; b->outstanding = true; @@ -454,6 +454,7 @@ impl_node_port_use_buffers(struct spa_node *node, b->h = spa_buffer_find_meta(b->outbuf, this->type.meta.Header); b->rb = spa_buffer_find_meta(b->outbuf, this->type.meta.Ringbuffer); + type = buffers[i]->datas[0].type; if ((type == this->type.data.MemFd || type == this->type.data.DmaBuf || type == this->type.data.MemPtr) && buffers[i]->datas[0].data == NULL) { @@ -569,10 +570,18 @@ static int impl_node_process_output(struct spa_node *node) return SPA_RESULT_NOT_IMPLEMENTED; } +static const struct spa_dict_item node_info_items[] = { + { "media.class", "Audio/Sink" }, +}; + +static const struct spa_dict node_info = { + SPA_N_ELEMENTS(node_info_items), + node_info_items +}; static const struct spa_node impl_node = { SPA_VERSION_NODE, - NULL, + &node_info, impl_node_get_props, impl_node_set_props, impl_node_send_command, @@ -693,10 +702,20 @@ impl_enum_interface_info(const struct spa_handle_factory *factory, return SPA_RESULT_OK; } +static const struct spa_dict_item info_items[] = { + { "factory.author", "Wim Taymans " }, + { "factory.description", "Play audio with the alsa API" }, +}; + +static const struct spa_dict info = { + SPA_N_ELEMENTS(info_items), + info_items +}; + const struct spa_handle_factory spa_alsa_sink_factory = { SPA_VERSION_HANDLE_FACTORY, NAME, - NULL, + &info, sizeof(struct state), impl_init, impl_enum_interface_info, diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index 3c7af64ff..9bb0babb4 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -580,9 +580,18 @@ static int impl_node_process_output(struct spa_node *node) return SPA_RESULT_OK; } +static const struct spa_dict_item node_info_items[] = { + { "media.class", "Audio/Sink" }, +}; + +static const struct spa_dict node_info = { + SPA_N_ELEMENTS(node_info_items), + node_info_items +}; + static const struct spa_node impl_node = { SPA_VERSION_NODE, - NULL, + &node_info, impl_node_get_props, impl_node_set_props, impl_node_send_command, @@ -749,10 +758,20 @@ impl_enum_interface_info(const struct spa_handle_factory *factory, return SPA_RESULT_OK; } +static const struct spa_dict_item info_items[] = { + { "factory.author", "Wim Taymans " }, + { "factory.description", "Record audio with the alsa API" }, +}; + +static const struct spa_dict info = { + SPA_N_ELEMENTS(info_items), + info_items +}; + const struct spa_handle_factory spa_alsa_source_factory = { SPA_VERSION_HANDLE_FACTORY, NAME, - NULL, + &info, sizeof(struct state), impl_init, impl_enum_interface_info, diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c index 4fc25b645..7509816fe 100644 --- a/spa/plugins/alsa/alsa-utils.c +++ b/spa/plugins/alsa/alsa-utils.c @@ -373,9 +373,7 @@ pull_frames(struct state *state, b->outstanding = true; state->io->buffer_id = b->outbuf->id; spa_log_trace(state->log, "alsa-util %p: reuse buffer %u", state, b->outbuf->id); - state->callbacks->reuse_buffer(state->callbacks_data, - 0, - b->outbuf->id); + state->callbacks->reuse_buffer(state->callbacks_data, 0, b->outbuf->id); state->ready_offset = 0; } total_frames += n_frames; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 9042da1b9..2b05767b0 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -32,6 +32,7 @@ #include #include #include + #include #include @@ -126,6 +127,7 @@ struct impl { const struct spa_node_callbacks *callbacks; void *callbacks_data; + bool async; struct spa_source timer_source; struct itimerspec timerspec; @@ -154,7 +156,7 @@ struct impl { #define CHECK_PORT_NUM(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS) #define CHECK_PORT(this,d,p) (CHECK_PORT_NUM(this,d,p) && this->io) -#define DEFAULT_LIVE true +#define DEFAULT_LIVE false #define DEFAULT_WAVE wave_sine #define DEFAULT_FREQ 440.0 #define DEFAULT_VOLUME 1.0 @@ -242,7 +244,7 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr static void set_timer(struct impl *this, bool enabled) { - if ((this->callbacks && this->callbacks->have_output) || this->props.live) { + if (this->async || this->props.live) { if (enabled) { if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time; @@ -264,7 +266,7 @@ static void read_timer(struct impl *this) { uint64_t expirations; - if ((this->callbacks && this->callbacks->have_output) || this->props.live) { + if (this->async || this->props.live) { if (read(this->timer_source.fd, &expirations, sizeof(uint64_t)) != sizeof(uint64_t)) perror("read timerfd"); } @@ -415,10 +417,6 @@ impl_node_set_callbacks(struct spa_node *node, this = SPA_CONTAINER_OF(node, struct impl, node); - if (this->data_loop == NULL && (callbacks && callbacks->have_output != NULL)) { - spa_log_error(this->log, "a data_loop is needed for async operation"); - return SPA_RESULT_ERROR; - } this->callbacks = callbacks; this->callbacks_data = data; @@ -680,15 +678,13 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - 1024 * this->bpf), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - this->bpf), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + PROP_U_MM(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, + 1024 * this->bpf, + 16 * this->bpf, + INT32_MAX / this->bpf), + PROP (&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0), + PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, 2, 1, 32), + PROP (&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); break; case 1: @@ -753,6 +749,7 @@ impl_node_port_use_buffers(struct spa_node *node, d[0].type == this->type.data.DmaBuf) && d[0].data == NULL) { spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this, buffers[i]); + return SPA_RESULT_ERROR; } spa_list_append(&this->empty, &b->link); } @@ -867,16 +864,24 @@ static int impl_node_process_output(struct spa_node *node) this->io->buffer_id = SPA_ID_INVALID; } - if ((this->callbacks == NULL || this->callbacks->have_output == NULL) && - (io->status == SPA_RESULT_NEED_BUFFER)) + if (!this->async && (io->status == SPA_RESULT_NEED_BUFFER)) return make_buffer(this); else return SPA_RESULT_OK; } +static const struct spa_dict_item node_info_items[] = { + { "media.class", "Audio/Source" }, +}; + +static const struct spa_dict node_info = { + SPA_N_ELEMENTS(node_info_items), + node_info_items +}; + static const struct spa_node impl_node = { SPA_VERSION_NODE, - NULL, + &node_info, impl_node_get_props, impl_node_set_props, impl_node_send_command, @@ -1061,10 +1066,20 @@ impl_enum_interface_info(const struct spa_handle_factory *factory, return SPA_RESULT_OK; } +static const struct spa_dict_item info_items[] = { + { "factory.author", "Wim Taymans " }, + { "factory.description", "Generate an audio test pattern" }, +}; + +static const struct spa_dict info = { + SPA_N_ELEMENTS(info_items), + info_items +}; + const struct spa_handle_factory spa_audiotestsrc_factory = { SPA_VERSION_HANDLE_FACTORY, NAME, - NULL, + &info, sizeof(struct impl), impl_init, impl_enum_interface_info, diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index fe5fbf409..fb4044e66 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -823,9 +823,18 @@ static int impl_node_process_output(struct spa_node *node) return res; } +static const struct spa_dict_item info_items[] = { + { "media.class", "Video/Source" }, +}; + +static const struct spa_dict info = { + SPA_N_ELEMENTS(info_items), + info_items +}; + static const struct spa_node impl_node = { SPA_VERSION_NODE, - NULL, + &info, impl_node_get_props, impl_node_set_props, impl_node_send_command, diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index 90f081f8f..1cf311862 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -116,6 +116,7 @@ struct impl { const struct spa_node_callbacks *callbacks; void *callbacks_data; + bool async; struct spa_source timer_source; struct itimerspec timerspec; @@ -143,7 +144,7 @@ struct impl { #define CHECK_PORT_NUM(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS) #define CHECK_PORT(this,d,p) (CHECK_PORT_NUM(this,d,p) && this->io) -#define DEFAULT_LIVE true +#define DEFAULT_LIVE false #define DEFAULT_PATTERN pattern_smpte_snow static void reset_props(struct impl *this, struct props *props) @@ -224,7 +225,7 @@ static int fill_buffer(struct impl *this, struct buffer *b) static void set_timer(struct impl *this, bool enabled) { - if ((this->callbacks && this->callbacks->have_output) || this->props.live) { + if (this->async || this->props.live) { if (enabled) { if (this->props.live) { uint64_t next_time = this->start_time + this->elapsed_time; @@ -246,7 +247,7 @@ static void read_timer(struct impl *this) { uint64_t expirations; - if ((this->callbacks && this->callbacks->have_output) || this->props.live) { + if (this->async || this->props.live) { if (read(this->timer_source.fd, &expirations, sizeof(uint64_t)) != sizeof(uint64_t)) perror("read timerfd"); } @@ -366,10 +367,6 @@ impl_node_set_callbacks(struct spa_node *node, this = SPA_CONTAINER_OF(node, struct impl, node); - if (this->data_loop == NULL && callbacks != NULL && callbacks->have_output != NULL) { - spa_log_error(this->log, "a data_loop is needed for async operation"); - return SPA_RESULT_ERROR; - } this->callbacks = callbacks; this->callbacks_data = data; @@ -631,7 +628,7 @@ impl_node_port_enum_params(struct spa_node *node, PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, this->stride), PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, 2, 32), + 2, 1, 32), PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); break; @@ -697,8 +694,9 @@ impl_node_port_use_buffers(struct spa_node *node, d[0].type == this->type.data.DmaBuf) && d[0].data == NULL) { spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this, buffers[i]); + return SPA_RESULT_ERROR; } - spa_list_insert(this->empty.prev, &b->link); + spa_list_append(&this->empty, &b->link); } this->n_buffers = n_buffers; @@ -712,7 +710,7 @@ impl_node_port_alloc_buffers(struct spa_node *node, struct spa_param **params, uint32_t n_params, struct spa_buffer **buffers, - uint32_t * n_buffers) + uint32_t *n_buffers) { struct impl *this; @@ -755,7 +753,7 @@ static inline void reuse_buffer(struct impl *this, uint32_t id) spa_log_trace(this->log, NAME " %p: reuse buffer %d", this, id); b->outstanding = false; - spa_list_insert(this->empty.prev, &b->link); + spa_list_append(&this->empty, &b->link); if (!this->props.live) set_timer(this, true); @@ -811,16 +809,24 @@ static int impl_node_process_output(struct spa_node *node) this->io->buffer_id = SPA_ID_INVALID; } - if ((this->callbacks == NULL || this->callbacks->have_output == NULL) && - (io->status == SPA_RESULT_NEED_BUFFER)) + if (!this->async && (io->status == SPA_RESULT_NEED_BUFFER)) return make_buffer(this); else return SPA_RESULT_OK; } +static const struct spa_dict_item node_info_items[] = { + { "media.class", "Video/Source" }, +}; + +static const struct spa_dict node_info = { + SPA_N_ELEMENTS(node_info_items), + node_info_items +}; + static const struct spa_node impl_node = { SPA_VERSION_NODE, - NULL, + &node_info, impl_node_get_props, impl_node_set_props, impl_node_send_command, @@ -1005,10 +1011,20 @@ impl_enum_interface_info(const struct spa_handle_factory *factory, return SPA_RESULT_OK; } +static const struct spa_dict_item info_items[] = { + { "factory.author", "Wim Taymans " }, + { "factory.description", "Generate a video test pattern" }, +}; + +static const struct spa_dict info = { + SPA_N_ELEMENTS(info_items), + info_items +}; + const struct spa_handle_factory spa_videotestsrc_factory = { SPA_VERSION_HANDLE_FACTORY, NAME, - NULL, + &info, sizeof(struct impl), impl_init, impl_enum_interface_info, diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c index 1b4ee91c8..7a355c083 100644 --- a/spa/tools/spa-inspect.c +++ b/spa/tools/spa-inspect.c @@ -89,6 +89,12 @@ static void inspect_node(struct data *data, struct spa_node *node) uint32_t *in_ports, *out_ports; struct spa_props *props; + printf("node info:\n"); + if (node->info) + spa_debug_dict(node->info); + else + printf(" none\n"); + if ((res = spa_node_get_props(node, &props)) < 0) printf("can't get properties: %d\n", res); else diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in index ccfd47251..9fda6a0db 100644 --- a/src/daemon/pipewire.conf.in +++ b/src/daemon/pipewire.conf.in @@ -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 diff --git a/src/examples/export-source.c b/src/examples/export-source.c index 1a555b3d3..c98c4f778 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -29,8 +29,6 @@ #include #include -#include -#include #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; diff --git a/src/examples/export-v4l2.c b/src/examples/export-spa.c similarity index 78% rename from src/examples/export-v4l2.c rename to src/examples/export-spa.c index cb2ce0969..4e5f67eee 100644 --- a/src/examples/export-v4l2.c +++ b/src/examples/export-spa.c @@ -29,7 +29,6 @@ #include #include -#include #include 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 [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); diff --git a/src/examples/meson.build b/src/examples/meson.build index cd3672c8e..e8eda5798 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -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', diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 5d293f733..e3872a8de 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -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; diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index f30eb80c9..84e38e977 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -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); diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c index 57e9db65a..6e086c456 100644 --- a/src/modules/spa/spa-node.c +++ b/src/modules/spa/spa-node.c @@ -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; diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c index 54319c2cd..3524ac990 100644 --- a/src/pipewire/introspect.c +++ b/src/pipewire/introspect.c @@ -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; diff --git a/src/pipewire/link.c b/src/pipewire/link.c index c90879f7e..4034fe8f2 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -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); } diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 47952fb6c..7643a23af 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -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) diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 543885389..c46497e8d 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -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) {