Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 8
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Tue May 10 14:06:03 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.51 + +------------------------------------------------------------------- Wed Apr 20 11:17:00 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.50
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.50 +Version: 0.3.51 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.50.tar.gz/NEWS -> pipewire-0.3.51.tar.gz/NEWS
Changed
@@ -1,3 +1,101 @@ +# PipeWire 0.3.51 (2022-04-28) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - Improved graph reconfiguration. + - Extra configuration options for streams and filters with config + rules and environment variable. + - Improve module-pulse-tunnel latency, stability and error recovery. + - pw-top, pw-cli and pw-link improvements. + - Fix a channelmixer upmixing clipping issue. + - The ROC module has seen many improvements. + - Many more bugfixes and improvements. + + +## PipeWire + - The graph reconfiguration code was reworked: + * Moved nodes will update the new driver quantum correctly. (#2293) + * Inactive nodes are ignored more. + * Nodes that require a driver are now not scheduled anymore when + they are passive (unused). (#2309) + * Improved performance, the graph is reconfigured with a minimal + amount of changes. + - Method and event argument names were improved. + - A linker garbage collection problem was fixed. (#2292) + - Properties on threads are now implemented. Use common code to + set thread name and add an option to set stack-size. + - Streams and filters always want a driver now. This makes it possible + to just link a playback stream to a capture stream without a driver + and have it work. (#1761). + - Streams and filters can now also have rules in the config file. + - Streams, filters, JACK, ALSA and v4l2 now support PIPEWIRE_PROPS + environment variable to override node properties. + - Add config section extensions. This provides a way for modules to + have specific config to override the default config. + - Handle realloc errors better. + - Improve stream and filter property updates. + +## Modules + - The pulse-tunnel modules has improved latency management and should + now work a lot better. (#2230) + - Module-loopback, module-echo-cancel, module-filter-chain unload the + module when a stream is destroyed. (#1754) + - Biquads in filter-chain now can have more gain (5->20 dB). + - Documentation updates. Most Wiki content was moved to the source code + inline comments. + - Filter-chain now has a builtin delay line filter. (#2320) + - Filter-chain can now parse the config key correctly in all cases. + - The ROC sink and source saw many improvements. roc-source is now a stream + by default that connects to the default sink. Both modules will try to set + a graph rate. Both modules have an option to select the FEC mode. + The ROC source has lower latency now. (#2331) + - Handle realloc errors better. + +## tools + - pw-cat does not have --list-targets anymore, use one of the more + advanced and less buggy tools such as wpctl or pw-cli to list + sinks and sources. + - pw-top has seen many improvements. + * It now has some timeouts to reset the node values to their default + state when unused. + * The man page was improved. + * Invalid timings and errors are displayed in a better way. + - pw-cli and pw-link can now create links between all ports of given nodes. + - pw-cat can now save to other file formats than wav, based on the extension + of the filename. + +## SPA + - The resampler now uses a different internal method for draining. It can + now also handle 0 size buffers as input without draining. + - The channelmixer now uses the front channel averages for FC and LFE. + This avoids clipping and results in much better upmixing. + - ALSA should now work again on 32 bits. (#2271) + - The JSON parser now converts escaped unicode correctly to UTF8. + +## bluetooth + - Codec switch improvements when the device is disconnected. (#2334) + +## pulse-server + - There is a new module-roc-sink-input module, the the PulseAudio equivalent. + - The ROC source and sink-input module now have a much lower latency. + - The ROC module now has an option to select FEC mode. + - Playback and record rate adjustements should work now. (#1159) + +## JACK + - Remove some useless pthread attributes. This makes JACK work in QEMU with + sandboxing enabled. (#2297) + - The buffer_size callback is now only called when something has changed + since the last process() callback or get_buffer_size() method. This + fixes a GStreamer issue and is more in line with what JACK does. (#2324) + - Fix a potential deadlock when the process thread is doing IPC and the + IPC thread is blocking on the data thread. + - Allocation errors in metadata are handled better. + + +Older versions: + # PipeWire 0.3.50 (2022-04-13) This is a bugfix release that is API and ABI compatible with previous @@ -85,10 +183,6 @@ (#1495). - Port sorting was improved/fixed. (#2260) - -Older versions: - - # PipeWire 0.3.49 (2022-03-29) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.50.tar.gz/doc/index.dox -> pipewire-0.3.51.tar.gz/doc/index.dox
Changed
@@ -33,8 +33,10 @@ ### Resources +- PipeWire and AGL(https://wiki.automotivelinux.org/_media/pipewire_agl_20181206.pdf) - LAC 2020 Paper(https://lac2020.sciencesconf.org/307881/document) - PipeWire Under The Hood(https://venam.nixers.net/blog/unix/2021/06/23/pipewire-under-the-hood.html) - PipeWire: The Linux audio/video bus (LWN)(https://lwn.net/Articles/847412) - PipeWire Wikipedia(https://en.wikipedia.org/wiki/PipeWire) +- Bluetooth, PipeWire and Whatsapp calls(https://gjhenrique.com/pipewire.html) */
View file
pipewire-0.3.50.tar.gz/doc/tutorial3.dox -> pipewire-0.3.51.tar.gz/doc/tutorial3.dox
Changed
@@ -28,7 +28,7 @@ \code{.c} int pending, done = 0; - void core_event_done(void *object, uint32_t id, int seq) { + void core_event_done(void *data, uint32_t id, int seq) { if (id == PW_ID_CORE && seq == pending) { done = 1; pw_main_loop_quit(loop);
View file
pipewire-0.3.50.tar.gz/man/pw-cat.1.rst.in -> pipewire-0.3.51.tar.gz/man/pw-cat.1.rst.in
Changed
@@ -78,7 +78,7 @@ Don't try to link this node <id> - The id of a target node + The object.serial or the node.name of a target node --latency=VALUE*units* Set the node latency (default 100ms) @@ -97,9 +97,6 @@ If no units are given, the latency value is samples with the samplerate of the file. ---list-targets - List the available targets for **--target** - -q | --quality=VALUE Resampler quality. When the samplerate of the source or destination file does not match the samplerate of the server, the
View file
pipewire-0.3.50.tar.gz/man/pw-top.1.rst.in -> pipewire-0.3.51.tar.gz/man/pw-top.1.rst.in
Changed
@@ -19,6 +19,11 @@ The *pw-top* program provides a dynamic real-time view of the pipewire node and device statistics. +A hierarchical view is shown of Driver nodes and follower nodes. The Driver +nodes are actively using a timer to schedule dataflow in the followers. The +followers of a driver node as shown below their driver with a + sign in +a tree-like representation. + The columns presented are as follows: S @@ -31,25 +36,95 @@ The ID of the pipewire node/device, as found in *pw-dump* QUANT - Current quantum at which the device/node is polled. - See https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#pipewire-buffering-explained + The current quantum (for drivers) and the suggested quantum for follower + nodes. + + The quantum by itself needs to be divided by the RATE column to calculate + the duration of a scheduling period in fractions of a second. + + For a QUANT of 1024 and a RATE of 48000, the duration of one period in the + graph is 1024/48000 or 21.3 milliseconds. + + Follower nodes can have a 0 QUANT field, which means that the node does not + have a suggestion for the quantum and thus uses what the driver selected. + + The driver will use the lowest quantum of any of the followers. If none of + the followers select a quantum, the default quantum in the pipewire configuration + file will be used. + + The QUANT on the drivers usually translates directly into the number of audio + samples processed per processing cycle of the graph. + + See also https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#pipewire-buffering-explained RATE - Sample rate used for communicating with this device/node. + The current rate (for drivers) and the suggested rate for follower + nodes. + + This is the rate at which the graph processes data and needs to be combined with + the QUANT value to derive the duration of a processing cycle in the graph. + + Some nodes can have a 0 RATE, which means that they don't have any rate + suggestion for the graph. Nodes that suggest a rate can make the graph switch + rates if the graph is otherwise idle and the new rate is allowed as + a possible graph rate (see the pipewire configuration file). + + The RATE on (audio) driver nodes usually also translates directly to the + samplerate used by the device. Although some devices might not be able to + operate at the given samplerate, in which case resampling will need to be + done. WAIT + The waiting time of a node is the elapsed time between when the node + is ready to start processing and when it actually started processing. + + For Driver nodes, this is the time between when the node wakes up to + start processing the graph and when the driver (and thus also the graph) + completes a cycle. The WAIT time for driver is thus the elapsed time + processing the graph. + + For follower nodes, it is the time spent between being woken up (when all + dependencies of the node are satisfied) and when processing starts. The + WAIT time for follower nodes is thus mostly caused by context switching. + + A value of --- means that the node was not signaled. A value of +++ + means that the node was signaled but not awake. BUSY + The processing time is started when the node starts processing until it + completes and wakes up the next nodes in the graph. + + A value of --- means that the node was not started. A value of +++ + means that the node was started but did not complete. W/Q Ratio of WAIT / QUANT. + The W/Q time of the driver node is a good measure of the graph + load. The running averages of the driver W/Q ratios are used as the DSP + load in other (JACK) tools. + + Values of --- and +++ are copied from the WAIT column. + B/Q Ratio of BUSY / QUANT + This is a good measure of the load of a particular driver or follower + node. + + Values of --- and +++ are copied from the BUSY column. + ERR Total of Xruns and Errors + Xruns for drivers are when the graph did not complete a cycle. This can + be because a node in the graph also has an Xrun. It can also be caused when + scheduling delays cause a deadline to be missed, causing a hardware + Xrun. + + Xruns for followers are incremented when the node started processing but + did not complete before the end of the graph cycle deadline. + NAME Name assigned to the device/node, as found in *pw-dump* node.name
View file
pipewire-0.3.50.tar.gz/meson.build -> pipewire-0.3.51.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.50', + version : '0.3.51', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3',
View file
pipewire-0.3.50.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> pipewire-0.3.51.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
@@ -784,9 +784,9 @@ }; /** device */ -static void device_event_info(void *object, const struct pw_device_info *info) +static void device_event_info(void *data, const struct pw_device_info *info) { - struct global *g = object; + struct global *g = data; snd_ctl_pipewire_t *ctl = g->ctl; uint32_t n; @@ -864,11 +864,11 @@ return NULL; } -static void device_event_param(void *object, int seq, +static void device_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct global *g = object; + struct global *g = data; snd_ctl_pipewire_t *ctl = g->ctl; pw_log_debug("param %d", id); @@ -922,9 +922,9 @@ }; /** node */ -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *data, const struct pw_node_info *info) { - struct global *g = object; + struct global *g = data; snd_ctl_pipewire_t *ctl = g->ctl; const char *str; uint32_t i; @@ -970,11 +970,11 @@ } -static void node_event_param(void *object, int seq, +static void node_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct global *g = object; + struct global *g = data; pw_log_debug("update param %d %d", g->id, id); switch (id) { @@ -1023,13 +1023,13 @@ return -ENOENT; } -static int metadata_property(void *object, +static int metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct global *g = object; + struct global *g = data; snd_ctl_pipewire_t *ctl = g->ctl; if (subject == PW_ID_CORE) {
View file
pipewire-0.3.50.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.51.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -473,7 +473,6 @@ snd_pcm_pipewire_t *pw = io->private_data; snd_pcm_sw_params_t *swparams; const struct spa_pod *params1; - const char *str; uint8_t buffer1024; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); struct pw_properties *props; @@ -504,11 +503,7 @@ pw->stream = NULL; } - props = NULL; - if ((str = getenv("PIPEWIRE_PROPS")) != NULL) - props = pw_properties_new_string(str); - if (props == NULL) - props = pw_properties_new(NULL, NULL); + props = pw_properties_new(NULL, NULL); if (props == NULL) goto error;
View file
pipewire-0.3.50.tar.gz/pipewire-jack/src/metadata.c -> pipewire-0.3.51.tar.gz/pipewire-jack/src/metadata.c
Changed
@@ -53,6 +53,13 @@ prop->type = strdup(type); } +static void clear_property(jack_property_t *prop) +{ + free((char*)prop->key); + free((char*)prop->data); + free((char*)prop->type); +} + static jack_property_t *copy_properties(jack_property_t *src, uint32_t cnt) { jack_property_t *dst; @@ -108,23 +115,22 @@ const char *value, const char *type) { jack_property_t *prop; + void *np; + size_t ns; if (desc->property_cnt == desc->property_size) { - desc->property_size = desc->property_size > 0 ? desc->property_size * 2 : 8; - desc->properties = realloc(desc->properties, sizeof(*prop) * desc->property_size); + ns = desc->property_size > 0 ? desc->property_size * 2 : 8; + np = reallocarray(desc->properties, ns, sizeof(*prop)); + if (np == NULL) + return NULL; + desc->property_size = ns; + desc->properties = np; } prop = &desc->propertiesdesc->property_cnt++; set_property(prop, key, value, type); return prop; } -static void clear_property(jack_property_t *prop) -{ - free((char*)prop->key); - free((char*)prop->data); - free((char*)prop->type); -} - static void remove_property(jack_description_t *desc, jack_property_t *prop) { clear_property(prop); @@ -186,9 +192,16 @@ } else if (prop == NULL) { if (desc == NULL) desc = add_description(subject); - add_property(desc, key, value, type); - change = PropertyCreated; - changed++; + if (desc == NULL) { + changed = -errno; + pw_log_warn("add_description failed: %m"); + } else if (add_property(desc, key, value, type) == NULL) { + changed = -errno; + pw_log_warn("add_property failed: %m"); + } else { + change = PropertyCreated; + changed++; + } } else { changed = change_property(prop, value, type); change = PropertyChanged; @@ -196,11 +209,10 @@ } pthread_mutex_unlock(&globals.lock); - if (c->property_callback && changed) { + if (c->property_callback && changed > 0) { pw_log_info("emit %lu %s", subject, key); c->property_callback(subject, key, change, c->property_arg); } - return changed; }
View file
pipewire-0.3.50.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.51.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -380,6 +380,7 @@ pthread_mutex_t rt_lock; unsigned int rt_locked:1; + unsigned int data_locked:1; unsigned int started:1; unsigned int active:1; @@ -872,13 +873,18 @@ client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync); while (true) { - if (in_data_thread && client->rt_locked) - pthread_mutex_unlock(&client->rt_lock); - + if (in_data_thread) { + if (client->rt_locked) + pthread_mutex_unlock(&client->rt_lock); + client->data_locked = true; + } pw_thread_loop_wait(client->context.loop); - if (in_data_thread && client->rt_locked) - pthread_mutex_lock(&client->rt_lock); + if (in_data_thread) { + client->data_locked = false; + if (client->rt_locked) + pthread_mutex_lock(&client->rt_lock); + } if (client->last_res < 0) return client->last_res; @@ -927,23 +933,21 @@ return NULL; } -static int -do_remove_sources(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) +static void client_remove_source(struct client *c) { - struct client *c = user_data; - if (c->socket_source) { pw_loop_destroy_source(c->loop->loop, c->socket_source); c->socket_source = NULL; } - return 0; } -static void unhandle_socket(struct client *c) +static int +do_remove_sources(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) { - pw_data_loop_invoke(c->loop, - do_remove_sources, 1, NULL, 0, true, c); + struct client *c = user_data; + client_remove_source(c); + return 0; } static inline void reuse_buffer(struct client *c, struct mix *mix, uint32_t id) @@ -1278,8 +1282,11 @@ if (SPA_UNLIKELY(buffer_frames != c->buffer_frames)) { pw_log_info("%p: bufferframes old:%d new:%d cb:%p", c, c->buffer_frames, buffer_frames, c->bufsize_callback); - pw_loop_invoke(c->context.l, do_buffer_frames, 0, - &buffer_frames, sizeof(buffer_frames), false, c); + if (c->buffer_frames != (uint32_t)-1) + pw_loop_invoke(c->context.l, do_buffer_frames, 0, + &buffer_frames, sizeof(buffer_frames), false, c); + else + c->buffer_frames = buffer_frames; } return c->buffer_frames == buffer_frames; } @@ -1460,7 +1467,7 @@ if (SPA_UNLIKELY(mask & (SPA_IO_ERR | SPA_IO_HUP))) { pw_log_warn("%p: got error", c); - unhandle_socket(c); + client_remove_source(c); return; } if (SPA_UNLIKELY(c->thread_callback)) { @@ -1493,7 +1500,7 @@ static void clear_link(struct client *c, struct link *link) { pw_data_loop_invoke(c->loop, - do_clear_link, 1, NULL, 0, true, link); + do_clear_link, 1, NULL, 0, !c->data_locked, link); pw_memmap_free(link->mem); close(link->signalfd); spa_list_remove(&link->link); @@ -1507,7 +1514,8 @@ if (!c->has_transport) return; - unhandle_socket(c); + pw_data_loop_invoke(c->loop, + do_remove_sources, 1, NULL, 0, !c->data_locked, c); spa_list_consume(l, &c->links, link) clear_link(c, l); @@ -1515,11 +1523,11 @@ c->has_transport = false; } -static int client_node_transport(void *object, +static int client_node_transport(void *data, int readfd, int writefd, uint32_t mem_id, uint32_t offset, uint32_t size) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; clean_transport(c); @@ -1547,11 +1555,11 @@ return 0; } -static int client_node_set_param(void *object, +static int client_node_set_param(void *data, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; pw_proxy_error((struct pw_proxy*)c->node, -ENOTSUP, "not supported"); return -ENOTSUP; } @@ -1633,19 +1641,19 @@ link = find_activation(&c->links, c->driver_id); c->driver_activation = link ? link->activation : NULL; pw_data_loop_invoke(c->loop, - do_update_driver_activation, SPA_ID_INVALID, NULL, 0, true, c); + do_update_driver_activation, SPA_ID_INVALID, NULL, 0, false, c); install_timeowner(c); return 0; } -static int client_node_set_io(void *object, +static int client_node_set_io(void *data, uint32_t id, uint32_t mem_id, uint32_t offset, uint32_t size) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct pw_memmap *old, *mm; void *ptr; uint32_t tag5 = { c->node_id, id, }; @@ -1680,14 +1688,14 @@ return 0; } -static int client_node_event(void *object, const struct spa_event *event) +static int client_node_event(void *data, const struct spa_event *event) { return -ENOTSUP; } -static int client_node_command(void *object, const struct spa_command *command) +static int client_node_command(void *data, const struct spa_command *command) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; pw_log_debug("%p: got command %d", c, SPA_COMMAND_TYPE(command)); @@ -1720,20 +1728,20 @@ return 0; } -static int client_node_add_port(void *object, +static int client_node_add_port(void *data, enum spa_direction direction, uint32_t port_id, const struct spa_dict *props) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; pw_proxy_error((struct pw_proxy*)c->node, -ENOTSUP, "add port not supported"); return -ENOTSUP; } -static int client_node_remove_port(void *object, +static int client_node_remove_port(void *data, enum spa_direction direction, uint32_t port_id) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; pw_proxy_error((struct pw_proxy*)c->node, -ENOTSUP, "remove port not supported"); return -ENOTSUP; } @@ -2071,13 +2079,13 @@ } /* called from thread-loop */ -static int client_node_port_set_param(void *object, +static int client_node_port_set_param(void *data, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct port *p = GET_PORT(c, direction, port_id); if (p == NULL || !p->valid) @@ -2121,7 +2129,7 @@ return data; } -static int client_node_port_use_buffers(void *object, +static int client_node_port_use_buffers(void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -2129,7 +2137,7 @@ uint32_t n_buffers, struct pw_client_node_buffer *buffers) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct port *p = GET_PORT(c, direction, port_id); struct buffer *b; uint32_t i, j, fl; @@ -2268,7 +2276,7 @@ return res; } -static int client_node_port_set_io(void *object, +static int client_node_port_set_io(void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -2277,7 +2285,7 @@ uint32_t offset, uint32_t size) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct port *p = GET_PORT(c, direction, port_id); struct pw_memmap *mm, *old; struct mix *mix; @@ -2340,14 +2348,14 @@ return 0; } -static int client_node_set_activation(void *object, +static int client_node_set_activation(void *data, uint32_t node_id, int signalfd, uint32_t mem_id, uint32_t offset, uint32_t size) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct pw_memmap *mm; struct link *link; void *ptr; @@ -2412,14 +2420,14 @@ return res; } -static int client_node_port_set_mix_info(void *object, +static int client_node_port_set_mix_info(void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, uint32_t peer_id, const struct spa_dict *props) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct port *p = GET_PORT(c, direction, port_id); struct mix *mix; struct object *l; @@ -2497,33 +2505,29 @@ } \ } while(false); -static struct spa_thread *impl_create(void *data, +static struct spa_thread *impl_create(void *object, const struct spa_dict *props, void *(*start)(void*), void *arg) { - struct client *c = (struct client *) data; + struct client *c = (struct client *) object; struct spa_thread *thr; int res = 0; pw_log_info("create thread"); if (globals.creator != NULL) { pthread_t pt; - pthread_attr_t attributes; - - pthread_attr_init(&attributes); - CHECK(pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE), error); - CHECK(pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM), error); - CHECK(pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED), error); - CHECK(pthread_attr_setstacksize(&attributes, THREAD_STACK), error); + pthread_attr_t *attr = NULL, attributes; - res = -globals.creator(&pt, &attributes, start, arg); + attr = pw_thread_fill_attr(props, &attributes); - pthread_attr_destroy(&attributes); + res = -globals.creator(&pt, attr, start, arg); + if (attr) + pthread_attr_destroy(attr); if (res != 0) goto error; thr = (struct spa_thread*)pt; } else { - thr = spa_thread_utils_create(c->context.old_thread_utils, NULL, start, arg); + thr = spa_thread_utils_create(c->context.old_thread_utils, props, start, arg); } return thr; error: @@ -2533,17 +2537,17 @@ } -static int impl_join(void *data, +static int impl_join(void *object, struct spa_thread *thread, void **retval) { - struct client *c = (struct client *) data; + struct client *c = (struct client *) object; pw_log_info("join thread"); return spa_thread_utils_join(c->context.old_thread_utils, thread, retval); } -static int impl_acquire_rt(void *data, struct spa_thread *thread, int priority) +static int impl_acquire_rt(void *object, struct spa_thread *thread, int priority) { - struct client *c = (struct client *) data; + struct client *c = (struct client *) object; return spa_thread_utils_acquire_rt(c->context.old_thread_utils, thread, priority); } @@ -2617,10 +2621,10 @@ return -ENOENT; } -static int metadata_property(void *object, uint32_t id, +static int metadata_property(void *data, uint32_t id, const char *key, const char *type, const char *value) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct object *o; jack_uuid_t uuid; @@ -2712,11 +2716,11 @@ .destroy = proxy_destroy, }; -static void port_param(void *object, int seq, +static void port_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object; + struct object *o = data; switch (id) { case SPA_PARAM_Latency: @@ -3073,9 +3077,9 @@ return; } -static void registry_event_global_remove(void *object, uint32_t id) +static void registry_event_global_remove(void *data, uint32_t id) { - struct client *c = (struct client *) object; + struct client *c = (struct client *) data; struct object *o; bool graph_changed = false; @@ -3232,9 +3236,6 @@ pw_context_conf_update_props(client->context.context, "jack.properties", client->props); - if ((str = getenv("PIPEWIRE_PROPS")) != NULL) - pw_properties_update_string(client->props, str, strlen(str)); - pw_context_conf_section_match_rules(client->context.context, "jack.rules", &client->props->dict, execute_match, client); @@ -3325,10 +3326,8 @@ &client->registry_listener, ®istry_events, client); - if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) - pw_properties_set(client->props, PW_KEY_NODE_LATENCY, str); - if ((str = getenv("PIPEWIRE_RATE")) != NULL) - pw_properties_set(client->props, PW_KEY_NODE_RATE, str); + if ((str = getenv("PIPEWIRE_PROPS")) != NULL) + pw_properties_update_string(client->props, str, strlen(str)); if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { @@ -3340,6 +3339,11 @@ pw_log_warn("invalid PIPEWIRE_QUANTUM: %s", str); } } + if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) + pw_properties_set(client->props, PW_KEY_NODE_LATENCY, str); + if ((str = getenv("PIPEWIRE_RATE")) != NULL) + pw_properties_set(client->props, PW_KEY_NODE_RATE, str); + if ((str = pw_properties_get(client->props, PW_KEY_NODE_LATENCY)) != NULL) { uint32_t num, denom; if (sscanf(str, "%u/%u", &num, &denom) == 2 && denom != 0) {
View file
pipewire-0.3.50.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.51.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c
Changed
@@ -1426,7 +1426,6 @@ { int res; struct global *g = file->node; - const char *str; struct timespec abstime; const char *error = NULL; uint8_t buffer1024; @@ -1442,11 +1441,7 @@ disconnect_stream(file); - props = NULL; - if ((str = getenv("PIPEWIRE_PROPS")) != NULL) - props = pw_properties_new_string(str); - if (props == NULL) - props = pw_properties_new(NULL, NULL); + props = pw_properties_new(NULL, NULL); if (props == NULL) { res = -errno; goto exit; @@ -1470,6 +1465,7 @@ &file->stream_listener, &stream_events, file); + file->error = 0; pw_stream_connect(file->stream,
View file
pipewire-0.3.50.tar.gz/po/sv.po -> pipewire-0.3.51.tar.gz/po/sv.po
Changed
@@ -19,8 +19,8 @@ "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2022-02-13 15:33+0000\n" -"PO-Revision-Date: 2022-02-14 22:57+0100\n" +"POT-Creation-Date: 2022-04-13 15:28+0000\n" +"PO-Revision-Date: 2022-04-15 22:03+0200\n" "Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -30,7 +30,7 @@ "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Poedit 3.0.1\n" -#: src/daemon/pipewire.c:45 +#: src/daemon/pipewire.c:46 #, c-format msgid "" "%s options\n" @@ -51,8 +51,8 @@ msgid "Start the PipeWire Media System" msgstr "Starta mediasystemet PipeWire" -#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:188 -#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:188 +#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:183 +#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:183 #, c-format msgid "Tunnel to %s/%s" msgstr "Tunnel till %s/%s" @@ -61,26 +61,26 @@ msgid "Dummy Output" msgstr "Attrapputgång" -#: src/modules/module-pulse-tunnel.c:536 +#: src/modules/module-pulse-tunnel.c:545 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunnel för %s@%s" -#: src/modules/module-zeroconf-discover.c:332 +#: src/modules/module-zeroconf-discover.c:313 msgid "Unknown device" msgstr "Okänd enhet" -#: src/modules/module-zeroconf-discover.c:344 +#: src/modules/module-zeroconf-discover.c:325 #, c-format msgid "%s on %s@%s" msgstr "%s på %s@%s" -#: src/modules/module-zeroconf-discover.c:348 +#: src/modules/module-zeroconf-discover.c:329 #, c-format msgid "%s on %s" msgstr "%s på %s" -#: src/tools/pw-cat.c:1075 +#: src/tools/pw-cat.c:867 #, c-format msgid "" "%s options <file>\n" @@ -95,7 +95,7 @@ " -v, --verbose Aktivera utförliga operationer\n" "\n" -#: src/tools/pw-cat.c:1082 +#: src/tools/pw-cat.c:874 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -109,7 +109,6 @@ " or direct samples (256)\n" " the rate is the one of the source " "file\n" -" --list-targets List available targets for --target\n" "\n" msgstr "" " -R, --remote Fjärrdemonnamn\n" @@ -122,10 +121,9 @@ " Xenhet (enhet = s, ms, us, ns)\n" " eller direkta samplar (256)\n" " hastigheten är källfilens\n" -" --list-targets Lista tillgängliga mål för --target\n" "\n" -#: src/tools/pw-cat.c:1100 +#: src/tools/pw-cat.c:891 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -160,7 +158,7 @@ "%d)\n" "\n" -#: src/tools/pw-cat.c:1117 +#: src/tools/pw-cat.c:908 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" @@ -174,7 +172,7 @@ " -d, --dsd DSD-läge\n" "\n" -#: src/tools/pw-cli.c:3050 +#: src/tools/pw-cli.c:3051 #, c-format msgid "" "%s options command\n" @@ -518,12 +516,12 @@ msgid "Mono Chat + 7.1 Surround" msgstr "Mono Chatt + 7.1 Surround" -#: spa/plugins/alsa/acp/alsa-mixer.c:4750 +#: spa/plugins/alsa/acp/alsa-mixer.c:4754 #, c-format msgid "%s Output" msgstr "%s-utgång" -#: spa/plugins/alsa/acp/alsa-mixer.c:4757 +#: spa/plugins/alsa/acp/alsa-mixer.c:4761 #, c-format msgid "%s Input" msgstr "%s-ingång"
View file
pipewire-0.3.50.tar.gz/spa/include/spa/support/thread.h -> pipewire-0.3.51.tar.gz/spa/include/spa/support/thread.h
Changed
@@ -61,19 +61,19 @@ uint32_t version; /** create a new thread that runs \a start with \a arg */ - struct spa_thread * (*create) (void *data, const struct spa_dict *props, + struct spa_thread * (*create) (void *object, const struct spa_dict *props, void *(*start)(void*), void *arg); /** stop and join a thread */ - int (*join)(void *data, struct spa_thread *thread, void **retval); + int (*join)(void *object, struct spa_thread *thread, void **retval); /** get realtime priority range for threads created with \a props */ - int (*get_rt_range) (void *data, const struct spa_dict *props, int *min, int *max); + int (*get_rt_range) (void *object, const struct spa_dict *props, int *min, int *max); /** acquire realtime priority, a priority of -1 refers to the priority * configured in the realtime module */ - int (*acquire_rt) (void *data, struct spa_thread *thread, int priority); + int (*acquire_rt) (void *object, struct spa_thread *thread, int priority); /** drop realtime priority */ - int (*drop_rt) (void *data, struct spa_thread *thread); + int (*drop_rt) (void *object, struct spa_thread *thread); }; /** \copydoc spa_thread_utils_methods.create @@ -135,6 +135,9 @@ return res; } +#define SPA_KEY_THREAD_NAME "thread.name" /* the thread name */ +#define SPA_KEY_THREAD_STACK_SIZE "thread.stack-size" /* the stack size of the thread */ + /** * \} */
View file
pipewire-0.3.50.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.51.tar.gz/spa/include/spa/utils/defs.h
Changed
@@ -174,7 +174,7 @@ #define SPA_MEMBER(b,o,t) SPA_PTROFF(b,o,t) #define SPA_MEMBER_ALIGN(b,o,a,t) SPA_PTROFF_ALIGN(b,o,a,t) -#define SPA_CONTAINER_OF(p,t,m) (t*)((uintptr_t)p - offsetof (t,m)) +#define SPA_CONTAINER_OF(p,t,m) ((t*)((uintptr_t)p - offsetof(t,m))) #define SPA_PTRDIFF(p1,p2) ((intptr_t)(p1) - (intptr_t)(p2)) @@ -236,7 +236,7 @@ #define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1)) #define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0) -#define SPA_PTR_ALIGN(p,align,type) (type*)SPA_ROUND_UP_N((intptr_t)(p), (intptr_t)(align)) +#define SPA_PTR_ALIGN(p,align,type) ((type*)SPA_ROUND_UP_N((intptr_t)(p), (intptr_t)(align))) #ifndef SPA_LIKELY #ifdef __GNUC__
View file
pipewire-0.3.50.tar.gz/spa/include/spa/utils/json.h -> pipewire-0.3.51.tar.gz/spa/include/spa/utils/json.h
Changed
@@ -331,6 +331,25 @@ return len > 1 && *val == '"'; } +static inline int spa_json_parse_hex(const char *p, int num, uint32_t *res) +{ + int i; + *res = 0; + for (i = 0; i < num; i++) { + char v = pi; + if (v >= '0' && v <= '9') + v = v - '0'; + else if (v >= 'a' && v <= 'f') + v = v - 'a' + 10; + else if (v >= 'A' && v <= 'F') + v = v - 'A' + 10; + else + return -1; + *res = (*res << 4) | v; + } + return 1; +} + static inline int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen) { const char *p; @@ -355,16 +374,33 @@ else if (*p == 'f') *result++ = '\f'; else if (*p == 'u') { - char *end; - uint16_t v = strtol(p+1, &end, 16); - if (p+1 == end) { + uint8_t prefix = { 0, 0xc0, 0xe0, 0xf0 }; + uint32_t idx, n, v, cp, enc = { 0x80, 0x800, 0x10000 }; + if (val + len - p < 5 || + spa_json_parse_hex(p+1, 4, &cp) < 0) { *result++ = *p; - } else { - p = end-1; - if (v > 0xff) - *result++ = (v >> 8) & 0xff; - *result++ = v & 0xff; + continue; } + p += 4; + + if (cp >= 0xd800 && cp <= 0xdbff) { + if (val + len - p < 7 || + p1 != '\\' || p2 != 'u' || + spa_json_parse_hex(p+3, 4, &v) < 0 || + v < 0xdc00 || v > 0xdfff) + continue; + p += 6; + cp = 0x010000 | ((cp & 0x3ff) << 10) | (v & 0x3ff); + } else if (cp >= 0xdc00 && cp <= 0xdfff) + continue; + + for (idx = 0; idx < 3; idx++) + if (cp < encidx) + break; + for (n = idx; n > 0; n--, cp >>= 6) + resultn = (cp | 0x80) & 0xbf; + *result++ = (cp | prefixidx) & 0xff; + result += idx; } else *result++ = *p; } else if (*p == '\"') {
View file
pipewire-0.3.50.tar.gz/spa/include/spa/utils/string.h -> pipewire-0.3.51.tar.gz/spa/include/spa/utils/string.h
Changed
@@ -276,10 +276,11 @@ static inline float spa_strtof(const char *str, char **endptr) { static locale_t locale = NULL; + locale_t prev; float v; if (SPA_UNLIKELY(locale == NULL)) locale = newlocale(LC_ALL_MASK, "C", NULL); - locale_t prev = uselocale(locale); + prev = uselocale(locale); v = strtof(str, endptr); uselocale(prev); return v; @@ -319,10 +320,11 @@ static inline double spa_strtod(const char *str, char **endptr) { static locale_t locale = NULL; + locale_t prev; double v; if (SPA_UNLIKELY(locale == NULL)) locale = newlocale(LC_ALL_MASK, "C", NULL); - locale_t prev = uselocale(locale); + prev = uselocale(locale); v = strtod(str, endptr); uselocale(prev); return v;
View file
pipewire-0.3.50.tar.gz/spa/plugins/aec/aec-null.c -> pipewire-0.3.51.tar.gz/spa/plugins/aec/aec-null.c
Changed
@@ -42,16 +42,16 @@ #undef SPA_LOG_TOPIC_DEFAULT #define SPA_LOG_TOPIC_DEFAULT &log_topic -static int null_init(void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info) +static int null_init(void *object, const struct spa_dict *args, const struct spa_audio_info_raw *info) { - struct impl *impl = data; + struct impl *impl = object; impl->channels = info->channels; return 0; } -static int null_run(void *data, const float *rec, const float *play, float *out, uint32_t n_samples) +static int null_run(void *object, const float *rec, const float *play, float *out, uint32_t n_samples) { - struct impl *impl = data; + struct impl *impl = object; uint32_t i; for (i = 0; i < impl->channels; i++) memcpy(outi, reci, n_samples * sizeof(float));
View file
pipewire-0.3.50.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.51.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -311,7 +311,7 @@ SPA_PROP_INFO_name, SPA_POD_String("latency.internal.ns"), SPA_PROP_INFO_description, SPA_POD_String("Internal latency in nanoseconds"), SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(state->process_latency.ns, - 0, 2 * SPA_NSEC_PER_SEC), + 0LL, 2 * SPA_NSEC_PER_SEC), SPA_PROP_INFO_params, SPA_POD_Bool(true)); break; case 15:
View file
pipewire-0.3.50.tar.gz/spa/plugins/alsa/test-timer.c -> pipewire-0.3.51.tar.gz/spa/plugins/alsa/test-timer.c
Changed
@@ -206,7 +206,7 @@ snd_pcm_hw_params_t *hparams; snd_pcm_sw_params_t *sparams; struct timespec now; - char c; + int c; static const struct option long_options = { { "help", no_argument, NULL, 'h' }, { "device", required_argument, NULL, 'D' },
View file
pipewire-0.3.50.tar.gz/spa/plugins/audioconvert/channelmix-ops-c.c -> pipewire-0.3.51.tar.gz/spa/plugins/audioconvert/channelmix-ops-c.c
Changed
@@ -47,11 +47,11 @@ } } -static inline void add_c(float *d, const float *s0, const float *s1, uint32_t n_samples) +static inline void avg_c(float *d, const float *s0, const float *s1, uint32_t n_samples) { uint32_t n; for (n = 0; n < n_samples; n++) - dn = s0n + s1n; + dn = (s0n + s1n) * 0.5f; } static inline void sub_c(float *d, const float *s0, const float *s1, uint32_t n_samples) @@ -211,14 +211,14 @@ if (mix->widen == 0.0f) { vol_c(d0, s0, v0, n_samples); vol_c(d1, s1, v1, n_samples); - add_c(d2, s0, s1, n_samples); + avg_c(d2, s0, s1, n_samples); } else { for (n = 0; n < n_samples; n++) { float c = s0n + s1n; float w = c * mix->widen; d0n = (s0n - w) * v0; d1n = (s1n - w) * v1; - d2n = c; + d2n = c * 0.5f; } } lr4_process(&mix->lr43, d3, d2, v3, n_samples);
View file
pipewire-0.3.50.tar.gz/spa/plugins/audioconvert/resample.c -> pipewire-0.3.51.tar.gz/spa/plugins/audioconvert/resample.c
Changed
@@ -979,7 +979,7 @@ return outio->status = inio->status; } inio->buffer_id = 0; - inport->buffers0.outbuf->datas0.chunk->size = 0; + inport->buffers0.outbuf->datas0.chunk->size = -1; } if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers)) @@ -993,7 +993,6 @@ sb = sbuf->outbuf; db = dbuf->outbuf; - size = sb->datas0.chunk->size; maxsize = db->datas0.maxsize; if (SPA_LIKELY(this->io_position)) { @@ -1036,12 +1035,11 @@ src_datas = alloca(sizeof(void*) * this->resample.channels); dst_datas = alloca(sizeof(void*) * this->resample.channels); - if (inport->offset > size) - inport->offset = size; if (outport->offset > maxsize) outport->offset = maxsize; - if (size == 0) { + size = sb->datas0.chunk->size; + if (size == (uint32_t)-1) { size = sb->datas0.maxsize; memset(sb->datas0.data, 0, size); for (i = 0; i < sb->n_datas; i++) @@ -1049,6 +1047,9 @@ inport->offset = 0; flush_in = draining = true; } else { + size = SPA_MIN(size, sb->datas0.maxsize); + if (inport->offset > size) + inport->offset = size; for (i = 0; i < sb->n_datas; i++) src_datasi = SPA_PTROFF(sb->datasi.data, inport->offset, void); } @@ -1058,7 +1059,6 @@ in_len = (size - inport->offset) / sizeof(float); out_len = (maxsize - outport->offset) / sizeof(float); - #ifndef FASTPATH pin_len = in_len; pout_len = out_len;
View file
pipewire-0.3.50.tar.gz/spa/plugins/bluez5/bluez-hardware.conf -> pipewire-0.3.51.tar.gz/spa/plugins/bluez5/bluez-hardware.conf
Changed
@@ -40,6 +40,7 @@ { name = "Motorola S305", no-features = sbc-xq }, # #pipewire-1590 { name = "Soundcore Life P2-L", no-features = msbc-alt1, msbc-alt1-rtl }, { name = "SoundCore mini", no-features = hw-volume }, # #pipewire-1686 + { name = "SoundCore 2", no-features = sbc-xq }, # #pipewire-2291 { name = "Tribit MAXSound Plus", no-features = hw-volume }, # #pipewire-1592 { name = "Urbanista Stockholm Plus", no-features = msbc-alt1, msbc-alt1-rtl },
View file
pipewire-0.3.50.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.51.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -1307,6 +1307,11 @@ if (connected) spa_bt_device_check_profiles(device, false); else { + /* Stop codec switch on disconnect */ + struct spa_bt_a2dp_codec_switch *sw; + spa_list_consume(sw, &device->codec_switch_list, device_link) + a2dp_codec_switch_free(sw); + if (device->reconnect_state != BT_DEVICE_RECONNECT_INIT) device_stop_timer(device); device_connected(monitor, device, BT_DEVICE_DISCONNECTED); @@ -1574,7 +1579,7 @@ if (j >= size) { const struct a2dp_codec **p; size = size * 2; - p = realloc(supported_codecs, size * sizeof(const struct a2dp_codec *)); + p = reallocarray(supported_codecs, size, sizeof(const struct a2dp_codec *)); if (p == NULL) { free(supported_codecs); return NULL;
View file
pipewire-0.3.50.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.51.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -1098,6 +1098,8 @@ struct spa_bt_transport *t; int i; + this->switching_codec = false; + if (this->supported_codecs) free(this->supported_codecs); this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs(
View file
pipewire-0.3.50.tar.gz/src/daemon/filter-chain/sink-eq6.conf -> pipewire-0.3.51.tar.gz/src/daemon/filter-chain/sink-eq6.conf
Changed
@@ -75,6 +75,8 @@ { output = "eq_band_5:Out" input = "eq_band_6:In" } } + audio.channels = 2 + audio.position = FL FR capture.props = { node.name = "effect_input.eq6" media.class = Audio/Sink
View file
pipewire-0.3.50.tar.gz/src/examples/export-spa.c -> pipewire-0.3.51.tar.gz/src/examples/export-spa.c
Changed
@@ -56,9 +56,9 @@ uint32_t id; }; -static void proxy_event_bound(void *object, uint32_t global_id) +static void proxy_event_bound(void *_data, uint32_t global_id) { - struct data *data = object; + struct data *data = _data; if (data->id != global_id) { printf("node id: %u\n", global_id); data->id = global_id;
View file
pipewire-0.3.50.tar.gz/src/gst/gstpipewirecore.c -> pipewire-0.3.51.tar.gz/src/gst/gstpipewirecore.c
Changed
@@ -48,9 +48,9 @@ pw_thread_loop_signal(core->loop, FALSE); } -static void on_core_done (void *object, uint32_t id, int seq) +static void on_core_done (void *data, uint32_t id, int seq) { - GstPipeWireCore * core = object; + GstPipeWireCore * core = data; if (id == PW_ID_CORE) { core->last_seq = seq; pw_thread_loop_signal (core->loop, FALSE);
View file
pipewire-0.3.50.tar.gz/src/modules/meson.build -> pipewire-0.3.51.tar.gz/src/modules/meson.build
Changed
@@ -23,6 +23,7 @@ 'module-pulse-tunnel.c', 'module-rt.c', 'module-raop-discover.c', + 'module-raop-sink.c', 'module-session-manager.c', 'module-zeroconf-discover.c', 'module-roc-source.c', @@ -248,6 +249,7 @@ 'module-protocol-pulse/modules/module-remap-sink.c', 'module-protocol-pulse/modules/module-remap-source.c', 'module-protocol-pulse/modules/module-roc-sink.c', + 'module-protocol-pulse/modules/module-roc-sink-input.c', 'module-protocol-pulse/modules/module-roc-source.c', 'module-protocol-pulse/modules/module-simple-protocol-tcp.c', 'module-protocol-pulse/modules/module-switch-on-connect.c',
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-device/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-device/protocol-native.c
Changed
@@ -218,10 +218,10 @@ return 0; } -static void device_marshal_info(void *object, +static void device_marshal_info(void *data, const struct spa_device_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; struct spa_pod_frame f2; uint32_t i, n_items; @@ -262,10 +262,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_info(void *object, +static int device_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod *ipod; struct spa_device_info info = SPA_DEVICE_INFO_INIT(), *infop; @@ -306,10 +306,10 @@ return 0; } -static void device_marshal_result(void *object, +static void device_marshal_result(void *data, int seq, int res, uint32_t type, const void *result) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; struct spa_pod_frame f2; @@ -342,10 +342,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_result(void *object, +static int device_demarshal_result(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod_frame f1; int seq, res; @@ -384,9 +384,9 @@ return 0; } -static void device_marshal_event(void *object, const struct spa_event *event) +static void device_marshal_event(void *data, const struct spa_event *event) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, SPA_DEVICE_EVENT_EVENT, NULL); @@ -397,10 +397,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_event(void *object, +static int device_demarshal_event(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_event *event; @@ -413,10 +413,10 @@ return 0; } -static void device_marshal_object_info(void *object, uint32_t id, +static void device_marshal_object_info(void *data, uint32_t id, const struct spa_device_object_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; struct spa_pod_frame f2; uint32_t i, n_items; @@ -452,10 +452,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static int device_demarshal_object_info(void *object, +static int device_demarshal_object_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_device_object_info info = SPA_DEVICE_OBJECT_INFO_INIT(), *infop; struct spa_pod *ipod;
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/client-node.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/client-node.c
Changed
@@ -76,6 +76,11 @@ struct buffer buffersMAX_BUFFERS; }; +struct params { + uint32_t n_params; + struct spa_pod **params; +}; + struct port { struct pw_impl_port *port; struct node *node; @@ -89,8 +94,7 @@ struct spa_port_info info; struct pw_properties *properties; - uint32_t n_params; - struct spa_pod **params; + struct params params; unsigned int removed:1; unsigned int destroyed:1; @@ -120,8 +124,7 @@ struct port dummy; - uint32_t n_params; - struct spa_pod **params; + struct params params; }; struct impl { @@ -177,6 +180,32 @@ #define pw_client_node_resource_port_set_mix_info(r,...) \ pw_client_node_resource(r,port_set_mix_info,1,__VA_ARGS__) +static int update_params(struct params *p, uint32_t n_params, const struct spa_pod **params) +{ + uint32_t i; + for (i = 0; i < p->n_params; i++) + free(p->paramsi); + p->n_params = n_params; + if (p->n_params == 0) { + free(p->params); + p->params = NULL; + } else { + struct spa_pod **np; + np = reallocarray(p->params, p->n_params, sizeof(struct spa_pod *)); + if (np == NULL) { + pw_log_error("%p: can't realloc: %m", p); + free(p->params); + p->params = NULL; + p->n_params = 0; + return -errno; + } + p->params = np; + } + for (i = 0; i < p->n_params; i++) + p->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; + return 0; +} + static int do_port_use_buffers(struct impl *impl, enum spa_direction direction, @@ -309,10 +338,10 @@ struct spa_pod *param; result.index = result.next++; - if (result.index >= this->n_params) + if (result.index >= this->params.n_params) break; - param = this->paramsresult.index; + param = this->params.paramsresult.index; if (param == NULL || !spa_pod_is_object_id(param, id)) continue; @@ -472,17 +501,9 @@ const struct spa_pod **params, const struct spa_port_info *info) { - uint32_t i; - if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) { spa_log_debug(this->log, "%p: port %u update %d params", this, port->id, n_params); - for (i = 0; i < port->n_params; i++) - free(port->paramsi); - port->n_params = n_params; - port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod *)); - for (i = 0; i < port->n_params; i++) { - port->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; - } + update_params(&port->params, n_params, params); } if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO) { @@ -577,7 +598,7 @@ spa_return_val_if_fail(port != NULL, -EINVAL); pw_log_debug("%p: seq:%d port %d.%d id:%u start:%u num:%u n_params:%d", - this, seq, direction, port_id, id, start, num, port->n_params); + this, seq, direction, port_id, id, start, num, port->params.n_params); result.id = id; result.next = 0; @@ -586,10 +607,10 @@ struct spa_pod *param; result.index = result.next++; - if (result.index >= port->n_params) + if (result.index >= port->params.n_params) break; - param = port->paramsresult.index; + param = port->params.paramsresult.index; if (param == NULL || !spa_pod_is_object_id(param, id)) continue; @@ -951,16 +972,8 @@ struct node *this = &impl->node; if (change_mask & PW_CLIENT_NODE_UPDATE_PARAMS) { - uint32_t i; pw_log_debug("%p: update %d params", this, n_params); - - for (i = 0; i < this->n_params; i++) - free(this->paramsi); - this->n_params = n_params; - this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *)); - - for (i = 0; i < this->n_params; i++) - this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; + update_params(&this->params, n_params, params); } if (change_mask & PW_CLIENT_NODE_UPDATE_INFO) { spa_node_emit_info(&this->hooks, info); @@ -1186,12 +1199,7 @@ static int node_clear(struct node *this) { - uint32_t i; - - for (i = 0; i < this->n_params; i++) - free(this->paramsi); - free(this->params); - + update_params(&this->params, 0, NULL); return 0; }
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/protocol-native.c
Changed
@@ -374,9 +374,9 @@ return pw_protocol_native_end_proxy(proxy, b); } -static int client_node_demarshal_transport(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_transport(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t mem_id, offset, sz; int64_t ridx, widx; @@ -403,9 +403,9 @@ return 0; } -static int client_node_demarshal_set_param(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, flags; const struct spa_pod *param = NULL; @@ -421,9 +421,9 @@ return 0; } -static int client_node_demarshal_event_event(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_event_event(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; const struct spa_event *event; @@ -436,9 +436,9 @@ return 0; } -static int client_node_demarshal_command(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_command(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; const struct spa_command *command; @@ -451,9 +451,9 @@ return 0; } -static int client_node_demarshal_add_port(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_add_port(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; int32_t direction, port_id; @@ -475,9 +475,9 @@ return 0; } -static int client_node_demarshal_remove_port(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_remove_port(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; int32_t direction, port_id; @@ -491,9 +491,9 @@ return 0; } -static int client_node_demarshal_port_set_param(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_port_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t direction, port_id, id, flags; const struct spa_pod *param = NULL; @@ -512,9 +512,9 @@ return 0; } -static int client_node_demarshal_port_use_buffers(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_port_use_buffers(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; uint32_t direction, port_id, mix_id, flags, n_buffers, data_id; @@ -588,9 +588,9 @@ return 0; } -static int client_node_demarshal_port_set_io(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_port_set_io(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t direction, port_id, mix_id, id, memid, off, sz; @@ -612,9 +612,9 @@ return 0; } -static int client_node_demarshal_set_activation(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_set_activation(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t node_id, memid, off, sz; int64_t sigidx; @@ -639,9 +639,9 @@ return 0; } -static int client_node_demarshal_port_set_mix_info(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_port_set_mix_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t direction, port_id, mix_id, peer_id; struct spa_pod_frame f2; @@ -664,9 +664,9 @@ return 0; } -static int client_node_demarshal_set_io(void *object, const struct pw_protocol_native_message *msg) +static int client_node_demarshal_set_io(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, memid, off, sz; @@ -683,11 +683,11 @@ return 0; } -static int client_node_marshal_transport(void *object, int readfd, int writefd, +static int client_node_marshal_transport(void *data, int readfd, int writefd, uint32_t mem_id, uint32_t offset, uint32_t size) { struct pw_protocol_native_message *msg; - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_TRANSPORT, &msg); @@ -703,10 +703,10 @@ } static int -client_node_marshal_set_param(void *object, uint32_t id, uint32_t flags, +client_node_marshal_set_param(void *data, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_SET_PARAM, NULL); @@ -719,9 +719,9 @@ return pw_protocol_native_end_resource(resource, b); } -static int client_node_marshal_event_event(void *object, const struct spa_event *event) +static int client_node_marshal_event_event(void *data, const struct spa_event *event) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_EVENT, NULL); @@ -733,9 +733,9 @@ } static int -client_node_marshal_command(void *object, const struct spa_command *command) +client_node_marshal_command(void *data, const struct spa_command *command) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_COMMAND, NULL); @@ -747,11 +747,11 @@ } static int -client_node_marshal_add_port(void *object, +client_node_marshal_add_port(void *data, enum spa_direction direction, uint32_t port_id, const struct spa_dict *props) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -768,10 +768,10 @@ } static int -client_node_marshal_remove_port(void *object, +client_node_marshal_remove_port(void *data, enum spa_direction direction, uint32_t port_id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_REMOVE_PORT, NULL); @@ -784,14 +784,14 @@ } static int -client_node_marshal_port_set_param(void *object, +client_node_marshal_port_set_param(void *data, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_PORT_SET_PARAM, NULL); @@ -807,14 +807,14 @@ } static int -client_node_marshal_port_use_buffers(void *object, +client_node_marshal_port_use_buffers(void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, uint32_t flags, uint32_t n_buffers, struct pw_client_node_buffer *buffers) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, j; @@ -862,7 +862,7 @@ } static int -client_node_marshal_port_set_io(void *object, +client_node_marshal_port_set_io(void *data, uint32_t direction, uint32_t port_id, uint32_t mix_id, @@ -871,7 +871,7 @@ uint32_t offset, uint32_t size) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_PORT_SET_IO, NULL); @@ -889,7 +889,7 @@ } static int -client_node_marshal_set_activation(void *object, +client_node_marshal_set_activation(void *data, uint32_t node_id, int signalfd, uint32_t memid, @@ -897,7 +897,7 @@ uint32_t size) { struct pw_protocol_native_message *msg; - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_SET_ACTIVATION, &msg); @@ -913,13 +913,13 @@ } static int -client_node_marshal_set_io(void *object, +client_node_marshal_set_io(void *data, uint32_t id, uint32_t memid, uint32_t offset, uint32_t size) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_EVENT_SET_IO, NULL); @@ -932,14 +932,14 @@ } static int -client_node_marshal_port_set_mix_info(void *object, +client_node_marshal_port_set_mix_info(void *data, uint32_t direction, uint32_t port_id, uint32_t mix_id, uint32_t peer_id, const struct spa_dict *props) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f;
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/remote-node.c
Changed
@@ -259,10 +259,10 @@ } -static int client_node_transport(void *object, +static int client_node_transport(void *_data, int readfd, int writefd, uint32_t mem_id, uint32_t offset, uint32_t size) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; clean_transport(data); @@ -317,8 +317,15 @@ res = spa_node_enum_params_sync(node->node, id, &idx, NULL, ¶m, &b.b); if (res == 1) { - params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1)); - paramsn_params++ = spa_pod_copy(param); + void *p; + p = reallocarray(params, n_params + 1, sizeof(struct spa_pod *)); + if (p == NULL) { + res = -errno; + pw_log_error("realloc failed: %m"); + } else { + params = p; + paramsn_params++ = spa_pod_copy(param); + } } spa_pod_dynamic_builder_clean(&b); if (res != 1) @@ -376,8 +383,15 @@ port->direction, port->port_id, id, &idx, NULL, ¶m, &b.b); if (res == 1) { - params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1)); - paramsn_params++ = spa_pod_copy(param); + void *p; + p = reallocarray(params, n_params + 1, sizeof(struct spa_pod*)); + if (p == NULL) { + res = -errno; + pw_log_error("realloc failed: %m"); + } else { + params = p; + paramsn_params++ = spa_pod_copy(param); + } } spa_pod_dynamic_builder_clean(&b); @@ -416,10 +430,10 @@ } static int -client_node_set_param(void *object, uint32_t id, uint32_t flags, +client_node_set_param(void *_data, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; int res; @@ -440,13 +454,13 @@ } static int -client_node_set_io(void *object, +client_node_set_io(void *_data, uint32_t id, uint32_t memid, uint32_t offset, uint32_t size) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; struct pw_memmap *old, *mm; void *ptr; @@ -483,15 +497,15 @@ return res; } -static int client_node_event(void *object, const struct spa_event *event) +static int client_node_event(void *data, const struct spa_event *event) { pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event)); return -ENOTSUP; } -static int client_node_command(void *object, const struct spa_command *command) +static int client_node_command(void *_data, const struct spa_command *command) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; int res; @@ -533,10 +547,10 @@ } static int -client_node_add_port(void *object, enum spa_direction direction, uint32_t port_id, +client_node_add_port(void *_data, enum spa_direction direction, uint32_t port_id, const struct spa_dict *props) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; pw_log_warn("add port not supported"); pw_proxy_error(proxy, -ENOTSUP, "add port not supported"); @@ -544,9 +558,9 @@ } static int -client_node_remove_port(void *object, enum spa_direction direction, uint32_t port_id) +client_node_remove_port(void *_data, enum spa_direction direction, uint32_t port_id) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; pw_log_warn("remove port not supported"); pw_proxy_error(proxy, -ENOTSUP, "remove port not supported"); @@ -579,12 +593,12 @@ } static int -client_node_port_set_param(void *object, +client_node_port_set_param(void *_data, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; struct pw_impl_port *port; int res; @@ -620,12 +634,12 @@ } static int -client_node_port_use_buffers(void *object, +client_node_port_use_buffers(void *_data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, uint32_t flags, uint32_t n_buffers, struct pw_client_node_buffer *buffers) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; struct buffer *bid; uint32_t i, j; @@ -769,7 +783,7 @@ } static int -client_node_port_set_io(void *object, +client_node_port_set_io(void *_data, uint32_t direction, uint32_t port_id, uint32_t mix_id, @@ -778,7 +792,7 @@ uint32_t offset, uint32_t size) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; struct mix *mix; struct pw_memmap *mm, *old; @@ -869,14 +883,14 @@ } static int -client_node_set_activation(void *object, +client_node_set_activation(void *_data, uint32_t node_id, int signalfd, uint32_t memid, uint32_t offset, uint32_t size) { - struct node_data *data = object; + struct node_data *data = _data; struct pw_proxy *proxy = (struct pw_proxy*)data->client_node; struct pw_impl_node *node = data->node; struct pw_memmap *mm;
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/v0/client-node.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/v0/client-node.c
Changed
@@ -471,8 +471,19 @@ for (i = 0; i < port->n_params; i++) free(port->paramsi); port->n_params = n_params; - port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod *)); - + if (port->n_params == 0) { + free(port->params); + port->params = NULL; + } else { + void *p; + p = reallocarray(port->params, port->n_params, sizeof(struct spa_pod *)); + if (p == NULL) { + pw_log_error("%p: port %u can't realloc: %m", this, port_id); + free(port->params); + port->n_params = 0; + } + port->params = p; + } for (i = 0; i < port->n_params; i++) { port->paramsi = paramsi ? pw_protocol_native0_pod_from_v2(this->resource->client, paramsi) : NULL; @@ -1033,8 +1044,19 @@ for (i = 0; i < this->n_params; i++) free(this->paramsi); this->n_params = n_params; - this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *)); - + if (this->n_params == 0) { + free(this->params); + this->params = NULL; + } else { + void *p; + p = reallocarray(this->params, this->n_params, sizeof(struct spa_pod *)); + if (p == NULL) { + pw_log_error("%p: can't realloc: %m", this); + free(this->params); + this->n_params = 0; + } + this->params = p; + } for (i = 0; i < this->n_params; i++) this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; }
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/v0/ext-client-node.h -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/v0/ext-client-node.h
Changed
@@ -259,7 +259,7 @@ * \param memfd the fd of the memory * \param flags flags for the \a memfd */ - void (*add_mem) (void *object, + void (*add_mem) (void *data, uint32_t mem_id, uint32_t type, int memfd, @@ -275,7 +275,7 @@ * \param writefd fd for signal data can be written * \param transport the shared transport area */ - void (*transport) (void *object, + void (*transport) (void *data, uint32_t node_id, int readfd, int writefd, @@ -291,20 +291,20 @@ * \param flags parameter flags * \param param the param to set */ - void (*set_param) (void *object, uint32_t seq, + void (*set_param) (void *data, uint32_t seq, uint32_t id, uint32_t flags, const struct spa_pod *param); /** * Receive an event from the client node * \param event the received event */ - void (*event) (void *object, const struct spa_event *event); + void (*event) (void *data, const struct spa_event *event); /** * Notify of a new node command * * \param seq a sequence number * \param command the command */ - void (*command) (void *object, uint32_t seq, const struct spa_command *command); + void (*command) (void *data, uint32_t seq, const struct spa_command *command); /** * A new port was added to the node * @@ -315,7 +315,7 @@ * \param direction the direction of the port * \param port_id the new port id */ - void (*add_port) (void *object, + void (*add_port) (void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id); @@ -326,7 +326,7 @@ * \param direction a port direction * \param port_id the remove port id */ - void (*remove_port) (void *object, + void (*remove_port) (void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id); @@ -340,7 +340,7 @@ * \param flags flags used when setting the param * \param param the new param */ - void (*port_set_param) (void *object, + void (*port_set_param) (void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id, @@ -355,7 +355,7 @@ * \param n_buffer the number of buffers * \param buffers and array of buffer descriptions */ - void (*port_use_buffers) (void *object, + void (*port_use_buffers) (void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id, @@ -368,7 +368,7 @@ * \param port_id the port id * \param command the command */ - void (*port_command) (void *object, + void (*port_command) (void *data, enum spa_direction direction, uint32_t port_id, const struct spa_command *command); @@ -384,7 +384,7 @@ * \param offset offset of io area in memory * \param size size of the io area */ - void (*port_set_io) (void *object, + void (*port_set_io) (void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id,
View file
pipewire-0.3.50.tar.gz/src/modules/module-client-node/v0/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-client-node/v0/protocol-native.c
Changed
@@ -47,12 +47,12 @@ const struct spa_type_info *info, uint32_t type); static void -client_node_marshal_add_mem(void *object, +client_node_marshal_add_mem(void *data, uint32_t mem_id, uint32_t type, int memfd, uint32_t flags) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; const char *typename; @@ -80,10 +80,10 @@ pw_protocol_native_end_resource(resource, b); } -static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd, +static void client_node_marshal_transport(void *data, uint32_t node_id, int readfd, int writefd, struct pw_client_node0_transport *transport) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct pw_client_node0_transport_info info; @@ -103,10 +103,10 @@ } static void -client_node_marshal_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags, +client_node_marshal_set_param(void *data, uint32_t seq, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_SET_PARAM, NULL); @@ -120,9 +120,9 @@ pw_protocol_native_end_resource(resource, b); } -static void client_node_marshal_event_event(void *object, const struct spa_event *event) +static void client_node_marshal_event_event(void *data, const struct spa_event *event) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_EVENT, NULL); @@ -133,9 +133,9 @@ } static void -client_node_marshal_command(void *object, uint32_t seq, const struct spa_command *command) +client_node_marshal_command(void *data, uint32_t seq, const struct spa_command *command) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -154,10 +154,10 @@ } static void -client_node_marshal_add_port(void *object, +client_node_marshal_add_port(void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_ADD_PORT, NULL); @@ -171,10 +171,10 @@ } static void -client_node_marshal_remove_port(void *object, +client_node_marshal_remove_port(void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_REMOVE_PORT, NULL); @@ -188,7 +188,7 @@ } static void -client_node_marshal_port_set_param(void *object, +client_node_marshal_port_set_param(void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id, @@ -196,7 +196,7 @@ uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -229,13 +229,13 @@ } static void -client_node_marshal_port_use_buffers(void *object, +client_node_marshal_port_use_buffers(void *data, uint32_t seq, enum spa_direction direction, uint32_t port_id, uint32_t n_buffers, struct pw_client_node0_buffer *buffers) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -283,12 +283,12 @@ } static void -client_node_marshal_port_command(void *object, +client_node_marshal_port_command(void *data, uint32_t direction, uint32_t port_id, const struct spa_command *command) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -306,7 +306,7 @@ } static void -client_node_marshal_port_set_io(void *object, +client_node_marshal_port_set_io(void *data, uint32_t seq, uint32_t direction, uint32_t port_id, @@ -315,7 +315,7 @@ uint32_t offset, uint32_t size) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE0_EVENT_PORT_SET_IO, NULL);
View file
pipewire-0.3.50.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.51.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -401,6 +401,13 @@ pw_stream_flush(impl->source, false); pw_stream_flush(impl->capture, false); break; + case PW_STREAM_STATE_UNCONNECTED: + pw_log_info("%p: input unconnected", impl); + pw_impl_module_schedule_destroy(impl->module); + break; + case PW_STREAM_STATE_ERROR: + pw_log_info("%p: input error: %s", impl, error); + break; default: break; } @@ -466,6 +473,13 @@ pw_stream_flush(impl->sink, false); pw_stream_flush(impl->playback, false); break; + case PW_STREAM_STATE_UNCONNECTED: + pw_log_info("%p: output unconnected", impl); + pw_impl_module_schedule_destroy(impl->module); + break; + case PW_STREAM_STATE_ERROR: + pw_log_info("%p: output error: %s", impl, error); + break; default: break; }
View file
pipewire-0.3.50.tar.gz/src/modules/module-example-sink.c -> pipewire-0.3.51.tar.gz/src/modules/module-example-sink.c
Changed
@@ -49,6 +49,47 @@ #include <pipewire/i18n.h> /** \page page_module_example_sink PipeWire Module: Example Sink + * + * The example sink is a good starting point for writing a custom + * sink. We refer to the source code for more information. + * + * ## Module Options + * + * - `node.name`: a unique name for the stream + * - `node.description`: a human readable name for the stream + * - `stream.props = {}`: properties to be passed to the stream + * + * ## General options + * + * Options with well-known behavior. + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_MEDIA_CLASS + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-example-sink + * args = { + * node.name = "example_sink" + * node.description = "My Example Sink" + * stream.props = { + * audio.position = FL FR + * } + * } + * } + * + *\endcode */ #define NAME "example-sink" @@ -401,8 +442,6 @@ impl->context = context; impl->work = pw_context_get_work_queue(context); - if (pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); @@ -424,7 +463,6 @@ copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); - copy_props(impl, props, PW_KEY_NODE_WANT_DRIVER); copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS);
View file
pipewire-0.3.50.tar.gz/src/modules/module-example-source.c -> pipewire-0.3.51.tar.gz/src/modules/module-example-source.c
Changed
@@ -49,6 +49,47 @@ #include <pipewire/i18n.h> /** \page page_module_example_source PipeWire Module: Example Source + * + * The example source is a good starting point for writing a custom + * source. We refer to the source code for more information. + * + * ## Module Options + * + * - `node.name`: a unique name for the stream + * - `node.description`: a human readable name for the stream + * - `stream.props = {}`: properties to be passed to the stream + * + * ## General options + * + * Options with well-known behavior. + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_MEDIA_CLASS + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-example-source + * args = { + * node.name = "example_source" + * node.description = "My Example Source" + * stream.props = { + * audio.position = FL FR + * } + * } + * } + * + *\endcode */ #define NAME "example-source" @@ -407,8 +448,6 @@ impl->context = context; impl->work = pw_context_get_work_queue(context); - if (pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); @@ -430,7 +469,6 @@ copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); - copy_props(impl, props, PW_KEY_NODE_WANT_DRIVER); copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS);
View file
pipewire-0.3.50.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.51.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -55,13 +55,338 @@ /** * \page page_module_filter_chain PipeWire Module: Filter-Chain * + * The filter-chain allows you to create an arbitrary processing graph + * from LADSPA, LV2 and builtin filters. This filter can be made into a + * virtual sink/source or between any 2 nodes in the graph. + * + * The filter chain is built with 2 streams, a capture stream providing + * the input to the filter chain and a playback stream sending out the + * filtered stream to the next nodes in the graph. + * + * Because both ends of the filter-chain are built with streams, the session + * manager can manage the configuration and connection with the sinks and + * sources automatically. + * + * ## Module Options + * + * - `node.description`: a human readable name for the filter chain + * - `filter.graph = `: a description of the filter graph to run, see below + * - `capture.props = {}`: properties to be passed to the input stream + * - `playback.props = {}`: properties to be passed to the output stream + * + * ## Filter graph description + * + * The general structure of the graph description is as follows: + * + *\code{.unparsed} + * filter.graph = { + * nodes = + * { + * type = <ladspa | lv2 | builtin> + * name = <name> + * plugin = <plugin> + * label = <label> + * config = { + * <configkey> = <value> ... + * } + * control = { + * <controlname|controlindex> = <value> ... + * } + * } + * ... + * + * links = + * { output = <portname> input = <portname> } + * ... + * + * inputs = <portname> ... + * outputs = <portname> ... + * } + *\endcode + * + * ### Nodes + * + * Nodes describe the processing filters in the graph. Use a tool like lv2ls + * or listplugins to get a list of available plugins, labels and the port names. + * + * - `type` is one of `ladspa`, `lv2` or `builtin` + * - `name` is the name for this node, you might need this later to refer to this node + * and its ports when setting controls or making links. + * - `plugin` is the type specific plugin name. + * - For LADSPA plugins it will append `.so` to find the shared object with that + * name in the LADSPA plugin path. + * - For LV2, this is the plugin URI obtained with lv2ls. + * - For builtin this is ignored + * - `label` is the type specific filter inside the plugin. + * - For LADSPA this is the label + * - For LV2 this is unused + * - For builtin this is the name of the filter to use + * + * - `config` contains a filter specific configuration section. The convolver + * plugin needs this. + * - `control` contains the initial values for the control ports of the filter. + * + * ### Links + * + * Links can be made between ports of nodes. The `portname` is given as + * `<node_name>:<port_name>`. + * + * You can tee the output of filters to multiple other filters. You need to + * use a mixer if you want the output of multiple filters to go into one + * filter input port. + * + * links can be omited when the graph has just 1 filter. + * + * ### Inputs and Outputs + * + * These are the entry and exit ports into the graph definition. Their number + * defines the number of channels used by the filter-chain. + * + * The `<portname>` can be `null` when a channel is to be ignored. + * + * Each input/output in the graph can only be linked to one filter input/output. + * You need to use the copy builtin filter if the stream signal needs to be routed + * to multiple filters. You need to use the mixer builtin plugin if multiple graph + * outputs need to go to one output stream. + * + * inputs and outputs can be omitted, in which case the filter-chain will use all + * inputs from the first filter and all outputs from the last filter node. The + * graph will then be duplicated as many times to match the number of input/output + * channels of the streams. + * + * ## Builtin filters + * + * There are some useful builtin filters available. You select them with the label + * of the filter node. + * + * ### Mixer + * + * Use the `mixer` plugin if you have multiple input signals that need to be mixed together. + * + * The mixer plugin has up to 8 input ports labeled "In 1" to "In 8" and each with + * a gain control labeled "Gain 1" to "Gain 8". There is an output port labeled + * "Out". Unused input ports will be ignoded and not cause overhead. + * + * ### Copy + * + * Use the `copy` plugin if you need to copy a stream input signal to multiple filters. + * + * It has one input port "In" and one output port "Out". + * + * ### Biquads + * + * Biquads can be used to do all kinds of filtering. They are also used when creating + * equalizers. + * + * All biquad filters have an input port "In" and an output port "Out". They have + * a "Freq", "Q" and "Gain" control. Their meaning depends on the particular biquad that + * is used. The following labels can be used: + * + * - `bq_lowpass` a lowpass filter. + * - `bq_highpass` a highpass filter. + * - `bq_bandpass` a bandpass filter. + * - `bq_lowshelf` a low shelf filter. + * - `bq_highshelf` a high shelf filter. + * - `bq_peaking` a peaking filter. + * - `bq_notch` a notch filter. + * - `bq_allpass` an allpass filter. + * + * ### Convolver + * + * The convolver can be used to apply an impulse response to a signal. It is usually used + * for reverbs or virtual surround. The convolver is implemented with a fast FFT + * implementation. + * + * The convolver has an input port "In" and an output port "Out". It requires a config + * section in the node declaration in this format: + * + *\code{.unparsed} + * filter.graph = { + * nodes = + * { + * type = builtin + * name = ... + * label = convolver + * config = { + * blocksize = ... + * tailsize = ... + * gain = ... + * delay = ... + * filename = ... + * offset = ... + * length = ... + * channel = ... + * } + * ... + * } + * } + * ... + * } + *\endcode + * + * - `blocksize` specifies the size of the blocks to use in the FFT. It is a value + * between 64 and 256. When not specified, this value is + * computed automatically from the number of samples in the file. + * - `tailsize` specifies the size of the tail blocks to use in the FFT. + * - `gain` the overall gain to apply to the IR file. + * - `delay` The extra delay (in samples) to add to the IR. + * - `filename` The IR to load or create. Possible values are: + * - `/hilbert` creates a hilbert function(https://en.wikipedia.org/wiki/Hilbert_transform) + * that can be used to phase shift the signal by +/-90 degrees. The + * `length` will be used as the number of coefficients. + * - `/dirac` creates a Dirac function(https://en.wikipedia.org/wiki/Dirac_delta_function) that + * can be used as gain. + * - A filename to load as the IR. This needs to be a file format supported + * by sndfile. + * - `offset` The sample offset in the file as the start of the IR. + * - `length` The number of samples to use as the IR. + * - `channel` The channel to use from the file as the IR. + * + * ### Delay + * + * The delay can be used to delay a signal in time. + * + * The delay has an input port "In" and an output port "Out". It also has + * a "Delay (s)" control port. It requires a config section in the node declaration + * in this format: + * + *\code{.unparsed} + * filter.graph = { + * nodes = + * { + * type = builtin + * name = ... + * label = delay + * config = { + * "max-delay" = ... + * } + * control = { + * "Delay (s)" = ... + * } + * ... + * } + * } + * ... + * } + *\endcode + * + * - `max-delay` the maximum delay in seconds. The "Delay (s)" parameter will + * be clamped to this value. + * + * ## General options + * + * Options with well-known behavior. Most options can be added to the global + * configuration or the individual streams: + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_LINK_GROUP + * - \ref PW_KEY_NODE_VIRTUAL + * + * Stream only properties: + * + * - \ref PW_KEY_MEDIA_CLASS + * - \ref PW_KEY_NODE_NAME + * + * ## Example configuration of a virtual source + * + * This example uses the rnnoise LADSPA plugin to create a new + * virtual source. + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-filter-chain + * args = { + * node.description = "Noise Canceling source" + * media.name = "Noise Canceling source" + * filter.graph = { + * nodes = + * { + * type = ladspa + * name = rnnoise + * plugin = ladspa/librnnoise_ladspa + * label = noise_suppressor_stereo + * control = { + * "VAD Threshold (%)" 50.0 + * } + * } + * + * } + * capture.props = { + * node.name = "capture.rnnoise_source" + * node.passive = true + * } + * playback.props = { + * node.name = "rnnoise_source" + * media.class = Audio/Source + * } + * } + * } + * + *\endcode + * + * ## Example configuration of a Dolby Surround encoder virtual Sink + * + * This example uses the ladpsa surrounf encoder to encode a 5.1 signal + * to a stereo Dolby Surround signal. + * + *\code{.unparsed} + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-filter-chain + * args = { + * node.description = "Dolby Surround Sink" + * media.name = "Dolby Surround Sink" + * filter.graph = { + * nodes = + * { + * type = builtin + * name = mixer + * label = mixer + * control = { "Gain 1" = 0.5 "Gain 2" = 0.5 } + * } + * { + * type = ladspa + * name = enc + * plugin = surround_encoder_1401 + * label = surroundEncoder + * } + * + * links = + * { output = "mixer:Out" input = "enc:S" } + * + * inputs = "enc:L" "enc:R" "enc:C" null "mixer:In 1" "mixer:In 2" + * outputs = "enc:Lt" "enc:Rt" + * } + * capture.props = { + * node.name = "effect_input.dolby_surround" + * media.class = Audio/Sink + * audio.channels = 6 + * audio.position = FL FR FC LFE SL SR + * } + * playback.props = { + * node.name = "effect_output.dolby_surround" + * node.passive = true + * audio.channels = 2 + * audio.position = FL FR + * } + * } + * } + * + *\endcode */ static const struct spa_dict_item module_props = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, { PW_KEY_MODULE_DESCRIPTION, "Create filter chain streams" }, { PW_KEY_MODULE_USAGE, " remote.name=<remote> " " node.latency=<latency as fraction> " - " node.name=<name of the nodes> " " node.description=<description of the nodes> " " audio.rate=<sample rate> " " audio.channels=<number of channels> " @@ -69,7 +394,7 @@ "filter.graph = " " nodes = " " { " - " type = ladspa " + " type = <ladspa | lv2 | builtin> " " name = <name> " " plugin = <plugin> " " label = <label> " @@ -77,7 +402,7 @@ " <configkey> = <value> ... " " } " " control = { " - " <controlname> = <value> ... " + " <controlname|controlindex> = <value> ... " " } " " } " " " @@ -322,6 +647,12 @@ return NULL; } +/* find a port by name. Valid syntax is: + * "<node_name>:<port_name>" + * "<node_name>:<port_id>" + * "<port_name>" + * "<port_id>" + * When no node_name is given, the port is assumed in the current node. */ static struct port *find_port(struct node *node, const char *name, int descriptor) { char *col, *node_name, *port_name, *str; @@ -515,6 +846,7 @@ while (true) { const char *name; float value, *val = NULL; + double dbl_val; bool bool_val; int32_t int_val; @@ -522,6 +854,9 @@ break; if (spa_pod_parser_get_float(&prs, &value) >= 0) { val = &value; + } else if (spa_pod_parser_get_double(&prs, &dbl_val) >= 0) { + value = dbl_val; + val = &value; } else if (spa_pod_parser_get_int(&prs, &int_val) >= 0) { value = int_val; val = &value; @@ -605,6 +940,13 @@ pw_stream_flush(impl->capture, false); graph_reset(graph); break; + case PW_STREAM_STATE_UNCONNECTED: + pw_log_info("module %p: unconnected", impl); + pw_impl_module_schedule_destroy(impl->module); + break; + case PW_STREAM_STATE_ERROR: + pw_log_info("module %p: error: %s", impl, error); + break; default: break; } @@ -1119,6 +1461,8 @@ } else if (spa_streq("config", key)) { config = SPA_JSON_SAVE(json); have_config = true; + if (spa_json_next(json, &val) < 0) + break; } else if (spa_json_next(json, &val) < 0) break; } @@ -1345,8 +1689,8 @@ for (i = 0; i < n_hndl; i++) { pw_log_info("instantiate %s %d", d->name, i); if ((node->hndli = d->instantiate(d, &impl->rate, i, node->config)) == NULL) { - pw_log_error("cannot create plugin instance"); - res = -ENOMEM; + pw_log_error("cannot create plugin instance: %m"); + res = -errno; goto error; } node->n_hndl = i + 1;
View file
pipewire-0.3.50.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.51.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -264,7 +264,7 @@ { .index = 4, .name = "Gain", .flags = FC_PORT_INPUT | FC_PORT_CONTROL, - .def = 0.0f, .min = -120.0f, .max = 5.0f, + .def = 0.0f, .min = -120.0f, .max = 20.0f, }, }; @@ -730,6 +730,135 @@ .cleanup = convolver_cleanup, }; +/** delay */ +struct delay_impl { + unsigned long rate; + float *port4; + + float delay; + uint32_t delay_samples; + uint32_t buffer_samples; + float *buffer; + uint32_t ptr; +}; + +static void delay_cleanup(void * Instance) +{ + struct delay_impl *impl = Instance; + free(impl->buffer); + free(impl); +} + +static void *delay_instantiate(const struct fc_descriptor * Descriptor, + unsigned long *SampleRate, int index, const char *config) +{ + struct delay_impl *impl; + struct spa_json it2; + const char *val; + char key256; + float max_delay = 1.0f; + + if (config == NULL) { + errno = EINVAL; + return NULL; + } + + spa_json_init(&it0, config, strlen(config)); + if (spa_json_enter_object(&it0, &it1) <= 0) + return NULL; + + while (spa_json_get_string(&it1, key, sizeof(key)) > 0) { + if (spa_streq(key, "max-delay")) { + if (spa_json_get_float(&it1, &max_delay) <= 0) + return NULL; + } + else if (spa_json_next(&it1, &val) < 0) + break; + } + if (max_delay <= 0.0f) + max_delay = 1.0f; + + impl = calloc(1, sizeof(*impl)); + if (impl == NULL) + return NULL; + + impl->rate = *SampleRate; + impl->buffer_samples = max_delay * impl->rate; + pw_log_info("%lu %d", impl->rate, impl->buffer_samples); + + impl->buffer = calloc(impl->buffer_samples, sizeof(float)); + if (impl->buffer == NULL) { + delay_cleanup(impl); + return NULL; + } + return impl; +} + +static void delay_connect_port(void * Instance, unsigned long Port, + float * DataLocation) +{ + struct delay_impl *impl = Instance; + if (Port > 2) + return; + impl->portPort = DataLocation; +} + +static void delay_run(void * Instance, unsigned long SampleCount) +{ + struct delay_impl *impl = Instance; + float *in = impl->port1, *out = impl->port0; + float delay = impl->port20; + unsigned long n; + uint32_t r, w; + + if (delay != impl->delay) { + impl->delay_samples = SPA_CLAMP(delay * impl->rate, 0, impl->buffer_samples-1); + impl->delay = delay; + } + r = impl->ptr; + w = impl->ptr + impl->delay_samples; + if (w >= impl->buffer_samples) + w -= impl->buffer_samples; + + for (n = 0; n < SampleCount; n++) { + impl->bufferw = inn; + outn = impl->bufferr; + if (++r >= impl->buffer_samples) + r = 0; + if (++w >= impl->buffer_samples) + w = 0; + } + impl->ptr = r; +} + +static struct fc_port delay_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Delay (s)", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 0.0f, .min = 0.0f, .max = 100.0f + }, +}; + +static const struct fc_descriptor delay_desc = { + .name = "delay", + + .n_ports = 3, + .ports = delay_ports, + + .instantiate = delay_instantiate, + .connect_port = delay_connect_port, + .run = delay_run, + .cleanup = delay_cleanup, +}; + static const struct fc_descriptor * builtin_descriptor(unsigned long Index) { switch(Index) { @@ -755,6 +884,8 @@ return ©_desc; case 10: return &convolve_desc; + case 11: + return &delay_desc; } return NULL; }
View file
pipewire-0.3.50.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.51.tar.gz/src/modules/module-loopback.c
Changed
@@ -43,6 +43,70 @@ #include <pipewire/extensions/profiler.h> /** \page page_module_loopback PipeWire Module: Loopback + * + * The loopback module passes the output of a capture stream unmodified to a playback stream. + * It can be used to construct a link between a source and sink but also to + * create new virtual sinks or sources or to remap channel between streams. + * + * Because both ends of the loopback are built with streams, the session manager can + * manage the configuration and connection with the sinks and sources. + * + * ## Module Options + * + * - `node.description`: a human readable name for the loopback streams + * - `capture.props = {}`: properties to be passed to the input stream + * - `playback.props = {}`: properties to be passed to the output stream + * + * ## General options + * + * Options with well-known behavior. Most options can be added to the global + * configuration or the individual streams: + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_LINK_GROUP + * - \ref PW_KEY_NODE_VIRTUAL + * + * Stream only properties: + * + * - \ref PW_KEY_MEDIA_CLASS + * - \ref PW_KEY_NODE_NAME + * + * ## Example configuration of a virtual sink + * + * This Virtual sink routes stereo input to the rear channels of a 7.1 sink. + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-loopback + * args = { + * node.description = "CM106 Stereo Pair 2" + * capture.props = { + * node.name = "CM106_stereo_pair_2" + * media.class = "Audio/Sink" + * audio.position = FL FR + * } + * playback.props = { + * node.name = "playback.CM106_stereo_pair_2" + * audio.position = RL RR + * node.target = "alsa_output.usb-0d8c_USB_Sound_Device-00.analog-surround-71" + * stream.dont-remix = true + * node.passive = true + * } + * } + * } + * + *\endcode + * + * ## See also + * + * `pw-loopback` : a tool that loads the loopback module with given parameters. */ #define NAME "loopback" @@ -55,7 +119,6 @@ { PW_KEY_MODULE_DESCRIPTION, "Create loopback streams" }, { PW_KEY_MODULE_USAGE, " remote.name=<remote> " " node.latency=<latency as fraction> " - " node.name=<name of the nodes> " " node.description=<description of the nodes> " " audio.rate=<sample rate> " " audio.channels=<number of channels> " @@ -180,6 +243,13 @@ pw_stream_flush(impl->playback, false); pw_stream_flush(impl->capture, false); break; + case PW_STREAM_STATE_UNCONNECTED: + pw_log_info("module %p: unconnected", impl); + pw_impl_module_schedule_destroy(impl->module); + break; + case PW_STREAM_STATE_ERROR: + pw_log_info("module %p: error: %s", impl, error); + break; default: break; } @@ -211,7 +281,6 @@ impl->playback = NULL; } - static void playback_param_changed(void *data, uint32_t id, const struct spa_pod *param) { struct impl *impl = data;
View file
pipewire-0.3.50.tar.gz/src/modules/module-metadata/metadata.c -> pipewire-0.3.51.tar.gz/src/modules/module-metadata/metadata.c
Changed
@@ -59,13 +59,13 @@ #define pw_metadata_resource_property(r,...) \ pw_metadata_resource(r,property,0,__VA_ARGS__) -static int metadata_property(void *object, +static int metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct resource_data *d = object; + struct resource_data *d = data; struct pw_resource *resource = d->resource; struct pw_impl_client *client = pw_resource_get_client(resource); struct impl *impl = d->impl; @@ -166,10 +166,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_resource *resource; struct resource_data *data;
View file
pipewire-0.3.50.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.51.tar.gz/src/modules/module-profiler.c
Changed
@@ -42,6 +42,28 @@ #include <pipewire/extensions/profiler.h> /** \page page_module_profiler PipeWire Module: Profiler + * + * The profiler module provides a Profiler interface for applications that + * can be used to receive profiling information. + * + * Use tools like pw-top and pw-profiler to collect profiling information + * about the pipewire graph. + * + * ## Example configuration + * + * The module has no arguments and is usually added to the config file of + * the main pipewire daemon. + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-profiler } + * + *\endcode + * + * ## See also + * + * - `pw-top`: a tool to display realtime profiler data + * - `pw-profiler`: a tool to collect and render profiler data */ #define NAME "profiler" @@ -312,10 +334,10 @@ return 0; } static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_global *global = impl->global; struct pw_resource *resource; struct resource_data *data;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-native.c
Changed
@@ -72,6 +72,54 @@ #include <spa/debug/types.h> /** \page page_module_protocol_native PipeWire Module: Protocol Native + * + * The native protocol module implements the PipeWire communication between + * a client and a server using unix local sockets. + * + * Normally this module is loaded in both client and server config files + * so that they cam communicate. + * + * ## Module Options + * + * The module has no options. + * + * ## General Options + * + * The name of the core is obtained as: + * + * - PIPEWIRE_CORE : the environment variable with the name of the core + * - \ref PW_KEY_CORE_NAME : in the context properties + * - a name based on the process id + * + * The context will also become a server if: + * + * - PIPEWIRE_DAEMON : the environment is true + * - \ref PW_KEY_CORE_DAEMON : in the context properties is true + * + * The socket will be located in the directory obtained by looking at the + * following environment variables: + * + * - PIPEWIRE_RUNTIME_DIR + * - XDG_RUNTIME_DIR + * - USERPROFILE + * + * When a client connect, the connection will be made to: + * + * - PIPEWIRE_REMOTE : the environment with the remote name + * - \ref PW_KEY_REMOTE_NAME : the property in the context. + * - The default remote named "pipewire-0" + * + * A Special remote named "internal" can be used to make a connection to the + * local context. This can be done even when the server is not a daemon. It can + * be used to treat a local context as if it was a server. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + { name = libpipewire-module-protocol-native } + * + *\endcode */ #ifndef UNIX_PATH_MAX
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-native/connection.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-native/connection.c
Changed
@@ -140,8 +140,13 @@ } buf->msg.fdsindex = fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (buf->msg.fdsindex == -1) { + pw_log_error("connection %p: can't DUP fd:%d %m", conn, fd); + return SPA_IDX_INVALID; + } buf->msg.n_fds++; - pw_log_debug("connection %p: add fd %d at index %d", conn, fd, index); + pw_log_debug("connection %p: add fd %d (new fd:%d) at index %d", + conn, fd, buf->msg.fdsindex, index); return index; } @@ -151,17 +156,23 @@ int res; if (buf->buffer_size + size > buf->buffer_maxsize) { - buf->buffer_maxsize = SPA_ROUND_UP_N(buf->buffer_size + size, MAX_BUFFER_SIZE); - buf->buffer_data = realloc(buf->buffer_data, buf->buffer_maxsize); - if (buf->buffer_data == NULL) { + void *np; + size_t ns; + + ns = SPA_ROUND_UP_N(buf->buffer_size + size, MAX_BUFFER_SIZE); + np = realloc(buf->buffer_data, ns); + if (np == NULL) { res = -errno; + free(buf->buffer_data); buf->buffer_maxsize = 0; spa_hook_list_call(&conn->listener_list, struct pw_protocol_native_connection_events, - error, 0, -res); + error, 0, res); errno = -res; return NULL; } + buf->buffer_maxsize = ns; + buf->buffer_data = np; pw_log_debug("connection %p: resize buffer to %zd %zd %zd", conn, buf->buffer_size, size, buf->buffer_maxsize); } @@ -198,6 +209,7 @@ int fd; memcpy(&fd, p, sizeof(fd)); + pw_log_debug("%p: close fd:%d", msg, fd); close(fd); } } @@ -275,8 +287,10 @@ { uint32_t i; if (fds) { - for (i = 0; i < buf->n_fds; i++) + for (i = 0; i < buf->n_fds; i++) { + pw_log_debug("%p: close fd:%d", buf, buf->fdsi); close(buf->fdsi); + } } buf->n_fds = 0; buf->buffer_size = 0; @@ -813,8 +827,10 @@ if (size > 0) memmove(buf->buffer_data, data, size); buf->buffer_size = size; - for (i = 0; i < to_close; i++) + for (i = 0; i < to_close; i++) { + pw_log_debug("%p: close fd:%d", conn, buf->fdsi); close(buf->fdsi); + } if (n_fds > 0) memmove(buf->fds, fds, n_fds * sizeof(int)); buf->n_fds = n_fds;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-native/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-native/protocol-native.c
Changed
@@ -308,9 +308,9 @@ return pw_protocol_native_end_proxy(proxy, b); } -static int core_event_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_dict props = SPA_DICT_INIT(NULL, 0); struct pw_core_info info = { .props = &props }; struct spa_pod_frame f2; @@ -335,9 +335,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, info, 0, &info); } -static int core_event_demarshal_done(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_done(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, seq; @@ -353,9 +353,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, done, 0, id, seq); } -static int core_event_demarshal_ping(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_ping(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, seq; @@ -368,9 +368,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, ping, 0, id, seq); } -static int core_event_demarshal_error(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_error(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, res; int seq; @@ -387,9 +387,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, error, 0, id, seq, res, error); } -static int core_event_demarshal_remove_id(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_remove_id(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id; @@ -400,9 +400,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, remove_id, 0, id); } -static int core_event_demarshal_bound_id(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_bound_id(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, global_id; @@ -415,9 +415,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, bound_id, 0, id, global_id); } -static int core_event_demarshal_add_mem(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_add_mem(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, type, flags; int64_t idx; @@ -436,9 +436,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, add_mem, 0, id, type, fd, flags); } -static int core_event_demarshal_remove_mem(void *object, const struct pw_protocol_native_message *msg) +static int core_event_demarshal_remove_mem(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id; @@ -450,9 +450,9 @@ return pw_proxy_notify(proxy, struct pw_core_events, remove_mem, 0, id); } -static void core_event_marshal_info(void *object, const struct pw_core_info *info) +static void core_event_marshal_info(void *data, const struct pw_core_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -474,9 +474,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_done(void *object, uint32_t id, int seq) +static void core_event_marshal_done(void *data, uint32_t id, int seq) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_DONE, NULL); @@ -488,9 +488,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_ping(void *object, uint32_t id, int seq) +static void core_event_marshal_ping(void *data, uint32_t id, int seq) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct pw_protocol_native_message *msg; @@ -503,9 +503,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_error(void *object, uint32_t id, int seq, int res, const char *error) +static void core_event_marshal_error(void *data, uint32_t id, int seq, int res, const char *error) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_ERROR, NULL); @@ -519,9 +519,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_remove_id(void *object, uint32_t id) +static void core_event_marshal_remove_id(void *data, uint32_t id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_REMOVE_ID, NULL); @@ -532,9 +532,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_bound_id(void *object, uint32_t id, uint32_t global_id) +static void core_event_marshal_bound_id(void *data, uint32_t id, uint32_t global_id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_BOUND_ID, NULL); @@ -546,9 +546,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_add_mem(void *object, uint32_t id, uint32_t type, int fd, uint32_t flags) +static void core_event_marshal_add_mem(void *data, uint32_t id, uint32_t type, int fd, uint32_t flags) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_ADD_MEM, NULL); @@ -562,9 +562,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_event_marshal_remove_mem(void *object, uint32_t id) +static void core_event_marshal_remove_mem(void *data, uint32_t id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_EVENT_REMOVE_MEM, NULL); @@ -718,10 +718,10 @@ return 0; } -static void registry_marshal_global(void *object, uint32_t id, uint32_t permissions, +static void registry_marshal_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -740,9 +740,9 @@ pw_protocol_native_end_resource(resource, b); } -static void registry_marshal_global_remove(void *object, uint32_t id) +static void registry_marshal_global_remove(void *data, uint32_t id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_EVENT_GLOBAL_REMOVE, NULL); @@ -794,9 +794,9 @@ return 0; } -static void module_marshal_info(void *object, const struct pw_module_info *info) +static void module_marshal_info(void *data, const struct pw_module_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -816,9 +816,9 @@ pw_protocol_native_end_resource(resource, b); } -static int module_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int module_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -849,9 +849,9 @@ return 0; } -static void device_marshal_info(void *object, const struct pw_device_info *info) +static void device_marshal_info(void *data, const struct pw_device_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -869,9 +869,9 @@ pw_protocol_native_end_resource(resource, b); } -static int device_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int device_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -890,10 +890,10 @@ return pw_proxy_notify(proxy, struct pw_device_events, info, 0, &info); } -static void device_marshal_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, +static void device_marshal_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_DEVICE_EVENT_PARAM, NULL); @@ -908,9 +908,9 @@ pw_protocol_native_end_resource(resource, b); } -static int device_demarshal_param(void *object, const struct pw_protocol_native_message *msg) +static int device_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1043,9 +1043,9 @@ return 0; } -static void factory_marshal_info(void *object, const struct pw_factory_info *info) +static void factory_marshal_info(void *data, const struct pw_factory_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1065,9 +1065,9 @@ pw_protocol_native_end_resource(resource, b); } -static int factory_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int factory_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1098,9 +1098,9 @@ return 0; } -static void node_marshal_info(void *object, const struct pw_node_info *info) +static void node_marshal_info(void *data, const struct pw_node_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1124,9 +1124,9 @@ pw_protocol_native_end_resource(resource, b); } -static int node_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int node_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1151,10 +1151,10 @@ return pw_proxy_notify(proxy, struct pw_node_events, info, 0, &info); } -static void node_marshal_param(void *object, int seq, uint32_t id, +static void node_marshal_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_NODE_EVENT_PARAM, NULL); @@ -1169,9 +1169,9 @@ pw_protocol_native_end_resource(resource, b); } -static int node_demarshal_param(void *object, const struct pw_protocol_native_message *msg) +static int node_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1329,9 +1329,9 @@ return 0; } -static void port_marshal_info(void *object, const struct pw_port_info *info) +static void port_marshal_info(void *data, const struct pw_port_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1350,9 +1350,9 @@ pw_protocol_native_end_resource(resource, b); } -static int port_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int port_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1372,10 +1372,10 @@ return pw_proxy_notify(proxy, struct pw_port_events, info, 0, &info); } -static void port_marshal_param(void *object, int seq, uint32_t id, +static void port_marshal_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_PORT_EVENT_PARAM, NULL); @@ -1390,9 +1390,9 @@ pw_protocol_native_end_resource(resource, b); } -static int port_demarshal_param(void *object, const struct pw_protocol_native_message *msg) +static int port_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1493,9 +1493,9 @@ return 0; } -static void client_marshal_info(void *object, const struct pw_client_info *info) +static void client_marshal_info(void *data, const struct pw_client_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1512,9 +1512,9 @@ pw_protocol_native_end_resource(resource, b); } -static int client_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int client_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1532,10 +1532,10 @@ return pw_proxy_notify(proxy, struct pw_client_events, info, 0, &info); } -static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_permissions, +static void client_marshal_permissions(void *data, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f2; uint32_t i, n = 0; @@ -1564,9 +1564,9 @@ pw_protocol_native_end_resource(resource, b); } -static int client_demarshal_permissions(void *object, const struct pw_protocol_native_message *msg) +static int client_demarshal_permissions(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct pw_permission *permissions; struct spa_pod_parser prs; struct spa_pod_frame f2; @@ -1721,9 +1721,9 @@ return 0; } -static void link_marshal_info(void *object, const struct pw_link_info *info) +static void link_marshal_info(void *data, const struct pw_link_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1747,9 +1747,9 @@ pw_protocol_native_end_resource(resource, b); } -static int link_demarshal_info(void *object, const struct pw_protocol_native_message *msg) +static int link_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1774,9 +1774,9 @@ return pw_proxy_notify(proxy, struct pw_link_events, info, 0, &info); } -static int registry_demarshal_global(void *object, const struct pw_protocol_native_message *msg) +static int registry_demarshal_global(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f2; uint32_t id, permissions, version; @@ -1798,9 +1798,9 @@ global, 0, id, permissions, type, version, &props); } -static int registry_demarshal_global_remove(void *object, const struct pw_protocol_native_message *msg) +static int registry_demarshal_global_remove(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-native/v0/interfaces.h -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-native/v0/interfaces.h
Changed
@@ -192,7 +192,7 @@ * \param types the types as a string * \param n_types the number of \a types */ - void (*update_types) (void *object, + void (*update_types) (void *data, uint32_t first_id, const char **types, uint32_t n_types); @@ -203,7 +203,7 @@ * same sequence number. * \param seq the sequence number passed to the sync method call */ - void (*done) (void *object, uint32_t seq); + void (*done) (void *data, uint32_t seq); /** * Fatal error event * @@ -216,7 +216,7 @@ * \param res error code * \param error error description */ - void (*error) (void *object, uint32_t id, int res, const char *error, ...); + void (*error) (void *data, uint32_t id, int res, const char *error, ...); /** * Remove an object ID * @@ -227,13 +227,13 @@ * safely reuse the object ID. * \param id deleted object ID */ - void (*remove_id) (void *object, uint32_t id); + void (*remove_id) (void *data, uint32_t id); /** * Notify new core info * * \param info new core info */ - void (*info) (void *object, struct pw_core_info *info); + void (*info) (void *data, struct pw_core_info *info); }; #define pw_core_resource_v0_update_types(r,...) pw_resource_notify(r,struct pw_core_v0_events,update_types,__VA_ARGS__) @@ -319,7 +319,7 @@ * \param version the version of the interface * \param props extra properties of the global */ - void (*global) (void *object, uint32_t id, uint32_t parent_id, + void (*global) (void *data, uint32_t id, uint32_t parent_id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props); /** @@ -331,7 +331,7 @@ * * \param id the id of the global that was removed */ - void (*global_remove) (void *object, uint32_t id); + void (*global_remove) (void *data, uint32_t id); }; #define pw_registry_resource_v0_global(r,...) pw_resource_notify(r,struct pw_registry_v0_events,global,__VA_ARGS__) @@ -352,7 +352,7 @@ * * \param info info about the module */ - void (*info) (void *object, struct pw_module_info *info); + void (*info) (void *data, struct pw_module_info *info); }; #define pw_module_resource_v0_info(r,...) pw_resource_notify(r,struct pw_module_v0_events,info,__VA_ARGS__) @@ -372,7 +372,7 @@ * * \param info info about the node */ - void (*info) (void *object, struct pw_node_info *info); + void (*info) (void *data, struct pw_node_info *info); /** * Notify a node param * @@ -383,7 +383,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, + void (*param) (void *data, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -428,7 +428,7 @@ * * \param info info about the port */ - void (*info) (void *object, struct pw_port_info *info); + void (*info) (void *data, struct pw_port_info *info); /** * Notify a port param * @@ -439,7 +439,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, + void (*param) (void *data, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -483,7 +483,7 @@ * * \param info info about the factory */ - void (*info) (void *object, struct pw_factory_info *info); + void (*info) (void *data, struct pw_factory_info *info); }; #define pw_factory_resource_v0_info(r,...) pw_resource_notify(r,struct pw_factory_v0_events,info,__VA_ARGS__) @@ -502,7 +502,7 @@ * * \param info info about the client */ - void (*info) (void *object, struct pw_client_info *info); + void (*info) (void *data, struct pw_client_info *info); }; #define pw_client_resource_v0_info(r,...) pw_resource_notify(r,struct pw_client_v0_events,info,__VA_ARGS__) @@ -522,7 +522,7 @@ * * \param info info about the link */ - void (*info) (void *object, struct pw_link_info *info); + void (*info) (void *data, struct pw_link_info *info); }; #define pw_link_resource_v0_info(r,...) pw_resource_notify(r,struct pw_link_v0_events,info,__VA_ARGS__)
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-native/v0/protocol-native.c
Changed
@@ -83,9 +83,9 @@ } -static void core_marshal_info(void *object, const struct pw_core_info *info) +static void core_marshal_info(void *data, const struct pw_core_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct protocol_compat_v2 *compat_v2 = client->compat_v2; struct spa_pod_builder *b; @@ -138,9 +138,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_marshal_done(void *object, uint32_t id, int seq) +static void core_marshal_done(void *data, uint32_t id, int seq) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_V0_EVENT_DONE, NULL); @@ -150,9 +150,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_marshal_error(void *object, uint32_t id, int seq, int res, const char *error) +static void core_marshal_error(void *data, uint32_t id, int seq, int res, const char *error) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_V0_EVENT_ERROR, NULL); @@ -165,9 +165,9 @@ pw_protocol_native_end_resource(resource, b); } -static void core_marshal_remove_id(void *object, uint32_t id) +static void core_marshal_remove_id(void *data, uint32_t id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_CORE_V0_EVENT_REMOVE_ID, NULL); @@ -798,10 +798,10 @@ return 0; } -static void registry_marshal_global(void *object, uint32_t id, uint32_t permissions, +static void registry_marshal_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -854,9 +854,9 @@ pw_protocol_native_end_resource(resource, b); } -static void registry_marshal_global_remove(void *object, uint32_t id) +static void registry_marshal_global_remove(void *data, uint32_t id) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_V0_EVENT_GLOBAL_REMOVE, NULL); @@ -889,9 +889,9 @@ return pw_resource_notify(resource, struct pw_registry_methods, bind, 0, id, type_name, version, new_id); } -static void module_marshal_info(void *object, const struct pw_module_info *info) +static void module_marshal_info(void *data, const struct pw_module_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, n_items; @@ -919,9 +919,9 @@ pw_protocol_native_end_resource(resource, b); } -static void factory_marshal_info(void *object, const struct pw_factory_info *info) +static void factory_marshal_info(void *data, const struct pw_factory_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -956,9 +956,9 @@ pw_protocol_native_end_resource(resource, b); } -static void node_marshal_info(void *object, const struct pw_node_info *info) +static void node_marshal_info(void *data, const struct pw_node_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, n_items; @@ -990,10 +990,10 @@ pw_protocol_native_end_resource(resource, b); } -static void node_marshal_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, +static void node_marshal_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1037,9 +1037,9 @@ 0, id, index, num, filter); } -static void port_marshal_info(void *object, const struct pw_port_info *info) +static void port_marshal_info(void *data, const struct pw_port_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, n_items; @@ -1083,10 +1083,10 @@ pw_protocol_native_end_resource(resource, b); } -static void port_marshal_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, +static void port_marshal_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct pw_impl_client *client = pw_resource_get_client(resource); struct spa_pod_builder *b; struct spa_pod_frame f; @@ -1130,9 +1130,9 @@ 0, id, index, num, filter); } -static void client_marshal_info(void *object, const struct pw_client_info *info) +static void client_marshal_info(void *data, const struct pw_client_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, n_items; @@ -1157,15 +1157,15 @@ pw_protocol_native_end_resource(resource, b); } -static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_permissions, +static void client_marshal_permissions(void *data, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions) { } -static void link_marshal_info(void *object, const struct pw_link_info *info) +static void link_marshal_info(void *data, const struct pw_link_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; struct spa_pod_frame f; uint32_t i, n_items;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse.c
Changed
@@ -39,6 +39,264 @@ #include "module-protocol-pulse/pulse-server.h" /** \page page_module_protocol_pulse PipeWire Module: Protocol Pulse + * + * This module implements a complete PulseAudio server on top of + * PipeWire. This is only the server implementation, client are expected + * to use the original PulseAudio client library. This provides a + * high level of compatibility with existing applications; in fact, + * all usual PulseAudio tools such as pavucontrol, pactl, pamon, paplay + * should continue to work as they did before. + * + * This module is usually loaded as part of a standalone pipewire process, + * called pipewire-pulse, with the pipewire-pulse.conf config file. + * + * The pulse server implements a sample cache that is otherwise not + * available in PipeWire. + * + * ## Module Options + * + * The module arguments can be the contents of the pulse.properties but + * it is recommended to make a separate pulse.properties section in the + * config file so that overrides can be done. + * + * ## pulse.properties + * + * A config section with server properties can be given. + * + *\code{.unparsed} + * pulse.properties = { + * # the addresses this server listens on + * server.address = + * "unix:native" + * #"unix:/tmp/something" # absolute paths may be used + * #"tcp:4713" # IPv4 and IPv6 on all addresses + * #"tcp::::9999" # IPv6 on all addresses + * #"tcp:127.0.0.1:8888" # IPv4 on a single address + * # + * #{ address = "tcp:4713" # address + * # max-clients = 64 # maximum number of clients + * # listen-backlog = 32 # backlog in the server listen queue + * # client.access = "restricted" # permissions for clients + * #} + * + * #pulse.min.req = 256/48000 # 5ms + * #pulse.default.req = 960/48000 # 20 milliseconds + * #pulse.min.frag = 256/48000 # 5ms + * #pulse.default.frag = 96000/48000 # 2 seconds + * #pulse.default.tlength = 96000/48000 # 2 seconds + * #pulse.min.quantum = 256/48000 # 5ms + * #pulse.default.format = F32 + * #pulse.default.position = FL FR + * # These overrides are only applied when running in a vm. + * vm.overrides = { + * pulse.min.quantum = 1024/48000 # 22ms + * } + * } + *\endcode + * + * ### Connection options + * + *\code{.unparsed} + * ... + * server.address = + * "unix:native" + * # "tcp:4713" + * + * ... + *\endcode + * + * The addresses the server listens on when starting. Uncomment the `tcp:4713` entry to also + * make the server listen on a tcp socket. This is equivalent to loading `module-native-protocol-tcp`. + * + * There is also a slightly more verbose syntax with more options: + * + *\code{.unparsed} + * .... + * server.address = + * { address = "tcp:4713" # address + * max-clients = 64 # maximum number of clients + * listen-backlog = 32 # backlog in the server listen queue + * client.access = "restricted" # permissions for clients + * } + * .... + *\endcode + * + * Use `client.access` to use one of the access methods to restrict the permissions given to + * clients connected via this address. + * + * By default network access is given the "restricted" permissions. The session manager is responsible + * for assigning permission to clients with restricted permissions (usually read-only permissions). + * + * ### Playback buffering options + * + *\code{.unparsed} + * pulse.min.req = 256/48000 # 5ms + *\endcode + * + * The minimum amount of data to request for clients. The client requested + * values will be clamped to this value. Lowering this value together with + * tlength can decrease latency if the client wants this, but increase CPU overhead. + * + *\code{.unparsed} + * pulse.default.req = 960/48000 # 20 milliseconds + *\endcode + * + * The default amount of data to request for clients. If the client does not + * specify any particular value, this default will be used. Lowering this value + * together with tlength can decrease latency but increase CPU overhead. + * + *\code{.unparsed} + * pulse.default.tlength = 96000/48000 # 2 seconds + *\endcode + * + * The target amount of data to buffer on the server side. If the client did not + * specify a value, this default will be used. Lower values can decrease the + * latency. + * + * ### Record buffering options + * + *\code{.unparsed} + * pulse.min.frag = 256/48000 # 5ms + *\endcode + * + * The minimum allowed size of the capture buffer before it is sent to a client. + * The requested value of the client will be clamped to this. Lowering this value + * can reduce latency at the expense of more CPU usage. + * + *\code{.unparsed} + * pulse.default.frag = 96000/48000 # 2 seconds + *\endcode + * + * The default size of the capture buffer before it is sent to a client. If the client + * did not specify any value, this default will be used. Lowering this value can + * reduce latency at the expense of more CPU usage. + * + * ### Scheduling options + * + *\code{.unparsed} + * pulse.min.quantum = 256/48000 # 5ms + *\endcode + * + * The minimum quantum (buffer size in samples) to use for pulseaudio clients. + * This value is calculated based on the frag and req/tlength for record and + * playback streams respectively and then clamped to this value to ensure no + * pulseaudio client asks for too small quantums. Lowering this value might + * decrease latency at the expense of more CPU usage. + * + * ### Format options + * + *\code{.unparsed} + * pulse.default.format = F32 + *\endcode + * + * Some modules will default to this format when no other format was given. This + * is equivalent to the PulseAudio `default-sample-format` option in + * `/etc/pulse/daemon.conf`. + * + *\code{.unparsed} + * pulse.default.position = FL FR + *\endcode + * + * Some modules will default to this channelmap (with its number of channels). + * This is equivalent to the PulseAudio `default-sample-channels` and + * `default-channel-map` options in `/etc/pulse/daemon.conf`. + * + * ### VM options + * + *\code{.unparsed} + * vm.overrides = { + * pulse.min.quantum = 1024/48000 # 22ms + * } + *\endcode + * + * When running in a VM, the `vm.override` section will override the properties + * in pulse.properties with the given values. This might be interesting because + * VMs usually can't support the low latency settings that are possible on real + * hardware. + * + * ## Application settings (Rules) + * + * The pulse protocol module supports generic config rules. It provides a `quirks` + * and an `update-props` action. + * + * Streams created by module-protocol-pulse will use the stream.properties + * section and stream.rules sections as usual. + * + *\code{.unparsed} + * pulse.rules = + * { + * # skype does not want to use devices that don't have an S16 sample format. + * matches = + * { application.process.binary = "teams" } + * { application.process.binary = "teams-insiders" } + * { application.process.binary = "skypeforlinux" } + * + * actions = { quirks = force-s16-info } + * } + * { + * # speech dispatcher asks for too small latency and then underruns. + * matches = { application.name = "~speech-dispatcher*" } + * actions = { + * update-props = { + * pulse.min.req = 1024/48000 # 21ms + * pulse.min.quantum = 1024/48000 # 21ms + * } + * } + * } + * + *\endcode + * + * ### Quirks + * + * The quirks action takes an array of quirks to apply for the client. + * + * * `force-s16-info` makes the sink and source introspect code pretend that the sample format + * is S16 (16 bits) samples. Some application refuse the sink/source if this + * is not the case. + * * `remove-capture-dont-move` Removes the DONT_MOVE flag on capture streams. Some applications + * set this flag so that the stream can't be moved anymore with tools such as + * pavucontrol. + * + * ### update-props + * + * Takes an object with the properties to update on the client. Common actions are to + * tweak the quantum values. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-protocol-pulse + * args = { } + * } + * + * + * pulse.properties = { + * server.address = "unix:native" + * } + * + * pulse.rules = + * { + * # skype does not want to use devices that don't have an S16 sample format. + * matches = + * { application.process.binary = "teams" } + * { application.process.binary = "teams-insiders" } + * { application.process.binary = "skypeforlinux" } + * + * actions = { quirks = force-s16-info } + * } + * { + * # speech dispatcher asks for too small latency and then underruns. + * matches = { application.name = "~speech-dispatcher*" } + * actions = { + * update-props = { + * pulse.min.req = 1024/48000 # 21ms + * pulse.min.quantum = 1024/48000 # 21ms + * } + * } + * } + * + *\endcode */ #define NAME "protocol-pulse"
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
@@ -215,9 +215,9 @@ }; /* client */ -static void client_event_info(void *object, const struct pw_client_info *info) +static void client_event_info(void *data, const struct pw_client_info *info) { - struct object *o = object; + struct object *o = data; int changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); @@ -254,9 +254,9 @@ }; /* module */ -static void module_event_info(void *object, const struct pw_module_info *info) +static void module_event_info(void *data, const struct pw_module_info *info) { - struct object *o = object; + struct object *o = data; int changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); @@ -293,9 +293,9 @@ }; /* device */ -static void device_event_info(void *object, const struct pw_device_info *info) +static void device_event_info(void *data, const struct pw_device_info *info) { - struct object *o = object; + struct object *o = data; uint32_t i, changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); @@ -364,11 +364,11 @@ return NULL; } -static void device_event_param(void *object, int seq, +static void device_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object, *dev; + struct object *o = data, *dev; struct manager *m = o->manager; struct pw_manager_param *p; @@ -413,9 +413,9 @@ }; /* node */ -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *data, const struct pw_node_info *info) { - struct object *o = object; + struct object *o = data; uint32_t i, changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); @@ -459,11 +459,11 @@ } } -static void node_event_param(void *object, int seq, +static void node_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object; + struct object *o = data; add_param(&o->pending_list, seq, o->param_seq, id, param); } @@ -495,13 +495,13 @@ }; /* metadata */ -static int metadata_property(void *object, +static int metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct object *o = object; + struct object *o = data; struct manager *m = o->manager; manager_emit_metadata(m, &o->this, subject, key, type, value); return 0; @@ -639,9 +639,9 @@ core_sync(m); } -static void registry_event_global_remove(void *object, uint32_t id) +static void registry_event_global_remove(void *data, uint32_t id) { - struct manager *m = object; + struct manager *m = data; struct object *o; if ((o = find_object_by_id(m, id)) == NULL)
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/message.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/message.c
Changed
@@ -395,8 +395,12 @@ alloc = SPA_ROUND_UP_N(SPA_MAX(m->allocated + size, 4096u), 4096u); diff = alloc - m->allocated; - if ((data = realloc(m->data, alloc)) == NULL) + if ((data = realloc(m->data, alloc)) == NULL) { + free(m->data); + m->stat->allocated -= m->allocated; + m->allocated = 0; return -errno; + } m->stat->allocated += diff; m->stat->accumulated += diff; m->data = data;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/module.h -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/module.h
Changed
@@ -47,6 +47,7 @@ #define DEFINE_MODULE_INFO(name) \ __attribute__((used)) \ + __attribute__((retain)) \ __attribute__((section("pw_mod_pulse_modules"))) \ __attribute__((aligned(__alignof__(struct module_info)))) \ const struct module_info name
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c
Changed
@@ -298,8 +298,6 @@ goto out; } - if (pw_properties_get(capture_props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(capture_props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(capture_props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(capture_props, PW_KEY_NODE_VIRTUAL, "true"); pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink");
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c
Changed
@@ -357,8 +357,6 @@ goto out; } - if (pw_properties_get(playback_props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(playback_props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(playback_props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_VIRTUAL, "true"); pw_properties_set(playback_props, PW_KEY_MEDIA_CLASS, "Audio/Source");
View file
pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c
Added
@@ -0,0 +1,213 @@ +/* PipeWire + * + * Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> + * Copyright © 2021 Sanchayan Maity <sanchayan@asymptotic.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <spa/utils/hook.h> +#include <pipewire/pipewire.h> +#include <pipewire/private.h> + +#include "../defs.h" +#include "../module.h" + +#define NAME "roc-source" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +struct module_roc_sink_input_data { + struct module *module; + + struct spa_hook mod_listener; + struct pw_impl_module *mod; + + struct pw_properties *source_props; + struct pw_properties *roc_props; +}; + +static void module_destroy(void *data) +{ + struct module_roc_sink_input_data *d = data; + spa_hook_remove(&d->mod_listener); + d->mod = NULL; + module_schedule_unload(d->module); +} + +static const struct pw_impl_module_events module_events = { + PW_VERSION_IMPL_MODULE_EVENTS, + .destroy = module_destroy +}; + +static int module_roc_sink_input_load(struct client *client, struct module *module) +{ + struct module_roc_sink_input_data *data = module->user_data; + FILE *f; + char *args; + size_t size; + + pw_properties_setf(data->source_props, "pulse.module.id", + "%u", module->index); + + if ((f = open_memstream(&args, &size)) == NULL) + return -errno; + + fprintf(f, "{"); + pw_properties_serialize_dict(f, &data->roc_props->dict, 0); + fprintf(f, " source.props = {"); + pw_properties_serialize_dict(f, &data->source_props->dict, 0); + fprintf(f, " } }"); + fclose(f); + + data->mod = pw_context_load_module(module->impl->context, + "libpipewire-module-roc-source", + args, NULL); + + free(args); + + if (data->mod == NULL) + return -errno; + + pw_impl_module_add_listener(data->mod, + &data->mod_listener, + &module_events, data); + + return 0; +} + +static int module_roc_sink_input_unload(struct module *module) +{ + struct module_roc_sink_input_data *d = module->user_data; + + if (d->mod) { + spa_hook_remove(&d->mod_listener); + pw_impl_module_destroy(d->mod); + d->mod = NULL; + } + + pw_properties_free(d->roc_props); + pw_properties_free(d->source_props); + + return 0; +} + +static const struct spa_dict_item module_roc_sink_input_info = { + { PW_KEY_MODULE_AUTHOR, "Sanchayan Maity <sanchayan@asymptotic.io>" }, + { PW_KEY_MODULE_DESCRIPTION, "roc sink-input" }, + { PW_KEY_MODULE_USAGE, "sink=<name for the sink> " + "sink_input_properties=<properties for the sink_input> " + "resampler_profile=<empty>|disable|high|medium|low " + "fec_code=<empty>|disable|rs8m|ldpc " + "sess_latency_msec=<target network latency in milliseconds> " + "local_ip=<local receiver ip> " + "local_source_port=<local receiver port for source packets> " + "local_repair_port=<local receiver port for repair packets> " }, + { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, +}; + +struct module *create_module_roc_sink_input(struct impl *impl, const char *argument) +{ + struct module *module; + struct module_roc_sink_input_data *d; + struct pw_properties *props = NULL, *source_props = NULL, *roc_props = NULL; + const char *str; + int res; + + PW_LOG_TOPIC_INIT(mod_topic); + + props = pw_properties_new_dict(&SPA_DICT_INIT_ARRAY(module_roc_sink_input_info)); + source_props = pw_properties_new(NULL, NULL); + roc_props = pw_properties_new(NULL, NULL); + if (!props || !source_props || !roc_props) { + res = -errno; + goto out; + } + + if (argument != NULL) + module_args_add_props(props, argument); + + if ((str = pw_properties_get(props, "sink")) != NULL) { + pw_properties_set(source_props, PW_KEY_TARGET_OBJECT, str); + pw_properties_set(props, "sink", NULL); + } + if ((str = pw_properties_get(props, "sink_input_properties")) != NULL) { + module_args_add_props(source_props, str); + pw_properties_set(props, "sink_input_properties", NULL); + } + + if ((str = pw_properties_get(props, "local_ip")) != NULL) { + pw_properties_set(roc_props, "local.ip", str); + pw_properties_set(props, "local_ip", NULL); + } + + if ((str = pw_properties_get(props, "local_source_port")) != NULL) { + pw_properties_set(roc_props, "local.source.port", str); + pw_properties_set(props, "local_source_port", NULL); + } + + if ((str = pw_properties_get(props, "local_repair_port")) != NULL) { + pw_properties_set(roc_props, "local.repair.port", str); + pw_properties_set(props, "local_repair_port", NULL); + } + + if ((str = pw_properties_get(props, "sess_latency_msec")) != NULL) { + pw_properties_set(roc_props, "sess.latency.msec", str); + pw_properties_set(props, "sess_latency_msec", NULL); + } + + if ((str = pw_properties_get(props, "resampler_profile")) != NULL) { + pw_properties_set(roc_props, "resampler.profile", str); + pw_properties_set(props, "resampler_profile", NULL); + } + + if ((str = pw_properties_get(props, "fec_code")) != NULL) { + pw_properties_set(roc_props, "fec.code", str); + pw_properties_set(props, "fec_code", NULL); + } + + module = module_new(impl, sizeof(*d)); + if (module == NULL) { + res = -errno; + goto out; + } + + module->props = props; + d = module->user_data; + d->module = module; + d->source_props = source_props; + d->roc_props = roc_props; + + return module; +out: + pw_properties_free(props); + pw_properties_free(source_props); + pw_properties_free(roc_props); + errno = -res; + return NULL; +} + +DEFINE_MODULE_INFO(module_roc_sink_input) = { + .name = "module-roc-sink-input", + .create = create_module_roc_sink_input, + .load = module_roc_sink_input_load, + .unload = module_roc_sink_input_unload, +};
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c
Changed
@@ -35,10 +35,6 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define ROC_DEFAULT_IP "0.0.0.0" -#define ROC_DEFAULT_SOURCE_PORT "10001" -#define ROC_DEFAULT_REPAIR_PORT "10002" - struct module_roc_sink_data { struct module *module; @@ -119,6 +115,7 @@ { PW_KEY_MODULE_DESCRIPTION, "roc sink" }, { PW_KEY_MODULE_USAGE, "sink_name=<name for the sink> " "sink_properties=<properties for the sink> " + "fec_code=<empty>|disable|rs8m|ldpc " "local_ip=<local sender ip> " "remote_ip=<remote receiver ip> " "remote_source_port=<remote receiver port for source packets> " @@ -172,22 +169,20 @@ if ((str = pw_properties_get(props, "local_ip")) != NULL) { pw_properties_set(roc_props, "local.ip", str); pw_properties_set(props, "local_ip", NULL); - } else { - pw_properties_set(roc_props, "local.ip", ROC_DEFAULT_IP); } if ((str = pw_properties_get(props, "remote_source_port")) != NULL) { pw_properties_set(roc_props, "remote.source.port", str); pw_properties_set(props, "remote_source_port", NULL); - } else { - pw_properties_set(roc_props, "remote.source.port", ROC_DEFAULT_SOURCE_PORT); } if ((str = pw_properties_get(props, "remote_repair_port")) != NULL) { pw_properties_set(roc_props, "remote.repair.port", str); pw_properties_set(props, "remote_repair_port", NULL); - } else { - pw_properties_set(roc_props, "remote.repair.port", ROC_DEFAULT_REPAIR_PORT); + } + if ((str = pw_properties_get(props, "fec_code")) != NULL) { + pw_properties_set(roc_props, "fec.code", str); + pw_properties_set(props, "fec_code", NULL); } module = module_new(impl, sizeof(*d));
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c
Changed
@@ -35,10 +35,6 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define ROC_DEFAULT_IP "0.0.0.0" -#define ROC_DEFAULT_SOURCE_PORT "10001" -#define ROC_DEFAULT_REPAIR_PORT "10002" - struct module_roc_source_data { struct module *module; @@ -120,6 +116,7 @@ { PW_KEY_MODULE_USAGE, "source_name=<name for the source> " "source_properties=<properties for the source> " "resampler_profile=<empty>|disable|high|medium|low " + "fec_code=<empty>|disable|rs8m|ldpc " "sess_latency_msec=<target network latency in milliseconds> " "local_ip=<local receiver ip> " "local_source_port=<local receiver port for source packets> " @@ -165,36 +162,31 @@ if ((str = pw_properties_get(props, "local_ip")) != NULL) { pw_properties_set(roc_props, "local.ip", str); pw_properties_set(props, "local_ip", NULL); - } else { - pw_properties_set(roc_props, "local.ip", ROC_DEFAULT_IP); } if ((str = pw_properties_get(props, "local_source_port")) != NULL) { pw_properties_set(roc_props, "local.source.port", str); pw_properties_set(props, "local_source_port", NULL); - } else { - pw_properties_set(roc_props, "local.source.port", ROC_DEFAULT_SOURCE_PORT); } if ((str = pw_properties_get(props, "local_repair_port")) != NULL) { pw_properties_set(roc_props, "local.repair.port", str); pw_properties_set(props, "local_repair_port", NULL); - } else { - pw_properties_set(roc_props, "local.repair.port", ROC_DEFAULT_REPAIR_PORT); } if ((str = pw_properties_get(props, "sess_latency_msec")) != NULL) { pw_properties_set(roc_props, "sess.latency.msec", str); pw_properties_set(props, "sess_latency_msec", NULL); - } else { - pw_properties_set(roc_props, "sess.latency.msec", ROC_DEFAULT_REPAIR_PORT); } if ((str = pw_properties_get(props, "resampler_profile")) != NULL) { pw_properties_set(roc_props, "resampler.profile", str); pw_properties_set(props, "resampler_profile", NULL); - } else { - pw_properties_set(roc_props, "resampler.profile", ROC_DEFAULT_REPAIR_PORT); + } + + if ((str = pw_properties_get(props, "fec_code")) != NULL) { + pw_properties_set(roc_props, "fec.code", str); + pw_properties_set(props, "fec_code", NULL); } module = module_new(impl, sizeof(*d));
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1113,9 +1113,6 @@ { struct stream *stream = data; switch (id) { - case SPA_IO_RateMatch: - stream->rate_match = area; - break; case SPA_IO_Position: stream->position = area; break; @@ -4443,7 +4440,7 @@ { uint32_t channel, rate; struct stream *stream; - bool match; + float corr; if (message_get(m, TAG_U32, &channel, @@ -4458,15 +4455,10 @@ if (stream == NULL || stream->type == STREAM_TYPE_UPLOAD) return -ENOENT; - if (stream->rate_match == NULL) - return -ENOTSUP; - - match = rate != stream->ss.rate; stream->rate = rate; - stream->rate_match->rate = match ? - (double)rate/(double)stream->ss.rate : 1.0; - SPA_FLAG_UPDATE(stream->rate_match->flags, - SPA_IO_RATE_MATCH_FLAG_ACTIVE, match); + + corr = (double)rate/(double)stream->ss.rate; + pw_stream_set_control(stream->stream, SPA_PROP_rate, 1, &corr, NULL); return reply_simple_ack(client, tag); }
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
@@ -402,6 +402,7 @@ client->props = pw_properties_new( PW_KEY_CLIENT_API, "pipewire-pulse", + "config.ext", pw_properties_get(impl->props, "config.ext"), NULL); if (client->props == NULL) goto error;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-pulse/stream.h -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-pulse/stream.h
Changed
@@ -70,7 +70,6 @@ struct pw_stream *stream; struct spa_hook stream_listener; - struct spa_io_rate_match *rate_match; struct spa_io_position *position; struct spa_ringbuffer ring; void *buffer;
View file
pipewire-0.3.50.tar.gz/src/modules/module-protocol-simple.c -> pipewire-0.3.51.tar.gz/src/modules/module-protocol-simple.c
Changed
@@ -50,6 +50,77 @@ #include <pipewire/impl.h> /** \page page_module_protocol_simple PipeWire Module: Protocol Simple + * + * The simple protocol provides a bidirectional audio stream on a network + * socket. + * + * It is meant to be used with the `simple protocol player` app, available on + * Android to play and record a stream. + * + * Each client that connects will create a capture and/or playback stream, + * depending on the configuration options. + * + * ## Module Options + * + * - `capture`: boolean if capture is enabled. This will create a capture stream + * for each connected client. + * - `playback`: boolean if playback is enabled. This will create a playback + * stream for each connected client. + * - `capture.node`: an optional node id or name to use for capture. + * - `playback.node`: an optional node id or name to use for playback. + * - `server.address = `: an array of server addresses to listen on as + * tcp:<ip>:<port>. + * + * ## General options + * + * Options with well-known behavior. + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_FORMAT + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_RATE + * - \ref PW_KEY_STREAM_CAPTURE_SINK + * + * By default the server will work with stereo 16 bits samples at 44.1KHz. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-protocol-simple + * args = { + * # Provide capture stream, clients can capture data from PipeWire + * capture = true + * # + * # Provide playback stream, client can send data to PipeWire for playback + * playback = true + * # + * # The node name or id to use for capture. + * #capture.node = null + * # + * # To make the capture stream capture the monitor ports + * #stream.capture.sink = false + * # + * # The node name or id to use for playback. + * #playback.node = null + * # + * #audio.rate = 44100 + * #audio.format = S16 + * #audio.channels = 2 + * #audio.position = FL FR + * # + * # The addresses this server listens on for new + * # client connections + * server.address = + * "tcp:4711" + * + * } + * } + * + *\endcode */ #define NAME "protocol-simple" @@ -70,6 +141,7 @@ #define MODULE_USAGE " capture=<bool> " \ " playback=<bool> " \ + " remote.name=<remote> " \ " node.latency=<num/denom, default:"DEFAULT_LATENCY"> " \ " node.rate=<1/rate, default:1/"DEFAULT_RATE"> " \ " capture.node=<source-target> stream.capture.sink=true " \ @@ -378,7 +450,6 @@ if (impl->capture) { props = pw_properties_new( - PW_KEY_NODE_WANT_DRIVER, "true", PW_KEY_NODE_LATENCY, latency, PW_KEY_NODE_RATE, pw_properties_get(impl->props, PW_KEY_NODE_RATE), PW_KEY_NODE_TARGET, pw_properties_get(impl->props, "capture.node"), @@ -402,7 +473,6 @@ } if (impl->playback) { props = pw_properties_new( - PW_KEY_NODE_WANT_DRIVER, "true", PW_KEY_NODE_LATENCY, latency, PW_KEY_NODE_RATE, pw_properties_get(impl->props, PW_KEY_NODE_RATE), PW_KEY_NODE_TARGET, pw_properties_get(impl->props, "playback.node"), @@ -509,6 +579,8 @@ props = pw_properties_new( PW_KEY_CLIENT_API, "protocol-simple", + PW_KEY_REMOTE_NAME, + pw_properties_get(impl->props, PW_KEY_REMOTE_NAME), NULL); if (props == NULL) goto error;
View file
pipewire-0.3.50.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.51.tar.gz/src/modules/module-pulse-tunnel.c
Changed
@@ -55,6 +55,62 @@ #include "module-protocol-pulse/format.h" /** \page page_module_pulse_tunnel PipeWire Module: Pulse Tunnel + * + * The pulse-tunnel module provides a source or sink that tunnels all audio to + * a remote PulseAudio connection. + * + * It is usually used with the PulseAudio or module-protocol-pulse on the remote + * end to accept the connection. + * + * This module is usually used together with module-zeroconf-discover that will + * automatically load the tunnel with the right parameters based on zeroconf + * information. + * + * ## Module Options + * + * - `tunnel.mode`: the desired tunnel to create, must be `capture` or `playback`. + * (Default `playback`) + * - `pulse.server.address`: the address of the PulseAudio server to tunnel to. + * - `pulse.latency`: the latency to end-to-end latency in milliseconds to + * maintain (Default 200ms). + * - `stream.props`: Extra properties for the local stream. + * + * ## General options + * + * Options with well-known behavior. + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_VIRTUAL + * - \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 sink + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-pulse-tunnel + * args = { + * tunnel.mode = playback + * # Set the remote address to tunnel to + * pulse.server.address = "tcp:192.168.1.126" + * #audio.rate=<sample rate> + * #audio.channels=<number of channels> + * #audio.position=<channel map> + * #node.target=<remote target node> + * stream.props = { + * # extra sink properties + * } + * } + * } + * + *\endcode */ #define NAME "pulse-tunnel" @@ -120,9 +176,12 @@ pa_context *pa_context; pa_stream *pa_stream; + uint32_t target_latency; + uint32_t current_latency; uint32_t target_buffer; struct spa_dll dll; float max_error; + unsigned resync:1; unsigned int do_disconnect:1; }; @@ -133,7 +192,7 @@ pa_threaded_mainloop_lock(impl->pa_mainloop); - pw_log_info("corking: %d", cork); + pw_log_debug("corking: %d", cork); if (cork && impl->mode == MODE_PLAYBACK) { /* When the sink becomes suspended (which is the only case where we * cork the stream), we don't want to keep any old data around, because @@ -141,8 +200,13 @@ * played at the time when the sink starts running again. */ if ((operation = pa_stream_flush(impl->pa_stream, NULL, NULL))) pa_operation_unref(operation); + spa_ringbuffer_init(&impl->ring); + memset(impl->buffer, 0, RINGBUFFER_SIZE); } + if (!cork) + impl->resync = true; + if ((operation = pa_stream_cork(impl->pa_stream, cork, NULL, NULL))) pa_operation_unref(operation); @@ -197,25 +261,23 @@ if (filled < 0) { pw_log_warn("%p: underrun write:%u filled:%d", impl, write_index, filled); + } else if ((uint32_t)filled + size > RINGBUFFER_SIZE) { + pw_log_warn("%p: overrun write:%u filled:%d + size:%u > max:%u", + impl, write_index, filled, + size, RINGBUFFER_SIZE); + impl->resync = true; } else { float error, corr; - if ((uint32_t)filled + size > impl->target_buffer * 2) { - pw_log_warn("%p: overrun write:%u filled:%d size:%u max:%u", - impl, write_index, filled, - size, RINGBUFFER_SIZE); - write_index -= impl->target_buffer; - filled -= impl->target_buffer; - } else { - error = (float)filled - (float)impl->target_buffer; - error = SPA_CLAMP(error, -impl->max_error, impl->max_error); + error = (float)(impl->current_latency) - (float)impl->target_latency; + error = SPA_CLAMP(error, -impl->max_error, impl->max_error); - pw_log_debug("filled:%u target:%u error:%f corr:%f", filled, - impl->target_buffer, error, corr); - corr = spa_dll_update(&impl->dll, error); - pw_stream_set_control(impl->stream, - SPA_PROP_rate, 1, &corr, NULL); - } + corr = spa_dll_update(&impl->dll, error); + pw_log_debug("filled:%u target:%u error:%f corr:%f %u %u", filled, + impl->target_buffer, error, corr, + impl->current_latency, impl->target_latency); + pw_stream_set_control(impl->stream, + SPA_PROP_rate, 1, &corr, NULL); } spa_ringbuffer_write_data(&impl->ring, impl->buffer, RINGBUFFER_SIZE, @@ -234,7 +296,7 @@ struct pw_buffer *buf; struct spa_data *bd; int32_t avail; - uint32_t size, req, read_index; + uint32_t size, req, index; if ((buf = pw_stream_dequeue_buffer(impl->stream)) == NULL) { pw_log_debug("out of buffers: %m"); @@ -246,42 +308,41 @@ if ((req = buf->requested * impl->frame_size) == 0) req = 4096 * impl->frame_size; - avail = spa_ringbuffer_get_read_index(&impl->ring, &read_index); - if (avail <= 0) { - size = SPA_MIN(bd->maxsize, req); + size = SPA_MIN(bd->maxsize, req); + + avail = spa_ringbuffer_get_read_index(&impl->ring, &index); + if (avail < (int32_t)size) { memset(bd->data, 0, size); } else { float error, corr; - if (avail > (int32_t)impl->target_buffer * 2) { - avail -= impl->target_buffer; - read_index += impl->target_buffer; + if (avail > (int32_t)RINGBUFFER_SIZE) { + avail = impl->target_buffer; + index += avail - impl->target_buffer; } else { - error = (float)impl->target_buffer - (float)avail; + error = (float)(impl->current_latency) - (float)impl->target_latency; error = SPA_CLAMP(error, -impl->max_error, impl->max_error); corr = spa_dll_update(&impl->dll, error); - pw_log_debug("avail:%u target:%u error:%f corr:%f", avail, - impl->target_buffer, error, corr); + pw_log_debug("avail:%u target:%u error:%f corr:%f %u %u", avail, + impl->target_buffer, error, corr, + impl->current_latency, impl->target_latency); pw_stream_set_control(impl->stream, SPA_PROP_rate, 1, &corr, NULL); } - size = SPA_MIN(bd->maxsize, (uint32_t)avail); - size = SPA_MIN(size, req); - spa_ringbuffer_read_data(&impl->ring, impl->buffer, RINGBUFFER_SIZE, - read_index & RINGBUFFER_MASK, + index & RINGBUFFER_MASK, bd->data, size); - read_index += size; - spa_ringbuffer_read_update(&impl->ring, read_index); - + index += size; + spa_ringbuffer_read_update(&impl->ring, index); } bd->chunk->offset = 0; bd->chunk->size = size; + bd->chunk->stride = impl->frame_size; pw_stream_queue_buffer(impl->stream, buf); } @@ -385,16 +446,18 @@ { struct impl *impl = userdata; int32_t filled; - uint32_t write_index; + uint32_t index; + pa_usec_t latency; + int negative; - filled = spa_ringbuffer_get_write_index(&impl->ring, &write_index); + filled = spa_ringbuffer_get_write_index(&impl->ring, &index); if (filled < 0) { pw_log_warn("%p: underrun write:%u filled:%d", - impl, write_index, filled); + impl, index, filled); } else if (filled + length > RINGBUFFER_SIZE) { pw_log_warn("%p: overrun write:%u filled:%d", - impl, write_index, filled); + impl, index, filled); } while (length > 0) { const void *p; @@ -415,26 +478,45 @@ spa_ringbuffer_write_data(&impl->ring, impl->buffer, RINGBUFFER_SIZE, - write_index & RINGBUFFER_MASK, + index & RINGBUFFER_MASK, p ? p : impl->empty, to_write); - write_index += to_write; + index += to_write; p = p ? SPA_PTROFF(p, to_write, void) : NULL; nbytes -= to_write; length -= to_write; + filled += to_write; } pa_stream_drop(impl->pa_stream); } - spa_ringbuffer_write_update(&impl->ring, write_index); + + pa_stream_get_latency(impl->pa_stream, &latency, &negative); + impl->current_latency = latency * impl->info.rate / SPA_USEC_PER_SEC; + impl->current_latency += filled / impl->frame_size; + + spa_ringbuffer_write_update(&impl->ring, index); } static void stream_write_request_cb(pa_stream *s, size_t length, void *userdata) { struct impl *impl = userdata; int32_t avail; - uint32_t read_index, len, offset, l0, l1; + uint32_t index, len, offset, l0, l1; + pa_usec_t latency; + int negative; - avail = spa_ringbuffer_get_read_index(&impl->ring, &read_index); + if (impl->resync) { + impl->resync = false; + avail = length + impl->target_buffer; + spa_ringbuffer_get_write_index(&impl->ring, &index); + index -= avail; + } else { + avail = spa_ringbuffer_get_read_index(&impl->ring, &index); + } + + pa_stream_get_latency(impl->pa_stream, &latency, &negative); + impl->current_latency = latency * impl->info.rate / SPA_USEC_PER_SEC; + impl->current_latency += avail / impl->frame_size; while (avail < (int32_t)length) { /* send silence for the data we don't have */ @@ -447,7 +529,7 @@ if (length > 0 && avail >= (int32_t)length) { /* always send as much as is requested */ len = length; - offset = read_index & RINGBUFFER_MASK; + offset = index & RINGBUFFER_MASK; l0 = SPA_MIN(len, RINGBUFFER_SIZE - offset); l1 = len - l0; @@ -460,10 +542,22 @@ impl->buffer, l1, NULL, 0, PA_SEEK_RELATIVE); } - read_index += len; - spa_ringbuffer_read_update(&impl->ring, read_index); + index += len; + spa_ringbuffer_read_update(&impl->ring, index); } } +static void stream_underflow_cb(pa_stream *s, void *userdata) +{ + struct impl *impl = userdata; + pw_log_warn("underflow"); + impl->resync = true; +} +static void stream_overflow_cb(pa_stream *s, void *userdata) +{ + struct impl *impl = userdata; + pw_log_warn("overflow"); + impl->resync = true; +} static void stream_latency_update_cb(pa_stream *s, void *userdata) { @@ -553,6 +647,8 @@ pa_stream_set_state_callback(impl->pa_stream, stream_state_cb, impl); pa_stream_set_read_callback(impl->pa_stream, stream_read_request_cb, impl); pa_stream_set_write_callback(impl->pa_stream, stream_write_request_cb, impl); + pa_stream_set_underflow_callback(impl->pa_stream, stream_underflow_cb, impl); + pa_stream_set_overflow_callback(impl->pa_stream, stream_overflow_cb, impl); pa_stream_set_latency_update_callback(impl->pa_stream, stream_latency_update_cb, impl); remote_node_target = pw_properties_get(impl->props, PW_KEY_NODE_TARGET); @@ -564,6 +660,8 @@ latency_bytes = pa_usec_to_bytes(impl->latency_msec * SPA_USEC_PER_MSEC, &ss); + impl->target_latency = latency_bytes / impl->frame_size; + /* half in our buffer, half in the network + remote */ impl->target_buffer = latency_bytes / 2; @@ -847,8 +945,6 @@ impl->latency_msec = pw_properties_get_uint32(props, "pulse.latency", DEFAULT_LATENCY_MSEC); - if (pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); 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_NODE_NETWORK) == NULL) @@ -869,7 +965,6 @@ copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); - copy_props(impl, props, PW_KEY_NODE_WANT_DRIVER); copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS); @@ -884,7 +979,7 @@ goto error; } spa_dll_set_bw(&impl->dll, SPA_DLL_BW_MIN, 128, impl->info.rate); - impl->max_error = 256.0f * impl->frame_size; + impl->max_error = 256.0f; impl->core = pw_context_get_object(impl->context, PW_TYPE_INTERFACE_Core); if (impl->core == NULL) {
View file
pipewire-0.3.50.tar.gz/src/modules/module-raop-discover.c -> pipewire-0.3.51.tar.gz/src/modules/module-raop-discover.c
Changed
@@ -48,6 +48,31 @@ #include "module-zeroconf-discover/avahi-poll.h" /** \page page_module_raop_discover PipeWire Module: RAOP Discover + * + * Automatically creates RAOP (Airplay) sink devices based on zeroconf + * information. + * + * This module will load module-raop-sink for each discovered sink + * with the right parameters. + * + * ## Module Options + * + * This module has no options. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-raop-discover + * args = { } + * } + * } + * + *\endcode + * + * ## See also + * + * \ref page_module_raop_sink */ #define NAME "raop-discover"
View file
pipewire-0.3.50.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.51.tar.gz/src/modules/module-raop-sink.c
Changed
@@ -63,6 +63,16 @@ #include "module-raop/rtsp-client.h" /** \page page_module_raop_sink PipeWire Module: AirPlay Sink + * + * Creates a new Sink to stream to an Airplay device. + * + * ## Module Options + * + * ## Example configuration + * + * ## See also + * + * \ref page_module_raop_discover */ #define NAME "raop-sink" @@ -1579,8 +1589,6 @@ impl->context = context; impl->loop = pw_context_get_main_loop(context); - if (pw_properties_get(props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); @@ -1605,7 +1613,6 @@ copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); - copy_props(impl, props, PW_KEY_NODE_WANT_DRIVER); copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS);
View file
pipewire-0.3.50.tar.gz/src/modules/module-roc-sink.c -> pipewire-0.3.51.tar.gz/src/modules/module-roc-sink.c
Changed
@@ -56,6 +56,7 @@ * - `remote.ip = <str>`: remote receiver ip * - `remote.source.port = <str>`: remote receiver TCP/UDP port for source packets * - `remote.repair.port = <str>`: remote receiver TCP/UDP port for receiver packets + * - `fec.code = <str>`: Possible values: `disable`, `rs8m`, `ldpc` * * ## General options * @@ -71,6 +72,7 @@ * { name = libpipewire-module-roc-sink * args = { * local.ip = 0.0.0.0 + * fec.code = disable * remote.ip = 192.168.0.244 * remote.source.port = 10001 * remote.repair.port = 10002 @@ -116,12 +118,28 @@ roc_context *context; roc_sender *sender; + roc_fec_code fec_code; char *local_ip; char *remote_ip; int remote_source_port; int remote_repair_port; }; +static int roc_parse_fec_code(roc_fec_code *out, const char *str) +{ + if (!str || !*str) + *out = ROC_FEC_DEFAULT; + else if (spa_streq(str, "disable")) + *out = ROC_FEC_DISABLE; + else if (spa_streq(str, "rs8m")) + *out = ROC_FEC_RS8M; + else if (spa_streq(str, "ldpc")) + *out = ROC_FEC_LDPC_STAIRCASE; + else + return -EINVAL; + return 0; +} + static void stream_destroy(void *d) { struct module_roc_sink_data *data = d; @@ -260,6 +278,7 @@ uint32_t n_params; uint8_t buffer1024; int res; + roc_protocol audio_proto, repair_proto; if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { pw_log_error("Invalid local IP address"); @@ -291,6 +310,7 @@ sender_config.frame_sample_rate = 44100; sender_config.frame_channels = ROC_CHANNEL_SET_STEREO; sender_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; + sender_config.fec_code = data->fec_code; /* Fixed to be the same as ROC sender config above */ info.rate = 44100; @@ -299,6 +319,8 @@ info.position0 = SPA_AUDIO_CHANNEL_FL; info.position1 = SPA_AUDIO_CHANNEL_FR; + pw_properties_setf(data->capture_props, PW_KEY_NODE_RATE, "1/%d", info.rate); + data->sender = roc_sender_open(data->context, &sender_config); if (!data->sender) { pw_log_error("Failed to create roc sender"); @@ -310,16 +332,34 @@ return -EINVAL; } - if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_SOURCE, ROC_PROTO_RTP_RS8M_SOURCE, + switch (data->fec_code) { + case ROC_FEC_DEFAULT: + case ROC_FEC_RS8M: + audio_proto = ROC_PROTO_RTP_RS8M_SOURCE; + repair_proto = ROC_PROTO_RS8M_REPAIR; + break; + case ROC_FEC_LDPC_STAIRCASE: + audio_proto = ROC_PROTO_RTP_LDPC_SOURCE; + repair_proto = ROC_PROTO_LDPC_REPAIR; + break; + default: + audio_proto = ROC_PROTO_RTP; + repair_proto = 0; + break; + } + + if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_SOURCE, audio_proto, &data->remote_source_addr) != 0) { pw_log_error("can't connect roc sender to remote source address"); return -EINVAL; } - if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_REPAIR, ROC_PROTO_RS8M_REPAIR, - &data->remote_repair_addr) != 0) { - pw_log_error("can't connect roc sender to remote repair address"); - return -EINVAL; + if (repair_proto != 0) { + if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_REPAIR, repair_proto, + &data->remote_repair_addr) != 0) { + pw_log_error("can't connect roc sender to remote repair address"); + return -EINVAL; + } } data->capture = pw_stream_new(data->core, @@ -353,6 +393,7 @@ { PW_KEY_MODULE_DESCRIPTION, "roc sink" }, { PW_KEY_MODULE_USAGE, "sink.name=<name for the sink> " "local.ip=<local sender ip> " + "fec.code=<empty>|disable|rs8m|ldpc " "remote.ip=<remote receiver ip> " "remote.source.port=<remote receiver port for source packets> " "remote.repair.port=<remote receiver port for repair packets> " @@ -367,8 +408,7 @@ struct module_roc_sink_data *data; struct pw_properties *props = NULL, *capture_props = NULL; const char *str; - char *local_ip = NULL, *remote_ip = NULL; - int res = 0, remote_repair_port, remote_source_port; + int res = 0; PW_LOG_TOPIC_INIT(mod_topic); @@ -410,8 +450,6 @@ pw_properties_set(capture_props, PW_KEY_NODE_NAME, "roc-sink"); if (pw_properties_get(capture_props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(capture_props, PW_KEY_NODE_DESCRIPTION, "ROC Sink"); - if (pw_properties_get(capture_props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(capture_props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(capture_props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(capture_props, PW_KEY_NODE_VIRTUAL, "true"); if (pw_properties_get(capture_props, PW_KEY_NODE_NETWORK) == NULL) @@ -420,7 +458,7 @@ pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); if ((str = pw_properties_get(props, "remote.ip")) != NULL) { - remote_ip = strdup(str); + data->remote_ip = strdup(str); pw_properties_set(props, "remote.ip", NULL); } else { pw_log_error("Remote IP not specified"); @@ -429,24 +467,34 @@ } if ((str = pw_properties_get(props, "local.ip")) != NULL) { - local_ip = strdup(str); + data->local_ip = strdup(str); pw_properties_set(props, "local.ip", NULL); } else { - local_ip = strdup(ROC_DEFAULT_IP); + data->local_ip = strdup(ROC_DEFAULT_IP); } if ((str = pw_properties_get(props, "remote.source.port")) != NULL) { - remote_source_port = pw_properties_parse_int(str); + data->remote_source_port = pw_properties_parse_int(str); pw_properties_set(props, "remote.source.port", NULL); } else { - remote_source_port = ROC_DEFAULT_SOURCE_PORT; + data->remote_source_port = ROC_DEFAULT_SOURCE_PORT; } if ((str = pw_properties_get(props, "remote.repair.port")) != NULL) { - remote_repair_port = pw_properties_parse_int(str); + data->remote_repair_port = pw_properties_parse_int(str); pw_properties_set(props, "remote.repair.port", NULL); } else { - remote_repair_port = ROC_DEFAULT_REPAIR_PORT; + data->remote_repair_port = ROC_DEFAULT_REPAIR_PORT; + } + if ((str = pw_properties_get(props, "fec.code")) != NULL) { + if (roc_parse_fec_code(&data->fec_code, str)) { + pw_log_error("Invalid fec code %s, using default", str); + data->fec_code = ROC_FEC_DEFAULT; + } + pw_log_info("using fec.code %s %d", str, data->fec_code); + pw_properties_set(props, "fec.code", NULL); + } else { + data->fec_code = ROC_FEC_DEFAULT; } data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core); @@ -472,12 +520,6 @@ &data->core_listener, &core_events, data); - data->capture_props = capture_props; - data->local_ip = local_ip; - data->remote_ip = remote_ip; - data->remote_source_port = remote_source_port; - data->remote_repair_port = remote_repair_port; - if ((res = roc_sink_setup(data)) < 0) goto out;
View file
pipewire-0.3.50.tar.gz/src/modules/module-roc-source.c -> pipewire-0.3.51.tar.gz/src/modules/module-roc-source.c
Changed
@@ -58,6 +58,7 @@ * - `sess.latency.msec = <str>`: target network latency in milliseconds * - `resampler.profile = <str>`: Possible values: `disable`, `high`, * `medium`, `low`. + * - `fec.code = <str>`: Possible values: `disable`, `rs8m`, `ldpc` * * ## General options * @@ -74,6 +75,7 @@ * args = { * local.ip = 0.0.0.0 * resampler.profile = medium + * fec.code = disable * sess.latency.msec = 5000 * local.source.port = 10001 * local.repair.port = 10002 @@ -113,6 +115,7 @@ struct pw_properties *playback_props; unsigned int do_disconnect:1; + uint32_t stride; roc_address local_addr; roc_address local_source_addr; @@ -120,7 +123,8 @@ roc_context *context; roc_receiver *receiver; - char *resampler_profile; + roc_resampler_profile resampler_profile; + roc_fec_code fec_code; char *local_ip; int local_source_port; int local_repair_port; @@ -136,25 +140,34 @@ static int roc_parse_resampler_profile(roc_resampler_profile *out, const char *str) { - if (!str || !*str) { + if (!str || !*str) *out = ROC_RESAMPLER_DEFAULT; - return 0; - } else if (spa_streq(str, "disable") == 0) { + else if (spa_streq(str, "disable")) *out = ROC_RESAMPLER_DISABLE; - return 0; - } else if (spa_streq(str, "high") == 0) { + else if (spa_streq(str, "high")) *out = ROC_RESAMPLER_HIGH; - return 0; - } else if (spa_streq(str, "medium") == 0) { + else if (spa_streq(str, "medium")) *out = ROC_RESAMPLER_MEDIUM; - return 0; - } else if (spa_streq(str, "low") == 0) { + else if (spa_streq(str, "low")) *out = ROC_RESAMPLER_LOW; - return 0; - } else { - pw_log_error("Invalid resampler profile: %s", str); + else return -EINVAL; - } + return 0; +} + +static int roc_parse_fec_code(roc_fec_code *out, const char *str) +{ + if (!str || !*str) + *out = ROC_FEC_DEFAULT; + else if (spa_streq(str, "disable")) + *out = ROC_FEC_DISABLE; + else if (spa_streq(str, "rs8m")) + *out = ROC_FEC_RS8M; + else if (spa_streq(str, "ldpc")) + *out = ROC_FEC_LDPC_STAIRCASE; + else + return -EINVAL; + return 0; } static void playback_process(void *data) @@ -175,22 +188,22 @@ return; buf->datas0.chunk->offset = 0; - buf->datas0.chunk->stride = 8; /* channels = 2, format = F32LE */ + buf->datas0.chunk->stride = impl->stride; buf->datas0.chunk->size = 0; - memset(&frame, 0, sizeof(frame)); - + spa_zero(frame); frame.samples = dst; - frame.samples_size = buf->datas0.maxsize; + frame.samples_size = SPA_MIN(b->requested * impl->stride, buf->datas0.maxsize); if (roc_receiver_read(impl->receiver, &frame) != 0) { /* Handle EOF and error */ pw_log_error("Failed to read from roc source"); pw_impl_module_schedule_destroy(impl->module); - return; + frame.samples_size = 0; } buf->datas0.chunk->size = frame.samples_size; + b->size = frame.samples_size / impl->stride; pw_stream_queue_buffer(impl->playback, b); } @@ -264,7 +277,6 @@ roc_context_close(data->context); free(data->local_ip); - free(data->resampler_profile); free(data); } @@ -290,6 +302,7 @@ uint32_t n_params; uint8_t buffer1024; int res; + roc_protocol audio_proto, repair_proto; if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { pw_log_error("Invalid local IP address"); @@ -308,19 +321,18 @@ return -EINVAL; } - memset(&context_config, 0, sizeof(context_config)); - + spa_zero(context_config); data->context = roc_context_open(&context_config); if (!data->context) { pw_log_error("Failed to create roc context"); return -EINVAL; } - memset(&receiver_config, 0, sizeof(receiver_config)); - + spa_zero(receiver_config); receiver_config.frame_sample_rate = 44100; receiver_config.frame_channels = ROC_CHANNEL_SET_STEREO; receiver_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; + receiver_config.resampler_profile = data->resampler_profile; /* Fixed to be the same as ROC receiver config above */ info.rate = 44100; @@ -328,12 +340,9 @@ info.format = SPA_AUDIO_FORMAT_F32_LE; info.position0 = SPA_AUDIO_CHANNEL_FL; info.position1 = SPA_AUDIO_CHANNEL_FR; + data->stride = info.channels * sizeof(float); - if (roc_parse_resampler_profile(&receiver_config.resampler_profile, - data->resampler_profile)) { - pw_log_error("Invalid resampler profile"); - return -EINVAL; - } + pw_properties_setf(data->playback_props, PW_KEY_NODE_RATE, "1/%d", info.rate); /* * Note that target latency is in nano seconds. @@ -354,16 +363,33 @@ return -EINVAL; } - if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_SOURCE, ROC_PROTO_RTP_RS8M_SOURCE, + switch (data->fec_code) { + case ROC_FEC_DEFAULT: + case ROC_FEC_RS8M: + audio_proto = ROC_PROTO_RTP_RS8M_SOURCE; + repair_proto = ROC_PROTO_RS8M_REPAIR; + break; + case ROC_FEC_LDPC_STAIRCASE: + audio_proto = ROC_PROTO_RTP_LDPC_SOURCE; + repair_proto = ROC_PROTO_LDPC_REPAIR; + break; + default: + audio_proto = ROC_PROTO_RTP; + repair_proto = 0; + break; + } + + if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_SOURCE, audio_proto, &data->local_source_addr) != 0) { pw_log_error("can't connect roc receiver to local source address"); return -EINVAL; } - - if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_REPAIR, ROC_PROTO_RS8M_REPAIR, - &data->local_repair_addr) != 0) { - pw_log_error("can't connect roc receiver to local repair address"); - return -EINVAL; + if (repair_proto != 0) { + if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_REPAIR, repair_proto, + &data->local_repair_addr) != 0) { + pw_log_error("can't connect roc receiver to local repair address"); + return -EINVAL; + } } data->playback = pw_stream_new(data->core, @@ -385,6 +411,7 @@ PW_DIRECTION_OUTPUT, PW_ID_ANY, PW_STREAM_FLAG_MAP_BUFFERS | + PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_RT_PROCESS, params, n_params)) < 0) return res; @@ -397,6 +424,7 @@ { PW_KEY_MODULE_DESCRIPTION, "roc source" }, { PW_KEY_MODULE_USAGE, "source.name=<name for the source> " "resampler.profile=<empty>|disable|high|medium|low " + "fec.code=<empty>|disable|rs8m|ldpc " "sess.latency.msec=<target network latency in milliseconds> " "local.ip=<local receiver ip> " "local.source.port=<local receiver port for source packets> " @@ -412,8 +440,7 @@ struct module_roc_source_data *data; struct pw_properties *props = NULL, *playback_props = NULL; const char *str; - char *local_ip = NULL, *resampler_profile = NULL; - int res = 0, local_repair_port, local_source_port, sess_latency_msec; + int res = 0; PW_LOG_TOPIC_INIT(mod_topic); @@ -455,46 +482,56 @@ pw_properties_set(playback_props, PW_KEY_NODE_NAME, "roc-source"); if (pw_properties_get(playback_props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_DESCRIPTION, "ROC Source"); - if (pw_properties_get(playback_props, PW_KEY_NODE_WANT_DRIVER) == NULL) - pw_properties_set(playback_props, PW_KEY_NODE_WANT_DRIVER, "true"); if (pw_properties_get(playback_props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_VIRTUAL, "true"); if (pw_properties_get(playback_props, PW_KEY_NODE_NETWORK) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_NETWORK, "true"); - if ((str = pw_properties_get(playback_props, PW_KEY_MEDIA_CLASS)) == NULL) - pw_properties_set(playback_props, PW_KEY_MEDIA_CLASS, "Audio/Source"); if ((str = pw_properties_get(props, "local.ip")) != NULL) { - local_ip = strdup(str); + data->local_ip = strdup(str); pw_properties_set(props, "local.ip", NULL); } else { - local_ip = strdup(ROC_DEFAULT_IP); + data->local_ip = strdup(ROC_DEFAULT_IP); } if ((str = pw_properties_get(props, "local.source.port")) != NULL) { - local_source_port = pw_properties_parse_int(str); + data->local_source_port = pw_properties_parse_int(str); pw_properties_set(props, "local.source.port", NULL); } else { - local_source_port = ROC_DEFAULT_SOURCE_PORT; + data->local_source_port = ROC_DEFAULT_SOURCE_PORT; } if ((str = pw_properties_get(props, "local.repair.port")) != NULL) { - local_repair_port = pw_properties_parse_int(str); + data->local_repair_port = pw_properties_parse_int(str); pw_properties_set(props, "local.repair.port", NULL); } else { - local_repair_port = ROC_DEFAULT_REPAIR_PORT; + data->local_repair_port = ROC_DEFAULT_REPAIR_PORT; } if ((str = pw_properties_get(props, "sess.latency.msec")) != NULL) { - sess_latency_msec = pw_properties_parse_int(str); + data->sess_latency_msec = pw_properties_parse_int(str); pw_properties_set(props, "sess.latency.msec", NULL); } else { - sess_latency_msec = ROC_DEFAULT_SESS_LATENCY; + data->sess_latency_msec = ROC_DEFAULT_SESS_LATENCY; } if ((str = pw_properties_get(props, "resampler.profile")) != NULL) { - resampler_profile = strdup(str); + if (roc_parse_resampler_profile(&data->resampler_profile, str)) { + pw_log_warn("Invalid resampler profile %s, using default", str); + data->resampler_profile = ROC_RESAMPLER_DEFAULT; + } pw_properties_set(props, "resampler.profile", NULL); + } else { + data->resampler_profile = ROC_RESAMPLER_DEFAULT; + } + if ((str = pw_properties_get(props, "fec.code")) != NULL) { + if (roc_parse_fec_code(&data->fec_code, str)) { + pw_log_error("Invalid fec code %s, using default", str); + data->fec_code = ROC_FEC_DEFAULT; + } + pw_properties_set(props, "fec.code", NULL); + } else { + data->fec_code = ROC_FEC_DEFAULT; } data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core); @@ -520,12 +557,6 @@ &data->core_listener, &core_events, data); - data->local_ip = local_ip; - data->local_source_port = local_source_port; - data->local_repair_port = local_repair_port; - data->sess_latency_msec = sess_latency_msec; - data->resampler_profile = resampler_profile; - if ((res = roc_source_setup(data)) < 0) goto out;
View file
pipewire-0.3.50.tar.gz/src/modules/module-rt.c -> pipewire-0.3.51.tar.gz/src/modules/module-rt.c
Changed
@@ -76,12 +76,46 @@ /** \page page_module_rt PipeWire Module: RT * - * The `rt` module uses the operating system's scheduler to enable realtime - * scheduling for certain threads to assist with low latency audio processing. + * The `rt` modules can give real-time priorities to processing threads. + * + * It uses the operating system's scheduler to enable realtime scheduling + * for certain threads to assist with low latency audio processing. * This requires `RLIMIT_RTPRIO` to be set to a value that's equal to this * module's `rt.prio` parameter or higher. Most distros will come with some * package that configures this for certain groups or users. If this is not set * up and DBus is available, then this module will fall back to using RTKit. + * + * ## Module Options + * + * - `nice.level`: The nice value set for the application thread. It improves + * performance of the communication with the pipewire daemon. + * - `rt.prio`: The realtime priority of the data thread. Higher values are + * higher priority. + * - `rt.time.soft`, `rt.time.hard`: The amount of CPU time an RT thread can + * consume without doing any blocking calls before the kernel kills + * the thread. This is a safety measure to avoid lockups of the complete + * system when some thread consumes 100%. + + * The nice level is by default set to an invalid value so that clients don't + * automatically have the nice level raised. + * + * The PipeWire server processes are explicitly configured with a valid nice level. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-rt + * args = { + * #nice.level = 20 + * #rt.prio = 88 + * #rt.time.soft = -1 + * #rt.time.hard = -1 + * } + * flags = ifexists nofail + * } + * + *\endcode */ #define NAME "rt" @@ -496,24 +530,23 @@ * scheduling without that rlimit being set such as `CAP_SYS_NICE` or * running as root. Instead of checking a bunch of preconditions, we * just try if setting realtime scheduling works or not. */ - if ((old_policy = sched_getscheduler(0)) < 0 || - sched_getparam(0, &old_sched_params) != 0) { + if (pthread_getschedparam(pthread_self(),&old_policy,&old_sched_params) < 0) { + pw_log_warn("Failed to check RLIMIT_RTPRIO %m"); return false; } /* If the current scheduling policy has `SCHED_RESET_ON_FORK` set, then - * this also needs to be set here or `sched_setscheduler()` will return + * this also needs to be set here or `pthread_setschedparam()` will return * an error code. Similarly, if it is not set, then we don't want to set * it here as it would irreversible change the current thread's * scheduling policy. */ spa_zero(new_sched_params); new_sched_params.sched_priority = priority; - if ((old_policy & PW_SCHED_RESET_ON_FORK) != 0) { + if ((old_policy & PW_SCHED_RESET_ON_FORK) != 0) new_policy |= PW_SCHED_RESET_ON_FORK; - } - if (sched_setscheduler(0, new_policy, &new_sched_params) == 0) { - sched_setscheduler(0, old_policy, &old_sched_params); + if (pthread_setschedparam(pthread_self(), new_policy, &new_sched_params) == 0) { + pthread_setschedparam(pthread_self(), old_policy, &old_sched_params); return true; } else { return false; @@ -612,7 +645,7 @@ return 0; } -static int impl_drop_rt_generic(void *data, struct spa_thread *thread) +static int impl_drop_rt_generic(void *object, struct spa_thread *thread) { struct sched_param sp; pthread_t pt = (pthread_t)thread; @@ -653,12 +686,12 @@ return this->start(this->arg); } -static struct spa_thread *impl_create(void *data, const struct spa_dict *props, +static struct spa_thread *impl_create(void *object, const struct spa_dict *props, void *(*start_routine)(void*), void *arg) { - struct impl *impl = data; + struct impl *impl = object; struct thread *this; - int err; + struct spa_thread *thread; this = calloc(1, sizeof(*this)); this->impl = impl; @@ -667,27 +700,27 @@ /* This thread list is only used for the RTKit implementation */ pthread_mutex_lock(&impl->lock); - err = pthread_create(&this->thread, NULL, custom_start, this); - if (err != 0) + thread = pw_thread_utils_create(props, custom_start, this); + if (thread == NULL) goto exit; + this->thread = (pthread_t)thread; pthread_cond_wait(&impl->cond, &impl->lock); spa_list_append(&impl->threads_list, &this->link); exit: pthread_mutex_unlock(&impl->lock); - if (err != 0) { - errno = err; + if (thread == NULL) { free(this); return NULL; } - return (struct spa_thread*)this->thread; + return thread; } -static int impl_join(void *data, struct spa_thread *thread, void **retval) +static int impl_join(void *object, struct spa_thread *thread, void **retval) { - struct impl *impl = data; + struct impl *impl = object; pthread_t pt = (pthread_t)thread; struct thread *thr; @@ -701,10 +734,10 @@ return pthread_join(pt, retval); } -static int impl_get_rt_range(void *data, const struct spa_dict *props, +static int impl_get_rt_range(void *object, const struct spa_dict *props, int *min, int *max) { - struct impl *impl = data; + struct impl *impl = object; if (impl->use_rtkit) { if (min) *min = 1; @@ -735,9 +768,9 @@ return pid; } -static int impl_acquire_rt(void *data, struct spa_thread *thread, int priority) +static int impl_acquire_rt(void *object, struct spa_thread *thread, int priority) { - struct impl *impl = data; + struct impl *impl = object; struct sched_param sp; int err, rtprio_limit; pthread_t pt = (pthread_t)thread; @@ -786,26 +819,18 @@ #else /* HAVE_DBUS */ -static struct spa_thread *impl_create(void *data, const struct spa_dict *props, +static struct spa_thread *impl_create(void *object, const struct spa_dict *props, void *(*start_routine)(void*), void *arg) { - pthread_t pt; - int err; - - err = pthread_create(&pt, NULL, start_routine, arg); - if (err != 0) { - errno = err; - return NULL; - } - return (struct spa_thread*)pt; + return pw_thread_utils_create(props, start_routine, arg); } -static int impl_join(void *data, struct spa_thread *thread, void **retval) +static int impl_join(void *object, struct spa_thread *thread, void **retval) { - return pthread_join((pthread_t)thread, retval); + return pw_thread_utils_join(thread, retval); } -static int impl_get_rt_range(void *data, const struct spa_dict *props, +static int impl_get_rt_range(void *object, const struct spa_dict *props, int *min, int *max) { if (min) @@ -815,9 +840,9 @@ return 0; } -static int impl_acquire_rt(void *data, struct spa_thread *thread, int priority) +static int impl_acquire_rt(void *object, struct spa_thread *thread, int priority) { - struct impl *impl = data; + struct impl *impl = object; /* See the docstring on `spa_thread_utils_methods::acquire_rt` */ if (priority == -1) {
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager.c
Changed
@@ -28,6 +28,9 @@ #include <pipewire/impl.h> /** \page page_module_session_manager PipeWire Module: Session Manager + * + * This module implements some usefull objects for implementing a session + * manager. It is not yet actively used. */ /* client-endpoint.c */
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c
Changed
@@ -185,19 +185,26 @@ { if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS) { uint32_t i; - size_t size = n_params * sizeof(struct spa_pod *); pw_log_debug(NAME" %p: update %d params", this, n_params); for (i = 0; i < this->n_params; i++) free(this->paramsi); - this->params = realloc(this->params, size); - if (size > 0 && !this->params) { - this->n_params = 0; - goto no_mem; - } this->n_params = n_params; - + if (this->n_params == 0) { + free(this->params); + this->params = NULL; + } else { + void *p; + p = reallocarray(this->params, n_params, sizeof(struct spa_pod*)); + if (p == NULL) { + free(this->params); + this->params = NULL; + this->n_params = 0; + goto no_mem; + } + this->params = p; + } for (i = 0; i < this->n_params; i++) { this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; endpoint_stream_notify_subscribed(this, i, i+1); @@ -214,16 +221,22 @@ pw_properties_update(this->props, info->props); if (info->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS) { - size_t size = info->n_params * sizeof(struct spa_param_info); - - this->info.params = realloc(this->info.params, size); - if (size > 0 && !this->info.params) { - this->info.n_params = 0; - goto no_mem; - } this->info.n_params = info->n_params; - - memcpy(this->info.params, info->params, size); + if (info->n_params == 0) { + free(this->info.params); + this->info.params = NULL; + } else { + void *p; + p = reallocarray(this->info.params, info->n_params, sizeof(struct spa_param_info)); + if (p == NULL) { + free(this->info.params); + this->info.params = NULL; + this->info.n_params = 0; + goto no_mem; + } + this->info.params = p; + memcpy(this->info.params, info->params, info->n_params * sizeof(struct spa_param_info)); + } } if (!this->info.name)
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c
Changed
@@ -202,19 +202,26 @@ { if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS) { uint32_t i; - size_t size = n_params * sizeof(struct spa_pod *); pw_log_debug(NAME" %p: update %d params", this, n_params); for (i = 0; i < this->n_params; i++) free(this->paramsi); - this->params = realloc(this->params, size); - if (size > 0 && !this->params) { - this->n_params = 0; - goto no_mem; - } this->n_params = n_params; - + if (this->n_params == 0) { + free(this->params); + this->params = NULL; + } else { + void *p; + p = reallocarray(this->params, n_params, sizeof(struct spa_pod*)); + if (p == NULL) { + free(this->params); + this->params = NULL; + this->n_params = 0; + goto no_mem; + } + this->params = p; + } for (i = 0; i < this->n_params; i++) { this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; endpoint_notify_subscribed(this, i, i+1); @@ -232,16 +239,22 @@ pw_properties_update(this->props, info->props); if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) { - size_t size = info->n_params * sizeof(struct spa_param_info); - - this->info.params = realloc(this->info.params, size); - if (size > 0 && !this->info.params) { - this->info.n_params = 0; - goto no_mem; - } this->info.n_params = info->n_params; - - memcpy(this->info.params, info->params, size); + if (info->n_params == 0) { + free(this->info.params); + this->info.params = NULL; + } else { + void *p; + p = reallocarray(this->info.params, info->n_params, sizeof(struct spa_param_info)); + if (p == NULL) { + free(this->info.params); + this->info.params = NULL; + this->info.n_params = 0; + goto no_mem; + } + this->info.params = p; + memcpy(this->info.params, info->params, info->n_params * sizeof(struct spa_param_info)); + } } if (!this->info.name) {
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c
Changed
@@ -198,19 +198,26 @@ { if (change_mask & PW_CLIENT_SESSION_UPDATE_PARAMS) { uint32_t i; - size_t size = n_params * sizeof(struct spa_pod *); pw_log_debug(NAME" %p: update %d params", this, n_params); for (i = 0; i < this->n_params; i++) free(this->paramsi); - this->params = realloc(this->params, size); - if (size > 0 && !this->params) { - this->n_params = 0; - goto no_mem; - } this->n_params = n_params; - + if (this->n_params == 0) { + free(this->params); + this->params = NULL; + } else { + void *p; + p = reallocarray(this->params, n_params, sizeof(struct spa_pod*)); + if (p == NULL) { + free(this->params); + this->params = NULL; + this->n_params = 0; + goto no_mem; + } + this->params = p; + } for (i = 0; i < this->n_params; i++) { this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; endpoint_link_notify_subscribed(this, i, i+1); @@ -228,16 +235,22 @@ pw_properties_update(this->props, info->props); if (info->change_mask & PW_ENDPOINT_LINK_CHANGE_MASK_PARAMS) { - size_t size = info->n_params * sizeof(struct spa_param_info); - - this->info.params = realloc(this->info.params, size); - if (size > 0 && !this->info.params) { - this->info.n_params = 0; - goto no_mem; - } this->info.n_params = info->n_params; - - memcpy(this->info.params, info->params, size); + if (info->n_params == 0) { + free(this->info.params); + this->info.params = NULL; + } else { + void *p; + p = reallocarray(this->info.params, info->n_params, sizeof(struct spa_param_info)); + if (p == NULL) { + free(this->info.params); + this->info.params = NULL; + this->info.n_params = 0; + goto no_mem; + } + this->info.params = p; + memcpy(this->info.params, info->params, info->n_params * sizeof(struct spa_param_info)); + } } if (!this->info.output_endpoint_id) {
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/client-session/session.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/client-session/session.c
Changed
@@ -185,19 +185,26 @@ { if (change_mask & PW_CLIENT_SESSION_UPDATE_PARAMS) { uint32_t i; - size_t size = n_params * sizeof(struct spa_pod *); pw_log_debug(NAME" %p: update %d params", this, n_params); for (i = 0; i < this->n_params; i++) free(this->paramsi); - this->params = realloc(this->params, size); - if (size > 0 && !this->params) { - this->n_params = 0; - goto no_mem; - } this->n_params = n_params; - + if (this->n_params == 0) { + free(this->params); + this->params = NULL; + } else { + void *p; + p = reallocarray(this->params, n_params, sizeof(struct spa_pod*)); + if (p == NULL) { + free(this->params); + this->params = NULL; + this->n_params = 0; + goto no_mem; + } + this->params = p; + } for (i = 0; i < this->n_params; i++) { this->paramsi = paramsi ? spa_pod_copy(paramsi) : NULL; session_notify_subscribed(this, i, i+1); @@ -209,18 +216,23 @@ pw_properties_update(this->props, info->props); if (info->change_mask & PW_SESSION_CHANGE_MASK_PARAMS) { - size_t size = info->n_params * sizeof(struct spa_param_info); - - this->info.params = realloc(this->info.params, size); - if (size > 0 && !this->info.params) { - this->info.n_params = 0; - goto no_mem; - } this->info.n_params = info->n_params; - - memcpy(this->info.params, info->params, size); + if (info->n_params == 0) { + free(this->info.params); + this->info.params = NULL; + } else { + void *p; + p = reallocarray(this->info.params, info->n_params, sizeof(struct spa_param_info)); + if (p == NULL) { + free(this->info.params); + this->info.params = NULL; + this->info.n_params = 0; + goto no_mem; + } + this->info.params = p; + memcpy(this->info.params, info->params, info->n_params * sizeof(struct spa_param_info)); + } } - this->info.change_mask = info->change_mask; pw_global_for_each_resource(this->global, emit_info, this); this->info.change_mask = 0;
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/endpoint-link.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/endpoint-link.c
Changed
@@ -183,10 +183,10 @@ .request_state = method_request_state, }; -static int global_bind(void *_data, struct pw_impl_client *client, +static int global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_resource *resource; struct resource_data *data; @@ -285,9 +285,9 @@ return 0; } -static void event_info(void *object, const struct pw_endpoint_link_info *info) +static void event_info(void *data, const struct pw_endpoint_link_info *info) { - struct impl *impl = object; + struct impl *impl = data; uint32_t changed_idsMAX_PARAMS, n_changed_ids = 0; uint32_t i; @@ -350,11 +350,11 @@ return 0; } -static void event_param(void *object, int seq, +static void event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct impl *impl = object; + struct impl *impl = data; struct param_data *pdata; struct spa_pod **pod; struct param_event_args args = { id, index, next, param };
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/endpoint-stream.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/endpoint-stream.c
Changed
@@ -174,10 +174,10 @@ .set_param = method_set_param, }; -static int global_bind(void *_data, struct pw_impl_client *client, +static int global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_resource *resource; struct resource_data *data; @@ -276,9 +276,9 @@ return 0; } -static void event_info(void *object, const struct pw_endpoint_stream_info *info) +static void event_info(void *data, const struct pw_endpoint_stream_info *info) { - struct impl *impl = object; + struct impl *impl = data; uint32_t changed_idsMAX_PARAMS, n_changed_ids = 0; uint32_t i; @@ -341,11 +341,11 @@ return 0; } -static void event_param(void *object, int seq, +static void event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct impl *impl = object; + struct impl *impl = data; struct param_data *pdata; struct spa_pod **pod; struct param_event_args args = { id, index, next, param };
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/endpoint.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/endpoint.c
Changed
@@ -183,10 +183,10 @@ .create_link = method_create_link, }; -static int global_bind(void *_data, struct pw_impl_client *client, +static int global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_resource *resource; struct resource_data *data; @@ -285,9 +285,9 @@ return 0; } -static void event_info(void *object, const struct pw_endpoint_info *info) +static void event_info(void *data, const struct pw_endpoint_info *info) { - struct impl *impl = object; + struct impl *impl = data; uint32_t changed_idsMAX_PARAMS, n_changed_ids = 0; uint32_t i; @@ -350,11 +350,11 @@ return 0; } -static void event_param(void *object, int seq, +static void event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct impl *impl = object; + struct impl *impl = data; struct param_data *pdata; struct spa_pod **pod; struct param_event_args args = { id, index, next, param };
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/protocol-native.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/protocol-native.c
Changed
@@ -470,10 +470,10 @@ return pw_protocol_native_end_proxy(proxy, b); } -static int client_endpoint_demarshal_set_session_id(void *object, +static int client_endpoint_demarshal_set_session_id(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id; @@ -486,10 +486,10 @@ set_session_id, 0, id); } -static int client_endpoint_demarshal_set_param(void *object, +static int client_endpoint_demarshal_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, flags; const struct spa_pod *param = NULL; @@ -505,10 +505,10 @@ set_param, 0, id, flags, param); } -static int client_endpoint_demarshal_stream_set_param(void *object, +static int client_endpoint_demarshal_stream_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t stream_id, id, flags; const struct spa_pod *param = NULL; @@ -525,10 +525,10 @@ stream_set_param, 0, stream_id, id, flags, param); } -static int client_endpoint_demarshal_create_link(void *object, +static int client_endpoint_demarshal_create_link(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -672,11 +672,11 @@ * CLIENT SESSION ***********************************************/ -static int client_session_marshal_set_param (void *object, +static int client_session_marshal_set_param (void *data, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -690,11 +690,11 @@ return pw_protocol_native_end_resource(resource, b); } -static int client_session_marshal_link_set_param (void *object, +static int client_session_marshal_link_set_param (void *data, uint32_t link_id, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -709,10 +709,10 @@ return pw_protocol_native_end_resource(resource, b); } -static int client_session_marshal_link_request_state (void *object, +static int client_session_marshal_link_request_state (void *data, uint32_t link_id, uint32_t state) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -803,10 +803,10 @@ return pw_protocol_native_end_proxy(proxy, b); } -static int client_session_demarshal_set_param(void *object, +static int client_session_demarshal_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, flags; const struct spa_pod *param = NULL; @@ -822,10 +822,10 @@ set_param, 0, id, flags, param); } -static int client_session_demarshal_link_set_param(void *object, +static int client_session_demarshal_link_set_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t link_id, id, flags; const struct spa_pod *param = NULL; @@ -842,10 +842,10 @@ link_set_param, 0, link_id, id, flags, param); } -static int client_session_demarshal_link_request_state(void *object, +static int client_session_demarshal_link_request_state(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t link_id, state; @@ -988,10 +988,10 @@ * ENDPOINT LINK ***********************************************/ -static void endpoint_link_proxy_marshal_info (void *object, +static void endpoint_link_proxy_marshal_info (void *data, const struct pw_endpoint_link_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -1002,10 +1002,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_link_resource_marshal_info (void *object, +static void endpoint_link_resource_marshal_info (void *data, const struct pw_endpoint_link_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -1016,11 +1016,11 @@ pw_protocol_native_end_resource(resource, b); } -static void endpoint_link_proxy_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_link_proxy_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -1035,11 +1035,11 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_link_resource_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_link_resource_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -1213,10 +1213,10 @@ return pw_protocol_native_end_resource(resource, b); } -static int endpoint_link_proxy_demarshal_info(void *object, +static int endpoint_link_proxy_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1230,10 +1230,10 @@ info, 0, &info); } -static int endpoint_link_resource_demarshal_info(void *object, +static int endpoint_link_resource_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1247,10 +1247,10 @@ info, 0, &info); } -static int endpoint_link_proxy_demarshal_param(void *object, +static int endpoint_link_proxy_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1269,10 +1269,10 @@ param, 0, seq, id, index, next, param); } -static int endpoint_link_resource_demarshal_param(void *object, +static int endpoint_link_resource_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1537,10 +1537,10 @@ * ENDPOINT STREAM ***********************************************/ -static void endpoint_stream_proxy_marshal_info (void *object, +static void endpoint_stream_proxy_marshal_info (void *data, const struct pw_endpoint_stream_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -1551,10 +1551,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_stream_resource_marshal_info (void *object, +static void endpoint_stream_resource_marshal_info (void *data, const struct pw_endpoint_stream_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -1565,11 +1565,11 @@ pw_protocol_native_end_resource(resource, b); } -static void endpoint_stream_proxy_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_stream_proxy_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -1585,11 +1585,11 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_stream_resource_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_stream_resource_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -1735,10 +1735,10 @@ return pw_protocol_native_end_resource(resource, b); } -static int endpoint_stream_proxy_demarshal_info(void *object, +static int endpoint_stream_proxy_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1752,10 +1752,10 @@ info, 0, &info); } -static int endpoint_stream_resource_demarshal_info(void *object, +static int endpoint_stream_resource_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -1769,10 +1769,10 @@ info, 0, &info); } -static int endpoint_stream_proxy_demarshal_param(void *object, +static int endpoint_stream_proxy_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -1791,10 +1791,10 @@ param, 0, seq, id, index, next, param); } -static int endpoint_stream_resource_demarshal_param(void *object, +static int endpoint_stream_resource_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -2023,10 +2023,10 @@ * ENDPOINT ***********************************************/ -static void endpoint_proxy_marshal_info (void *object, +static void endpoint_proxy_marshal_info (void *data, const struct pw_endpoint_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -2037,10 +2037,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_resource_marshal_info (void *object, +static void endpoint_resource_marshal_info (void *data, const struct pw_endpoint_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -2051,11 +2051,11 @@ pw_protocol_native_end_resource(resource, b); } -static void endpoint_proxy_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_proxy_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -2071,11 +2071,11 @@ pw_protocol_native_end_proxy(proxy, b); } -static void endpoint_resource_marshal_param (void *object, int seq, uint32_t id, +static void endpoint_resource_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -2249,10 +2249,10 @@ return pw_protocol_native_end_resource(resource, b); } -static int endpoint_proxy_demarshal_info(void *object, +static int endpoint_proxy_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -2266,10 +2266,10 @@ info, 0, &info); } -static int endpoint_resource_demarshal_info(void *object, +static int endpoint_resource_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -2283,10 +2283,10 @@ info, 0, &info); } -static int endpoint_proxy_demarshal_param(void *object, +static int endpoint_proxy_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -2305,10 +2305,10 @@ param, 0, seq, id, index, next, param); } -static int endpoint_resource_demarshal_param(void *object, +static int endpoint_resource_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -2573,10 +2573,10 @@ * SESSION ***********************************************/ -static void session_proxy_marshal_info (void *object, +static void session_proxy_marshal_info (void *data, const struct pw_session_info *info) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -2587,10 +2587,10 @@ pw_protocol_native_end_proxy(proxy, b); } -static void session_resource_marshal_info (void *object, +static void session_resource_marshal_info (void *data, const struct pw_session_info *info) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -2601,11 +2601,11 @@ pw_protocol_native_end_resource(resource, b); } -static void session_proxy_marshal_param (void *object, int seq, uint32_t id, +static void session_proxy_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_proxy(proxy, @@ -2621,11 +2621,11 @@ pw_protocol_native_end_proxy(proxy, b); } -static void session_resource_marshal_param (void *object, int seq, uint32_t id, +static void session_resource_marshal_param (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_builder *b; b = pw_protocol_native_begin_resource(resource, @@ -2771,10 +2771,10 @@ return pw_protocol_native_end_resource(resource, b); } -static int session_proxy_demarshal_info(void *object, +static int session_proxy_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -2788,10 +2788,10 @@ info, 0, &info); } -static int session_resource_demarshal_info(void *object, +static int session_resource_demarshal_info(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; struct spa_pod_frame f; struct spa_dict props = SPA_DICT_INIT(NULL, 0); @@ -2805,10 +2805,10 @@ info, 0, &info); } -static int session_proxy_demarshal_param(void *object, +static int session_proxy_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_proxy *proxy = object; + struct pw_proxy *proxy = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq; @@ -2827,10 +2827,10 @@ param, 0, seq, id, index, next, param); } -static int session_resource_demarshal_param(void *object, +static int session_resource_demarshal_param(void *data, const struct pw_protocol_native_message *msg) { - struct pw_resource *resource = object; + struct pw_resource *resource = data; struct spa_pod_parser prs; uint32_t id, index, next; int seq;
View file
pipewire-0.3.50.tar.gz/src/modules/module-session-manager/session.c -> pipewire-0.3.51.tar.gz/src/modules/module-session-manager/session.c
Changed
@@ -174,10 +174,10 @@ .set_param = method_set_param, }; -static int global_bind(void *_data, struct pw_impl_client *client, +static int global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct impl *impl = _data; + struct impl *impl = object; struct pw_resource *resource; struct resource_data *data; @@ -274,9 +274,9 @@ return 0; } -static void event_info(void *object, const struct pw_session_info *info) +static void event_info(void *data, const struct pw_session_info *info) { - struct impl *impl = object; + struct impl *impl = data; uint32_t changed_idsMAX_PARAMS, n_changed_ids = 0; uint32_t i; @@ -339,11 +339,11 @@ return 0; } -static void event_param(void *object, int seq, +static void event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct impl *impl = object; + struct impl *impl = data; struct param_data *pdata; struct spa_pod **pod; struct param_event_args args = { id, index, next, param };
View file
pipewire-0.3.50.tar.gz/src/modules/module-zeroconf-discover.c -> pipewire-0.3.51.tar.gz/src/modules/module-zeroconf-discover.c
Changed
@@ -48,6 +48,23 @@ #include "module-zeroconf-discover/avahi-poll.h" /** \page page_module_zeroconf_discover PipeWire Module: Zeroconf Discover + * + * Use zeroconf to detect and load module-pulse-tunnel with the right + * parameters. This will automatically create sinks and sources to stream + * audio to/from remote PulseAudio servers. It also works with + * module-protocol-pulse. + * + * This module has no options. + * + * ## Example configuration + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-zeroconf-discover + * args = { } + * } + * + *\endcode */ #define NAME "zeroconf-discover" @@ -171,7 +188,9 @@ .destroy = module_destroy, }; -static void pw_properties_from_avahi_string(const char *key, const char *value, struct pw_properties *props) { +static void pw_properties_from_avahi_string(const char *key, const char *value, + struct pw_properties *props) +{ if (spa_streq(key, "device")) { pw_properties_set(props, PW_KEY_NODE_TARGET, value); }
View file
pipewire-0.3.50.tar.gz/src/pipewire/client.h -> pipewire-0.3.51.tar.gz/src/pipewire/client.h
Changed
@@ -85,7 +85,7 @@ * * \param info info about the client */ - void (*info) (void *object, const struct pw_client_info *info); + void (*info) (void *data, const struct pw_client_info *info); /** * Notify a client permission * @@ -96,7 +96,7 @@ * \param n_permissions the number of permissions * \param permissions the permissions */ - void (*permissions) (void *object, + void (*permissions) (void *data, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions);
View file
pipewire-0.3.50.tar.gz/src/pipewire/conf.c -> pipewire-0.3.51.tar.gz/src/pipewire/conf.c
Changed
@@ -897,8 +897,16 @@ { struct data data = { .context = context, .props = props }; int res; + const char *str = pw_properties_get(props, "config.ext"); + res = pw_context_conf_section_for_each(context, section, + update_props, &data); + if (res == 0 && str != NULL) { + char key128; + snprintf(key, sizeof(key), "%s.%s", section, str); + res = pw_context_conf_section_for_each(context, key, update_props, &data); + } return res == 0 ? data.count : res; } @@ -972,7 +980,7 @@ * rules = * { * matches = - * # any of the items in matches needs to match, it one does, + * # any of the items in matches needs to match, if one does, * # actions are emited. * { * # all keys must match the value. ~ in value starts regex. @@ -1040,7 +1048,7 @@ SPA_EXPORT int pw_context_conf_section_match_rules(struct pw_context *context, const char *section, - struct spa_dict *props, + const struct spa_dict *props, int (*callback) (void *data, const char *location, const char *action, const char *str, size_t len), void *data) @@ -1049,5 +1057,16 @@ .props = props, .matched = callback, .data = data }; - return pw_context_conf_section_for_each(context, section, match_rules, &match); + int res; + const char *str = spa_dict_lookup(props, "config.ext"); + + res = pw_context_conf_section_for_each(context, section, + match_rules, &match); + if (res == 0 && str != NULL) { + char key128; + snprintf(key, sizeof(key), "%s.%s", section, str); + res = pw_context_conf_section_for_each(context, key, + match_rules, &match); + } + return res; }
View file
pipewire-0.3.50.tar.gz/src/pipewire/context.c -> pipewire-0.3.51.tar.gz/src/pipewire/context.c
Changed
@@ -915,27 +915,15 @@ return pw_impl_node_set_state(node, state); } -static int collect_nodes(struct pw_context *context, struct pw_impl_node *node) +static int collect_nodes(struct pw_context *context, struct pw_impl_node *node, struct spa_list *collect) { struct spa_list queue; - struct pw_impl_node *n, *t, *driver; + struct pw_impl_node *n, *t; struct pw_impl_port *p; struct pw_impl_link *l; pw_log_debug("node %p: '%s'", node, node->name); - if (node->driver) { - driver = node; - spa_list_consume(t, &driver->follower_list, follower_link) { - spa_list_remove(&t->follower_link); - spa_list_init(&t->follower_link); - } - } else { - driver = node->driver_node; - if (driver == NULL) - return -EINVAL; - } - /* start with node in the queue */ spa_list_init(&queue); spa_list_append(&queue, &node->sort_link); @@ -944,10 +932,15 @@ /* now follow all the links from the nodes in the queue * and add the peers to the queue. */ spa_list_consume(n, &queue, sort_link) { + pw_log_debug(" next node %p: '%s'", n, n->name); + spa_list_remove(&n->sort_link); - pw_impl_node_set_driver(n, driver); + spa_list_append(collect, &n->sort_link); n->passive = true; + if (!n->active) + continue; + spa_list_for_each(p, &n->input_ports, link) { spa_list_for_each(l, &p->links, input_link) { t = l->output->node; @@ -961,7 +954,7 @@ continue; if (!l->passive) - driver->passive = n->passive = false; + node->passive = n->passive = false; if (!t->visited) { t->visited = true; @@ -982,7 +975,7 @@ continue; if (!l->passive) - driver->passive = n->passive = false; + node->passive = n->passive = false; if (!t->visited) { t->visited = true; @@ -1008,6 +1001,27 @@ return 0; } +static void move_to_driver(struct pw_context *context, struct spa_list *nodes, + struct pw_impl_node *driver) +{ + struct pw_impl_node *n; + pw_log_debug("driver: %p %s", driver, driver->name); + spa_list_consume(n, nodes, sort_link) { + spa_list_remove(&n->sort_link); + pw_log_debug(" follower: %p %s", n, n->name); + pw_impl_node_set_driver(n, driver); + } +} +static void remove_from_driver(struct pw_context *context, struct spa_list *nodes) +{ + struct pw_impl_node *n; + spa_list_consume(n, nodes, sort_link) { + spa_list_remove(&n->sort_link); + pw_impl_node_set_driver(n, NULL); + ensure_state(n, false); + } +} + static inline void get_quantums(struct pw_context *context, uint32_t *def, uint32_t *min, uint32_t *max, uint32_t *limit, uint32_t *rate) { @@ -1084,6 +1098,24 @@ return false; } +/* here we evaluate the complete state of the graph. + * + * It roughly operates in 3 stages: + * + * 1. go over all drivers and collect the nodes that need to be scheduled with the + * driver. This include all nodes that have an active link with the driver or + * with a node already scheduled with the driver. + * + * 2. go over all nodes that are not assigned to a driver. The ones that require + * a driver are moved to some random active driver found in step 1. + * + * 3. go over all drivers again, collect the quantum/rate of all followers, select + * the desired final value and activate the followers and then the driver. + * + * A complete graph evaluation is performed for each change that is made to the + * graph, such as making/destroting links, adding/removing nodes, property changes such + * as quantum/rate changes or metadata changes. + */ int pw_context_recalc_graph(struct pw_context *context, const char *reason) { struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this); @@ -1092,6 +1124,7 @@ uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum; uint32_t *rates, n_rates, def_rate; bool freewheel = false, global_force_rate, force_rate, force_quantum, global_force_quantum; + struct spa_list collect; pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason); @@ -1119,9 +1152,11 @@ if (n->exported) continue; - if (!n->visited) - collect_nodes(context, n); - + if (!n->visited) { + spa_list_init(&collect); + collect_nodes(context, n, &collect); + move_to_driver(context, &collect, n); + } /* from now on we are only interested in active driving nodes. * We're going to see if there are active followers. */ if (!n->driving || !n->active) @@ -1158,30 +1193,41 @@ /* now go through all available nodes. The ones we didn't visit * in collect_nodes() are not linked to any driver. We assign them - * to either an active driver of the first driver */ + * to either an active driver or the first driver if they are in a + * group that needs a driver. Else we remove them from a driver + * and stop them. */ spa_list_for_each(n, &context->node_list, link) { - if (n->exported) - continue; + struct pw_impl_node *t, *driver; - if (!n->visited) { - struct pw_impl_node *t; + if (n->exported || n->visited) + continue; - pw_log_debug("%p: unassigned node %p: '%s' active:%d want_driver:%d target:%p", - context, n, n->name, n->active, n->want_driver, target); + pw_log_debug("%p: unassigned node %p: '%s' active:%d want_driver:%d target:%p", + context, n, n->name, n->active, n->want_driver, target); - t = n->want_driver ? target : NULL; + /* collect all nodes in this group */ + spa_list_init(&collect); + collect_nodes(context, n, &collect); - pw_impl_node_set_driver(n, t); - if (t == NULL) - ensure_state(n, false); - else { - if (n->always_process) - t->passive = false; - collect_nodes(context, n); - } + driver = NULL; + spa_list_for_each(t, &collect, sort_link) { + /* is any active and want a driver or it want process */ + if ((t->want_driver && t->active && !n->passive) || + t->always_process) + driver = target; + } + if (driver != NULL) { + /* driver needed for this group */ + driver->passive = false; + move_to_driver(context, &collect, driver); + } else { + /* no driver, make sure the nodes stops */ + remove_from_driver(context, &collect); } - n->visited = false; } + /* clean up the visited flag now */ + spa_list_for_each(n, &context->node_list, link) + n->visited = false; /* assign final quantum and set state for followers and drivers */ spa_list_for_each(n, &context->driver_list, driver_link) { @@ -1198,7 +1244,11 @@ /* collect quantum and rate */ spa_list_for_each(s, &n->follower_list, follower_link) { - if (s->info.state > PW_NODE_STATE_SUSPENDED) { + if (!s->moved) { + /* We only try to enforce the lock flags for nodes that + * are not recently moved between drivers. The nodes that + * are moved should try to enforce their quantum on the + * new driver. */ lock_quantum |= s->lock_quantum; lock_rate |= s->lock_rate; } @@ -1236,6 +1286,8 @@ if (s->active) running = !n->passive; + + s->moved = false; } if (force_quantum) @@ -1247,9 +1299,14 @@ if (lock_rate || (!force_rate && (n->info.state > PW_NODE_STATE_IDLE))) + /* when someone wants us to lock the rate of this driver or + * when the driver is busy and we don't need to force a rate, + * keep the current rate */ target_rate = current_rate; else { - /* calculate desired rate */ + /* Here we are allowed to change the rate of the driver. + * Start with the default rate. If the desired rate is + * allowed, switch to it */ target_rate = def_rate; if (rate.denom != 0 && rate.num == 1) { if (rates_contains(rates, n_rates, rate.denom)) @@ -1258,6 +1315,7 @@ } if (target_rate != current_rate) { + /* we doing a rate switch */ pw_log_info("(%s-%u) state:%s new rate:%u->%u", n->name, n->info.id, pw_node_state_as_string(n->info.state), @@ -1271,6 +1329,8 @@ if (n->info.state >= PW_NODE_STATE_IDLE) suspend_driver(context, n); } + /* we're setting the pending rate. This will become the new + * current rate in the next iteration of the graph. */ n->current_rate = SPA_FRACTION(1, target_rate); n->current_pending = true; current_rate = target_rate; @@ -1279,6 +1339,7 @@ } if (rate_quantum != 0 && current_rate != rate_quantum) { + /* the quantum values are scaled with the current rate */ def_quantum = def_quantum * current_rate / rate_quantum; min_quantum = min_quantum * current_rate / rate_quantum; max_quantum = max_quantum * current_rate / rate_quantum; @@ -1305,11 +1366,16 @@ n->name, n->info.id, n->current_quantum, quantum); + /* this is the new pending quantum */ n->current_quantum = quantum; n->current_pending = true; } if (n->info.state < PW_NODE_STATE_RUNNING && n->current_pending) { + /* the driver node is not actually running and we have a + * panding change. Apply the change to the position now so + * that we have the right values when we change the node + * states of the driver and followers to RUNNING below */ n->rt.position->clock.duration = n->current_quantum; n->rt.position->clock.rate = n->current_rate; n->current_pending = false; @@ -1318,6 +1384,7 @@ pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'", context, n, running, n->passive, quantum, n->name); + /* first change the node states of the followers to the new target */ spa_list_for_each(s, &n->follower_list, follower_link) { if (s == n) continue; @@ -1325,6 +1392,7 @@ context, s, s->active, s->name); ensure_state(s, running); } + /* now that all the followers are ready, start the driver */ ensure_state(n, running); } impl->recalc = false;
View file
pipewire-0.3.50.tar.gz/src/pipewire/context.h -> pipewire-0.3.51.tar.gz/src/pipewire/context.h
Changed
@@ -125,7 +125,7 @@ void *data); /** emit callback for all matched properties. Since 0.3.46 */ int pw_context_conf_section_match_rules(struct pw_context *context, const char *section, - struct spa_dict *props, + const struct spa_dict *props, int (*callback) (void *data, const char *location, const char *action, const char *str, size_t len), void *data);
View file
pipewire-0.3.50.tar.gz/src/pipewire/core.h -> pipewire-0.3.51.tar.gz/src/pipewire/core.h
Changed
@@ -125,7 +125,7 @@ * * \param info new core info */ - void (*info) (void *object, const struct pw_core_info *info); + void (*info) (void *data, const struct pw_core_info *info); /** * Emit a done event * @@ -134,14 +134,14 @@ * * \param seq the seq number passed to the sync method call */ - void (*done) (void *object, uint32_t id, int seq); + void (*done) (void *data, uint32_t id, int seq); /** Emit a ping event * * The client should reply with a pong reply with the same seq * number. */ - void (*ping) (void *object, uint32_t id, int seq); + void (*ping) (void *data, uint32_t id, int seq); /** * Fatal error event @@ -160,7 +160,7 @@ * \param res error code * \param message error description */ - void (*error) (void *object, uint32_t id, int seq, int res, const char *message); + void (*error) (void *data, uint32_t id, int seq, int res, const char *message); /** * Remove an object ID * @@ -172,7 +172,7 @@ * * \param id deleted object ID */ - void (*remove_id) (void *object, uint32_t id); + void (*remove_id) (void *data, uint32_t id); /** * Notify an object binding @@ -184,7 +184,7 @@ * \param id bound object ID * \param global_id the global id bound to */ - void (*bound_id) (void *object, uint32_t id, uint32_t global_id); + void (*bound_id) (void *data, uint32_t id, uint32_t global_id); /** * Add memory for a client @@ -200,14 +200,14 @@ * \param fd the file descriptor * \param flags extra flags */ - void (*add_mem) (void *object, uint32_t id, uint32_t type, int fd, uint32_t flags); + void (*add_mem) (void *data, uint32_t id, uint32_t type, int fd, uint32_t flags); /** * Remove memory for a client * * \param id the memory id to remove */ - void (*remove_mem) (void *object, uint32_t id); + void (*remove_mem) (void *data, uint32_t id); }; #define PW_CORE_METHOD_ADD_LISTENER 0 @@ -442,7 +442,7 @@ * \param version the version of the interface * \param props extra properties of the global */ - void (*global) (void *object, uint32_t id, + void (*global) (void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props); /** @@ -454,7 +454,7 @@ * * \param id the id of the global that was removed */ - void (*global_remove) (void *object, uint32_t id); + void (*global_remove) (void *data, uint32_t id); }; #define PW_REGISTRY_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/device.h -> pipewire-0.3.51.tar.gz/src/pipewire/device.h
Changed
@@ -84,7 +84,7 @@ * * \param info info about the device */ - void (*info) (void *object, const struct pw_device_info *info); + void (*info) (void *data, const struct pw_device_info *info); /** * Notify a device param * @@ -96,7 +96,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); };
View file
pipewire-0.3.50.tar.gz/src/pipewire/extensions/client-node.h -> pipewire-0.3.51.tar.gz/src/pipewire/extensions/client-node.h
Changed
@@ -84,7 +84,7 @@ * \param offset offset of activation memory * \param size size of activation memory */ - int (*transport) (void *object, + int (*transport) (void *data, int readfd, int writefd, uint32_t mem_id, @@ -100,7 +100,7 @@ * \param flags parameter flags * \param param the param to set */ - int (*set_param) (void *object, + int (*set_param) (void *data, uint32_t id, uint32_t flags, const struct spa_pod *param); /** @@ -114,7 +114,7 @@ * \param offset offset of io area in memory * \param size size of the io area */ - int (*set_io) (void *object, + int (*set_io) (void *data, uint32_t id, uint32_t mem_id, uint32_t offset, @@ -122,13 +122,13 @@ /** * Receive an event from the client node * \param event the received event */ - int (*event) (void *object, const struct spa_event *event); + int (*event) (void *data, const struct spa_event *event); /** * Notify of a new node command * * \param command the command */ - int (*command) (void *object, const struct spa_command *command); + int (*command) (void *data, const struct spa_command *command); /** * A new port was added to the node * @@ -139,7 +139,7 @@ * \param port_id the new port id * \param props extra properties */ - int (*add_port) (void *object, + int (*add_port) (void *data, enum spa_direction direction, uint32_t port_id, const struct spa_dict *props); @@ -149,7 +149,7 @@ * \param direction a port direction * \param port_id the remove port id */ - int (*remove_port) (void *object, + int (*remove_port) (void *data, enum spa_direction direction, uint32_t port_id); /** @@ -161,7 +161,7 @@ * \param flags flags used when setting the param * \param param the new param */ - int (*port_set_param) (void *object, + int (*port_set_param) (void *data, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, @@ -175,7 +175,7 @@ * \param n_buffer the number of buffers * \param buffers and array of buffer descriptions */ - int (*port_use_buffers) (void *object, + int (*port_use_buffers) (void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -193,7 +193,7 @@ * \param offset offset of io area in memory * \param size size of the io area */ - int (*port_set_io) (void *object, + int (*port_set_io) (void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -212,7 +212,7 @@ * \param the offset in \a mem_id to map * \param the size of \a mem_id to map */ - int (*set_activation) (void *object, + int (*set_activation) (void *data, uint32_t node_id, int signalfd, uint32_t mem_id, @@ -230,7 +230,7 @@ * * Since version 4:1 */ - int (*port_set_mix_info) (void *object, + int (*port_set_mix_info) (void *data, enum spa_direction direction, uint32_t port_id, uint32_t mix_id,
View file
pipewire-0.3.50.tar.gz/src/pipewire/extensions/metadata.h -> pipewire-0.3.51.tar.gz/src/pipewire/extensions/metadata.h
Changed
@@ -54,7 +54,7 @@ #define PW_VERSION_METADATA_EVENTS 0 uint32_t version; - int (*property) (void *object, + int (*property) (void *data, uint32_t subject, const char *key, const char *type,
View file
pipewire-0.3.50.tar.gz/src/pipewire/extensions/profiler.h -> pipewire-0.3.51.tar.gz/src/pipewire/extensions/profiler.h
Changed
@@ -54,7 +54,7 @@ #define PW_VERSION_PROFILER_EVENTS 0 uint32_t version; - void (*profile) (void *object, const struct spa_pod *pod); + void (*profile) (void *data, const struct spa_pod *pod); }; #define PW_PROFILER_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/extensions/session-manager/impl-interfaces.h -> pipewire-0.3.51.tar.gz/src/pipewire/extensions/session-manager/impl-interfaces.h
Changed
@@ -71,7 +71,7 @@ * -EINVAL when the session id has already been set * -ENOTSUP when the endpoint is a session master */ - int (*set_session_id) (void *object, uint32_t session_id); + int (*set_session_id) (void *data, uint32_t session_id); /** * Set the configurable parameter in \a endpoint. @@ -94,7 +94,7 @@ * -ENOTSUP when there are no parameters implemented on \a endpoint * -ENOENT the parameter is unknown */ - int (*set_param) (void *object, + int (*set_param) (void *data, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -118,11 +118,11 @@ * -ESRCH when the type or size of a property is not correct. * -ENOENT when the param id is not found */ - int (*stream_set_param) (void *object, uint32_t stream_id, + int (*stream_set_param) (void *data, uint32_t stream_id, uint32_t id, uint32_t flags, const struct spa_pod *param); - int (*create_link) (void *object, const struct spa_dict *props); + int (*create_link) (void *data, const struct spa_dict *props); }; #define PW_CLIENT_ENDPOINT_METHOD_ADD_LISTENER 0 @@ -208,7 +208,7 @@ * -ENOTSUP when there are no parameters implemented on \a session * -ENOENT the parameter is unknown */ - int (*set_param) (void *object, + int (*set_param) (void *data, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -232,11 +232,11 @@ * -ESRCH when the type or size of a property is not correct. * -ENOENT when the param id is not found */ - int (*link_set_param) (void *object, uint32_t link_id, + int (*link_set_param) (void *data, uint32_t link_id, uint32_t id, uint32_t flags, const struct spa_pod *param); - int (*link_request_state) (void *object, uint32_t link_id, uint32_t state); + int (*link_request_state) (void *data, uint32_t link_id, uint32_t state); }; #define PW_CLIENT_SESSION_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/extensions/session-manager/interfaces.h -> pipewire-0.3.51.tar.gz/src/pipewire/extensions/session-manager/interfaces.h
Changed
@@ -71,7 +71,7 @@ * * \param info info about the session */ - void (*info) (void *object, const struct pw_session_info *info); + void (*info) (void *data, const struct pw_session_info *info); /** * Notify a session param @@ -84,7 +84,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -173,7 +173,7 @@ * * \param info info about the endpoint */ - void (*info) (void *object, const struct pw_endpoint_info *info); + void (*info) (void *data, const struct pw_endpoint_info *info); /** * Notify a endpoint param @@ -186,7 +186,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -277,7 +277,7 @@ * * \param info info about the endpoint stream */ - void (*info) (void *object, const struct pw_endpoint_stream_info *info); + void (*info) (void *data, const struct pw_endpoint_stream_info *info); /** * Notify a endpoint stream param @@ -290,7 +290,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -377,7 +377,7 @@ * * \param info info about the endpoint link */ - void (*info) (void *object, const struct pw_endpoint_link_info *info); + void (*info) (void *data, const struct pw_endpoint_link_info *info); /** * Notify a endpoint link param @@ -390,7 +390,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); };
View file
pipewire-0.3.50.tar.gz/src/pipewire/factory.h -> pipewire-0.3.51.tar.gz/src/pipewire/factory.h
Changed
@@ -84,7 +84,7 @@ * * \param info info about the factory */ - void (*info) (void *object, const struct pw_factory_info *info); + void (*info) (void *data, const struct pw_factory_info *info); }; #define PW_FACTORY_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/filter.c -> pipewire-0.3.51.tar.gz/src/pipewire/filter.c
Changed
@@ -1175,6 +1175,22 @@ .error = on_core_error, }; +struct match { + struct pw_filter *filter; + int count; +}; +#define MATCH_INIT(f) (struct match){ .filter = f } + +static int execute_match(void *data, const char *location, const char *action, + const char *val, size_t len) +{ + struct match *match = data; + struct pw_filter *this = match->filter; + if (spa_streq(action, "update-props")) + match->count += pw_properties_update_string(this->properties, val, len); + return 1; +} + static struct filter * filter_new(struct pw_context *context, const char *name, struct pw_properties *props, const struct pw_properties *extra) @@ -1182,6 +1198,7 @@ struct filter *impl; struct pw_filter *this; const char *str; + struct match match; int res; impl = calloc(1, sizeof(struct filter)); @@ -1202,20 +1219,17 @@ res = -errno; goto error_properties; } + spa_hook_list_init(&impl->hooks); + this->properties = props; + pw_context_conf_update_props(context, "filter.properties", props); - if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { - str = pw_properties_get(extra, PW_KEY_APP_NAME); - if (str == NULL) - str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY); - if (str == NULL) - str = name; - pw_properties_set(props, PW_KEY_NODE_NAME, str); - } - if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - if ((str = getenv("PIPEWIRE_RATE")) != NULL) - pw_properties_set(props, PW_KEY_NODE_RATE, str); + match = MATCH_INIT(this); + pw_context_conf_section_match_rules(context, "filter.rules", + &this->properties->dict, execute_match, &match); + + if ((str = getenv("PIPEWIRE_PROPS")) != NULL) + pw_properties_update_string(props, str, strlen(str)); if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { @@ -1225,9 +1239,19 @@ "%u/%u", q.num, q.denom); } } + if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) + pw_properties_set(props, PW_KEY_NODE_LATENCY, str); + if ((str = getenv("PIPEWIRE_RATE")) != NULL) + pw_properties_set(props, PW_KEY_NODE_RATE, str); - spa_hook_list_init(&impl->hooks); - this->properties = props; + if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { + str = pw_properties_get(extra, PW_KEY_APP_NAME); + if (str == NULL) + str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY); + if (str == NULL) + str = name; + pw_properties_set(props, PW_KEY_NODE_NAME, str); + } this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1454,9 +1478,16 @@ emit_port_info(impl, port, false); } } else { + struct match match; + changed = pw_properties_update(filter->properties, dict); + + match = MATCH_INIT(filter); + pw_context_conf_section_match_rules(impl->context, "filter.rules", + &filter->properties->dict, execute_match, &match); + impl->info.props = &filter->properties->dict; - if (changed > 0) { + if (changed > 0 || match.count > 0) { impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; emit_node_info(impl, false); } @@ -1513,6 +1544,11 @@ impl->disconnecting = false; filter_set_state(filter, PW_FILTER_STATE_CONNECTING, NULL); + if (flags & PW_FILTER_FLAG_DRIVER) + pw_properties_set(filter->properties, PW_KEY_NODE_DRIVER, "true"); + if ((pw_properties_get(filter->properties, PW_KEY_NODE_WANT_DRIVER) == NULL)) + pw_properties_set(filter->properties, PW_KEY_NODE_WANT_DRIVER, "true"); + if (filter->core == NULL) { filter->core = pw_context_connect(impl->context, pw_properties_copy(filter->properties), 0);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-client.c
Changed
@@ -303,10 +303,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_client *this = _data; + struct pw_impl_client *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -469,9 +469,9 @@ return NULL; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_client *client = object; + struct pw_impl_client *client = data; spa_hook_remove(&client->global_listener); client->global = NULL; pw_impl_client_destroy(client);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-core.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-core.c
Changed
@@ -157,9 +157,9 @@ .destroy = registry_destroy }; -static void destroy_registry_resource(void *object) +static void destroy_registry_resource(void *_data) { - struct resource_data *data = object; + struct resource_data *data = _data; struct pw_resource *resource = data->resource; spa_list_remove(&resource->link); spa_hook_remove(&data->resource_listener); @@ -507,13 +507,13 @@ }; static int -global_bind(void *_data, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_core *this = _data; + struct pw_impl_core *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -555,9 +555,9 @@ return res; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_core *core = object; + struct pw_impl_core *core = data; spa_hook_remove(&core->global_listener); core->global = NULL; pw_impl_core_destroy(core);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-device.c
Changed
@@ -502,10 +502,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_device *this = _data; + struct pw_impl_device *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -540,9 +540,9 @@ return -errno; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_device *device = object; + struct pw_impl_device *device = data; spa_hook_remove(&device->global_listener); device->global = NULL; pw_impl_device_destroy(device);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-factory.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-factory.c
Changed
@@ -106,10 +106,10 @@ } static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_factory *this = _data; + struct pw_impl_factory *this = object; struct pw_global *global = this->global; struct pw_resource *resource; @@ -131,9 +131,9 @@ return -errno; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_factory *factory = object; + struct pw_impl_factory *factory = data; spa_hook_remove(&factory->global_listener); factory->global = NULL; pw_impl_factory_destroy(factory);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-link.c
Changed
@@ -849,10 +849,10 @@ } static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_link *this = _data; + struct pw_impl_link *this = object; struct pw_global *global = this->global; struct pw_resource *resource; @@ -1322,9 +1322,9 @@ return NULL; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_link *link = object; + struct pw_impl_link *link = data; spa_hook_remove(&link->global_listener); link->global = NULL; pw_impl_link_destroy(link);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-metadata.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-metadata.c
Changed
@@ -268,10 +268,10 @@ }; -static int metadata_property(void *object, uint32_t subject, const char *key, +static int metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct pw_impl_metadata *this = object; + struct pw_impl_metadata *this = data; pw_impl_metadata_emit_property(this, subject, key, type, value); return 0; } @@ -391,13 +391,13 @@ #define pw_metadata_resource_property(r,...) \ pw_metadata_resource(r,property,0,__VA_ARGS__) -static int metadata_resource_property(void *object, +static int metadata_resource_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct resource_data *d = object; + struct resource_data *d = data; struct pw_resource *resource = d->resource; struct pw_impl_client *client = pw_resource_get_client(resource); @@ -465,10 +465,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_metadata *this = _data; + struct pw_impl_metadata *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -506,9 +506,9 @@ return -errno; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_metadata *metadata = object; + struct pw_impl_metadata *metadata = data; spa_hook_remove(&metadata->global_listener); metadata->global = NULL; pw_impl_metadata_destroy(metadata);
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-module.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-module.c
Changed
@@ -109,10 +109,10 @@ } static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_module *this = _data; + struct pw_impl_module *this = object; struct pw_global *global = this->global; struct pw_resource *resource; @@ -134,9 +134,9 @@ return -errno; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_module *module = object; + struct pw_impl_module *module = data; spa_hook_remove(&module->global_listener); module->global = NULL; pw_impl_module_destroy(module); @@ -197,6 +197,7 @@ if (hnd != NULL) break; + pw_log_debug("open failed: %s", dlerror()); free(filename); filename = NULL; }
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-node.c
Changed
@@ -592,10 +592,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_node *this = _data; + struct pw_impl_node *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -842,6 +842,7 @@ old->name, old->info.id, driver->name, driver->info.id); node->driver_node = driver; + node->moved = true; pw_loop_invoke(node->data_loop, do_move_nodes, SPA_ID_INVALID, &driver, sizeof(struct pw_impl_node *),
View file
pipewire-0.3.50.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.51.tar.gz/src/pipewire/impl-port.c
Changed
@@ -847,10 +847,10 @@ }; static int -global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, +global_bind(void *object, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) { - struct pw_impl_port *this = _data; + struct pw_impl_port *this = object; struct pw_global *global = this->global; struct pw_resource *resource; struct resource_data *data; @@ -886,9 +886,9 @@ return res; } -static void global_destroy(void *object) +static void global_destroy(void *data) { - struct pw_impl_port *port = object; + struct pw_impl_port *port = data; spa_hook_remove(&port->global_listener); port->global = NULL; pw_impl_port_destroy(port);
View file
pipewire-0.3.50.tar.gz/src/pipewire/introspect.c -> pipewire-0.3.51.tar.gz/src/pipewire/introspect.c
Changed
@@ -211,10 +211,15 @@ } if (update->change_mask & PW_NODE_CHANGE_MASK_PARAMS) { uint32_t i, user, n_params = update->n_params; + void *np; - info->params = realloc(info->params, n_params * sizeof(struct spa_param_info)); - if (info->params == NULL) - n_params = 0; + np = reallocarray(info->params, n_params, sizeof(struct spa_param_info)); + if (np == NULL) { + free(info->params); + info->params = NULL; + info->n_params = n_params = 0; + } + info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { user = reset ? 0 : info->paramsi.user; @@ -276,10 +281,15 @@ } if (update->change_mask & PW_PORT_CHANGE_MASK_PARAMS) { uint32_t i, user, n_params = update->n_params; + void *np; - info->params = realloc(info->params, n_params * sizeof(struct spa_param_info)); - if (info->params == NULL) - n_params = 0; + np = reallocarray(info->params, n_params, sizeof(struct spa_param_info)); + if (np == NULL) { + free(info->params); + info->params = NULL; + info->n_params = n_params = 0; + } + info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { user = reset ? 0 : info->paramsi.user; @@ -431,10 +441,15 @@ } if (update->change_mask & PW_DEVICE_CHANGE_MASK_PARAMS) { uint32_t i, user, n_params = update->n_params; + void *np; - info->params = realloc(info->params, n_params * sizeof(struct spa_param_info)); - if (info->params == NULL) - n_params = 0; + np = reallocarray(info->params, n_params, sizeof(struct spa_param_info)); + if (np == NULL) { + free(info->params); + info->params = NULL; + info->n_params = n_params = 0; + } + info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { user = reset ? 0 : info->paramsi.user;
View file
pipewire-0.3.50.tar.gz/src/pipewire/link.h -> pipewire-0.3.51.tar.gz/src/pipewire/link.h
Changed
@@ -109,7 +109,7 @@ * * \param info info about the link */ - void (*info) (void *object, const struct pw_link_info *info); + void (*info) (void *data, const struct pw_link_info *info); }; #define PW_LINK_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/loop.c -> pipewire-0.3.51.tar.gz/src/pipewire/loop.c
Changed
@@ -33,12 +33,9 @@ #include <pipewire/log.h> #include <pipewire/type.h> -#define DATAS_SIZE (4096 * 8) - PW_LOG_TOPIC_EXTERN(log_loop); #define PW_LOG_TOPIC_DEFAULT log_loop - /** \cond */ struct impl {
View file
pipewire-0.3.50.tar.gz/src/pipewire/mem.c -> pipewire-0.3.51.tar.gz/src/pipewire/mem.c
Changed
@@ -545,6 +545,7 @@ return &b->this; error_close: + pw_log_debug("%p: close fd:%d", pool, b->this.fd); close(b->this.fd); error_free: free(b);
View file
pipewire-0.3.50.tar.gz/src/pipewire/module.h -> pipewire-0.3.51.tar.gz/src/pipewire/module.h
Changed
@@ -82,7 +82,7 @@ * * \param info info about the module */ - void (*info) (void *object, const struct pw_module_info *info); + void (*info) (void *data, const struct pw_module_info *info); }; #define PW_MODULE_METHOD_ADD_LISTENER 0
View file
pipewire-0.3.50.tar.gz/src/pipewire/node.h -> pipewire-0.3.51.tar.gz/src/pipewire/node.h
Changed
@@ -111,7 +111,7 @@ * * \param info info about the node */ - void (*info) (void *object, const struct pw_node_info *info); + void (*info) (void *data, const struct pw_node_info *info); /** * Notify a node param * @@ -123,7 +123,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); };
View file
pipewire-0.3.50.tar.gz/src/pipewire/port.h -> pipewire-0.3.51.tar.gz/src/pipewire/port.h
Changed
@@ -96,7 +96,7 @@ * * \param info info about the port */ - void (*info) (void *object, const struct pw_port_info *info); + void (*info) (void *data, const struct pw_port_info *info); /** * Notify a port param * @@ -108,7 +108,7 @@ * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, int seq, + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); };
View file
pipewire-0.3.50.tar.gz/src/pipewire/private.h -> pipewire-0.3.51.tar.gz/src/pipewire/private.h
Changed
@@ -700,6 +700,7 @@ unsigned int lock_rate:1; /**< don't change graph rate */ unsigned int transport_sync:1; /**< supports transport sync */ unsigned int current_pending:1; /**< a quantum/rate update is pending */ + unsigned int moved:1; /**< the node was moved drivers */ uint32_t port_user_data_size; /**< extra size for port user data */ @@ -1289,6 +1290,8 @@ void pw_impl_module_schedule_destroy(struct pw_impl_module *module); +pthread_attr_t *pw_thread_fill_attr(const struct spa_dict *props, pthread_attr_t *attr); + /** \endcond */ #ifdef __cplusplus
View file
pipewire-0.3.50.tar.gz/src/pipewire/stream.c -> pipewire-0.3.51.tar.gz/src/pipewire/stream.c
Changed
@@ -1306,9 +1306,9 @@ return 0; } -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *data, const struct pw_node_info *info) { - struct pw_stream *stream = object; + struct pw_stream *stream = data; struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); uint32_t i; @@ -1336,9 +1336,9 @@ .info_changed = node_event_info, }; -static void on_core_error(void *object, uint32_t id, int seq, int res, const char *message) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct pw_stream *stream = object; + struct pw_stream *stream = data; pw_log_debug("%p: error id:%u seq:%d res:%d (%s): %s", stream, id, seq, res, spa_strerror(res), message); @@ -1370,6 +1370,22 @@ .drained = context_drained, }; +struct match { + struct pw_stream *stream; + int count; +}; +#define MATCH_INIT(s) (struct match){ .stream = s } + +static int execute_match(void *data, const char *location, const char *action, + const char *val, size_t len) +{ + struct match *match = data; + struct pw_stream *this = match->stream; + if (spa_streq(action, "update-props")) + match->count += pw_properties_update_string(this->properties, val, len); + return 1; +} + static struct stream * stream_new(struct pw_context *context, const char *name, struct pw_properties *props, const struct pw_properties *extra) @@ -1377,6 +1393,7 @@ struct stream *impl; struct pw_stream *this; const char *str; + struct match match; int res; impl = calloc(1, sizeof(struct stream)); @@ -1402,23 +1419,17 @@ res = -errno; goto error_properties; } + spa_hook_list_init(&impl->hooks); + this->properties = props; + pw_context_conf_update_props(context, "stream.properties", props); - if (pw_properties_get(props, PW_KEY_STREAM_IS_LIVE) == NULL) - pw_properties_set(props, PW_KEY_STREAM_IS_LIVE, "true"); + match = MATCH_INIT(this); + pw_context_conf_section_match_rules(context, "stream.rules", + &this->properties->dict, execute_match, &match); - if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { - str = pw_properties_get(extra, PW_KEY_APP_NAME); - if (str == NULL) - str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY); - if (str == NULL) - str = name; - pw_properties_set(props, PW_KEY_NODE_NAME, str); - } - if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - if ((str = getenv("PIPEWIRE_RATE")) != NULL) - pw_properties_set(props, PW_KEY_NODE_RATE, str); + if ((str = getenv("PIPEWIRE_PROPS")) != NULL) + pw_properties_update_string(props, str, strlen(str)); if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { @@ -1428,9 +1439,21 @@ "%u/%u", q.num, q.denom); } } + if ((str = getenv("PIPEWIRE_LATENCY")) != NULL) + pw_properties_set(props, PW_KEY_NODE_LATENCY, str); + if ((str = getenv("PIPEWIRE_RATE")) != NULL) + pw_properties_set(props, PW_KEY_NODE_RATE, str); - spa_hook_list_init(&impl->hooks); - this->properties = props; + if (pw_properties_get(props, PW_KEY_STREAM_IS_LIVE) == NULL) + pw_properties_set(props, PW_KEY_STREAM_IS_LIVE, "true"); + if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL && extra) { + str = pw_properties_get(extra, PW_KEY_APP_NAME); + if (str == NULL) + str = pw_properties_get(extra, PW_KEY_APP_PROCESS_BINARY); + if (str == NULL) + str = name; + pw_properties_set(props, PW_KEY_NODE_NAME, str); + } this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1640,14 +1663,21 @@ { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); int changed, res = 0; + struct match match; changed = pw_properties_update(stream->properties, dict); - if (!changed) return 0; + match = MATCH_INIT(stream); + pw_context_conf_section_match_rules(impl->context, "stream.rules", + &stream->properties->dict, execute_match, &match); + if (impl->node) - res = pw_impl_node_update_properties(impl->node, dict); + res = pw_impl_node_update_properties(impl->node, + match.count == 0 ? + dict : + &stream->properties->dict); return res; } @@ -1834,6 +1864,9 @@ } if (flags & PW_STREAM_FLAG_DRIVER) pw_properties_set(stream->properties, PW_KEY_NODE_DRIVER, "true"); + if ((pw_properties_get(stream->properties, PW_KEY_NODE_WANT_DRIVER) == NULL)) + pw_properties_set(stream->properties, PW_KEY_NODE_WANT_DRIVER, "true"); + if (flags & PW_STREAM_FLAG_EXCLUSIVE) pw_properties_set(stream->properties, PW_KEY_NODE_EXCLUSIVE, "true"); if (flags & PW_STREAM_FLAG_DONT_RECONNECT) @@ -1852,6 +1885,7 @@ direction == PW_DIRECTION_INPUT ? "Input" : "Output", media_type ? media_type : get_media_class(impl)); } + if ((str = pw_properties_get(stream->properties, PW_KEY_FORMAT_DSP)) != NULL) pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str); else if (impl->media_type == SPA_MEDIA_TYPE_application &&
View file
pipewire-0.3.50.tar.gz/src/pipewire/thread-loop.c -> pipewire-0.3.51.tar.gz/src/pipewire/thread-loop.c
Changed
@@ -26,9 +26,11 @@ #include <errno.h> #include <sys/time.h> +#include <spa/support/thread.h> #include <spa/utils/result.h> #include "log.h" +#include "thread.h" #include "thread-loop.h" PW_LOG_TOPIC_EXTERN(log_thread_loop); @@ -38,17 +40,6 @@ #define pw_thread_loop_events_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_thread_loop_events, m, v, ##__VA_ARGS__) #define pw_thread_loop_events_destroy(o) pw_thread_loop_events_emit(o, destroy, 0) -#ifdef __FreeBSD__ -#include <sys/param.h> -#if __FreeBSD_version < 1202000 -int pthread_setname_np(pthread_t thread, const char *name) -{ - pthread_set_name_np(thread, name); - return 0; -} -#endif -#endif - /** \cond */ struct pw_thread_loop { struct pw_loop *loop; @@ -282,20 +273,29 @@ SPA_EXPORT int pw_thread_loop_start(struct pw_thread_loop *loop) { + int err; + if (!loop->running) { - int err; + struct spa_thread *thr; + struct spa_dict_item items1; loop->running = true; - if ((err = pthread_create(&loop->thread, NULL, do_loop, loop)) != 0) { - pw_log_warn("%p: can't create thread: %s", loop, - strerror(err)); - loop->running = false; - return -err; - } - if ((err = pthread_setname_np(loop->thread, loop->name)) != 0) - pw_log_warn("%p: error: %s", loop, strerror(err)); + + items0 = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_NAME, loop->name); + thr = pw_thread_utils_create(&SPA_DICT_INIT_ARRAY(items), do_loop, loop); + if (thr == NULL) + goto error; + + loop->thread = (pthread_t)thr; } return 0; + +error: + err = errno; + pw_log_warn("%p: can't create thread: %s", loop, + strerror(err)); + loop->running = false; + return -err; } /** Quit the loop and stop its thread
View file
pipewire-0.3.50.tar.gz/src/pipewire/thread.c -> pipewire-0.3.51.tar.gz/src/pipewire/thread.c
Changed
@@ -27,6 +27,7 @@ #include <sys/types.h> #include <pthread.h> +#include <spa/utils/dict.h> #include <spa/utils/defs.h> #include <spa/utils/list.h> @@ -34,26 +35,79 @@ #include "thread.h" -static struct spa_thread *impl_create(void *data, +#define CHECK(expression,label) \ +do { \ + if ((errno = expression) != 0) { \ + res = -errno; \ + pw_log_error(#expression ": %s", strerror(errno)); \ + goto label; \ + } \ +} while(false); + +SPA_EXPORT +pthread_attr_t *pw_thread_fill_attr(const struct spa_dict *props, pthread_attr_t *attr) +{ + const char *str; + int res; + + if (props == NULL) + return NULL; + + pthread_attr_init(attr); + if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_STACK_SIZE)) != NULL) + CHECK(pthread_attr_setstacksize(attr, atoi(str)), error); + return attr; +error: + errno = -res; + return NULL; +} + +#ifdef __FreeBSD__ +#include <sys/param.h> +#if __FreeBSD_version < 1202000 +int pthread_setname_np(pthread_t thread, const char *name) +{ + pthread_set_name_np(thread, name); + return 0; +} +#endif +#endif + +static struct spa_thread *impl_create(void *object, const struct spa_dict *props, void *(*start)(void*), void *arg) { pthread_t pt; + pthread_attr_t *attr = NULL, attributes; + const char *str; int err; - if ((err = pthread_create(&pt, NULL, start, arg)) != 0) { + + attr = pw_thread_fill_attr(props, &attributes); + + err = pthread_create(&pt, attr, start, arg); + + if (attr) + pthread_attr_destroy(attr); + + if (err != 0) { errno = err; return NULL; } + if (props) { + if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_NAME)) != NULL && + (err = pthread_setname_np(pt, str)) != 0) + pw_log_warn("pthread_setname error: %s", strerror(err)); + } return (struct spa_thread*)pt; } -static int impl_join(void *data, struct spa_thread *thread, void **retval) +static int impl_join(void *object, struct spa_thread *thread, void **retval) { pthread_t pt = (pthread_t)thread; return pthread_join(pt, retval); } -static int impl_get_rt_range(void *data, const struct spa_dict *props, +static int impl_get_rt_range(void *object, const struct spa_dict *props, int *min, int *max) { if (min)
View file
pipewire-0.3.50.tar.gz/src/tests/test-endpoint.c -> pipewire-0.3.51.tar.gz/src/tests/test-endpoint.c
Changed
@@ -267,9 +267,9 @@ }; static void -endpoint_event_info(void *object, const struct pw_endpoint_info *info) +endpoint_event_info(void *data, const struct pw_endpoint_info *info) { - struct test_endpoint_data *d = object; + struct test_endpoint_data *d = data; const char *val; spa_assert_se(info); @@ -299,11 +299,11 @@ } static void -endpoint_event_param(void *object, int seq, +endpoint_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct test_endpoint_data *d = object; + struct test_endpoint_data *d = data; if (id == SPA_PARAM_Props) { struct props *p = &d->props; @@ -326,9 +326,9 @@ }; static void -endpoint_proxy_destroy(void *object) +endpoint_proxy_destroy(void *data) { - struct test_endpoint_data *d = object; + struct test_endpoint_data *d = data; d->bound_proxy = NULL; pw_main_loop_quit(d->loop); } @@ -339,11 +339,11 @@ }; static void -test_endpoint_global(void *object, uint32_t id, +test_endpoint_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) { - struct test_endpoint_data *d = object; + struct test_endpoint_data *d = data; const char *val; if (!spa_streq(type, PW_TYPE_INTERFACE_Endpoint)) @@ -366,9 +366,9 @@ } static void -test_endpoint_global_remove(void *object, uint32_t id) +test_endpoint_global_remove(void *data, uint32_t id) { - struct test_endpoint_data *d = object; + struct test_endpoint_data *d = data; if (d->bound_proxy && id == pw_proxy_get_bound_id(d->bound_proxy)) pw_proxy_destroy(d->bound_proxy); }
View file
pipewire-0.3.50.tar.gz/src/tests/test-interfaces.c -> pipewire-0.3.51.tar.gz/src/tests/test-interfaces.c
Changed
@@ -54,14 +54,14 @@ } methods = { PW_VERSION_CORE_METHODS, }; static const struct { uint32_t version; - void (*info) (void *object, const struct pw_core_info *info); - void (*done) (void *object, uint32_t id, int seq); - void (*ping) (void *object, uint32_t id, int seq); - void (*error) (void *object, uint32_t id, int seq, int res, const char *error); - void (*remove_id) (void *object, uint32_t id); - void (*bound_id) (void *object, uint32_t id, uint32_t global_id); - void (*add_mem) (void *object, uint32_t id, uint32_t type, int fd, uint32_t flags); - void (*remove_mem) (void *object, uint32_t id); + void (*info) (void *data, const struct pw_core_info *info); + void (*done) (void *data, uint32_t id, int seq); + void (*ping) (void *data, uint32_t id, int seq); + void (*error) (void *data, uint32_t id, int seq, int res, const char *error); + void (*remove_id) (void *data, uint32_t id); + void (*bound_id) (void *data, uint32_t id, uint32_t global_id); + void (*add_mem) (void *data, uint32_t id, uint32_t type, int fd, uint32_t flags); + void (*remove_mem) (void *data, uint32_t id); } events = { PW_VERSION_CORE_EVENTS, }; struct pw_core_events e; @@ -108,10 +108,10 @@ } methods = { PW_VERSION_REGISTRY_METHODS, }; struct { uint32_t version; - void (*global) (void *object, uint32_t id, + void (*global) (void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props); - void (*global_remove) (void *object, uint32_t id); + void (*global_remove) (void *data, uint32_t id); } events = { PW_VERSION_REGISTRY_EVENTS, }; TEST_FUNC(m, methods, version); @@ -141,7 +141,7 @@ } methods = { PW_VERSION_MODULE_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_module_info *info); + void (*info) (void *data, const struct pw_module_info *info); } events = { PW_VERSION_MODULE_EVENTS, }; TEST_FUNC(m, methods, version); @@ -174,8 +174,8 @@ } methods = { PW_VERSION_DEVICE_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_device_info *info); - void (*param) (void *object, int seq, + void (*info) (void *data, const struct pw_device_info *info); + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_DEVICE_EVENTS, }; @@ -214,8 +214,8 @@ } methods = { PW_VERSION_NODE_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_node_info *info); - void (*param) (void *object, int seq, + void (*info) (void *data, const struct pw_node_info *info); + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_NODE_EVENTS, }; @@ -252,8 +252,8 @@ } methods = { PW_VERSION_PORT_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_port_info *info); - void (*param) (void *object, int seq, + void (*info) (void *data, const struct pw_port_info *info); + void (*param) (void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_PORT_EVENTS, }; @@ -284,7 +284,7 @@ } methods = { PW_VERSION_FACTORY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_factory_info *info); + void (*info) (void *data, const struct pw_factory_info *info); } events = { PW_VERSION_FACTORY_EVENTS, }; TEST_FUNC(m, methods, version); @@ -316,8 +316,8 @@ } methods = { PW_VERSION_CLIENT_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_client_info *info); - void (*permissions) (void *object, uint32_t index, + void (*info) (void *data, const struct pw_client_info *info); + void (*permissions) (void *data, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions); } events = { PW_VERSION_CLIENT_EVENTS, }; @@ -350,7 +350,7 @@ } methods = { PW_VERSION_LINK_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_link_info *info); + void (*info) (void *data, const struct pw_link_info *info); } events = { PW_VERSION_LINK_EVENTS, }; TEST_FUNC(m, methods, version);
View file
pipewire-0.3.50.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.51.tar.gz/src/tools/pw-cat.c
Changed
@@ -88,18 +88,6 @@ typedef int (*fill_fn)(struct data *d, void *dest, unsigned int n_frames); -struct target { - struct spa_list link; - uint32_t id; -#define TARGET_TYPE_SINK 0 -#define TARGET_TYPE_SOURCE 1 -#define TARGET_TYPE_STREAM 2 - uint32_t type; - char *name; - char *desc; - int prio; -}; - struct channelmap { int n_channels; int channelsSPA_AUDIO_MAX_CHANNELS; @@ -110,12 +98,6 @@ struct pw_context *context; struct pw_core *core; struct spa_hook core_listener; - struct pw_registry *registry; - struct spa_hook registry_listener; - struct pw_metadata *metadata; - struct spa_hook metadata_listener; - char default_sink1024; - char default_source1024; struct pw_stream *stream; struct spa_hook stream_listener; @@ -157,12 +139,6 @@ fill_fn fill; - uint32_t target_id; - bool list_targets; - bool targets_listed; - struct spa_list targets; - int sync; - struct spa_io_position *position; bool drained; uint64_t clock_time; @@ -612,39 +588,6 @@ } } -static void -target_destroy(struct target *target) -{ - if (!target) - return; - if (target->name) - free(target->name); - if (target->desc) - free(target->desc); - free(target); -} - -static struct target * -target_create(uint32_t id, uint32_t type, const char *name, const char *desc, int prio) -{ - struct target *target; - - target = malloc(sizeof(*target)); - if (!target) - return NULL; - target->id = id; - target->type = type; - target->name = strdup(name); - target->desc = strdup(desc ? : ""); - target->prio = prio; - - if (!target->name || !target->desc) { - target_destroy(target); - return NULL; - } - return target; -} - static void on_core_info(void *userdata, const struct pw_core_info *info) { struct data *data = userdata; @@ -654,17 +597,6 @@ info->id, info->name); } -static void on_core_done(void *userdata, uint32_t id, int seq) -{ - struct data *data = userdata; - - /* if we're listing targets just exist */ - if (data->sync == seq && data->list_targets) { - data->targets_listed = true; - pw_main_loop_quit(data->loop); - } -} - static void on_core_error(void *userdata, uint32_t id, int seq, int res, const char *message) { struct data *data = userdata; @@ -679,158 +611,9 @@ static const struct pw_core_events core_events = { PW_VERSION_CORE_EVENTS, .info = on_core_info, - .done = on_core_done, .error = on_core_error, }; -static int json_object_find(const char *obj, const char *key, char *value, size_t len) -{ - struct spa_json it2; - const char *v; - char k128; - - spa_json_init(&it0, obj, strlen(obj)); - if (spa_json_enter_object(&it0, &it1) <= 0) - return -EINVAL; - - while (spa_json_get_string(&it1, k, sizeof(k)) > 0) { - if (spa_streq(k, key)) { - if (spa_json_get_string(&it1, value, len) <= 0) - continue; - return 0; - } else { - if (spa_json_next(&it1, &v) <= 0) - break; - } - } - return -ENOENT; -} - -static int metadata_property(void *object, - uint32_t subject, const char *key, const char *type, const char *value) -{ - struct data *data = object; - - if (subject == PW_ID_CORE) { - if (key == NULL || spa_streq(key, "default.audio.sink")) { - if (value == NULL || - json_object_find(value, "name", - data->default_sink, sizeof(data->default_sink)) < 0) - data->default_sink0 = '\0'; - } - if (key == NULL || spa_streq(key, "default.audio.source")) { - if (value == NULL || - json_object_find(value, "name", - data->default_source, sizeof(data->default_source)) < 0) - data->default_source0 = '\0'; - } - } - return 0; -} - -static const struct pw_metadata_events metadata_events = { - PW_VERSION_METADATA_EVENTS, - .property = metadata_property, -}; - -static void registry_event_global(void *userdata, uint32_t id, - uint32_t permissions, const char *type, uint32_t version, - const struct spa_dict *props) -{ - struct data *data = userdata; - const struct spa_dict_item *item; - const char *name, *desc, *media_class, *prio_session; - int prio; - struct target *target; - uint32_t ttype; - - /* only once */ - if (data->targets_listed) - return; - - /* must be listing targets and interface must be a node */ - if (!data->list_targets) - return; - - if (spa_streq(type, PW_TYPE_INTERFACE_Metadata)) { - if (data->metadata != NULL) - return; - if ((name = spa_dict_lookup(props, PW_KEY_METADATA_NAME)) != NULL && - !spa_streq(name, "default")) - return; - - data->metadata = pw_registry_bind(data->registry, - id, type, PW_VERSION_METADATA, 0); - pw_metadata_add_listener(data->metadata, - &data->metadata_listener, - &metadata_events, data); - - data->sync = pw_core_sync(data->core, 0, data->sync); - - } else if (spa_streq(type, PW_TYPE_INTERFACE_Node)) { - name = spa_dict_lookup(props, PW_KEY_NODE_NAME); - desc = spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION); - media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS); - prio_session = spa_dict_lookup(props, PW_KEY_PRIORITY_SESSION); - - /* name and media class must exist */ - if (!name || !media_class) - return; - - if (desc == NULL) - desc = name; - - /* get allowed mode from the media class */ - if (spa_streq(media_class, "Audio/Source")) { - if (data->mode != mode_record) - return; - ttype = TARGET_TYPE_SOURCE; - } - else if (spa_streq(media_class, "Stream/Output/Audio")) { - if (data->mode != mode_record) - return; - ttype = TARGET_TYPE_STREAM; - } - else if (spa_streq(media_class, "Audio/Sink")) { - if (data->mode != mode_playback && - data->mode != mode_record) - return; - ttype = TARGET_TYPE_SINK; - } - else - return; - - prio = prio_session ? atoi(prio_session) : -1; - - if (data->verbose) { - printf("registry: id=%"PRIu32" type=%s name=\"%s\" media_class=\"%s\" desc=\"%s\" prio=%d\n", - id, type, name, media_class, desc ? : "", prio); - - spa_dict_for_each(item, props) { - printf("\t\t%s = \"%s\"\n", item->key, item->value); - } - } - - target = target_create(id, ttype, name, desc, prio); - if (target) - spa_list_append(&data->targets, &target->link); - } -} - -static void registry_event_global_remove(void *userdata, uint32_t id) -{ - struct data *data = userdata; - - if (data->verbose) - printf("registry: remove id=%"PRIu32"\n", id); -} - -static const struct pw_registry_events registry_events = { - PW_VERSION_REGISTRY_EVENTS, - .global = registry_event_global, - .global_remove = registry_event_global_remove, -}; - static void on_state_changed(void *userdata, enum pw_stream_state old, enum pw_stream_state state, const char *error) @@ -962,7 +745,7 @@ n_fill_frames = data->fill(data, p, n_frames); - if (n_fill_frames > 0) { + if (n_fill_frames > 0 || n_frames == 0) { d->chunk->offset = 0; d->chunk->stride = data->stride; d->chunk->size = n_fill_frames * data->stride; @@ -970,6 +753,9 @@ b->size = n_frames; } else if (n_fill_frames < 0) { fprintf(stderr, "fill error %d\n", n_fill_frames); + } else { + if (data->verbose) + printf("drain start\n"); } } else { offset = SPA_MIN(d->chunk->offset, d->maxsize); @@ -1045,7 +831,6 @@ OPT_CHANNELMAP, OPT_FORMAT, OPT_VOLUME, - OPT_LIST_TARGETS, }; static const struct option long_options = { @@ -1072,8 +857,6 @@ { "volume", required_argument, NULL, OPT_VOLUME }, { "quality", required_argument, NULL, 'q' }, - { "list-targets", no_argument, NULL, OPT_LIST_TARGETS }, - { NULL, 0, NULL, 0 } }; @@ -1101,7 +884,6 @@ " Xunit (unit = s, ms, us, ns)\n" " or direct samples (256)\n" " the rate is the one of the source file\n" - " --list-targets List available targets for --target\n" "\n"), DEFAULT_MEDIA_TYPE, DEFAULT_MEDIA_CATEGORY_PLAYBACK, @@ -1338,6 +1120,45 @@ return 0; } +static void format_from_filename(SF_INFO *info, const char *filename) +{ + int i, count = 0; + int format = -1; + +#if __BYTE_ORDER == __BIG_ENDIAN + info->format |= SF_ENDIAN_BIG; +#else + info->format |= SF_ENDIAN_LITTLE; +#endif + + if (sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)) != 0) + count = 0; + + for (i = 0; i < count; i++) { + SF_FORMAT_INFO fi; + + spa_zero(fi); + fi.format = i; + if (sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) != 0) + continue; + + if (spa_strendswith(filename, fi.extension)) { + format = fi.format; + break; + } + } + if (format == -1) + format = SF_FORMAT_WAV; + if (format == SF_FORMAT_WAV && info->channels > 2) + format = SF_FORMAT_WAVEX; + + info->format |= format; + + if (format == SF_FORMAT_OGG || format == SF_FORMAT_FLAC) + info->format = (info->format & ~SF_FORMAT_ENDMASK) | SF_ENDIAN_FILE; + if (format == SF_FORMAT_OGG) + info->format = (info->format & ~SF_FORMAT_SUBMASK) | SF_FORMAT_VORBIS; +} static int setup_sndfile(struct data *data) { @@ -1365,12 +1186,7 @@ fprintf(stderr, "error: unknown format \"%s\"\n", data->format); return -EINVAL; } - info.format |= SF_FORMAT_WAV; -#if __BYTE_ORDER == __BIG_ENDIAN - info.format |= SF_ENDIAN_BIG; -#else - info.format |= SF_ENDIAN_LITTLE; -#endif + format_from_filename(&info, data->filename); } data->file = sf_open(data->filename, @@ -1535,9 +1351,6 @@ data.volume = -1.0; data.quality = -1; - /* initialize list every time */ - spa_list_init(&data.targets); - while ((c = getopt_long(argc, argv, "hvprmdR:q:", long_options, NULL)) != -1) { switch (c) { @@ -1597,17 +1410,8 @@ case OPT_TARGET: data.target = optarg; - if (spa_streq(optarg, "auto")) { - data.target_id = PW_ID_ANY; - break; - } - if (!isdigit(optarg0)) { - fprintf(stderr, "error: bad target option \"%s\"\n", optarg); - goto error_usage; - } - data.target_id = atoi(optarg); - if (data.target_id == 0) { - data.target_id = PW_ID_ANY; + if (spa_streq(data.target, "0")) { + data.target = NULL; flags &= ~PW_STREAM_FLAG_AUTOCONNECT; } break; @@ -1646,10 +1450,6 @@ data.volume = atof(optarg); break; - case OPT_LIST_TARGETS: - data.list_targets = true; - break; - default: fprintf(stderr, "error: unknown option '%c'\n", c); goto error_usage; @@ -1677,10 +1477,7 @@ DEFAULT_MEDIA_CATEGORY_RECORD; if (!data.media_role) data.media_role = DEFAULT_MEDIA_ROLE; - if (!data.target) { - data.target = DEFAULT_TARGET; - data.target_id = PW_ID_ANY; - } + if (!data.latency) data.latency = data.mode == mode_playback ? DEFAULT_LATENCY_PLAY : @@ -1701,7 +1498,7 @@ if (data.volume < 0) data.volume = DEFAULT_VOLUME; - if (!data.list_targets && optind >= argc) { + if (optind >= argc) { fprintf(stderr, "error: filename argument missing\n"); goto error_usage; } @@ -1715,6 +1512,7 @@ PW_KEY_MEDIA_FILENAME, data.filename, PW_KEY_MEDIA_NAME, data.filename, PW_KEY_NODE_NAME, prog, + PW_KEY_TARGET_OBJECT, data.target, NULL); if (data.props == NULL) { @@ -1755,127 +1553,115 @@ } pw_core_add_listener(data.core, &data.core_listener, &core_events, &data); - data.registry = pw_core_get_registry(data.core, PW_VERSION_REGISTRY, 0); - if (!data.registry) { - fprintf(stderr, "error: pw_core_get_registry() failed: %m\n"); - goto error_no_registry; + switch (data.data_type) { + case TYPE_PCM: + ret = setup_sndfile(&data); + break; + case TYPE_MIDI: + ret = setup_midifile(&data); + break; + case TYPE_DSD: + ret = setup_dsffile(&data); + break; + default: + ret = -ENOTSUP; + break; } - pw_registry_add_listener(data.registry, &data.registry_listener, ®istry_events, &data); - - data.sync = pw_core_sync(data.core, 0, data.sync); - if (!data.list_targets) { - - switch (data.data_type) { - case TYPE_PCM: - ret = setup_sndfile(&data); - break; - case TYPE_MIDI: - ret = setup_midifile(&data); - break; - case TYPE_DSD: - ret = setup_dsffile(&data); - break; + if (ret < 0) { + fprintf(stderr, "error: open failed: %s\n", spa_strerror(ret)); + switch (ret) { + case -EIO: + goto error_bad_file; + case -EINVAL: default: - ret = -ENOTSUP; - break; + goto error_usage; } + } + switch (data.data_type) { + case TYPE_PCM: + { + struct spa_audio_info_raw info; + info = SPA_AUDIO_INFO_RAW_INIT( + .flags = data.channelmap.n_channels ? 0 : SPA_AUDIO_FLAG_UNPOSITIONED, + .format = data.spa_format, + .rate = data.rate, + .channels = data.channels); + + if (data.channelmap.n_channels) + memcpy(info.position, data.channelmap.channels, data.channels * sizeof(int)); + + params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info); + break; + } + case TYPE_MIDI: + params0 = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); - if (ret < 0) { - fprintf(stderr, "error: open failed: %s\n", spa_strerror(ret)); - switch (ret) { - case -EIO: - goto error_bad_file; - case -EINVAL: - default: - goto error_usage; - } - } - switch (data.data_type) { - case TYPE_PCM: - { - struct spa_audio_info_raw info; - info = SPA_AUDIO_INFO_RAW_INIT( - .flags = data.channelmap.n_channels ? 0 : SPA_AUDIO_FLAG_UNPOSITIONED, - .format = data.spa_format, - .rate = data.rate, - .channels = data.channels); - - if (data.channelmap.n_channels) - memcpy(info.position, data.channelmap.channels, data.channels * sizeof(int)); - - params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info); - break; - } - case TYPE_MIDI: - params0 = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, - SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); + pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + break; + case TYPE_DSD: + { + struct spa_audio_info_dsd info; + size_t i; - pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); - break; - case TYPE_DSD: - { - struct spa_audio_info_dsd info; - size_t i; - - spa_zero(info); - info.channels = data.dsf.info.channels; - info.rate = data.dsf.info.rate / 8; - - for (i = 0; i < SPA_N_ELEMENTS(dsd_layouts); i++) { - if (dsd_layoutsi.type != data.dsf.info.channel_type) - continue; - info.channels = dsd_layoutsi.info.n_channels; - memcpy(info.position, dsd_layoutsi.info.position, - info.channels * sizeof(uint32_t)); - } - params0 = spa_format_audio_dsd_build(&b, SPA_PARAM_EnumFormat, &info); - break; - } + spa_zero(info); + info.channels = data.dsf.info.channels; + info.rate = data.dsf.info.rate / 8; + + for (i = 0; i < SPA_N_ELEMENTS(dsd_layouts); i++) { + if (dsd_layoutsi.type != data.dsf.info.channel_type) + continue; + info.channels = dsd_layoutsi.info.n_channels; + memcpy(info.position, dsd_layoutsi.info.position, + info.channels * sizeof(uint32_t)); } + params0 = spa_format_audio_dsd_build(&b, SPA_PARAM_EnumFormat, &info); + break; + } + } - data.stream = pw_stream_new(data.core, prog, data.props); - data.props = NULL; + data.stream = pw_stream_new(data.core, prog, data.props); + data.props = NULL; - if (data.stream == NULL) { - fprintf(stderr, "error: failed to create stream: %m\n"); - goto error_no_stream; - } - pw_stream_add_listener(data.stream, &data.stream_listener, &stream_events, &data); - - if (data.verbose) - printf("connecting %s stream; target_id=%"PRIu32"\n", - data.mode == mode_playback ? "playback" : "record", - data.target_id); - - if (data.verbose) - data.timer = pw_loop_add_timer(l, do_print_delay, &data); - - ret = pw_stream_connect(data.stream, - data.mode == mode_playback ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT, - data.target_id, - flags | - PW_STREAM_FLAG_MAP_BUFFERS, - params, 1); - if (ret < 0) { - fprintf(stderr, "error: failed connect: %s\n", spa_strerror(ret)); - goto error_connect_fail; - } + if (data.stream == NULL) { + fprintf(stderr, "error: failed to create stream: %m\n"); + goto error_no_stream; + } + pw_stream_add_listener(data.stream, &data.stream_listener, &stream_events, &data); + + if (data.verbose) + printf("connecting %s stream; target=%s\n", + data.mode == mode_playback ? "playback" : "record", + data.target); + + if (data.verbose) + data.timer = pw_loop_add_timer(l, do_print_delay, &data); + + ret = pw_stream_connect(data.stream, + data.mode == mode_playback ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT, + PW_ID_ANY, + flags | + PW_STREAM_FLAG_MAP_BUFFERS, + params, 1); + if (ret < 0) { + fprintf(stderr, "error: failed connect: %s\n", spa_strerror(ret)); + goto error_connect_fail; + } - if (data.verbose) { - const struct pw_properties *props; - void *pstate; - const char *key, *val; - - if ((props = pw_stream_get_properties(data.stream)) != NULL) { - printf("stream properties:\n"); - pstate = NULL; - while ((key = pw_properties_iterate(props, &pstate)) != NULL && - (val = pw_properties_get(props, key)) != NULL) { - printf("\t%s = \"%s\"\n", key, val); - } + if (data.verbose) { + const struct pw_properties *props; + void *pstate; + const char *key, *val; + + if ((props = pw_stream_get_properties(data.stream)) != NULL) { + printf("stream properties:\n"); + pstate = NULL; + while ((key = pw_properties_iterate(props, &pstate)) != NULL && + (val = pw_properties_get(props, key)) != NULL) { + printf("\t%s = \"%s\"\n", key, val); } } } @@ -1884,61 +1670,8 @@ pw_main_loop_run(data.loop); /* we're returning OK only if got to the point to drain */ - if (!data.list_targets) { - if (data.drained) - exit_code = EXIT_SUCCESS; - } else { - if (data.targets_listed) { - struct target *target, *target_default; - char *default_name; - - default_name = (data.mode == mode_record) ? - data.default_source : data.default_sink; - - exit_code = EXIT_SUCCESS; - - /* first find the highest priority */ - target_default = NULL; - spa_list_for_each(target, &data.targets, link) { - if (target_default == NULL || - spa_streq(default_name, target->name) || - (default_name0 == '\0' && - target->prio > target_default->prio)) - target_default = target; - } - printf("Available targets (\"*\" denotes default): %s\n", default_name); - spa_list_for_each(target, &data.targets, link) { - if (target->type != TARGET_TYPE_SOURCE) - continue; - printf("%s\t%"PRIu32": source description=\"%s\" prio=%d\n", - target == target_default ? "*" : "", - target->id, target->desc, target->prio); - } - spa_list_for_each(target, &data.targets, link) { - if (target->type != TARGET_TYPE_SINK) - continue; - printf("%s\t%"PRIu32": %s description=\"%s\" prio=%d\n", - target == target_default ? "*" : "", - target->id, data.mode == mode_record ? "monitor" : "sink", - target->desc, target->prio); - } - spa_list_for_each(target, &data.targets, link) { - if (target->type != TARGET_TYPE_STREAM) - continue; - printf("%s\t%"PRIu32": stream description=\"%s\" prio=%d\n", - target == target_default ? "*" : "", - target->id, target->desc, target->prio); - } - } - } - - /* destroy targets */ - while (!spa_list_is_empty(&data.targets)) { - struct target *target; - target = spa_list_last(&data.targets, struct target, link); - spa_list_remove(&target->link); - target_destroy(target); - } + if (data.drained) + exit_code = EXIT_SUCCESS; error_connect_fail: if (data.stream) { @@ -1946,15 +1679,6 @@ pw_stream_destroy(data.stream); } error_no_stream: - if (data.metadata) { - spa_hook_remove(&data.metadata_listener); - pw_proxy_destroy((struct pw_proxy*)data.metadata); - } - if (data.registry) { - spa_hook_remove(&data.registry_listener); - pw_proxy_destroy((struct pw_proxy*)data.registry); - } -error_no_registry: spa_hook_remove(&data.core_listener); pw_core_disconnect(data.core); error_ctx_connect_failed:
View file
pipewire-0.3.50.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.51.tar.gz/src/tools/pw-cli.c
Changed
@@ -133,6 +133,11 @@ bool (*func) (struct data *data, const char *cmd, char *args, char **error); }; +static struct spa_dict * global_props(struct global *global); +static struct global * obj_global(struct remote_data *rd, uint32_t id); +static int children_of(struct remote_data *rd, uint32_t parent_id, + const char *child_type, uint32_t **children); + static int pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens) { const char *state = NULL; @@ -801,9 +806,9 @@ info->change_mask = 0; } -static void core_event_info(void *object, const struct pw_core_info *info) +static void core_event_info(void *data, const struct pw_core_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d core %d changed\n", rd->id, info->id); @@ -822,9 +827,9 @@ }; -static void module_event_info(void *object, const struct pw_module_info *info) +static void module_event_info(void *data, const struct pw_module_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d module %d changed\n", rd->id, info->id); @@ -842,9 +847,9 @@ .info = module_event_info }; -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *data, const struct pw_node_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d node %d changed\n", rd->id, info->id); @@ -857,10 +862,10 @@ } } -static void event_param(void *object, int seq, uint32_t id, +static void event_param(void *_data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct proxy_data *data = object; + struct proxy_data *data = _data; struct remote_data *rd = data->rd; if (rd->data->interactive) @@ -877,9 +882,9 @@ }; -static void port_event_info(void *object, const struct pw_port_info *info) +static void port_event_info(void *data, const struct pw_port_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d port %d changed\n", rd->id, info->id); @@ -898,9 +903,9 @@ .param = event_param }; -static void factory_event_info(void *object, const struct pw_factory_info *info) +static void factory_event_info(void *data, const struct pw_factory_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d factory %d changed\n", rd->id, info->id); @@ -918,9 +923,9 @@ .info = factory_event_info }; -static void client_event_info(void *object, const struct pw_client_info *info) +static void client_event_info(void *data, const struct pw_client_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d client %d changed\n", rd->id, info->id); @@ -933,10 +938,10 @@ } } -static void client_event_permissions(void *object, uint32_t index, +static void client_event_permissions(void *_data, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions) { - struct proxy_data *data = object; + struct proxy_data *data = _data; struct remote_data *rd = data->rd; uint32_t i; @@ -959,9 +964,9 @@ .permissions = client_event_permissions }; -static void link_event_info(void *object, const struct pw_link_info *info) +static void link_event_info(void *data, const struct pw_link_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d link %d changed\n", rd->id, info->id); @@ -980,9 +985,9 @@ }; -static void device_event_info(void *object, const struct pw_device_info *info) +static void device_event_info(void *data, const struct pw_device_info *info) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; if (pd->info) printf("remote %d device %d changed\n", rd->id, info->id); @@ -1008,10 +1013,10 @@ free(info); } -static void session_event_info(void *object, +static void session_event_info(void *data, const struct pw_session_info *update) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; struct pw_session_info *info = pd->info; @@ -1055,10 +1060,10 @@ free(info); } -static void endpoint_event_info(void *object, +static void endpoint_event_info(void *data, const struct pw_endpoint_info *update) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; struct pw_endpoint_info *info = pd->info; @@ -1109,10 +1114,10 @@ free(info); } -static void endpoint_stream_event_info(void *object, +static void endpoint_stream_event_info(void *data, const struct pw_endpoint_stream_info *update) { - struct proxy_data *pd = object; + struct proxy_data *pd = data; struct remote_data *rd = pd->rd; struct pw_endpoint_stream_info *info = pd->info; @@ -1498,16 +1503,69 @@ return true; } -static bool do_create_link(struct data *data, const char *cmd, char *args, char **error) +static struct global * +obj_global_port(struct remote_data *rd, struct global *global, const char *port_direction, const char *port_id) +{ + struct global *global_port_found = NULL; + uint32_t *ports = NULL; + int port_count; + + port_count = children_of(rd, global->id, PW_TYPE_INTERFACE_Port, &ports); + + if (port_count <= 0) + return NULL; + + for (int i = 0; i < port_count; i++) { + struct global *global_port = obj_global(rd, portsi); + + if (!global_port) + continue; + + struct spa_dict *props_port = global_props(global_port); + + if (spa_streq(spa_dict_lookup(props_port, "port.direction"), port_direction) + && spa_streq(spa_dict_lookup(props_port, "port.id"), port_id)) { + global_port_found = global_port; + break; + } + } + + free(ports); + return global_port_found; +} + +static void create_link_with_properties(struct data *data, struct pw_properties *props) { struct remote_data *rd = data->current; - char *a5; - int n; uint32_t id; struct pw_proxy *proxy; - struct pw_properties *props = NULL; struct proxy_data *pd; + proxy = (struct pw_proxy*)pw_core_create_object(rd->core, + "link-factory", + PW_TYPE_INTERFACE_Link, + PW_VERSION_LINK, + props ? &props->dict : NULL, + sizeof(struct proxy_data)); + + pd = pw_proxy_get_user_data(proxy); + pd->rd = rd; + pd->proxy = proxy; + pd->class = &link_class; + pw_proxy_add_object_listener(proxy, &pd->object_listener, &link_events, pd); + pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); + + id = pw_map_insert_new(&data->vars, proxy); + printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); +} + +static bool do_create_link(struct data *data, const char *cmd, char *args, char **error) +{ + struct remote_data *rd = data->current; + char *a5; + int n; + struct pw_properties *props = NULL; + n = pw_split_ip(args, WHITESPACE, 5, a); if (n < 4) { *error = spa_aprintf("%s <node-id> <port> <node-id> <port> <properties>", cmd); @@ -1527,24 +1585,54 @@ if (!spa_streq(a3, "-")) pw_properties_set(props, PW_KEY_LINK_INPUT_PORT, a3); - proxy = (struct pw_proxy*)pw_core_create_object(rd->core, - "link-factory", - PW_TYPE_INTERFACE_Link, - PW_VERSION_LINK, - props ? &props->dict : NULL, - sizeof(struct proxy_data)); + if (spa_streq(a1, "*") && spa_streq(a3, "*")) { + struct global *global_out, *global_in; + struct proxy_data *pd_out, *pd_in; + uint32_t n_output_ports, n_input_ports; - pw_properties_free(props); + global_out = find_global(rd, a0); + if (global_out == NULL) { + *error = spa_aprintf("%s: unknown global '%s'", cmd, a0); + return false; + } + global_in = find_global(rd, a2); + if (global_in == NULL) { + *error = spa_aprintf("%s: unknown global '%s'", cmd, a2); + return false; + } - pd = pw_proxy_get_user_data(proxy); - pd->rd = rd; - pd->proxy = proxy; - pd->class = &link_class; - pw_proxy_add_object_listener(proxy, &pd->object_listener, &link_events, pd); - pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); + pd_out = pw_proxy_get_user_data(global_out->proxy); + pd_in = pw_proxy_get_user_data(global_in->proxy); - id = pw_map_insert_new(&data->vars, proxy); - printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); + n_output_ports = ((struct pw_node_info *)pd_out->info)->n_output_ports; + n_input_ports = ((struct pw_node_info *)pd_in->info)->n_input_ports; + + if (n_output_ports != n_input_ports) { + *error = spa_aprintf("%s: Number of ports don't match (%u != %u)", cmd, n_output_ports, n_input_ports); + return false; + } + + for (uint32_t i = 0; i < n_output_ports; i++) { + char port_id4; + struct global *global_port_out, *global_port_in; + + snprintf(port_id, 4, "%d", i); + + global_port_out = obj_global_port(rd, global_out, "out", port_id); + global_port_in = obj_global_port(rd, global_in, "in", port_id); + + if (!global_port_out || !global_port_in) + continue; + + pw_properties_setf(props, PW_KEY_LINK_OUTPUT_PORT, "%d", global_port_out->id); + pw_properties_setf(props, PW_KEY_LINK_INPUT_PORT, "%d", global_port_in->id); + + create_link_with_properties(data, props); + } + } else + create_link_with_properties(data, props); + + pw_properties_free(props); return true; }
View file
pipewire-0.3.50.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.51.tar.gz/src/tools/pw-dot.c
Changed
@@ -603,15 +603,15 @@ .info = module_event_info }; -static void removed_proxy(void *user_data) +static void removed_proxy(void *data) { - struct global *g = user_data; + struct global *g = data; pw_proxy_destroy(g->proxy); } -static void destroy_proxy(void *user_data) +static void destroy_proxy(void *data) { - struct global *g = user_data; + struct global *g = data; spa_hook_remove(&g->object_listener); spa_hook_remove(&g->proxy_listener); }
View file
pipewire-0.3.50.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.51.tar.gz/src/tools/pw-dump.c
Changed
@@ -582,9 +582,9 @@ put_end(d, "}", 0); } -static void client_event_info(void *object, const struct pw_client_info *info) +static void client_event_info(void *data, const struct pw_client_info *info) { - struct object *o = object; + struct object *o = data; int changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -642,9 +642,9 @@ put_end(d, "}", 0); } -static void module_event_info(void *object, const struct pw_module_info *info) +static void module_event_info(void *data, const struct pw_module_info *info) { - struct object *o = object; + struct object *o = data; int changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -702,9 +702,9 @@ put_end(d, "}", 0); } -static void factory_event_info(void *object, const struct pw_factory_info *info) +static void factory_event_info(void *data, const struct pw_factory_info *info) { - struct object *o = object; + struct object *o = data; int changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -761,9 +761,9 @@ put_end(d, "}", 0); } -static void device_event_info(void *object, const struct pw_device_info *info) +static void device_event_info(void *data, const struct pw_device_info *info) { - struct object *o = object; + struct object *o = data; uint32_t i, changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -796,11 +796,11 @@ } } -static void device_event_param(void *object, int seq, +static void device_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object; + struct object *o = data; add_param(&o->pending_list, id, param); } @@ -855,9 +855,9 @@ put_end(d, "}", 0); } -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *data, const struct pw_node_info *info) { - struct object *o = object; + struct object *o = data; uint32_t i, changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -893,11 +893,11 @@ } } -static void node_event_param(void *object, int seq, +static void node_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object; + struct object *o = data; add_param(&o->pending_list, id, param); } @@ -944,9 +944,9 @@ put_end(d, "}", 0); } -static void port_event_info(void *object, const struct pw_port_info *info) +static void port_event_info(void *data, const struct pw_port_info *info) { - struct object *o = object; + struct object *o = data; uint32_t i, changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -979,11 +979,11 @@ } } -static void port_event_param(void *object, int seq, +static void port_event_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct object *o = object; + struct object *o = data; add_param(&o->pending_list, id, param); } @@ -1036,9 +1036,9 @@ put_end(d, "}", 0); } -static void link_event_info(void *object, const struct pw_link_info *info) +static void link_event_info(void *data, const struct pw_link_info *info) { - struct object *o = object; + struct object *o = data; uint32_t changed = 0; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); @@ -1163,13 +1163,13 @@ return NULL; } -static int metadata_property(void *object, +static int metadata_property(void *data, uint32_t subject, const char *key, const char *type, const char *value) { - struct object *o = object; + struct object *o = data; struct metadata_entry *e; while ((e = metadata_find(o, subject, key)) != NULL) { @@ -1332,9 +1332,9 @@ return; } -static void registry_event_global_remove(void *object, uint32_t id) +static void registry_event_global_remove(void *data, uint32_t id) { - struct data *d = object; + struct data *d = data; struct object *o; if ((o = find_object(d, id)) == NULL)
View file
pipewire-0.3.50.tar.gz/src/tools/pw-link.c -> pipewire-0.3.51.tar.gz/src/tools/pw-link.c
Changed
@@ -109,6 +109,8 @@ struct pw_proxy *proxy; struct spa_hook listener; + data->link_res = 0; + proxy = pw_core_create_object(data->core, "link-factory", PW_TYPE_INTERFACE_Link, @@ -139,6 +141,47 @@ return NULL; } +static struct object *find_node_port(struct data *data, struct object *node, enum pw_direction direction, const char *port_id) +{ + struct object *o; + + spa_list_for_each(o, &data->objects, link) { + const char *o_port_id; + if (o->type != OBJECT_PORT) + continue; + if (o->extra1 != node->id) + continue; + if (o->extra0 != direction) + continue; + if ((o_port_id = pw_properties_get(o->props, PW_KEY_PORT_ID)) == NULL) + continue; + if (spa_streq(o_port_id, port_id)) + return o; + } + + return NULL; +} + +static char *node_name(char *buffer, int size, struct object *n) +{ + const char *name; + buffer0 = '\0'; + if ((name = pw_properties_get(n->props, PW_KEY_NODE_NAME)) == NULL) + return buffer; + snprintf(buffer, size, "%s", name); + return buffer; +} + +static char *node_path(char *buffer, int size, struct object *n) +{ + const char *name; + buffer0 = '\0'; + if ((name = pw_properties_get(n->props, PW_KEY_OBJECT_PATH)) == NULL) + return buffer; + snprintf(buffer, size, "%s", name); + return buffer; +} + static char *port_name(char *buffer, int size, struct object *n, struct object *p) { const char *name1, *name2; @@ -241,6 +284,19 @@ } } +static int node_matches(struct data *data, struct object *n, const char *name) +{ + char buffer1024; + uint32_t id = atoi(name); + if (n->id == id) + return 1; + if (spa_streq(node_name(buffer, sizeof(buffer), n), name)) + return 1; + if (spa_streq(node_path(buffer, sizeof(buffer), n), name)) + return 1; + return 0; +} + static int port_matches(struct data *data, struct object *n, struct object *p, const char *name) { char buffer1024; @@ -304,11 +360,20 @@ { uint32_t in_port = 0, out_port = 0; struct object *n, *p; + struct object *in_node = NULL, *out_node = NULL; spa_list_for_each(n, &data->objects, link) { if (n->type != OBJECT_NODE) continue; + if (out_node == NULL && node_matches(data, n, data->opt_output)) { + out_node = n; + continue; + } else if (in_node == NULL && node_matches(data, n, data->opt_input)) { + in_node = n; + continue; + } + spa_list_for_each(p, &data->objects, link) { if (p->type != OBJECT_PORT) continue; @@ -323,6 +388,33 @@ in_port = p->id; } } + + if (in_node && out_node) { + int i, ret; + char port_id32; + bool all_links_exist = true; + + for (i=0;; i++) { + snprintf(port_id, sizeof(port_id), "%d", i); + + struct object *port_out = find_node_port(data, out_node, PW_DIRECTION_OUTPUT, port_id); + struct object *port_in = find_node_port(data, in_node, PW_DIRECTION_INPUT, port_id); + + if (!port_out || !port_in) + break; + + pw_properties_setf(data->props, PW_KEY_LINK_OUTPUT_PORT, "%u", port_out->id); + pw_properties_setf(data->props, PW_KEY_LINK_INPUT_PORT, "%u", port_in->id); + + if ((ret = create_link(data)) < 0 && ret != -EEXIST) + return ret; + + if (ret >= 0) + all_links_exist = false; + } + return (all_links_exist ? -EEXIST : 0); + } + if (in_port == 0 || out_port == 0) return -ENOENT; @@ -335,7 +427,24 @@ static int do_unlink_ports(struct data *data) { struct object *l, *n, *p; - uint32_t link_id = 0; + bool found_any = false; + struct object *in_node = NULL, *out_node = NULL; + + if (data->opt_input != NULL) { + /* 2 args, check if they are node names */ + spa_list_for_each(n, &data->objects, link) { + if (n->type != OBJECT_NODE) + continue; + + if (out_node == NULL && node_matches(data, n, data->opt_output)) { + out_node = n; + continue; + } else if (in_node == NULL && node_matches(data, n, data->opt_input)) { + in_node = n; + continue; + } + } + } spa_list_for_each(l, &data->objects, link) { if (l->type != OBJECT_LINK) @@ -345,6 +454,21 @@ /* 1 arg, check link id */ if (l->id != (uint32_t)atoi(data->opt_output)) continue; + } else if (out_node && in_node) { + /* 2 args, check nodes */ + if ((p = find_object(data, OBJECT_PORT, l->extra0)) == NULL) + continue; + if ((n = find_object(data, OBJECT_NODE, p->extra1)) == NULL) + continue; + if (n->id != out_node->id) + continue; + + if ((p = find_object(data, OBJECT_PORT, l->extra1)) == NULL) + continue; + if ((n = find_object(data, OBJECT_NODE, p->extra1)) == NULL) + continue; + if (n->id != in_node->id) + continue; } else { /* 2 args, check port names */ if ((p = find_object(data, OBJECT_PORT, l->extra0)) == NULL) @@ -361,14 +485,12 @@ if (!port_matches(data, n, p, data->opt_input)) continue; } - link_id = l->id; - break; + pw_registry_destroy(data->registry, l->id); + found_any = true; } - if (link_id == 0) + if (!found_any) return -ENOENT; - pw_registry_destroy(data->registry, link_id); - core_sync(data); pw_main_loop_run(data->loop); @@ -492,9 +614,9 @@ } } -static void registry_event_global_remove(void *object, uint32_t id) +static void registry_event_global_remove(void *data, uint32_t id) { - struct data *d = object; + struct data *d = data; struct object *obj; if ((obj = find_object(d, OBJECT_ANY, id)) == NULL)
View file
pipewire-0.3.50.tar.gz/src/tools/pw-mididump.c -> pipewire-0.3.51.tar.gz/src/tools/pw-mididump.c
Changed
@@ -75,9 +75,9 @@ return 0; } -static void on_process(void *userdata, struct spa_io_position *position) +static void on_process(void *_data, struct spa_io_position *position) { - struct data *data = userdata; + struct data *data = _data; struct pw_buffer *b; struct spa_buffer *buf; struct spa_data *d;
View file
pipewire-0.3.50.tar.gz/src/tools/pw-mon.c -> pipewire-0.3.51.tar.gz/src/tools/pw-mon.c
Changed
@@ -148,10 +148,10 @@ } } -static void event_param(void *object, int seq, uint32_t id, +static void event_param(void *_data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { - struct proxy_data *data = object; + struct proxy_data *data = _data; struct param *p; /* remove all params with the same id and older seq */ @@ -233,9 +233,9 @@ } } -static void module_event_info(void *object, const struct pw_module_info *info) +static void module_event_info(void *_data, const struct pw_module_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; bool print_all, print_mark; print_all = true; @@ -309,9 +309,9 @@ } } -static void node_event_info(void *object, const struct pw_node_info *info) +static void node_event_info(void *_data, const struct pw_node_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; uint32_t i; info = data->info = pw_node_info_update(data->info, info); @@ -368,9 +368,9 @@ } } -static void port_event_info(void *object, const struct pw_port_info *info) +static void port_event_info(void *_data, const struct pw_port_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; uint32_t i; info = data->info = pw_port_info_update(data->info, info); @@ -399,9 +399,9 @@ .param = event_param }; -static void factory_event_info(void *object, const struct pw_factory_info *info) +static void factory_event_info(void *_data, const struct pw_factory_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; bool print_all, print_mark; print_all = true; @@ -433,9 +433,9 @@ .info = factory_event_info }; -static void client_event_info(void *object, const struct pw_client_info *info) +static void client_event_info(void *_data, const struct pw_client_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; bool print_all, print_mark; print_all = true; @@ -465,9 +465,9 @@ .info = client_event_info }; -static void link_event_info(void *object, const struct pw_link_info *info) +static void link_event_info(void *_data, const struct pw_link_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; bool print_all, print_mark; print_all = true; @@ -544,9 +544,9 @@ } -static void device_event_info(void *object, const struct pw_device_info *info) +static void device_event_info(void *_data, const struct pw_device_info *info) { - struct proxy_data *data = object; + struct proxy_data *data = _data; uint32_t i; info = data->info = pw_device_info_update(data->info, info); @@ -700,9 +700,9 @@ return NULL; } -static void registry_event_global_remove(void *object, uint32_t id) +static void registry_event_global_remove(void *data, uint32_t id) { - struct data *d = object; + struct data *d = data; struct proxy_data *pd; printf("removed:\n");
View file
pipewire-0.3.50.tar.gz/src/tools/pw-top.c -> pipewire-0.3.51.tar.gz/src/tools/pw-top.c
Changed
@@ -65,6 +65,7 @@ struct node *driver; uint32_t errors; int32_t last_error_status; + uint32_t generation; }; struct data { @@ -85,6 +86,7 @@ int n_nodes; struct spa_list node_list; + uint32_t generation; WINDOW *win; }; @@ -182,6 +184,7 @@ n->measurement = m; n->info = point->info; point->driver = n; + n->generation = d->generation; if (m.status != 3) { n->errors++; @@ -216,6 +219,7 @@ n->measurement = m; n->driver = point->driver; + n->generation = d->generation; if (m.status != 3) { n->errors++; if (n->last_error_status == -1) @@ -226,7 +230,11 @@ static const char *print_time(char *buf, size_t len, uint64_t val) { - if (val < 1000000llu) + if (val == (uint64_t)-1) + snprintf(buf, len, " --- "); + else if (val == (uint64_t)-2) + snprintf(buf, len, " +++ "); + else if (val < 1000000llu) snprintf(buf, len, "%5.1fµs", val/1000.f); else if (val < 1000000000llu) snprintf(buf, len, "%5.1fms", val/1000000.f); @@ -235,9 +243,16 @@ return buf; } -static const char *print_perc(char *buf, size_t len, float val, float quantum) +static const char *print_perc(char *buf, size_t len, uint64_t val, float quantum) { - snprintf(buf, len, "%5.2f", quantum == 0.0f ? 0.0f : val/quantum); + if (val == (uint64_t)-1) { + snprintf(buf, len, " --- "); + } else if (val == (uint64_t)-2) { + snprintf(buf, len, " +++ "); + } else { + float frac = val / 1000000000.f; + snprintf(buf, len, "%5.2f", quantum == 0.0f ? 0.0f : frac/quantum); + } return buf; } @@ -247,7 +262,8 @@ char buf264; char buf364; char buf464; - float waiting, busy, quantum; + uint64_t waiting, busy; + float quantum; struct spa_fraction frac; if (n->driver == n) @@ -260,15 +276,26 @@ else quantum = 0.0; - waiting = (n->measurement.awake - n->measurement.signal) / 1000000000.f, - busy = (n->measurement.finish - n->measurement.awake) / 1000000000.f, + if (n->measurement.awake >= n->measurement.signal) + waiting = n->measurement.awake - n->measurement.signal; + else if (n->measurement.signal > n->measurement.prev_signal) + waiting = -2; + else + waiting = -1; + + if (n->measurement.finish >= n->measurement.awake) + busy = n->measurement.finish - n->measurement.awake; + else if (n->measurement.awake > n->measurement.prev_signal) + busy = -2; + else + busy = -1; mvwprintw(d->win, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %s%s", n->measurement.status != 3 ? "!" : " ", n->id, frac.num, frac.denom, - print_time(buf1, 64, n->measurement.awake - n->measurement.signal), - print_time(buf2, 64, n->measurement.finish - n->measurement.awake), + print_time(buf1, 64, waiting), + print_time(buf2, 64, busy), print_perc(buf3, 64, waiting, quantum), print_perc(buf4, 64, busy, quantum), i->xrun_count + n->errors, @@ -296,6 +323,14 @@ break; spa_list_for_each(f, &d->node_list, link) { + if (d->generation > f->generation + 2) { + f->driver = f; + spa_zero(f->measurement); + spa_zero(f->info); + f->errors = 0; + f->last_error_status = 0; + } + if (f->driver != n || f == n) continue; @@ -316,6 +351,7 @@ static void do_timeout(void *data, uint64_t expirations) { struct data *d = data; + d->generation++; do_refresh(d); }
View file
pipewire-0.3.50.tar.gz/test/pwtest-implementation.h -> pipewire-0.3.51.tar.gz/test/pwtest-implementation.h
Changed
@@ -131,7 +131,7 @@ struct pwtest_suite_decl { const char *name; enum pwtest_result (*setup)(struct pwtest_context *, struct pwtest_suite *); -} __attribute__((aligned(16))); +}; #endif /* PWTEST_IMPLEMENTATION_H */
View file
pipewire-0.3.50.tar.gz/test/pwtest.h -> pipewire-0.3.51.tar.gz/test/pwtest.h
Changed
@@ -494,9 +494,11 @@ */ #define PWTEST_SUITE(cname) \ static enum pwtest_result (cname##__setup)(struct pwtest_context *ctx, struct pwtest_suite *suite); \ - static const struct pwtest_suite_decl _test_suite \ __attribute__((used)) \ - __attribute((section("pwtest_suite_section"))) = { \ + __attribute__((retain)) \ + __attribute__((section("pwtest_suite_section"))) \ + __attribute__((aligned(__alignof__(struct pwtest_suite_decl)))) \ + static const struct pwtest_suite_decl _test_suite = { \ .name = #cname, \ .setup = cname##__setup, \ }; \
View file
pipewire-0.3.50.tar.gz/test/test-spa-json.c -> pipewire-0.3.51.tar.gz/test/test-spa-json.c
Changed
@@ -176,6 +176,12 @@ pwtest_str_eq(dst, "\"\\u0004\\u0005\\u001f \\u0001\x7f\x90\""); pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); pwtest_str_eq(result, "\x04\x05\x1f\x20\x01\x7f\x90"); + strcpy(dst, "\"\\u03b2a\""); + pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); + pwtest_str_eq(result, "\316\262a"); + strcpy(dst, "\"\\u 03b2a \""); + pwtest_int_eq(spa_json_parse_stringn(dst, sizeof(dst), result, sizeof(result)), 1); + pwtest_str_eq(result, "u 03b2a "); return PWTEST_PASS; }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.