Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
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),
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;
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);
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) {
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
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
.