Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 37
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Mon Oct 23 15:00:54 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.83 + +------------------------------------------------------------------- Wed Oct 18 08:54:11 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.82
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.82 +Version: 0.3.83 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/test-helper.h
Deleted
@@ -1,97 +0,0 @@ -#include <dlfcn.h> - -#include <spa/support/plugin.h> -#include <spa/utils/type.h> -#include <spa/utils/result.h> -#include <spa/support/cpu.h> -#include <spa/utils/names.h> - -static inline const struct spa_handle_factory *get_factory(spa_handle_factory_enum_func_t enum_func, - const char *name, uint32_t version) -{ - uint32_t i; - int res; - const struct spa_handle_factory *factory; - - for (i = 0;;) { - if ((res = enum_func(&factory, &i)) <= 0) { - if (res < 0) - errno = -res; - break; - } - if (factory->version >= version && - !strcmp(factory->name, name)) - return factory; - } - return NULL; -} - -static inline struct spa_handle *load_handle(const struct spa_support *support, - uint32_t n_support, const char *lib, const char *name) -{ - int res, len; - void *hnd; - spa_handle_factory_enum_func_t enum_func; - const struct spa_handle_factory *factory; - struct spa_handle *handle; - const char *str; - char *path; - - if ((str = getenv("SPA_PLUGIN_DIR")) == NULL) - str = PLUGINDIR; - - len = strlen(str) + strlen(lib) + 2; - path = alloca(len); - snprintf(path, len, "%s/%s", str, lib); - - if ((hnd = dlopen(path, RTLD_NOW)) == NULL) { - fprintf(stderr, "can't load %s: %s\n", lib, dlerror()); - res = -ENOENT; - goto error; - } - if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { - fprintf(stderr, "can't find enum function\n"); - res = -ENXIO; - goto error_close; - } - - if ((factory = get_factory(enum_func, name, SPA_VERSION_HANDLE_FACTORY)) == NULL) { - fprintf(stderr, "can't find factory\n"); - res = -ENOENT; - goto error_close; - } - handle = calloc(1, spa_handle_factory_get_size(factory, NULL)); - if ((res = spa_handle_factory_init(factory, handle, - NULL, support, n_support)) < 0) { - fprintf(stderr, "can't make factory instance: %d\n", res); - goto error_close; - } - return handle; - -error_close: - dlclose(hnd); -error: - errno = -res; - return NULL; -} - -static inline uint32_t get_cpu_flags(void) -{ - struct spa_handle *handle; - uint32_t flags; - void *iface; - int res; - - handle = load_handle(NULL, 0, "support/libspa-support.so", SPA_NAME_SUPPORT_CPU); - if (handle == NULL) - return 0; - if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_CPU, &iface)) < 0) { - fprintf(stderr, "can't get CPU interface %s\n", spa_strerror(res)); - return 0; - } - flags = spa_cpu_get_flags((struct spa_cpu*)iface); - - free(handle); - - return flags; -}
View file
pipewire-0.3.82.tar.gz/.gitlab-ci.yml -> pipewire-0.3.83.tar.gz/.gitlab-ci.yml
Changed
@@ -343,7 +343,7 @@ - echo "Building with ASan and UBSan" - meson setup "$BUILD_DIR" --prefix="$PREFIX" -D debug=true -D optimization=g -D b_sanitize=address,undefined -D session-managers= - meson compile -C "$BUILD_DIR" $COMPILE_ARGS - - meson test -C "$BUILD_DIR" --no-rebuild + - env UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1 ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1 meson test -C "$BUILD_DIR" --no-rebuild # A release build with NDEBUG, all options on auto() but tests explicitly # enabled. This should show issues with tests failing due to different
View file
pipewire-0.3.82.tar.gz/NEWS -> pipewire-0.3.83.tar.gz/NEWS
Changed
@@ -1,3 +1,60 @@ +# PipeWire 0.3.83 (2023-10-19) + +This is the third 1.0 release candidate that is API and ABI compatible +with previous 0.3.x releases. + +## Highlights + - A quantum change regression was fixed. + - Use a 2 socket server now for the manager and the applications + with (when wireplumber is updated) different permissions. + - Reduce memory usage a little in audioconvert and use fewer buffers. + - Some JACK deadlocks were fixed. + - More bugfixes and improvements. + + +## PipeWire + - Fix quantum change regression. (#3574) + - Use a 2 socket server by default. One for the session-manager and one + for applications. + - Fix a potential use-after-free in node and device cleanup. (#3588) + +## modules + - Some hardcoded buffer size limits were removed. + - Fix ASYNC flag on combined-streams. + - Add support for on-demand combined-streams using metadata. + +## SPA + - alsa-udev will now ignore PCMs with the ACP_IGNORE udev environment + variable. (#3570) + - The audioadapter now uses at least 2 buffers when the follower is + async. + - The number of buffers used by plugins was tweaked a little. Most + plugins now only ask 1 buffer. + - Memory usage in audioconvert was reduced. + - Fix some unaligned reads and writes and undefined left shifts reported + by ASAN. (#3572) + - Rework vulkan dependency checking. + - Don't try to link ALSA devices when prepare fails. This fixes some + crashes. + - Fix a stall when the allowed codecs are changed in ALSA. + - Improve ALSA rate control for sources to avoid xruns. (#3584) + - Try to fix IEC958 TrueHD and DTS playback. (#2284) + +## Bluetooth + - Improve fallback SCO mtu when the kernel doesn't tell us. + +## JACK + - The fixed buffer size limit was removed. + - Add an option to make input buffers writable (default true). + - A potential deadlock was fixed when applications lock the process + function. (#3585) + - Use a separate thread to dispatch notifications to avoid deadlocks. + (#3585) + - Potentially fix silent export in ardour in some cases. (#3514) + +Older versions: + + # PipeWire 0.3.82 (2023-10-13) This is the second 1.0 release candidate that is API and ABI compatible @@ -60,9 +117,6 @@ ## ALSA-plugins - Add also.deny option to block alsa clients from opening the PCM. -Older versions: - - # PipeWire 0.3.81 (2023-10-06) This is the first 1.0 release candidate that is API and ABI compatible
View file
pipewire-0.3.82.tar.gz/meson.build -> pipewire-0.3.83.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.82', + version : '0.3.83', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3',
View file
pipewire-0.3.82.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.83.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -52,8 +52,6 @@ #define MONITOR_EXT " Monitor" #define MAX_MIX 1024 -#define MAX_BUFFER_FRAMES 8192 - #define MAX_CLIENT_PORTS 768 #define MAX_ALIGN 16 @@ -255,10 +253,10 @@ unsigned int empty_out:1; unsigned int zeroed:1; - float *emptyptr; - float emptyMAX_BUFFER_FRAMES + MAX_ALIGN; - void *(*get_buffer) (struct port *p, jack_nframes_t frames); + + float *emptyptr; + float empty; }; struct link { @@ -275,6 +273,8 @@ struct pw_loop *l; struct pw_thread_loop *loop; /* thread_lock protects all below */ struct pw_context *context; + struct pw_loop *nl; + struct pw_thread_loop *notify; struct spa_thread_utils *old_thread_utils; struct spa_thread_utils thread_utils; @@ -433,6 +433,9 @@ char filter_char; uint32_t max_ports; unsigned int fill_aliases:1; + unsigned int writable_input:1; + + uint32_t max_frames; jack_position_t jack_position; jack_transport_state_t jack_state; @@ -536,7 +539,7 @@ do_mix_set_io(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) { - struct io_info *info = user_data; + const struct io_info *info = data; info->mix->io = info->data; return 0; } @@ -545,7 +548,7 @@ { struct io_info info = { .mix = mix, .data = data }; pw_data_loop_invoke(mix->port->client->loop, - do_mix_set_io, SPA_ID_INVALID, NULL, 0, true, &info); + do_mix_set_io, SPA_ID_INVALID, &info, sizeof(info), false, NULL); } static void init_mix(struct mix *mix, uint32_t mix_id, struct port *port, uint32_t peer_id) @@ -658,7 +661,7 @@ { struct port *p; struct object *o; - uint32_t i; + uint32_t i, port_size; if (c->n_ports >= c->max_ports) { errno = ENOSPC; @@ -666,11 +669,15 @@ } if (spa_list_is_empty(&c->free_ports)) { - p = calloc(OBJECT_CHUNK, sizeof(struct port)); + port_size = sizeof(struct port) + (c->max_frames * sizeof(float)) + MAX_ALIGN; + + p = calloc(OBJECT_CHUNK, port_size); if (p == NULL) return NULL; - for (i = 0; i < OBJECT_CHUNK; i++) - spa_list_append(&c->free_ports, &pi.link); + for (i = 0; i < OBJECT_CHUNK; i++) { + struct port *t = SPA_PTROFF(p, port_size * i, struct port); + spa_list_append(&c->free_ports, &t->link); + } } p = spa_list_first(&c->free_ports, struct port, link); spa_list_remove(&p->link); @@ -947,7 +954,7 @@ #define check_callbacks(c) \ ({ \ if ((c)->frozen_callbacks == 0 && (c)->pending_callbacks) \ - pw_loop_signal_event((c)->context.l, (c)->notify_source); \ + pw_loop_signal_event((c)->context.nl, (c)->notify_source); \ }) #define thaw_callbacks(c) \ ({ \ @@ -955,16 +962,18 @@ check_callbacks(c); \ }) -static void emit_callbacks(struct client *c) +static void on_notify_event(void *data, uint64_t count) { + struct client *c = data; struct object *o; int32_t avail; uint32_t index; struct notify *notify; bool do_graph = false, do_recompute_capture = false, do_recompute_playback = false; + pw_thread_loop_lock(c->context.loop); if (c->frozen_callbacks != 0 || !c->pending_callbacks) - return; + goto done; pw_log_debug("%p: enter active:%u", c, c->active); @@ -1080,7 +1089,9 @@ do_callback(c, graph_callback, c->active, c->graph_arg); thaw_callbacks(c); +done: pw_log_debug("%p: leave", c); + pw_thread_loop_unlock(c->context.loop); } static int queue_notify(struct client *c, int type, struct object *o, int arg1, const char *msg) @@ -1170,12 +1181,6 @@ return res; } -static void on_notify_event(void *data, uint64_t count) -{ - struct client *c = data; - emit_callbacks(c); -} - static void on_sync_reply(void *data, uint32_t id, int seq) { struct client *client = data; @@ -1481,6 +1486,7 @@ static inline void process_empty(struct port *p, uint32_t frames) { + struct client *c = p->client; void *ptr, *src = p->emptyptr; struct port *tied = p->tied; @@ -1498,10 +1504,10 @@ case TYPE_ID_MIDI: { struct buffer *b; - ptr = get_buffer_output(p, MAX_BUFFER_FRAMES, 1, &b); + ptr = get_buffer_output(p, c->max_frames, 1, &b); if (SPA_LIKELY(ptr != NULL)) b->datas0.chunk->size = convert_from_midi(src, - ptr, MAX_BUFFER_FRAMES * sizeof(float)); + ptr, c->max_frames * sizeof(float)); break; } default: @@ -1513,19 +1519,14 @@ static void prepare_output(struct port *p, uint32_t frames) { struct mix *mix; - struct spa_io_buffers *io; if (SPA_UNLIKELY(p->empty_out || p->tied)) process_empty(p, frames); - if (p->global_mix == NULL || (io = p->global_mix->io) == NULL) - return; - spa_list_for_each(mix, &p->mix, port_link) { if (SPA_LIKELY(mix->io != NULL)) - *mix->io = *io; + *mix->io = p->io; } - io->status = SPA_STATUS_NEED_DATA; } static void complete_process(struct client *c, uint32_t frames) @@ -1541,6 +1542,7 @@ if (!p->valid) continue; prepare_output(p, frames); + p->io.status = SPA_STATUS_NEED_DATA; } pw_array_for_each(item, &c->portsSPA_DIRECTION_INPUT.items) { if (pw_map_item_is_free(item)) @@ -2213,10 +2215,10 @@ case TYPE_ID_MIDI: *param = spa_pod_builder_add_object(b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_STEP_Int( - MAX_BUFFER_FRAMES * sizeof(float), + c->max_frames * sizeof(float), sizeof(float), INT32_MAX, sizeof(float)), @@ -2226,7 +2228,7 @@ case TYPE_ID_VIDEO: *param = spa_pod_builder_add_object(b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( 320 * 240 * 4 * 4, @@ -2517,6 +2519,7 @@ static inline void *init_buffer(struct port *p) { + struct client *c = p->client; void *data = p->emptyptr; if (p->zeroed) return data; @@ -2524,14 +2527,14 @@ if (p->object->port.type_id == TYPE_ID_MIDI) { struct midi_buffer *mb = data; mb->magic = MIDI_BUFFER_MAGIC; - mb->buffer_size = MAX_BUFFER_FRAMES * sizeof(float); - mb->nframes = MAX_BUFFER_FRAMES; + mb->buffer_size = c->max_frames * sizeof(float); + mb->nframes = c->max_frames; mb->write_pos = 0; mb->event_count = 0; mb->lost_events = 0; pw_log_debug("port %p: init midi buffer size:%d", p, mb->buffer_size); } else - memset(data, 0, MAX_BUFFER_FRAMES * sizeof(float)); + memset(data, 0, c->max_frames * sizeof(float)); p->zeroed = true; return data; @@ -2569,12 +2572,14 @@ return -ENOSPC; } - if (p->object->port.type_id == TYPE_ID_VIDEO && direction == SPA_DIRECTION_INPUT) { - fl = PW_MEMMAP_FLAG_READ; - } else { - /* some apps write to the input buffer so we want everything readwrite */ - fl = PW_MEMMAP_FLAG_READWRITE; - } + fl = PW_MEMMAP_FLAG_READ; + /* Make the buffer writable when output. Some apps write to the input buffer + * so we want to make them writable as well if the option is selected. + * We can't use a PRIVATE mapping here because then we might not see changes + * in the buffer by other apps (see mmap man page). */ + if (direction == SPA_DIRECTION_OUTPUT || + (p->object->port.type_id != TYPE_ID_VIDEO && c->writable_input)) + fl |= PW_MEMMAP_FLAG_WRITE; /* clear previous buffers */ clear_buffers(c, mix); @@ -2684,6 +2689,26 @@ return res; } +static int +do_memmap_free(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_memmap *mm = user_data; + pw_log_trace("memmap %p free", mm); + pw_memmap_free(mm); + return 0; +} + +static int +do_queue_memmap_free(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct client *c = user_data; + struct pw_memmap *mm = *((struct pw_memmap **)data); + pw_loop_invoke(c->context.l, do_memmap_free, 0, NULL, 0, false, mm); + return 0; +} + static int client_node_port_set_io(void *data, enum spa_direction direction, uint32_t port_id, @@ -2733,6 +2758,12 @@ switch (id) { case SPA_IO_Buffers: mix_set_io(mix, ptr); + if (old != NULL) { + old->tag0 = SPA_ID_INVALID; + pw_data_loop_invoke(c->loop, + do_queue_memmap_free, SPA_ID_INVALID, &old, sizeof(&old), false, c); + old = NULL; + } break; default: break; @@ -3568,7 +3599,6 @@ queue_notify(c, NOTIFY_TYPE_CONNECT, o, 1, NULL); break; } - emit_callbacks(c); exit: return; @@ -3626,7 +3656,6 @@ } break; } - emit_callbacks(c); return; } @@ -3734,6 +3763,8 @@ goto no_props; client->context.loop = pw_thread_loop_new(client->name, NULL); + if (client->context.loop == NULL) + goto no_props; client->context.l = pw_thread_loop_get_loop(client->context.loop); client->context.context = pw_context_new( client->context.l, @@ -3742,7 +3773,14 @@ if (client->context.context == NULL) goto no_props; - client->notify_source = pw_loop_add_event(client->context.l, + client->context.notify = pw_thread_loop_new(client->name, NULL); + if (client->context.notify == NULL) + goto no_props; + client->context.nl = pw_thread_loop_get_loop(client->context.notify); + + client->max_frames = client->context.context->settings.clock_quantum_limit; + + client->notify_source = pw_loop_add_event(client->context.nl, on_notify_event, client); client->notify_buffer = calloc(1, NOTIFY_BUFFER_SIZE + sizeof(struct notify)); spa_ringbuffer_init(&client->notify_ring); @@ -3896,6 +3934,7 @@ client->global_buffer_size = pw_properties_get_bool(client->props, "jack.global-buffer-size", false); client->max_ports = pw_properties_get_uint32(client->props, "jack.max-client-ports", MAX_CLIENT_PORTS); client->fill_aliases = pw_properties_get_bool(client->props, "jack.fill-aliases", false); + client->writable_input = pw_properties_get_bool(client->props, "jack.writable-input", true); client->self_connect_mode = SELF_CONNECT_ALLOW; if ((str = pw_properties_get(client->props, "jack.self-connect-mode")) != NULL) { @@ -3931,6 +3970,8 @@ } pw_thread_loop_unlock(client->context.loop); + pw_thread_loop_start(client->context.notify); + pw_log_info("%p: opened", client); return (jack_client_t *)client; @@ -3988,10 +4029,14 @@ clean_transport(c); if (c->context.loop) { - queue_notify(c, NOTIFY_TYPE_REGISTRATION, c->object, 0, NULL); pw_loop_invoke(c->context.l, NULL, 0, NULL, 0, false, c); pw_thread_loop_stop(c->context.loop); } + if (c->context.notify) { + queue_notify(c, NOTIFY_TYPE_REGISTRATION, c->object, 0, NULL); + pw_loop_invoke(c->context.nl, NULL, 0, NULL, 0, false, c); + pw_thread_loop_stop(c->context.notify); + } if (c->registry) { spa_hook_remove(&c->registry_listener); @@ -4015,11 +4060,13 @@ pw_context_destroy(c->context.context); if (c->notify_source) - pw_loop_destroy_source(c->context.l, c->notify_source); + pw_loop_destroy_source(c->context.nl, c->notify_source); free(c->notify_buffer); if (c->context.loop) pw_thread_loop_destroy(c->context.loop); + if (c->context.notify) + pw_thread_loop_destroy(c->context.notify); pw_log_debug("%p: free", client); @@ -5835,13 +5882,15 @@ SPA_EXPORT size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) { + struct client *c = (struct client *) client; + return_val_if_fail(client != NULL, 0); return_val_if_fail(port_type != NULL, 0); if (spa_streq(JACK_DEFAULT_AUDIO_TYPE, port_type)) return jack_get_buffer_size(client) * sizeof(float); else if (spa_streq(JACK_DEFAULT_MIDI_TYPE, port_type)) - return MAX_BUFFER_FRAMES * sizeof(float); + return c->max_frames * sizeof(float); else if (spa_streq(JACK_DEFAULT_VIDEO_TYPE, port_type)) return 320 * 240 * 4 * sizeof(float); else
View file
pipewire-0.3.82.tar.gz/spa/include/spa/support/log.h -> pipewire-0.3.83.tar.gz/spa/include/spa/support/log.h
Changed
@@ -208,12 +208,13 @@ { enum spa_log_level max_level; + if (SPA_UNLIKELY(!log)) + return false; + if (topic && topic->has_custom_level) max_level = topic->level; - else if (log) - max_level = log->level; else - max_level = SPA_LOG_LEVEL_NONE; + max_level = log->level; return level <= max_level; } @@ -222,8 +223,8 @@ #define spa_log_logt(l,lev,topic,...) \ ({ \ struct spa_log *_l = l; \ - struct spa_interface *_if = &_l->iface; \ if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \ + struct spa_interface *_if = &_l->iface; \ if (!spa_interface_call(_if, \ struct spa_log_methods, logt, 1, \ lev, topic, \ @@ -238,8 +239,8 @@ #define spa_log_logtv(l,lev,topic,...) \ ({ \ struct spa_log *_l = l; \ - struct spa_interface *_if = &_l->iface; \ if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \ + struct spa_interface *_if = &_l->iface; \ if (!spa_interface_call(_if, \ struct spa_log_methods, logtv, 1, \ lev, topic, \
View file
pipewire-0.3.82.tar.gz/spa/meson.build -> pipewire-0.3.83.tar.gz/spa/meson.build
Changed
@@ -87,9 +87,14 @@ endif jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack')) summary({'JACK2': jack_dep.found()}, bool_yn: true, section: 'Backend') - vulkan_dep = dependency('vulkan', disabler : true, version : '>= 1.1.69', required: get_option('vulkan')) - vulkan_headers = cc.has_header('vulkan/vulkan.h', dependencies : vulkan_dep) - #summary({'Vulkan': vulkan_headers}, bool_yn: true, section: 'Misc dependencies') + + have_vulkan = false + vulkan_dep = dependency('vulkan', version : '>= 1.2.170', required: get_option('vulkan')) + if vulkan_dep.found() + have_vulkan = cc.has_header('vulkan/vulkan.h', dependencies : vulkan_dep) + assert((not get_option('vulkan').enabled()) or have_vulkan, 'Vulkan headers are missing') + endif + summary({'Vulkan': have_vulkan}, bool_yn: true, section: 'Misc dependencies') libcamera_dep = dependency('libcamera', required: get_option('libcamera')) summary({'libcamera': libcamera_dep.found()}, bool_yn: true, section: 'Backend')
View file
pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
@@ -531,7 +531,7 @@ param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( this->quantum_limit * this->frame_size * this->frame_scale,
View file
pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
@@ -477,7 +477,7 @@ param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 2, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( this->quantum_limit * this->frame_size,
View file
pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -1480,6 +1480,37 @@ return res; } +static void recalc_headroom(struct state *state) +{ + uint32_t latency; + uint32_t rate = 0; + + if (state->position != NULL) + rate = state->position->clock.target_rate.denom; + + state->headroom = state->default_headroom; + if (!state->disable_tsched || state->resample) { + /* When using timers, we might miss the pointer update for batch + * devices so add some extra headroom. With IRQ, we know the pointers + * are updated when we wake up and we don't need the headroom. */ + if (state->is_batch) + state->headroom += state->period_frames; + /* Add 32 extra samples of headroom to handle jitter in capture. + * For IRQ, we don't need this because when we wake up, we have + * exactly enough samples to read or write. */ + if (state->stream == SND_PCM_STREAM_CAPTURE) + state->headroom = SPA_MAX(state->headroom, 32u); + } + state->headroom = SPA_MIN(state->headroom, state->buffer_frames); + + latency = SPA_MAX(state->min_delay, SPA_MIN(state->max_delay, state->headroom)); + if (rate != 0 && state->rate != 0) + latency = SPA_SCALE32_UP(latency, rate, state->rate); + + state->latencystate->port_direction.min_rate = + state->latencystate->port_direction.max_rate = latency; +} + int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) { unsigned int rrate, rchannels, val, rscale = 1; @@ -1490,14 +1521,15 @@ snd_pcm_access_mask_t *amask; snd_pcm_t *hndl; unsigned int periods; - bool match = true, planar = false, is_batch; + bool match = true, planar = false; char spdif_params128 = ""; - uint32_t default_period, latency; + uint32_t default_period; spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened, state->have_format, state->started); state->use_mmap = !state->disable_mmap; + state->force_position = false; switch (fmt->media_subtype) { case SPA_MEDIA_SUBTYPE_raw: @@ -1560,6 +1592,7 @@ IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO, IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, 0, aes3); + state->force_position = true; break; } case SPA_MEDIA_SUBTYPE_dsd: @@ -1721,20 +1754,20 @@ dir = 0; period_size = state->default_period_size; - is_batch = snd_pcm_hw_params_is_batch(params) && !state->disable_batch; + state->is_batch = snd_pcm_hw_params_is_batch(params) && !state->disable_batch; default_period = SPA_SCALE32_UP(DEFAULT_PERIOD, state->rate, DEFAULT_RATE); default_period = flp2(2 * default_period - 1); /* no period size specified. If we are batch or not using timers, * use the graph duration as the period */ - if (period_size == 0 && (is_batch || state->disable_tsched)) + if (period_size == 0 && (state->is_batch || state->disable_tsched)) period_size = state->position ? state->position->clock.target_duration : default_period; if (period_size == 0) period_size = default_period; - if (!state->disable_tsched) { - if (is_batch) { + if (!state->disable_tsched || state->resample) { + if (state->is_batch) { /* batch devices get their hw pointers updated every period. Make * the period smaller and add one period of headroom. Limit the * period size to our default so that we don't create too much @@ -1774,20 +1807,6 @@ return -EIO; } - state->headroom = state->default_headroom; - if (!state->disable_tsched) { - /* When using timers, we might miss the pointer update for batch - * devices so add some extra headroom. With IRQ, we know the pointers - * are updated when we wake up and we don't need the headroom. */ - if (is_batch) - state->headroom += period_size; - /* Add 32 extra samples of headroom to handle jitter in capture. - * For IRQ, we don't need this because when we wake up, we have - * exactly enough samples to read or write. */ - if (state->stream == SND_PCM_STREAM_CAPTURE) - state->headroom = SPA_MAX(state->headroom, 32u); - } - state->max_delay = state->buffer_frames / 2; if (spa_strstartswith(state->props.device, "a52") || spa_strstartswith(state->props.device, "dca")) @@ -1795,15 +1814,9 @@ else state->min_delay = 0; - state->headroom = SPA_MIN(state->headroom, state->buffer_frames); state->start_delay = state->default_start_delay; - latency = SPA_MAX(state->min_delay, SPA_MIN(state->max_delay, state->headroom)); - if (state->position != NULL) - latency = SPA_SCALE32_UP(latency, state->position->clock.target_rate.denom, state->rate); - - state->latencystate->port_direction.min_rate = - state->latencystate->port_direction.max_rate = latency; + recalc_headroom(state); spa_log_info(state->log, "%s: format:%s access:%s-%s rate:%d channels:%d " "buffer frames %lu, period frames %lu, periods %u, frame_size %zd " @@ -1813,7 +1826,7 @@ planar ? "planar" : "interleaved", state->rate, state->channels, state->buffer_frames, state->period_frames, periods, state->frame_size, state->headroom, state->start_delay, - is_batch, !state->disable_tsched); + state->is_batch, !state->disable_tsched); /* write the parameters to device */ CHECK(snd_pcm_hw_params(hndl, params), "set_hw_params"); @@ -2132,10 +2145,12 @@ static inline snd_pcm_sframes_t alsa_avail(struct state *state) { - if (state->disable_tsched) - return snd_pcm_avail_update(state->hndl); + snd_pcm_sframes_t avail; + if (state->disable_tsched && !state->resample) + avail = snd_pcm_avail_update(state->hndl); else - return snd_pcm_avail(state->hndl); + avail = snd_pcm_avail(state->hndl); + return avail; } static int get_avail(struct state *state, uint64_t current_time, snd_pcm_uframes_t *delay) @@ -2337,6 +2352,7 @@ state->matching = false; state->resample = !state->pitch_elem && (((uint32_t)state->rate != state->driver_rate.denom) || state->matching); + recalc_headroom(state); spa_log_info(state->log, "driver clock:'%s'@%d our clock:'%s'@%d matching:%d resample:%d", state->position->clock.name, state->driver_rate.denom, @@ -2364,7 +2380,8 @@ if (SPA_UNLIKELY((pos = state->position) == NULL)) return 0; - if (state->disable_tsched && state->started && !state->following) { + if (state->force_position || + (state->disable_tsched && state->started && !state->following)) { target_duration = state->period_frames; target_rate = SPA_FRACTION(1, state->rate); pos->clock.target_duration = target_duration; @@ -2428,18 +2445,20 @@ else lev = SPA_LOG_LEVEL_INFO; - if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) { - spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld " - "target:%ld thr:%u, resync (%d suppressed)", - state->name, avail, delay, - target, state->threshold, suppressed); - } + if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) + lev = SPA_LOG_LEVEL_DEBUG; + + spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld " + "target:%ld thr:%u, resync (%d suppressed)", + state->name, avail, delay, + target, state->threshold, suppressed); if (avail > target) snd_pcm_rewind(state->hndl, avail - target); else if (avail < target) spa_alsa_silence(state, target - avail); avail = target; + spa_dll_init(&state->dll); state->alsa_sync = false; } else state->alsa_sync_warning = true; @@ -2688,11 +2707,12 @@ else lev = SPA_LOG_LEVEL_INFO; - if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) >= 0) { - spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u, " - "resync (%d suppressed)", state->name, delay, - target, state->threshold, suppressed); - } + if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) + lev = SPA_LOG_LEVEL_DEBUG; + + spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u " + "resample:%d, resync (%d suppressed)", state->name, delay, + target, state->threshold, state->resample, suppressed); if (avail < target) max_read = target - avail; @@ -2701,6 +2721,7 @@ avail = target; } state->alsa_sync = false; + spa_dll_init(&state->dll); } else state->alsa_sync_warning = true; @@ -2714,7 +2735,7 @@ static int alsa_read_frames(struct state *state) { snd_pcm_t *hndl = state->hndl; - snd_pcm_uframes_t total_read = 0, to_read; + snd_pcm_uframes_t total_read = 0, avail; const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t read, frames, offset; snd_pcm_sframes_t commitres; @@ -2723,15 +2744,15 @@ frames = state->max_read; if (state->use_mmap) { - to_read = state->buffer_frames; - if ((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &to_read)) < 0) { + avail = state->buffer_frames; + if ((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &avail)) < 0) { spa_log_error(state->log, "%s: snd_pcm_mmap_begin error: %s", state->name, snd_strerror(res)); alsa_recover(state, res); return res; } - spa_log_trace_fp(state->log, "%p: begin offs:%ld frames:%ld to_read:%ld thres:%d", state, - offset, frames, to_read, state->threshold); + spa_log_trace_fp(state->log, "%p: begin offs:%ld frames:%ld avail:%ld thres:%d", state, + offset, frames, avail, state->threshold); } else { my_areas = NULL; offset = 0; @@ -2758,7 +2779,7 @@ lev = SPA_LOG_LEVEL_INFO; spa_log_lev(state->log, lev, "%s: snd_pcm_mmap_commit error %lu %lu %lu: %s", - state->name, frames, to_read, read, snd_strerror(commitres)); + state->name, frames, avail, read, snd_strerror(commitres)); if (commitres != -EPIPE && commitres != -ESTRPIPE) return res; } @@ -3042,7 +3063,8 @@ spa_list_for_each(follower, &state->followers, driver_link) { if (follower != state && !follower->matching) { - spa_alsa_prepare(follower); + if (spa_alsa_prepare(follower) < 0) + continue; if (!follower->linked && state->auto_link) do_link(state, follower); }
View file
pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -218,6 +218,8 @@ unsigned int sources_added:1; unsigned int auto_link:1; unsigned int linked:1; + unsigned int is_batch:1; + unsigned int force_position:1; uint64_t iec958_codecs;
View file
pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
@@ -329,6 +329,27 @@ return errno != 0 ? -errno : num_dev; } +static int check_udev_environment(struct udev *udev, const char *devname) +{ + char pathPATH_MAX; + struct udev_device *dev; + int ret = 0; + + /* Check for ACP_IGNORE on a specific PCM device (not the whole card) */ + spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s", devname); + + dev = udev_device_new_from_syspath(udev, path); + if (dev == NULL) + return 0; + + if (udev_device_get_property_value(dev, "ACP_IGNORE")) + ret = -ENXIO; + + udev_device_unref(dev); + + return ret; +} + static int check_pcm_device_availability(struct impl *this, struct card *card, int *num_pcm_devices) { @@ -376,6 +397,9 @@ card->card_nr, entry->d_name+3); if (check_device_pcm_class(path) < 0) continue; + /* Check udev environment */ + if (check_udev_environment(this->udev, path) < 0) + continue; /* Check busy status */ spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s",
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -432,6 +432,9 @@ SPA_PARAM_BUFFERS_align, SPA_POD_OPT_Int(&align))) < 0) return res; + if (this->async) + buffers = SPA_MAX(2u, buffers); + spa_log_debug(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", this, buffers, blocks, size, stride, align, follower_alloc, conv_alloc); @@ -1274,7 +1277,7 @@ } if (idx == IDX_EnumFormat) { spa_log_debug(this->log, "new formats"); - configure_format(this, 0, NULL); + /* we will renegotiate when restarting */ } this->paramsidx.user++;
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -158,6 +158,7 @@ uint32_t blocks; uint32_t stride; + uint32_t maxsize; const struct spa_pod_sequence *ctrl; uint32_t ctrl_offset; @@ -237,7 +238,8 @@ unsigned int rate_adjust:1; unsigned int port_ignore_latency:1; - uint32_t empty_size; + uint32_t scratch_size; + uint32_t scratch_ports; float *empty; float *scratch; float *tmp2; @@ -1754,10 +1756,68 @@ return 0; } +static void free_tmp(struct impl *this) +{ + uint32_t i; + + spa_log_debug(this->log, "free tmp %d", this->scratch_size); + + free(this->empty); + this->empty = NULL; + this->scratch_size = 0; + this->scratch_ports = 0; + free(this->scratch); + this->scratch = NULL; + free(this->tmp0); + this->tmp0 = NULL; + free(this->tmp1); + this->tmp1 = NULL; + for (i = 0; i < MAX_PORTS; i++) { + this->tmp_datas0i = NULL; + this->tmp_datas1i = NULL; + } +} + +static int ensure_tmp(struct impl *this, uint32_t maxsize, uint32_t maxports) +{ + if (maxsize > this->scratch_size || maxports > this->scratch_ports) { + float *empty, *scratch, *tmp2; + uint32_t i; + + spa_log_debug(this->log, "resize tmp %d -> %d", this->scratch_size, maxsize); + + if ((empty = realloc(this->empty, maxsize + MAX_ALIGN)) != NULL) + this->empty = empty; + if ((scratch = realloc(this->scratch, maxsize + MAX_ALIGN)) != NULL) + this->scratch = scratch; + if ((tmp0 = realloc(this->tmp0, (maxsize + MAX_ALIGN) * maxports)) != NULL) + this->tmp0 = tmp0; + if ((tmp1 = realloc(this->tmp1, (maxsize + MAX_ALIGN) * maxports)) != NULL) + this->tmp1 = tmp1; + + if (empty == NULL || scratch == NULL || tmp0 == NULL || tmp1 == NULL) { + free_tmp(this); + return -ENOMEM; + } + memset(this->empty, 0, maxsize + MAX_ALIGN); + this->scratch_size = maxsize; + this->scratch_ports = maxports; + + for (i = 0; i < maxports; i++) { + this->tmp_datas0i = SPA_PTROFF(tmp0, maxsize * i, void); + this->tmp_datas0i = SPA_PTR_ALIGN(this->tmp_datas0i, MAX_ALIGN, void); + this->tmp_datas1i = SPA_PTROFF(tmp1, maxsize * i, void); + this->tmp_datas1i = SPA_PTR_ALIGN(this->tmp_datas1i, MAX_ALIGN, void); + } + } + return 0; +} + static int setup_convert(struct impl *this) { struct dir *in, *out; - uint32_t i, rate; + uint32_t i, rate, maxsize, maxports; + struct port *p; int res; in = &this->dirSPA_DIRECTION_INPUT; @@ -1806,12 +1866,19 @@ if ((res = setup_out_convert(this)) < 0) return res; - for (i = 0; i < MAX_PORTS; i++) { - this->tmp_datas0i = SPA_PTROFF(this->tmp0, this->empty_size * i, void); - this->tmp_datas0i = SPA_PTR_ALIGN(this->tmp_datas0i, MAX_ALIGN, void); - this->tmp_datas1i = SPA_PTROFF(this->tmp1, this->empty_size * i, void); - this->tmp_datas1i = SPA_PTR_ALIGN(this->tmp_datas1i, MAX_ALIGN, void); + maxsize = this->quantum_limit * sizeof(float); + for (i = 0; i < in->n_ports; i++) { + p = GET_IN_PORT(this, i); + maxsize = SPA_MAX(maxsize, p->maxsize); + } + for (i = 0; i < out->n_ports; i++) { + p = GET_OUT_PORT(this, i); + maxsize = SPA_MAX(maxsize, p->maxsize); } + maxports = SPA_MAX(in->format.info.raw.channels, out->format.info.raw.channels); + if ((res = ensure_tmp(this, maxsize, maxports)) < 0) + return res; + this->setup = true; emit_node_info(this, false); @@ -2071,7 +2138,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(port->blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( size * port->stride, @@ -2445,53 +2512,6 @@ SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED); } -static void free_tmp(struct impl *this) -{ - uint32_t i; - - spa_log_debug(this->log, "free tmp %d", this->empty_size); - - free(this->empty); - this->empty = NULL; - this->empty_size = 0; - free(this->scratch); - this->scratch = NULL; - free(this->tmp0); - this->tmp0 = NULL; - free(this->tmp1); - this->tmp1 = NULL; - for (i = 0; i < MAX_PORTS; i++) { - this->tmp_datas0i = NULL; - this->tmp_datas1i = NULL; - } -} - -static int ensure_tmp(struct impl *this, uint32_t maxsize) -{ - if (maxsize > this->empty_size) { - float *empty, *scratch, *tmp2; - - spa_log_debug(this->log, "resize tmp %d -> %d", this->empty_size, maxsize); - - if ((empty = realloc(this->empty, maxsize + MAX_ALIGN)) != NULL) - this->empty = empty; - if ((scratch = realloc(this->scratch, maxsize + MAX_ALIGN)) != NULL) - this->scratch = scratch; - if ((tmp0 = realloc(this->tmp0, (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL) - this->tmp0 = tmp0; - if ((tmp1 = realloc(this->tmp1, (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL) - this->tmp1 = tmp1; - - if (empty == NULL || scratch == NULL || tmp0 == NULL || tmp1 == NULL) { - free_tmp(this); - return -ENOMEM; - } - memset(this->empty, 0, maxsize + MAX_ALIGN); - this->empty_size = maxsize; - } - return 0; -} - static int impl_node_port_use_buffers(void *object, enum spa_direction direction, @@ -2503,7 +2523,6 @@ struct impl *this = object; struct port *port; uint32_t i, j, maxsize; - int res; spa_return_val_if_fail(this != NULL, -EINVAL); @@ -2560,9 +2579,7 @@ if (direction == SPA_DIRECTION_OUTPUT) queue_buffer(this, port, i); } - if ((res = ensure_tmp(this, maxsize)) < 0) - return res; - + port->maxsize = maxsize; port->n_buffers = n_buffers; return 0; @@ -2869,7 +2886,7 @@ src_datasremap = SPA_PTR_ALIGN(this->empty, MAX_ALIGN, void); spa_log_trace_fp(this->log, "%p: empty input %d->%d", this, i * port->blocks + j, remap); - max_in = SPA_MIN(max_in, this->empty_size / port->stride); + max_in = SPA_MIN(max_in, this->scratch_size / port->stride); } } } else { @@ -2970,7 +2987,7 @@ dst_datasremap = SPA_PTR_ALIGN(this->scratch, MAX_ALIGN, void); spa_log_trace_fp(this->log, "%p: empty output %d->%d", this, i * port->blocks + j, remap); - max_out = SPA_MIN(max_out, this->empty_size / port->stride); + max_out = SPA_MIN(max_out, this->scratch_size / port->stride); } } } else {
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
@@ -523,6 +523,12 @@ } } +#define spa_write_unaligned(ptr, type, val) \ +__extension__ ({ \ + __typeof__(type) _val = (val); \ + memcpy((ptr), &_val, sizeof(_val)); \ +}) + static void conv_f32d_to_s32_2s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) @@ -558,14 +564,14 @@ t1 = _mm256_unpackhi_epi32(out0, out1); /* a2 b2 a3 b3 a6 b6 a7 b7 */ #ifdef __x86_64__ - *((int64_t*)(d + 0*n_channels)) = _mm256_extract_epi64(t0, 0); - *((int64_t*)(d + 1*n_channels)) = _mm256_extract_epi64(t0, 1); - *((int64_t*)(d + 2*n_channels)) = _mm256_extract_epi64(t1, 0); - *((int64_t*)(d + 3*n_channels)) = _mm256_extract_epi64(t1, 1); - *((int64_t*)(d + 4*n_channels)) = _mm256_extract_epi64(t0, 2); - *((int64_t*)(d + 5*n_channels)) = _mm256_extract_epi64(t0, 3); - *((int64_t*)(d + 6*n_channels)) = _mm256_extract_epi64(t1, 2); - *((int64_t*)(d + 7*n_channels)) = _mm256_extract_epi64(t1, 3); + spa_write_unaligned(d + 0*n_channels, uint64_t, _mm256_extract_epi64(t0, 0)); + spa_write_unaligned(d + 1*n_channels, uint64_t, _mm256_extract_epi64(t0, 1)); + spa_write_unaligned(d + 2*n_channels, uint64_t, _mm256_extract_epi64(t1, 0)); + spa_write_unaligned(d + 3*n_channels, uint64_t, _mm256_extract_epi64(t1, 1)); + spa_write_unaligned(d + 4*n_channels, uint64_t, _mm256_extract_epi64(t0, 2)); + spa_write_unaligned(d + 5*n_channels, uint64_t, _mm256_extract_epi64(t0, 3)); + spa_write_unaligned(d + 6*n_channels, uint64_t, _mm256_extract_epi64(t1, 2)); + spa_write_unaligned(d + 7*n_channels, uint64_t, _mm256_extract_epi64(t1, 3)); #else _mm_storel_pi((__m64*)(d + 0*n_channels), (__m128)_mm256_extracti128_si256(t0, 0)); _mm_storeh_pi((__m64*)(d + 1*n_channels), (__m128)_mm256_extracti128_si256(t0, 0)); @@ -772,14 +778,14 @@ out0 = _mm256_packs_epi32(t0, t1); /* a0 b0 a1 b1 a2 b2 a3 b3 a4 b4 a5 b5 a6 b6 a7 b7 */ - *((int32_t*)(d + 0*n_channels)) = _mm256_extract_epi32(out0,0); - *((int32_t*)(d + 1*n_channels)) = _mm256_extract_epi32(out0,1); - *((int32_t*)(d + 2*n_channels)) = _mm256_extract_epi32(out0,2); - *((int32_t*)(d + 3*n_channels)) = _mm256_extract_epi32(out0,3); - *((int32_t*)(d + 4*n_channels)) = _mm256_extract_epi32(out0,4); - *((int32_t*)(d + 5*n_channels)) = _mm256_extract_epi32(out0,5); - *((int32_t*)(d + 6*n_channels)) = _mm256_extract_epi32(out0,6); - *((int32_t*)(d + 7*n_channels)) = _mm256_extract_epi32(out0,7); + spa_write_unaligned(d + 0*n_channels, uint32_t, _mm256_extract_epi32(out0,0)); + spa_write_unaligned(d + 1*n_channels, uint32_t, _mm256_extract_epi32(out0,1)); + spa_write_unaligned(d + 2*n_channels, uint32_t, _mm256_extract_epi32(out0,2)); + spa_write_unaligned(d + 3*n_channels, uint32_t, _mm256_extract_epi32(out0,3)); + spa_write_unaligned(d + 4*n_channels, uint32_t, _mm256_extract_epi32(out0,4)); + spa_write_unaligned(d + 5*n_channels, uint32_t, _mm256_extract_epi32(out0,5)); + spa_write_unaligned(d + 6*n_channels, uint32_t, _mm256_extract_epi32(out0,6)); + spa_write_unaligned(d + 7*n_channels, uint32_t, _mm256_extract_epi32(out0,7)); d += 8*n_channels; } @@ -839,14 +845,14 @@ out3 = _mm256_unpackhi_epi32(out0, out1); /* a2 b2 c2 d2 a3 b3 c3 d3 a6 b6 c6 d6 a7 b7 c7 d7 */ #ifdef __x86_64__ - *(int64_t*)(d + 0*n_channels) = _mm256_extract_epi64(out2, 0); /* a0 b0 c0 d0 */ - *(int64_t*)(d + 1*n_channels) = _mm256_extract_epi64(out2, 1); /* a1 b1 c1 d1 */ - *(int64_t*)(d + 2*n_channels) = _mm256_extract_epi64(out3, 0); /* a2 b2 c2 d2 */ - *(int64_t*)(d + 3*n_channels) = _mm256_extract_epi64(out3, 1); /* a3 b3 c3 d3 */ - *(int64_t*)(d + 4*n_channels) = _mm256_extract_epi64(out2, 2); /* a4 b4 c4 d4 */ - *(int64_t*)(d + 5*n_channels) = _mm256_extract_epi64(out2, 3); /* a5 b5 c5 d5 */ - *(int64_t*)(d + 6*n_channels) = _mm256_extract_epi64(out3, 2); /* a6 b6 c6 d6 */ - *(int64_t*)(d + 7*n_channels) = _mm256_extract_epi64(out3, 3); /* a7 b7 c7 d7 */ + spa_write_unaligned(d + 0*n_channels, uint64_t, _mm256_extract_epi64(out2, 0)); /* a0 b0 c0 d0 */ + spa_write_unaligned(d + 1*n_channels, uint64_t, _mm256_extract_epi64(out2, 1)); /* a1 b1 c1 d1 */ + spa_write_unaligned(d + 2*n_channels, uint64_t, _mm256_extract_epi64(out3, 0)); /* a2 b2 c2 d2 */ + spa_write_unaligned(d + 3*n_channels, uint64_t, _mm256_extract_epi64(out3, 1)); /* a3 b3 c3 d3 */ + spa_write_unaligned(d + 4*n_channels, uint64_t, _mm256_extract_epi64(out2, 2)); /* a4 b4 c4 d4 */ + spa_write_unaligned(d + 5*n_channels, uint64_t, _mm256_extract_epi64(out2, 3)); /* a5 b5 c5 d5 */ + spa_write_unaligned(d + 6*n_channels, uint64_t, _mm256_extract_epi64(out3, 2)); /* a6 b6 c6 d6 */ + spa_write_unaligned(d + 7*n_channels, uint64_t, _mm256_extract_epi64(out3, 3)); /* a7 b7 c7 d7 */ #else _mm_storel_pi((__m64*)(d + 0*n_channels), (__m128)_mm256_extracti128_si256(out2, 0)); _mm_storeh_pi((__m64*)(d + 1*n_channels), (__m128)_mm256_extracti128_si256(out2, 0));
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/fmt-ops-sse2.c
Changed
@@ -114,6 +114,18 @@ } } +#define spa_read_unaligned(ptr, type) \ +__extension__ ({ \ + __typeof__(type) _val; \ + memcpy(&_val, (ptr), sizeof(_val)); \ + _val; \ +}) + +#define spa_write_unaligned(ptr, type, val) \ +__extension__ ({ \ + __typeof__(type) _val = (val); \ + memcpy((ptr), &_val, sizeof(_val)); \ +}) void conv_s24_to_f32d_1s_sse2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) @@ -134,10 +146,10 @@ for(n = 0; n < unrolled; n += 4) { in = _mm_setr_epi32( - *((uint32_t*)&s0 * n_channels), - *((uint32_t*)&s1 * n_channels), - *((uint32_t*)&s2 * n_channels), - *((uint32_t*)&s3 * n_channels)); + spa_read_unaligned(&s0 * n_channels, uint32_t), + spa_read_unaligned(&s1 * n_channels, uint32_t), + spa_read_unaligned(&s2 * n_channels, uint32_t), + spa_read_unaligned(&s3 * n_channels, uint32_t)); in = _mm_slli_epi32(in, 8); in = _mm_srai_epi32(in, 8); out = _mm_cvtepi32_ps(in); @@ -175,15 +187,15 @@ for(n = 0; n < unrolled; n += 4) { in0 = _mm_setr_epi32( - *((uint32_t*)&s0 + 0*n_channels), - *((uint32_t*)&s0 + 1*n_channels), - *((uint32_t*)&s0 + 2*n_channels), - *((uint32_t*)&s0 + 3*n_channels)); + spa_read_unaligned(&s0 + 0*n_channels, uint32_t), + spa_read_unaligned(&s0 + 1*n_channels, uint32_t), + spa_read_unaligned(&s0 + 2*n_channels, uint32_t), + spa_read_unaligned(&s0 + 3*n_channels, uint32_t)); in1 = _mm_setr_epi32( - *((uint32_t*)&s1 + 0*n_channels), - *((uint32_t*)&s1 + 1*n_channels), - *((uint32_t*)&s1 + 2*n_channels), - *((uint32_t*)&s1 + 3*n_channels)); + spa_read_unaligned(&s1 + 0*n_channels, uint32_t), + spa_read_unaligned(&s1 + 1*n_channels, uint32_t), + spa_read_unaligned(&s1 + 2*n_channels, uint32_t), + spa_read_unaligned(&s1 + 3*n_channels, uint32_t)); in0 = _mm_slli_epi32(in0, 8); in1 = _mm_slli_epi32(in1, 8); @@ -236,25 +248,25 @@ for(n = 0; n < unrolled; n += 4) { in0 = _mm_setr_epi32( - *((uint32_t*)&s0 + 0*n_channels), - *((uint32_t*)&s0 + 1*n_channels), - *((uint32_t*)&s0 + 2*n_channels), - *((uint32_t*)&s0 + 3*n_channels)); + spa_read_unaligned(&s0 + 0*n_channels, uint32_t), + spa_read_unaligned(&s0 + 1*n_channels, uint32_t), + spa_read_unaligned(&s0 + 2*n_channels, uint32_t), + spa_read_unaligned(&s0 + 3*n_channels, uint32_t)); in1 = _mm_setr_epi32( - *((uint32_t*)&s1 + 0*n_channels), - *((uint32_t*)&s1 + 1*n_channels), - *((uint32_t*)&s1 + 2*n_channels), - *((uint32_t*)&s1 + 3*n_channels)); + spa_read_unaligned(&s1 + 0*n_channels, uint32_t), + spa_read_unaligned(&s1 + 1*n_channels, uint32_t), + spa_read_unaligned(&s1 + 2*n_channels, uint32_t), + spa_read_unaligned(&s1 + 3*n_channels, uint32_t)); in2 = _mm_setr_epi32( - *((uint32_t*)&s2 + 0*n_channels), - *((uint32_t*)&s2 + 1*n_channels), - *((uint32_t*)&s2 + 2*n_channels), - *((uint32_t*)&s2 + 3*n_channels)); + spa_read_unaligned(&s2 + 0*n_channels, uint32_t), + spa_read_unaligned(&s2 + 1*n_channels, uint32_t), + spa_read_unaligned(&s2 + 2*n_channels, uint32_t), + spa_read_unaligned(&s2 + 3*n_channels, uint32_t)); in3 = _mm_setr_epi32( - *((uint32_t*)&s3 + 0*n_channels), - *((uint32_t*)&s3 + 1*n_channels), - *((uint32_t*)&s3 + 2*n_channels), - *((uint32_t*)&s3 + 3*n_channels)); + spa_read_unaligned(&s3 + 0*n_channels, uint32_t), + spa_read_unaligned(&s3 + 1*n_channels, uint32_t), + spa_read_unaligned(&s3 + 2*n_channels, uint32_t), + spa_read_unaligned(&s3 + 3*n_channels, uint32_t)); in0 = _mm_slli_epi32(in0, 8); in1 = _mm_slli_epi32(in1, 8); @@ -436,10 +448,10 @@ t0 = _mm_unpacklo_epi32(out0, out1); t1 = _mm_unpackhi_epi32(out0, out1); - _mm_storel_pd((double*)(d + 0*n_channels), (__m128d)t0); - _mm_storeh_pd((double*)(d + 1*n_channels), (__m128d)t0); - _mm_storel_pd((double*)(d + 2*n_channels), (__m128d)t1); - _mm_storeh_pd((double*)(d + 3*n_channels), (__m128d)t1); + _mm_storel_pi((__m64*)(d + 0*n_channels), (__m128)t0); + _mm_storeh_pi((__m64*)(d + 1*n_channels), (__m128)t0); + _mm_storel_pi((__m64*)(d + 2*n_channels), (__m128)t1); + _mm_storeh_pi((__m64*)(d + 3*n_channels), (__m128)t1); d += 4*n_channels; } for(; n < n_samples; n++) { @@ -1147,10 +1159,10 @@ out2 = _mm_shuffle_epi32(out0, _MM_SHUFFLE(1, 0, 3, 2)); out3 = _mm_shuffle_epi32(out0, _MM_SHUFFLE(2, 1, 0, 3)); - *((int32_t*)(d + 0*n_channels)) = _mm_cvtsi128_si32(out0); - *((int32_t*)(d + 1*n_channels)) = _mm_cvtsi128_si32(out1); - *((int32_t*)(d + 2*n_channels)) = _mm_cvtsi128_si32(out2); - *((int32_t*)(d + 3*n_channels)) = _mm_cvtsi128_si32(out3); + spa_write_unaligned(d + 0*n_channels, uint32_t, _mm_cvtsi128_si32(out0)); + spa_write_unaligned(d + 1*n_channels, uint32_t, _mm_cvtsi128_si32(out1)); + spa_write_unaligned(d + 2*n_channels, uint32_t, _mm_cvtsi128_si32(out2)); + spa_write_unaligned(d + 3*n_channels, uint32_t, _mm_cvtsi128_si32(out3)); d += 4*n_channels; } for(; n < n_samples; n++) {
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/fmt-ops-sse41.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/fmt-ops-sse41.c
Changed
@@ -6,6 +6,13 @@ #include <smmintrin.h> +#define spa_read_unaligned(ptr, type) \ +__extension__ ({ \ + __typeof__(type) _val; \ + memcpy(&_val, (ptr), sizeof(_val)); \ + _val; \ +}) + static void conv_s24_to_f32d_1s_sse41(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) @@ -22,10 +29,10 @@ unrolled = 0; for(n = 0; n < unrolled; n += 4) { - in = _mm_insert_epi32(in, *((uint32_t*)&s0 * n_channels), 0); - in = _mm_insert_epi32(in, *((uint32_t*)&s1 * n_channels), 1); - in = _mm_insert_epi32(in, *((uint32_t*)&s2 * n_channels), 2); - in = _mm_insert_epi32(in, *((uint32_t*)&s3 * n_channels), 3); + in = _mm_insert_epi32(in, spa_read_unaligned(&s0 * n_channels, uint32_t), 0); + in = _mm_insert_epi32(in, spa_read_unaligned(&s1 * n_channels, uint32_t), 1); + in = _mm_insert_epi32(in, spa_read_unaligned(&s2 * n_channels, uint32_t), 2); + in = _mm_insert_epi32(in, spa_read_unaligned(&s3 * n_channels, uint32_t), 3); in = _mm_slli_epi32(in, 8); in = _mm_srai_epi32(in, 8); out = _mm_cvtepi32_ps(in);
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
@@ -155,7 +155,7 @@ static inline int32_t s24_to_s32(int24_t src) { - return ((int32_t)src.v1 << 16) | ((uint32_t)src.v2 << 8) | (uint32_t)src.v3; + return ((uint32_t)((int32_t)src.v1 & 0xFFFF) << 16) | ((uint32_t)src.v2 << 8) | (uint32_t)src.v3; } #define S32_TO_S24(s) (int24_t) { .v1 = (int8_t)(((int32_t)s) >> 16), \
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/meson.build -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/meson.build
Changed
@@ -135,6 +135,7 @@ dependencies : spa_dep , install : false ) +test_inc = include_directories('../test') test_apps = 'test-audioadapter', @@ -149,7 +150,7 @@ test(a, executable(a, a + '.c', dependencies : spa_dep, dl_lib, pthread_lib, mathlib, audioconvert_dep, spa_audioconvert_dep , - include_directories : configinc , + include_directories : configinc, test_inc , link_with : test_lib , install_rpath : spa_plugindir / 'audioconvert', c_args : simd_cargs , @@ -180,7 +181,7 @@ benchmark(a, executable(a, a + '.c', dependencies : spa_dep, dl_lib, pthread_lib, mathlib, audioconvert_dep, spa_audioconvert_dep , - include_directories : configinc , + include_directories : configinc, test_inc , c_args : simd_cargs , install_rpath : spa_plugindir / 'audioconvert', install : installed_tests_enabled,
View file
pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c -> pipewire-0.3.83.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c
Changed
@@ -555,7 +555,7 @@ spa_assert_se(i == t); int32_t t2 = F32_TO_S32(v); - spa_assert_se(i<<16 == t2); + spa_assert_se((int32_t)(((uint32_t)i)<<16) == t2); spa_assert_se(i == t2>>16); } }
View file
pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/meson.build -> pipewire-0.3.83.tar.gz/spa/plugins/audiomixer/meson.build
Changed
@@ -74,7 +74,7 @@ test(a, executable(a, a + '.c', dependencies : spa_dep, dl_lib, pthread_lib, mathlib, audiomixer_dep , - include_directories : configinc , + include_directories : configinc, test_inc , link_with : test_lib , install_rpath : spa_plugindir / 'audiomixer', c_args : simd_cargs , @@ -104,7 +104,7 @@ benchmark(a, executable(a, a + '.c', dependencies : spa_dep, dl_lib, pthread_lib, mathlib, audiomixer_dep , - include_directories : configinc , + include_directories : configinc, test_inc , c_args : simd_cargs , install_rpath : spa_plugindir / 'audiomixer', install : installed_tests_enabled,
View file
pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/mix-ops.h -> pipewire-0.3.83.tar.gz/spa/plugins/audiomixer/mix-ops.h
Changed
@@ -43,7 +43,7 @@ static inline int32_t s24_to_s32(int24_t src) { - return ((int32_t)src.v1 << 16) | ((uint32_t)src.v2 << 8) | (uint32_t)src.v3; + return ((uint32_t)((int32_t)src.v1 & 0xFFFF) << 16) | ((uint32_t)src.v2 << 8) | (uint32_t)src.v3; } #define S32_TO_S24(s) (int24_t) { .v1 = (int8_t)(((int32_t)s) >> 16), \
View file
pipewire-0.3.82.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.83.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
@@ -1514,9 +1514,9 @@ len = sizeof(sco_opt); memset(&sco_opt, 0, len); if (getsockopt(t->fd, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) { - spa_log_warn(backend->log, "getsockopt(SCO_OPTIONS) failed, using defaults"); - t->read_mtu = 48; - t->write_mtu = 48; + spa_log_warn(backend->log, "getsockopt(SCO_OPTIONS) failed: %d (%m)", errno); + t->read_mtu = 144; + t->write_mtu = 144; } else { spa_log_debug(backend->log, "autodetected mtu = %u", sco_opt.mtu); t->read_mtu = sco_opt.mtu;
View file
pipewire-0.3.82.tar.gz/spa/plugins/bluez5/backend-ofono.c -> pipewire-0.3.83.tar.gz/spa/plugins/bluez5/backend-ofono.c
Changed
@@ -93,14 +93,14 @@ socklen_t len; /* Fallback values */ - t->read_mtu = 48; - t->write_mtu = 48; + t->read_mtu = 144; + t->write_mtu = 144; len = sizeof(sco_opt); memset(&sco_opt, 0, len); if (getsockopt(t->fd, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) - spa_log_warn(backend->log, "getsockopt(SCO_OPTIONS) failed, loading defaults"); + spa_log_warn(backend->log, "getsockopt(SCO_OPTIONS) failed: %d (%m)", errno); else { spa_log_debug(backend->log, "autodetected mtu = %u", sco_opt.mtu); t->read_mtu = sco_opt.mtu;
View file
pipewire-0.3.82.tar.gz/spa/plugins/control/mixer.c -> pipewire-0.3.83.tar.gz/spa/plugins/control/mixer.c
Changed
@@ -335,7 +335,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(4096, 512, INT32_MAX), SPA_PARAM_BUFFERS_stride, SPA_POD_Int(1));
View file
pipewire-0.3.82.tar.gz/spa/plugins/jack/jack-sink.c -> pipewire-0.3.83.tar.gz/spa/plugins/jack/jack-sink.c
Changed
@@ -552,7 +552,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( MAX_SAMPLES * port->stride,
View file
pipewire-0.3.82.tar.gz/spa/plugins/jack/jack-source.c -> pipewire-0.3.83.tar.gz/spa/plugins/jack/jack-source.c
Changed
@@ -552,7 +552,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( MAX_SAMPLES * port->stride,
View file
pipewire-0.3.82.tar.gz/spa/plugins/meson.build -> pipewire-0.3.83.tar.gz/spa/plugins/meson.build
Changed
@@ -40,7 +40,7 @@ if get_option('volume').allowed() subdir('volume') endif -if vulkan_headers +if have_vulkan subdir('vulkan') endif
View file
pipewire-0.3.83.tar.gz/spa/plugins/test/test-helper.h
Changed
(renamed from spa/plugins/audiomixer/test-helper.h)
View file
pipewire-0.3.82.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.83.tar.gz/src/daemon/jack.conf.in
Changed
@@ -89,6 +89,7 @@ #jack.global-buffer-size = false #jack.max-client-ports = 768 #jack.fill-aliases = false + #jack.writable-input = true } # client specific properties
View file
pipewire-0.3.82.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.83.tar.gz/src/daemon/pipewire.conf.in
Changed
@@ -105,7 +105,7 @@ { name = libpipewire-module-protocol-native args = { # List of server Unix sockets, and optionally permissions - #sockets = { name = "pipewire-0" }, { name = "pipewire-manager-0" } + #sockets = { name = "pipewire-0" }, { name = "pipewire-0-manager" } } } @@ -146,21 +146,12 @@ # new clients. { name = libpipewire-module-access args = { - # access.allowed to list an array of paths of allowed - # apps. - #access.allowed = - # @session_manager_path@ - # + # Socket-specific access permissions + #access.socket = { pipewire-0 = "default", pipewire-0-manager = "unrestricted" } - # An array of rejected paths. - #access.rejected = - - # An array of paths with restricted access. - #access.restricted = - - # Anything not in the above lists gets assigned the - # access.force permission. - #access.force = flatpak + # Deprecated legacy mode (not socket-based), + # for now enabled by default if access.socket is not specified + #access.legacy = true } condition = { module.access = true } }
View file
pipewire-0.3.82.tar.gz/src/daemon/systemd/system/pipewire.socket -> pipewire-0.3.83.tar.gz/src/daemon/systemd/system/pipewire.socket
Changed
@@ -1,9 +1,10 @@ Unit -Description=PipeWire Multimedia System Socket +Description=PipeWire Multimedia System Sockets Socket Priority=6 ListenStream=%t/pipewire/pipewire-0 +ListenStream=%t/pipewire/pipewire-0-manager SocketUser=pipewire SocketGroup=pipewire SocketMode=0660
View file
pipewire-0.3.82.tar.gz/src/daemon/systemd/user/pipewire.socket -> pipewire-0.3.83.tar.gz/src/daemon/systemd/user/pipewire.socket
Changed
@@ -1,9 +1,10 @@ Unit -Description=PipeWire Multimedia System Socket +Description=PipeWire Multimedia System Sockets Socket Priority=6 ListenStream=%t/pipewire-0 +ListenStream=%t/pipewire-0-manager Install WantedBy=sockets.target
View file
pipewire-0.3.82.tar.gz/src/modules/module-access.c -> pipewire-0.3.83.tar.gz/src/modules/module-access.c
Changed
@@ -25,6 +25,7 @@ #include <spa/utils/json.h> #include <pipewire/impl.h> +#include <pipewire/cleanup.h> #include "flatpak-utils.h" @@ -36,40 +37,51 @@ * resolution. * * Permissions assigned to a client are configured as arguments to this - * module, see the example configuration below. A special use-case is Flatpak - * where the permission management is delegated. + * module, see below. Permission management beyond unrestricted access + * is delegated to an external agent, usually the session manager. * - * This module sets the \ref PW_KEY_ACCESS property to one of - * - `allowed`: the client is explicitly allowed to access all resources - * - `rejected`: the client does not have access to any resources and a - * resource error is generated - * - `restricted`: the client is restricted, see note below - * - `flatpak`: restricted, special case for clients running inside flatpak, - * see note below - * - `$access.force`: the value of the `access.force` argument given in the - * module configuration. - * - `unrestricted`: the client is allowed to access all resources. This is the - * default for clients not listed in any of the `access.*` options - * unless the client requested reduced permissions in \ref - * PW_KEY_CLIENT_ACCESS. + * This module sets the \ref PW_KEY_ACCESS as follows: * - * \note Clients with a resolution other than `allowed` or `rejected` rely - * on an external actor to update that property once permission is - * granted or rejected. + * - If `access.legacy` module option is not enabled: + + * The value defined for the socket in `access.socket` module option, or + * `"default"` if no value is defined. + * + * - If `access.legacy` is enabled, the value is: + * + * - `"flatpak"`: if client is a Flatpak client + * - Value of \ref PW_KEY_CLIENT_ACCESS client property, if set + * - `"unrestricted"`: otherwise + * + * If the resulting \ref PW_KEY_ACCESS value is `"unrestricted"`, this module + * will give the client all permissions to access all resources. Otherwise, the + * client will be forced to wait until an external actor, such as the session + * manager, updates the client permissions. * - * For connections from applications running inside Flatpak not mediated - * by a portal, the `access` module itself sets the `pipewire.access.portal.app_id` - * property to the Flatpak application ID. + * For connections from applications running inside Flatpak, and not mediated by + * other clients (eg. portal or pipewire-pulse), the + * `pipewire.access.portal.app_id` property is to the Flatpak application ID, if + * found. In addition, `pipewire.sec.flatpak` is set to `true`. * * ## Module Options * * Options specific to the behavior of this module * - * - ``access.allowed = ``: an array of paths of allowed applications - * - ``access.rejected = ``: an array of paths of rejected applications - * - ``access.restricted = ``: an array of paths of restricted applications - * - ``access.force = <str>``: forces an external permissions check (e.g. a flatpak - * portal) + * - `access.socket = { "socket-name" = "access-value", ... }`: + * + * Socket-specific access permissions. Has the default value + * `{ "CORENAME-manager": "unrestricted" }` + * where `CORENAME` is the name of the PipeWire core, usually `pipewire-0`. + * + * - `access.legacy = true`: enable backward-compatible access mode. Cannot be + * enabled when using socket-based permissions. + * + * If `access.socket` is not specified, has the default value `true` + * otherwise `false`. + * + * \warning The legacy mode is deprecated. The default value is subject to + * change and the legacy mode may be removed in future PipeWire + * releases. * * ## General options * @@ -84,20 +96,12 @@ * context.modules = * { name = libpipewire-module-access * args = { - * access.allowed = - * /usr/bin/pipewire-media-session - * /usr/bin/important-thing - * - * - * access.rejected = - * /usr/bin/microphone-snooper - * - * - * #access.restricted = - * - * # Anything not in the above lists gets assigned the - * # access.force permission. - * #access.force = flatpak + * # Use separate socket for session manager applications, + * # and pipewire-0 for usual applications. + * access.socket = { + * pipewire-0 = "default", + * pipewire-0-manager = "unrestricted", + * } * } * } * @@ -112,10 +116,12 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define MODULE_USAGE "( access.force=flatpak ) " \ - "( access.allowed= <cmd-line>,.. ) " \ - "( access.rejected= <cmd-line>,.. ) " \ - "( access.restricted= <cmd-line>,.. ) " \ +#define MODULE_USAGE "( access.socket={ <socket>=<access>, ... } ) " \ + "( access.legacy=true ) " + +#define ACCESS_UNRESTRICTED "unrestricted" +#define ACCESS_FLATPAK "flatpak" +#define ACCESS_DEFAULT "default" static const struct spa_dict_item module_props = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, @@ -126,187 +132,98 @@ struct impl { struct pw_context *context; - struct pw_properties *properties; + + struct pw_properties *socket_access; struct spa_hook context_listener; struct spa_hook module_listener; -}; - -static int get_exe_name(int pid, char *buf, size_t buf_size) -{ - char path256; - struct stat s1, s2; - int res; - - /* - * Find executable name, checking it is an existing file - * (in the current namespace). - */ - -#if defined(__linux__) || defined(__GNU__) - spa_scnprintf(path, sizeof(path), "/proc/%u/exe", pid); -#elif defined(__FreeBSD__) || defined(__MidnightBSD__) - spa_scnprintf(path, sizeof(path), "/proc/%u/file", pid); -#else - return -ENOTSUP; -#endif - res = readlink(path, buf, buf_size); - if (res < 0) - return -errno; - if ((size_t)res >= buf_size) - return -E2BIG; - bufres = '\0'; - - /* Check the file exists (= not deleted, and is in current namespace) */ - if (stat(path, &s1) != 0 || stat(buf, &s2) != 0) - return -errno; - if (s1.st_dev != s2.st_dev || s1.st_ino != s2.st_ino) - return -ENXIO; - - return 0; -} - -static int check_exe(struct pw_impl_client *client, const char *path, const char *str) -{ - char key1024; - int res; - struct spa_json it2; - - spa_json_init(&it0, str, strlen(str)); - if ((res = spa_json_enter_array(&it0, &it1)) <= 0) - return res; - - while (spa_json_get_string(&it1, key, sizeof(key)) > 0) { - if (spa_streq(path, key)) - return 1; - } - - return 0; -} + unsigned int legacy:1; +}; static void context_check_access(void *data, struct pw_impl_client *client) { struct impl *impl = data; struct pw_permission permissions1; - struct spa_dict_item items2; - char exe_pathPATH_MAX; + struct spa_dict_item items3; const struct pw_properties *props; - const char *str, *access; - char *flatpak_app_id = NULL; + const char *str; + const char *access; + const char *socket; + spa_autofree char *flatpak_app_id = NULL; int nitems = 0; + bool sandbox_flatpak; int pid, res; + /* Get client properties */ + pid = -EINVAL; + socket = NULL; + sandbox_flatpak = false; + if ((props = pw_impl_client_get_properties(client)) != NULL) { if ((str = pw_properties_get(props, PW_KEY_ACCESS)) != NULL) { pw_log_info("client %p: has already access: '%s'", client, str); return; } pw_properties_fetch_int32(props, PW_KEY_SEC_PID, &pid); + socket = pw_properties_get(props, PW_KEY_SEC_SOCKET); } if (pid < 0) { pw_log_info("client %p: no trusted pid found, assuming not sandboxed", client); - access = "no-pid"; - goto granted; } else { pw_log_info("client %p has trusted pid %d", client, pid); - if ((res = get_exe_name(pid, exe_path, sizeof(exe_path))) >= 0) { - pw_log_info("client %p has trusted exe path '%s'", client, exe_path); - } else { - pw_log_info("client %p has no trusted exe path: %s", - client, spa_strerror(res)); - exe_path0 = '\0'; - } - } - if (impl->properties && (str = pw_properties_get(impl->properties, "access.allowed")) != NULL) { - res = check_exe(client, exe_path, str); - if (res < 0) { - pw_log_warn("%p: client %p allowed check failed: %s", - impl, client, spa_strerror(res)); - } else if (res > 0) { - access = "allowed"; - goto granted; - } - } + res = pw_check_flatpak(pid, &flatpak_app_id, NULL); + if (res != 0) { + if (res < 0) + pw_log_warn("%p: client %p flatpak check failed: %s", + impl, client, spa_strerror(res)); - if (impl->properties && (str = pw_properties_get(impl->properties, "access.rejected")) != NULL) { - res = check_exe(client, exe_path, str); - if (res < 0) { - pw_log_warn("%p: client %p rejected check failed: %s", - impl, client, spa_strerror(res)); - } else if (res > 0) { - res = -EACCES; - access = "rejected"; - goto rejected; + pw_log_info("client %p is from flatpak", client); + sandbox_flatpak = true; } } - if (impl->properties && (str = pw_properties_get(impl->properties, "access.restricted")) != NULL) { - res = check_exe(client, exe_path, str); - if (res < 0) { - pw_log_warn("%p: client %p restricted check failed: %s", - impl, client, spa_strerror(res)); - } - else if (res > 0) { - pw_log_debug(" %p: restricted client %p added", impl, client); - access = "restricted"; - goto wait_permissions; - } - } - if (impl->properties && - (access = pw_properties_get(impl->properties, "access.force")) != NULL) - goto wait_permissions; - - res = pw_check_flatpak(pid, &flatpak_app_id, NULL); - if (res != 0) { - if (res < 0) - pw_log_warn("%p: client %p sandbox check failed: %s", - impl, client, spa_strerror(res)); + /* Apply rules */ + + if (!impl->legacy) { + if ((str = pw_properties_get(impl->socket_access, socket)) != NULL) + access = str; + else + access = ACCESS_DEFAULT; + } else { + if (sandbox_flatpak) + access = ACCESS_FLATPAK; + else if ((str = pw_properties_get(props, PW_KEY_CLIENT_ACCESS)) != NULL) + access = str; else - pw_log_debug(" %p: flatpak client %p added", impl, client); - access = "flatpak"; + access = ACCESS_UNRESTRICTED; + } + + /* Handle resolution */ + + if (sandbox_flatpak) { itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id", flatpak_app_id); - goto wait_permissions; + itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.sec.flatpak", "true"); } - if ((access = pw_properties_get(props, PW_KEY_CLIENT_ACCESS)) == NULL) - access = "unrestricted"; + if (spa_streq(access, ACCESS_UNRESTRICTED)) { + pw_log_info("%p: client %p '%s' access granted", impl, client, access); + itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); + pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); - if (spa_streq(access, "unrestricted") || spa_streq(access, "allowed")) - goto granted; - else - goto wait_permissions; - -granted: - pw_log_info("%p: client %p '%s' access granted", impl, client, access); - itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); - - permissions0 = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_ALL); - pw_impl_client_update_permissions(client, 1, permissions); - goto done; - -wait_permissions: - pw_log_info("%p: client %p wait for '%s' permissions", - impl, client, access); - itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); - goto done; - -rejected: - pw_resource_error(pw_impl_client_get_core_resource(client), res, access); - itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); - goto done; - -done: - free(flatpak_app_id); - return; + permissions0 = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_ALL); + pw_impl_client_update_permissions(client, 1, permissions); + } else { + pw_log_info("%p: client %p wait for '%s' permissions", + impl, client, access); + itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); + pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); + } } static const struct pw_context_events context_events = { @@ -318,10 +235,12 @@ { struct impl *impl = data; - spa_hook_remove(&impl->context_listener); - spa_hook_remove(&impl->module_listener); + if (impl->context) { + spa_hook_remove(&impl->context_listener); + spa_hook_remove(&impl->module_listener); + } - pw_properties_free(impl->properties); + pw_properties_free(impl->socket_access); free(impl); } @@ -331,12 +250,105 @@ .destroy = module_destroy, }; +static const char * +get_server_name(const struct spa_dict *props) +{ + const char *name = NULL; + + name = getenv("PIPEWIRE_CORE"); + if (name == NULL && props != NULL) + name = spa_dict_lookup(props, PW_KEY_CORE_NAME); + if (name == NULL) + name = PW_DEFAULT_REMOTE; + return name; +} + +static int parse_socket_args(struct impl *impl, const char *str) +{ + struct spa_json it2; + char socketPATH_MAX; + + spa_json_init(&it0, str, strlen(str)); + + if (spa_json_enter_object(&it0, &it1) <= 0) + return -EINVAL; + + while (spa_json_get_string(&it1, socket, sizeof(socket)) > 0) { + char value256; + const char *val; + int len; + + if ((len = spa_json_next(&it1, &val)) <= 0) + return -EINVAL; + + if (spa_json_parse_stringn(val, len, value, sizeof(value)) <= 0) + return -EINVAL; + + pw_properties_set(impl->socket_access, socket, value); + } + + return 0; +} + +static int parse_args(struct impl *impl, const struct pw_properties *props, const char *args_str) +{ + spa_autoptr(pw_properties) args = NULL; + const char *str; + int res; + + if (args_str) + args = pw_properties_new_string(args_str); + else + args = pw_properties_new(NULL, NULL); + + if ((str = pw_properties_get(args, "access.legacy")) != NULL) { + impl->legacy = spa_atob(str); + } else if (pw_properties_get(args, "access.socket")) { + impl->legacy = false; + } else { + /* When time comes, we should change this to false */ + impl->legacy = true; + } + + if (pw_properties_get(args, "access.force") || + pw_properties_get(args, "access.allowed") || + pw_properties_get(args, "access.rejected") || + pw_properties_get(args, "access.restricted")) { + pw_log_warn("access.force/allowed/rejected/restricted are deprecated and ignored " + "but imply legacy access mode"); + impl->legacy = true; + } + + if ((str = pw_properties_get(args, "access.socket")) != NULL) { + if (impl->legacy) { + pw_log_error("access.socket and legacy mode cannot be both enabled"); + return -EINVAL; + } + + if ((res = parse_socket_args(impl, str)) < 0) { + pw_log_error("invalid access.socket value"); + return res; + } + } else { + char defPATH_MAX; + + spa_scnprintf(def, sizeof(def), "%s-manager", get_server_name(&props->dict)); + pw_properties_set(impl->socket_access, def, ACCESS_UNRESTRICTED); + } + + if (impl->legacy) + pw_log_info("Using backward-compatible legacy access mode."); + + return 0; +} + SPA_EXPORT int pipewire__module_init(struct pw_impl_module *module, const char *args) { struct pw_context *context = pw_impl_module_get_context(module); - struct pw_properties *props; + const struct pw_properties *props = pw_context_get_properties(context); struct impl *impl; + int res; PW_LOG_TOPIC_INIT(mod_topic); @@ -346,13 +358,12 @@ pw_log_debug("module %p: new %s", impl, args); - if (args) - props = pw_properties_new_string(args); - else - props = NULL; + impl->socket_access = pw_properties_new(NULL, NULL); + + if ((res = parse_args(impl, props, args)) < 0) + goto error; impl->context = context; - impl->properties = props; pw_context_add_listener(context, &impl->context_listener, &context_events, impl); pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl); @@ -360,4 +371,8 @@ pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props)); return 0; + +error: + module_destroy(impl); + return res; }
View file
pipewire-0.3.82.tar.gz/src/modules/module-combine-stream.c -> pipewire-0.3.83.tar.gz/src/modules/module-combine-stream.c
Changed
@@ -46,6 +46,7 @@ * - `node.description`: a human readable name for the stream * - `combine.mode` = capture | playback | sink | source, default sink * - `combine.latency-compensate`: use delay buffers to match stream latencies + * - `combine.on-demand-streams`: use metadata to create streams on demand * - `combine.props = {}`: properties to be passed to the sink/source * - `stream.props = {}`: properties to be passed to the streams * - `stream.rules = {}`: rules for matching streams, use create-stream actions @@ -250,6 +251,10 @@ struct pw_registry *registry; struct spa_hook registry_listener; + struct pw_metadata *metadata; + struct spa_hook metadata_listener; + uint32_t metadata_id; + struct spa_source *update_delay_event; struct pw_properties *combine_props; @@ -268,6 +273,7 @@ unsigned int do_disconnect:1; unsigned int latency_compensate:1; + unsigned int on_demand_streams:1; struct spa_list streams; uint32_t n_streams; @@ -281,6 +287,7 @@ struct stream { uint32_t id; + char *on_demand_id; struct impl *impl; @@ -402,6 +409,15 @@ return NULL; } +static struct stream *find_on_demand_stream(struct impl *impl, const char *on_demand_id) +{ + struct stream *s; + spa_list_for_each(s, &impl->streams, link) + if (spa_streq(s->on_demand_id, on_demand_id)) + return s; + return NULL; +} + static enum pw_direction get_combine_direction(struct impl *impl) { if (impl->mode == MODE_SINK || impl->mode == MODE_CAPTURE) @@ -624,6 +640,7 @@ pw_stream_destroy(s->stream); } + free(s->on_demand_id); free(s->delaybuf); free(s); } @@ -633,6 +650,14 @@ remove_stream(s, true); } +static void destroy_all_on_demand_streams(struct impl *impl) +{ + struct stream *s, *tmp; + spa_list_for_each_safe(s, tmp, &impl->streams, link) + if (s->on_demand_id) + destroy_stream(s); +} + static void stream_destroy(void *d) { struct stream *s = d; @@ -721,6 +746,7 @@ struct stream_info { struct impl *impl; uint32_t id; + const char *on_demand_id; const struct spa_dict *props; struct pw_properties *stream_props; }; @@ -739,13 +765,18 @@ enum pw_stream_flags flags; enum pw_direction direction; - node_name = spa_dict_lookup(info->props, "node.name"); - if (node_name == NULL) - node_name = spa_dict_lookup(info->props, "object.serial"); - if (node_name == NULL) - return -EIO; + if (info->on_demand_id) { + node_name = info->on_demand_id; + pw_log_info("create on demand stream: %s", node_name); + } else { + node_name = spa_dict_lookup(info->props, PW_KEY_NODE_NAME); + if (node_name == NULL) + node_name = spa_dict_lookup(info->props, PW_KEY_OBJECT_SERIAL); + if (node_name == NULL) + return -EIO; - pw_log_info("create stream for %d %s", info->id, node_name); + pw_log_info("create stream for %d %s", info->id, node_name); + } s = calloc(1, sizeof(*s)); if (s == NULL) @@ -798,8 +829,14 @@ if (pw_properties_get(info->stream_props, PW_KEY_NODE_NAME) == NULL) pw_properties_setf(info->stream_props, PW_KEY_NODE_NAME, "output.%s_%s", str, node_name); - if (pw_properties_get(info->stream_props, PW_KEY_TARGET_OBJECT) == NULL) - pw_properties_set(info->stream_props, PW_KEY_TARGET_OBJECT, node_name); + + if (info->on_demand_id) { + s->on_demand_id = strdup(info->on_demand_id); + pw_properties_set(info->stream_props, "combine.on-demand-id", s->on_demand_id); + } else { + if (pw_properties_get(info->stream_props, PW_KEY_TARGET_OBJECT) == NULL) + pw_properties_set(info->stream_props, PW_KEY_TARGET_OBJECT, node_name); + } s->stream = pw_stream_new(impl->core, "Combine stream", info->stream_props); info->stream_props = NULL; @@ -810,7 +847,8 @@ flags = PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | - PW_STREAM_FLAG_RT_PROCESS; + PW_STREAM_FLAG_RT_PROCESS | + PW_STREAM_FLAG_ASYNC; if (impl->mode == MODE_SINK || impl->mode == MODE_CAPTURE) { direction = PW_DIRECTION_OUTPUT; @@ -818,7 +856,6 @@ } else { direction = PW_DIRECTION_INPUT; s->stream_events.process = stream_input_process; - flags |= PW_STREAM_FLAG_ASYNC; } pw_stream_add_listener(s->stream, @@ -866,6 +903,62 @@ return res; } +static int metadata_property(void *data, uint32_t id, + const char *key, const char *type, const char *value) +{ + struct impl *impl = data; + const char *on_demand_id; + struct stream *s; + + if (id != impl->combine_id) + return 0; + + if (!key) { + destroy_all_on_demand_streams(impl); + goto out; + } + + if (!spa_strstartswith(key, "combine.on-demand-stream.")) + return 0; + + on_demand_id = key + strlen("combine.on-demand-stream."); + if (*on_demand_id == '\0') + return 0; + + if (value) { + struct stream_info info; + + s = find_on_demand_stream(impl, on_demand_id); + if (s) + destroy_stream(s); + + spa_zero(info); + info.impl = impl; + info.id = SPA_ID_INVALID; + info.on_demand_id = on_demand_id; + info.stream_props = pw_properties_copy(impl->stream_props); + + pw_properties_update_string(info.stream_props, value, strlen(value)); + + create_stream(&info); + + pw_properties_free(info.stream_props); + } else { + s = find_on_demand_stream(impl, on_demand_id); + if (s) + destroy_stream(s); + } + +out: + update_delay(impl); + return 0; +} + +static const struct pw_metadata_events metadata_events = { + PW_VERSION_METADATA_EVENTS, + .property = metadata_property +}; + static void registry_event_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) @@ -874,6 +967,22 @@ const char *str; struct stream_info info; + if (impl->on_demand_streams && spa_streq(type, PW_TYPE_INTERFACE_Metadata)) { + if (!props) + return; + + if (!spa_streq(spa_dict_lookup(props, "metadata.name"), "default")) + return; + + impl->metadata = pw_registry_bind(impl->registry, + id, type, PW_VERSION_METADATA, 0); + pw_metadata_add_listener(impl->metadata, + &impl->metadata_listener, + &metadata_events, impl); + impl->metadata_id = id; + return; + } + if (!spa_streq(type, PW_TYPE_INTERFACE_Node) || props == NULL) return; @@ -902,6 +1011,15 @@ struct impl *impl = data; struct stream *s; + if (impl->metadata && id == impl->metadata_id) { + destroy_all_on_demand_streams(impl); + update_delay(impl); + spa_hook_remove(&impl->metadata_listener); + pw_proxy_destroy((struct pw_proxy*)impl->metadata); + impl->metadata = NULL; + return; + } + s = find_stream(impl, id); if (s == NULL) return; @@ -1235,6 +1353,11 @@ pw_proxy_destroy((struct pw_proxy*)impl->registry); impl->registry = NULL; } + if (impl->metadata) { + spa_hook_remove(&impl->metadata_listener); + pw_proxy_destroy((struct pw_proxy*)impl->metadata); + impl->metadata = NULL; + } pw_impl_module_schedule_destroy(impl->module); } @@ -1256,6 +1379,11 @@ if (impl->update_delay_event) pw_loop_destroy_source(impl->main_loop, impl->update_delay_event); + if (impl->metadata) { + spa_hook_remove(&impl->metadata_listener); + pw_proxy_destroy((struct pw_proxy*)impl->metadata); + impl->metadata = NULL; + } if (impl->registry) { spa_hook_remove(&impl->registry_listener); pw_proxy_destroy((struct pw_proxy*)impl->registry); @@ -1354,6 +1482,8 @@ if ((str = pw_properties_get(props, "combine.latency-compensate")) != NULL) impl->latency_compensate = spa_atob(str); + if ((str = pw_properties_get(props, "combine.on-demand-streams")) != NULL) + impl->on_demand_streams = spa_atob(str); impl->combine_props = pw_properties_new(NULL, NULL); impl->stream_props = pw_properties_new(NULL, NULL);
View file
pipewire-0.3.82.tar.gz/src/modules/module-ffado-driver.c -> pipewire-0.3.83.tar.gz/src/modules/module-ffado-driver.c
Changed
@@ -505,7 +505,7 @@ port->latencys->direction = latency; port->is_midi = is_midi; - port->buffer = calloc(sizeof(float), impl->quantum_limit); + port->buffer = calloc(impl->quantum_limit, sizeof(float)); if (port->buffer == NULL) { pw_log_error("Can't create port buffer: %m"); return; @@ -1024,9 +1024,12 @@ "latency.internal.input", 0); impl->output_latency = pw_properties_get_uint32(props, "latency.internal.output", 0); - impl->quantum_limit = 8192; impl->utils = pw_thread_utils_get(); + impl->quantum_limit = pw_properties_get_uint32( + pw_context_get_properties(context), + "default.clock.quantum-limit", 8192u); + impl->sink.props = pw_properties_new(NULL, NULL); impl->source.props = pw_properties_new(NULL, NULL); if (impl->source.props == NULL || impl->sink.props == NULL) {
View file
pipewire-0.3.82.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.83.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -539,13 +539,9 @@ #include <pipewire/pipewire.h> #define MAX_HNDL 64 -#define MAX_SAMPLES 8192 #define DEFAULT_RATE 48000 -static float silence_dataMAX_SAMPLES; -static float discard_dataMAX_SAMPLES; - struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support, struct dsp_ops *dsp, const char *path, const char *config); struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support, @@ -696,6 +692,7 @@ struct spa_hook core_proxy_listener; struct spa_hook core_listener; + uint32_t quantum_limit; struct dsp_ops dsp; struct spa_list plugin_list; @@ -720,6 +717,9 @@ long unsigned rate; struct graph graph; + + float *silence_data; + float *discard_data; }; static int graph_instantiate(struct graph *graph); @@ -2180,11 +2180,11 @@ } } -static int port_ensure_data(struct port *port, uint32_t i) +static int port_ensure_data(struct port *port, uint32_t i, uint32_t max_samples) { float *data; if ((data = port->audio_datai) == NULL) { - data = calloc(1, MAX_SAMPLES * sizeof(float)); + data = calloc(max_samples, sizeof(float)); if (data == NULL) { pw_log_error("cannot create port data: %m"); return -errno; @@ -2237,8 +2237,9 @@ struct link *link; struct descriptor *desc; const struct fc_descriptor *d; - uint32_t i, j; + uint32_t i, j, max_samples = impl->quantum_limit; int res; + float *sd = impl->silence_data, *dd = impl->discard_data; if (graph->instantiated) return 0; @@ -2246,7 +2247,6 @@ graph->instantiated = true; spa_list_for_each(node, &graph->node_list, link) { - float *sd = silence_data, *dd = discard_data; node_cleanup(node); @@ -2269,7 +2269,7 @@ spa_list_for_each(link, &port->link_list, input_link) { struct port *peer = link->output; - if ((res = port_ensure_data(peer, i)) < 0) + if ((res = port_ensure_data(peer, i, max_samples)) < 0) goto error; pw_log_info("connect input port %s%d:%s %p", node->name, i, d->portsport->p.name, @@ -2279,7 +2279,7 @@ } for (j = 0; j < desc->n_output; j++) { port = &node->output_portj; - if ((res = port_ensure_data(port, i)) < 0) + if ((res = port_ensure_data(port, i, max_samples)) < 0) goto error; pw_log_info("connect output port %s%d:%s %p", node->name, i, d->portsport->p.name, @@ -2900,6 +2900,11 @@ add_plugin_func(impl, "ladspa", load_ladspa_plugin, NULL); support = pw_context_get_support(impl->context, &n_support); + impl->quantum_limit = pw_properties_get_uint32( + pw_context_get_properties(impl->context), + "default.clock.quantum-limit", 8192u); + impl->silence_data = calloc(impl->quantum_limit, sizeof(float)); + impl->discard_data = calloc(impl->quantum_limit, sizeof(float)); cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); impl->dsp.cpu_flags = cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0;
View file
pipewire-0.3.82.tar.gz/src/modules/module-netjack2-driver.c -> pipewire-0.3.83.tar.gz/src/modules/module-netjack2-driver.c
Changed
@@ -199,6 +199,7 @@ int dscp; int mtu; uint32_t latency; + uint32_t quantum_limit; struct pw_impl_module *module; struct spa_hook module_listener; @@ -868,6 +869,7 @@ peer->other_stream = 's'; peer->send_volume = &impl->sink.volume; peer->recv_volume = &impl->source.volume; + peer->quantum_limit = impl->quantum_limit; netjack2_init(peer); int bufsize = NETWORK_MAX_LATENCY * (peer->params.mtu + @@ -1238,6 +1240,9 @@ impl->props = props; data_loop = pw_context_get_data_loop(context); impl->data_loop = pw_data_loop_get_loop(data_loop); + impl->quantum_limit = pw_properties_get_uint32( + pw_context_get_properties(context), + "default.clock.quantum-limit", 8192u); impl->sink.props = pw_properties_new(NULL, NULL); impl->source.props = pw_properties_new(NULL, NULL);
View file
pipewire-0.3.82.tar.gz/src/modules/module-netjack2-manager.c -> pipewire-0.3.83.tar.gz/src/modules/module-netjack2-manager.c
Changed
@@ -242,6 +242,7 @@ uint32_t samplerate; uint32_t encoding; uint32_t kbps; + uint32_t quantum_limit; struct pw_impl_module *module; struct spa_hook module_listener; @@ -1011,6 +1012,7 @@ peer->other_stream = 'r'; peer->send_volume = &follower->sink.volume; peer->recv_volume = &follower->source.volume; + peer->quantum_limit = impl->quantum_limit; netjack2_init(peer); int bufsize = NETWORK_MAX_LATENCY * (peer->params.mtu + @@ -1279,6 +1281,9 @@ impl->props = props; data_loop = pw_context_get_data_loop(context); impl->data_loop = pw_data_loop_get_loop(data_loop); + impl->quantum_limit = pw_properties_get_uint32( + pw_context_get_properties(context), + "default.clock.quantum-limit", 8192u); impl->sink_props = pw_properties_new(NULL, NULL); impl->source_props = pw_properties_new(NULL, NULL);
View file
pipewire-0.3.82.tar.gz/src/modules/module-netjack2/peer.c -> pipewire-0.3.83.tar.gz/src/modules/module-netjack2/peer.c
Changed
@@ -6,8 +6,6 @@ #include <opus/opus_custom.h> #endif -#define MAX_BUFFER_FRAMES 8192 - struct volume { bool mute; uint32_t n_volumes; @@ -117,6 +115,7 @@ void *midi_data; uint32_t midi_size; + uint32_t quantum_limit; float *empty; void *encoded_data; uint32_t encoded_size; @@ -134,7 +133,7 @@ { int res = 0; - peer->empty = calloc(MAX_BUFFER_FRAMES, sizeof(float)); + peer->empty = calloc(peer->quantum_limit, sizeof(float)); peer->midi_size = peer->params.period_size * sizeof(float) * SPA_MAX(peer->params.send_midi_channels, peer->params.recv_midi_channels); @@ -252,7 +251,7 @@ uint32_t free_size; buf->magic = MIDI_BUFFER_MAGIC; - buf->buffer_size = MAX_BUFFER_FRAMES * sizeof(float); + buf->buffer_size = peer->quantum_limit * sizeof(float); buf->nframes = n_samples; buf->write_pos = 0; buf->event_count = 0; @@ -805,7 +804,7 @@ return 0; sub_cycle = ntohl(header->sub_cycle); - if (sub_cycle * sub_period_size > MAX_BUFFER_FRAMES) + if (sub_cycle * sub_period_size > peer->quantum_limit) return 0; for (i = 0; i < active_ports; i++) {
View file
pipewire-0.3.82.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.83.tar.gz/src/modules/module-protocol-native.c
Changed
@@ -79,8 +79,10 @@ * * Array of Unix socket names and (optionally) owner/permissions to serve, * if the context is a server. If not absolute paths, the sockets are created - * in the default runtime directory. If not specified, one socket with - * a default name is created. + * in the default runtime directory. + * + * Has the default value ` { name = "CORENAME" }, { name = "CORENAME-manager" } `, + * where `CORENAME` is the name of the PipeWire core, usually `pipewire-0`. * * The permissions have no effect for sockets from Systemd socket activation. * Those should be configured via the systemd.socket(5) mechanism. @@ -131,7 +133,7 @@ *\code{.unparsed} * context.modules = * { name = libpipewire-module-protocol-native, - * args = { sockets = { name = "pipewire-0" }, { name = "pipewire-1" } } } + * args = { sockets = { name = "pipewire-0" }, { name = "pipewire-0-manager" } } } * *\endcode */ @@ -1565,7 +1567,19 @@ struct spa_json it3; if (sockets == NULL) { - if (add_server(this, core, &props->dict, NULL) == NULL) + struct socket_info info = {0}; + spa_autofree char *manager_name = NULL; + + info.name = (char *)get_server_name(&props->dict); + if (add_server(this, core, &props->dict, &info) == NULL) + return -errno; + + manager_name = spa_aprintf("%s-manager", info.name); + if (manager_name == NULL) + return -ENOMEM; + + info.name = manager_name; + if (add_server(this, core, &props->dict, &info) == NULL) return -errno; return 0;
View file
pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.83.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1184,7 +1184,7 @@ param = spa_pod_builder_add_object(b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(MIN_BUFFERS, MIN_BUFFERS, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(
View file
pipewire-0.3.82.tar.gz/src/pipewire/buffers.c -> pipewire-0.3.83.tar.gz/src/pipewire/buffers.c
Changed
@@ -300,7 +300,7 @@ blocks, minsize, stride, max_buffers, align, types); } else { pw_log_warn("%p: no buffers param", result); - minsize = 8192; + minsize = context->settings.clock_quantum_limit; max_buffers = 2; }
View file
pipewire-0.3.82.tar.gz/src/pipewire/context.c -> pipewire-0.3.83.tar.gz/src/pipewire/context.c
Changed
@@ -1473,9 +1473,7 @@ } current_quantum = n->target_quantum; - if (!restore_quantum && - (lock_quantum || need_resume || !running || - (!force_quantum && (n->info.state > PW_NODE_STATE_IDLE)))) { + if (!restore_quantum && (lock_quantum || need_resume || !running)) { pw_log_debug("%p: keep quantum:%u restore:%u lock:%u resume:%u " "running:%u force:%u state:%s", context, current_quantum, restore_quantum, lock_quantum, need_resume,
View file
pipewire-0.3.82.tar.gz/src/pipewire/filter.c -> pipewire-0.3.83.tar.gz/src/pipewire/filter.c
Changed
@@ -26,7 +26,6 @@ PW_LOG_TOPIC_EXTERN(log_filter); #define PW_LOG_TOPIC_DEFAULT log_filter -#define MAX_SAMPLES 8192 #define MAX_BUFFERS 64 #define MASK_BUFFERS (MAX_BUFFERS-1) @@ -110,6 +109,8 @@ struct pw_loop *main_loop; struct pw_loop *data_loop; + uint32_t quantum_limit; + enum pw_filter_flags flags; struct spa_node impl_node; @@ -1236,6 +1237,7 @@ } impl->main_loop = pw_context_get_main_loop(context); + impl->quantum_limit = context->settings.clock_quantum_limit; this = &impl->this; pw_log_debug("%p: new", impl); @@ -1779,9 +1781,9 @@ SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_STEP_Int( - MAX_SAMPLES * sizeof(float), + impl->quantum_limit * sizeof(float), sizeof(float), - MAX_SAMPLES * sizeof(float), + impl->quantum_limit * sizeof(float), sizeof(float)), SPA_PARAM_BUFFERS_stride, SPA_POD_Int(4))); }
View file
pipewire-0.3.82.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.83.tar.gz/src/pipewire/impl-device.c
Changed
@@ -520,7 +520,7 @@ return -errno; } -static void global_destroy(void *data) +static void global_free(void *data) { struct pw_impl_device *device = data; spa_hook_remove(&device->global_listener); @@ -530,7 +530,7 @@ static const struct pw_global_events global_events = { PW_VERSION_GLOBAL_EVENTS, - .destroy = global_destroy, + .free = global_free, }; SPA_EXPORT
View file
pipewire-0.3.82.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.83.tar.gz/src/pipewire/impl-node.c
Changed
@@ -669,7 +669,7 @@ return -errno; } -static void global_destroy(void *data) +static void global_free(void *data) { struct pw_impl_node *this = data; spa_hook_remove(&this->global_listener); @@ -679,7 +679,7 @@ static const struct pw_global_events global_events = { PW_VERSION_GLOBAL_EVENTS, - .destroy = global_destroy, + .free = global_free, }; static inline void insert_driver(struct pw_context *context, struct pw_impl_node *node)
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
.