Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 70
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Sat Sep 26 15:37:38 UTC 2026 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.6.9 + +------------------------------------------------------------------- Thu Sep 3 06:15:16 UTC 2026 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.6.8
View file
pipewire-aptx.spec
Changed
@@ -8,7 +8,7 @@ %define minimum_version 1.6.0 Name: pipewire-aptx -Version: 1.6.8 +Version: 1.6.9 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
_service:download_files:pipewire-1.6.8.tar.bz2/NEWS -> _service:download_files:pipewire-1.6.9.tar.bz2/NEWS
Changed
@@ -1,3 +1,63 @@ +# PipeWire 1.6.9 (2026-09-17) + +This is a bugfix release that is API and ABI compatible with the previous +1.6.x releases. + +## Highlights + - Improve JACK object callbacks, avoid reporting old removed objects. + - Tweak the resampler cutoff frequencies to preserve more high frequencies + when upsampling. + - More small fixes and improvements. + +## Modules + - Fix RAOP encryption for OpenSSL >= 3. (#5370) + - Fix netjack2 discovery timeout. + - Fix potential truncated audio in RAOP. + - Fix potential metadata update problems. (#5445) + - Fix RAOP over TCP. + - Fix potential overflows in client node buffer checks. (#5462) + - Add node.network=true to network sinks and sources so that + pavucontrol and others don't wake them up. (#3268) + +## SPA + - Fix opus audio info type. + - Tweak the upsample cutoff frequencies to preserve more high frequencies + when upsampling. (#5390) + - Fix filter-graph property notification in some cases. + - Remove limits on filter-graph descriptions in audioconvert. + - Improve dynamic reconfiguration of filter-graphs in audioconvert. + - Improve passthrough format handling in audioconvert. + - Improve the FC and LFE volumes when upmixing is enabled. + - Fix v4l2 controls when one can not be read. + - Require 0.6.0 libcamera now. + - Improve format filtering in v4l2. + +## Pulse-server + - Don't let a pending sibling message starve capture. + - Fix name of ALSA source. + - Fix potential crash with the active_port_name. (#5435) + +## Bluetooth + - Fix a potential leak when transport fails to start. + - Fix potential crash when cleaning up iso-io transport. + +## JACK + - Rework the object lookups to avoid removed objects from leaking. (#5356) + +## GStreamer + - Add fixes for state changes and other lockups. + +## ALSA Plugin + - Generate poll errors when stopping. (#5444) + +## Tools + - Handle EOF correctly for encoded files in pw-cat. + - Fix loopback channel and position handling. + - Fix mp3 encoding in pw-record. + - Support A-law in pw-record. + +Older versions: + # PipeWire 1.6.8 (2026-07-09) This is a bugfix release that is API and ABI compatible with the previous @@ -38,9 +98,6 @@ - Skip invalid crop metadata. - Avoid crash because metadata listener was registered twice. - -Older versions: - # PipeWire 1.6.7 (2026-06-18) This is a bugfix release that is API and ABI compatible with the previous
View file
_service:download_files:pipewire-1.6.8.tar.bz2/meson.build -> _service:download_files:pipewire-1.6.9.tar.bz2/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '1.6.8', + version : '1.6.9', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3',
View file
_service:download_files:pipewire-1.6.8.tar.bz2/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> _service:download_files:pipewire-1.6.9.tar.bz2/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -87,7 +87,7 @@ static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io); -static int update_active(snd_pcm_ioplug_t *io) +static int update_active(snd_pcm_ioplug_t *io, bool force_wakeup) { snd_pcm_pipewire_t *pw = io->private_data; snd_pcm_sframes_t avail; @@ -96,7 +96,9 @@ avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr); - if (pw->error > 0) { + if (pw->error > 0 || force_wakeup || + io->state == SND_PCM_STATE_SETUP || + pw->xrun_detected) { active = true; } else if (io->state == SND_PCM_STATE_DRAINING) { @@ -167,8 +169,10 @@ return pw->error; *revents = pfds0.revents & ~(POLLIN | POLLOUT); - if (pfds0.revents & POLLIN && update_active(io)) + if (pfds0.revents & POLLIN && update_active(io, false)) *revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN; + if (io->state == SND_PCM_STATE_SETUP || pw->xrun_detected) + *revents |= POLLERR; pw_log_trace_fp("poll %d", *revents); @@ -392,7 +396,7 @@ if (state == PW_STREAM_STATE_ERROR) { pw_log_warn("%s", error); pw->error = -errno; - update_active(&pw->io); + update_active(&pw->io, false); } } @@ -466,7 +470,7 @@ } } done: - update_active(io); + update_active(io, false); } static const struct pw_stream_events stream_events = { @@ -611,7 +615,7 @@ snd_pcm_pipewire_t *pw = io->private_data; pw_log_debug("%p: stop", pw); - update_active(io); + update_active(io, true); pw_thread_loop_lock(pw->main_loop); if (pw->activated && pw->stream != NULL) { @@ -1219,7 +1223,7 @@ if (id == PW_ID_CORE) { pw->error = res; if (pw->fd != -1) - update_active(&pw->io); + update_active(&pw->io, false); } pw_thread_loop_signal(pw->main_loop, false); }
View file
_service:download_files:pipewire-1.6.8.tar.bz2/pipewire-jack/src/pipewire-jack.c -> _service:download_files:pipewire-1.6.9.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
@@ -879,6 +879,8 @@ static struct object *find_by_id(struct client *c, uint32_t id) { struct object *o; + if (id == SPA_ID_INVALID) + return NULL; spa_list_for_each(o, &c->context.objects, link) { if (o->id == id) return o; @@ -896,6 +898,14 @@ return NULL; } +static struct object *find_port_by_serial(struct client *c, uint32_t serial) +{ + struct object *o = find_by_serial(c, serial); + if (o != NULL && o->type == INTERFACE_Port) + return o; + return NULL; +} + static struct object *find_id(struct client *c, uint32_t id, bool valid) { struct object *o = find_by_id(c, id); @@ -917,15 +927,17 @@ return find_type(c, client_id, INTERFACE_Client, false); } -static struct object *find_link(struct client *c, uint32_t src, uint32_t dst) +/* Matches a link by serial instead of object id, since the object id might be + * re-used. See #5356. */ +static struct object *find_link(struct client *c, uint32_t src_serial, uint32_t dst_serial) { struct object *l; spa_list_for_each(l, &c->context.objects, link) { - if (l->type != INTERFACE_Link || l->removed) + if (l->type != INTERFACE_Link || l->removing || l->removed) continue; - if (l->port_link.src == src && - l->port_link.dst == dst) { + if (l->port_link.src_serial == src_serial && + l->port_link.dst_serial == dst_serial) { return l; } } @@ -4166,6 +4178,13 @@ } o->removing = true; + /* pipewire will reuse the global id for this object from now on, so we + * retire it here instead of when the jack object is freed. Until then the + * object remains reachable by its serial which is what's being used as + * jack_port_id, but unassigning the global id prevents that serial from + * being re-issued to new ports as they appear in the future. See #5356. */ + o->id = SPA_ID_INVALID; + switch (o->type) { case INTERFACE_Client: free_object(c, o); @@ -4178,20 +4197,20 @@ c->metadata->default_audio_source0 = '\0'; } if (find_node(c, o->node.name) == NULL) { - pw_log_info("%p: client %u removed \"%s\"", c, o->id, o->node.name); + pw_log_info("%p: client %u removed \"%s\"", c, id, o->node.name); queue_notify(c, NOTIFY_TYPE_REGISTRATION, o, 0, NULL); } else { free_object(c, o); } break; case INTERFACE_Port: - pw_log_info("%p: port %u/%u removed \"%s\"", c, o->id, o->serial, o->port.name); + pw_log_info("%p: port %u/%u removed \"%s\"", c, id, o->serial, o->port.name); queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, o, 0, NULL); break; case INTERFACE_Link: - if (find_type(c, o->port_link.src, INTERFACE_Port, true) != NULL && - find_type(c, o->port_link.dst, INTERFACE_Port, true) != NULL) { - pw_log_info("%p: link %u %u/%u -> %u/%u removed", c, o->id, + if (find_port_by_serial(c, o->port_link.src_serial) != NULL && + find_port_by_serial(c, o->port_link.dst_serial) != NULL) { + pw_log_info("%p: link %u %u/%u -> %u/%u removed", c, id, o->port_link.src, o->port_link.src_serial, o->port_link.dst, o->port_link.dst_serial); queue_notify(c, NOTIFY_TYPE_CONNECT, o, 0, NULL); @@ -4945,7 +4964,7 @@ pw_client_node_set_active(c->node, false); spa_list_for_each(o, &c->context.objects, link) { - if (o->type != INTERFACE_Link || o->removed) + if (o->type != INTERFACE_Link || o->removing || o->removed) continue; if (o->port_link.src_ours || o->port_link.dst_ours) pw_registry_destroy(c->registry, o->id); @@ -6107,7 +6126,7 @@ p = o; o = l; } - if ((l = find_link(c, o->id, p->id)) != NULL) + if ((l = find_link(c, o->serial, p->serial)) != NULL) res = 1; exit: @@ -6151,9 +6170,9 @@ if (l->type != INTERFACE_Link || l->removed) continue; if (l->port_link.src_serial == o->serial) - p = find_type(c, l->port_link.dst, INTERFACE_Port, true); + p = find_port_by_serial(c, l->port_link.dst_serial); else if (l->port_link.dst_serial == o->serial) - p = find_type(c, l->port_link.src, INTERFACE_Port, true); + p = find_port_by_serial(c, l->port_link.src_serial); else continue; @@ -6604,7 +6623,7 @@ if ((res = check_connect(c, src, dst)) != 1) goto exit; - if ((l = find_link(c, src->id, dst->id)) == NULL) { + if ((l = find_link(c, src->serial, dst->serial)) == NULL) { res = -ENOENT; goto exit; }
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/include/spa/param/audio/format.h -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/include/spa/param/audio/format.h
Changed
@@ -52,7 +52,7 @@ struct spa_audio_info_alac alac; struct spa_audio_info_flac flac; struct spa_audio_info_ape ape; - struct spa_audio_info_ape opus; + struct spa_audio_info_opus opus; struct spa_audio_info_ac3 ac3; struct spa_audio_info_eac3 eac3; struct spa_audio_info_truehd truehd;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/include/spa/pod/body.h -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/include/spa/pod/body.h
Changed
@@ -243,6 +243,12 @@ const char *s; if (spa_pod_body_get_string(pod, body, &s) < 0 || maxlen < 1) return -EINVAL; + /* pod->size includes the null terminator; a string that does not fit + * is reported as -ENOSPC instead of being silently truncated. */ + if (pod->size > maxlen) { + dest0 = '\0'; + return -ENOSPC; + } SPA_BARRIER; strncpy(dest, s, maxlen-1); SPA_BARRIER;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/meson.build -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/meson.build
Changed
@@ -131,7 +131,7 @@ endif summary({'Vulkan': have_vulkan}, bool_yn: true, section: 'Misc dependencies') - libcamera_dep = dependency('libcamera', version: '>= 0.2.0', required: get_option('libcamera')) + libcamera_dep = dependency('libcamera', version: '>= 0.6.0', required: get_option('libcamera')) summary({'libcamera': libcamera_dep.found()}, bool_yn: true, section: 'Backend') compress_offload_option = get_option('compress-offload')
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/aec/aec-null.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/aec/aec-null.c
Changed
@@ -39,7 +39,7 @@ } static const struct spa_audio_aec_methods impl_aec = { - SPA_VERSION_AUDIO_AEC, + SPA_VERSION_AUDIO_AEC_METHODS, .init = null_init, .run = null_run, };
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -678,14 +678,20 @@ const char *name; struct spa_pod *pod; char value512; + int res; if (spa_pod_parser_get_string(&prs, &name) < 0) break; if (spa_pod_parser_get_pod(&prs, &pod) < 0) break; + if (spa_pod_is_string(pod)) { - spa_pod_copy_string(pod, sizeof(value), value); + if ((res = spa_pod_copy_string(pod, sizeof(value), value)) < 0) { + spa_log_error(state->log, "can't copy value for '%s' (max %zu bytes): %s", + name, sizeof(value)-1, spa_strerror(res)); + continue; + } } else if (spa_pod_is_int(pod)) { snprintf(value, sizeof(value), "%d", SPA_POD_VALUE(struct spa_pod_int, pod));
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audioconvert/audioadapter.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -860,7 +860,7 @@ if (info.media_subtype == SPA_MEDIA_SUBTYPE_raw) { info.info.raw.rate = 0; - } else { + } else if (mode != SPA_PARAM_PORT_CONFIG_MODE_passthrough) { const char *subtype_name = spa_type_to_short_name(info.media_subtype, spa_type_media_subtype, "<unknown>");
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -952,7 +952,7 @@ { struct impl *this = object; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + struct spa_pod_dynamic_builder b; uint8_t buffer4096; struct spa_result_node_params result; uint32_t count = 0; @@ -966,37 +966,45 @@ next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); param = NULL; switch (id) { case SPA_PARAM_EnumPortConfig: - res = node_param_enum_port_config(this, id, result.index, ¶m, &b); + res = node_param_enum_port_config(this, id, result.index, ¶m, &b.b); break; case SPA_PARAM_PortConfig: - res = node_param_port_config(this, id, result.index, ¶m, &b); + res = node_param_port_config(this, id, result.index, ¶m, &b.b); break; case SPA_PARAM_PropInfo: - res = node_param_prop_info(this, id, result.index, ¶m, &b); + res = node_param_prop_info(this, id, result.index, ¶m, &b.b); break; case SPA_PARAM_Props: - res = node_param_props(this, id, result.index, ¶m, &b); + res = node_param_props(this, id, result.index, ¶m, &b.b); break; default: - return 0; + res = 0; + break; } if (res <= 0) - return res; + goto done; - if (param == NULL || spa_pod_filter(&b, &result.param, param, filter) < 0) + if (param == NULL || spa_pod_filter(&b.b, &result.param, param, filter) < 0) { + spa_pod_dynamic_builder_clean(&b); goto next; + } spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); + spa_pod_dynamic_builder_clean(&b); + if (++count != num) goto next; return 0; +done: + spa_pod_dynamic_builder_clean(&b); + return res; } static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size) @@ -1313,6 +1321,27 @@ do_sync_filter_graph(NULL, false, 0, NULL, 0, impl); } +/* Pull graphs that the data-loop must not run anymore out of its view (under + * the loop lock, via sync_filter_graph). A forced unpublish also drops graphs + * that are about to be deactivated and re-instantiated, which frees and + * recreates the underlying plugin handles, so the RT thread cannot run a graph + * while its handles are NULL. They are republished by the sync_filter_graph() + * that follows setup. */ +static void unpublish_filter_graphs(struct impl *impl, bool force) +{ + struct filter_graph *g; + bool sync = false; + + spa_list_for_each(g, &impl->active_graphs, link) { + if (force && !g->removing) + g->setup = false; + if (g->removing || !g->setup) + sync = true; + } + if (sync) + sync_filter_graph(impl); +} + static int setup_filter_graphs(struct impl *impl, bool force) { int res; @@ -1327,19 +1356,12 @@ position = in->format.info.raw.position; impl->maxports = SPA_MAX(in->format.info.raw.channels, out->format.info.raw.channels); - if (force) { - /* A forced setup deactivates and re-instantiates each graph below, - * which frees and recreates the underlying plugin handles. Pull the - * graphs out of the data-loop's view first (under the loop lock, via - * sync_filter_graph) so the RT thread cannot run a graph while its - * handles are NULL during the rebuild. They are republished by the - * sync_filter_graph() that follows setup. */ - spa_list_for_each(g, &impl->active_graphs, link) { - if (!g->removing) - g->setup = false; - } - sync_filter_graph(impl); - } + /* Only a forced setup rebuilds the graphs. Without it the currently + * published graphs stay valid and must keep running until the new ones + * are activated, so that the sync_filter_graph() after setup swaps them + * in without a gap. */ + if (force) + unpublish_filter_graphs(impl, true); spa_list_for_each_safe(g, t, &impl->active_graphs, link) { if (g->removing) @@ -1366,8 +1388,10 @@ { struct filter_graph *g, *t; + unpublish_filter_graphs(impl, force); + spa_list_for_each_safe(g, t, &impl->active_graphs, link) { - if (!g->removing) + if (!g->removing && !force) continue; spa_list_remove(&g->link); if (g->graph) @@ -1547,9 +1571,9 @@ return 0; while (true) { - const char *name; + const char *name, *value; struct spa_pod *pod; - char value4096; + char buffer64; if (spa_pod_parser_get_string(&prs, &name) < 0) break; @@ -1558,25 +1582,28 @@ break; if (spa_pod_is_string(pod)) { - spa_pod_copy_string(pod, sizeof(value), value); + if (spa_pod_get_string(pod, &value) < 0) + continue; } else if (spa_pod_is_float(pod)) { - spa_dtoa(value, sizeof(value), + spa_dtoa(buffer, sizeof(buffer), SPA_POD_VALUE(struct spa_pod_float, pod)); + value = buffer; } else if (spa_pod_is_double(pod)) { - spa_dtoa(value, sizeof(value), + spa_dtoa(buffer, sizeof(buffer), SPA_POD_VALUE(struct spa_pod_double, pod)); + value = buffer; } else if (spa_pod_is_int(pod)) { - snprintf(value, sizeof(value), "%d", + snprintf(buffer, sizeof(buffer), "%d", SPA_POD_VALUE(struct spa_pod_int, pod)); + value = buffer; } else if (spa_pod_is_long(pod)) { - snprintf(value, sizeof(value), "%"PRIi64, + snprintf(buffer, sizeof(buffer), "%"PRIi64, SPA_POD_VALUE(struct spa_pod_long, pod)); + value = buffer; } else if (spa_pod_is_bool(pod)) { - snprintf(value, sizeof(value), "%s", - SPA_POD_VALUE(struct spa_pod_bool, pod) ? - "true" : "false"); + value = SPA_POD_VALUE(struct spa_pod_bool, pod) ? "true" : "false"; } else if (spa_pod_is_none(pod)) { - spa_zero(value); + value = ""; } else continue; @@ -2573,6 +2600,10 @@ { struct filter_graph *g; + /* deactivating a graph tears down its plugin instances, so take the + * graphs out of the data-loop's view first */ + unpublish_filter_graphs(this, true); + spa_list_for_each(g, &this->active_graphs, link) { if (g->graph) spa_filter_graph_deactivate(g->graph);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audioconvert/channelmix-ops-c.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audioconvert/channelmix-ops-c.c
Changed
@@ -41,11 +41,11 @@ } } -static inline void avg_c(float *d, const float *s0, const float *s1, uint32_t n_samples) +static inline void add_c(float *d, const float *s0, const float *s1, uint32_t n_samples) { uint32_t n; for (n = 0; n < n_samples; n++) - dn = (s0n + s1n) * 0.5f; + dn = s0n + s1n; } static inline void sub_c(float *d, const float *s0, const float *s1, uint32_t n_samples) @@ -110,7 +110,7 @@ { uint32_t i, j; uint32_t w = *pos; - uint32_t o = n_buffer - delay - n_taps-1; + uint32_t o = n_buffer - delay - (n_taps-1); if (n_taps == 1) { for (i = 0; i < n_samples; i++) { @@ -299,7 +299,7 @@ if (mix->widen == 0.0f) { vol_c(d0, s0, v0, n_samples); vol_c(d1, s1, v1, n_samples); - avg_c(d2, s0, s1, n_samples); + add_c(d2, s0, s1, n_samples); } else { for (n = 0; n < n_samples; n++) { float c = s0n + s1n;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audioconvert/channelmix-ops-sse.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audioconvert/channelmix-ops-sse.c
Changed
@@ -83,10 +83,9 @@ } } -static inline void avg_sse(float *d, const float *s0, const float *s1, uint32_t n_samples) +static inline void add_sse(float *d, const float *s0, const float *s1, uint32_t n_samples) { uint32_t n, unrolled; - __m128 half = _mm_set1_ps(0.5f); if (SPA_IS_ALIGNED(d, 16) && SPA_IS_ALIGNED(s0, 16) && @@ -97,26 +96,20 @@ for (n = 0; n < unrolled; n += 8) { _mm_store_ps(&dn + 0, - _mm_mul_ps( - _mm_add_ps( - _mm_load_ps(&s0n + 0), - _mm_load_ps(&s1n + 0)), - half)); + _mm_add_ps( + _mm_load_ps(&s0n + 0), + _mm_load_ps(&s1n + 0))); _mm_store_ps(&dn + 4, - _mm_mul_ps( - _mm_add_ps( - _mm_load_ps(&s0n + 4), - _mm_load_ps(&s1n + 4)), - half)); + _mm_add_ps( + _mm_load_ps(&s0n + 4), + _mm_load_ps(&s1n + 4))); } for (; n < n_samples; n++) _mm_store_ss(&dn, - _mm_mul_ss( - _mm_add_ss( - _mm_load_ss(&s0n), - _mm_load_ss(&s1n)), - half)); + _mm_add_ss( + _mm_load_ss(&s0n), + _mm_load_ss(&s1n))); } static inline void sub_sse(float *d, const float *s0, const float *s1, uint32_t n_samples) @@ -280,11 +273,11 @@ const float *taps, uint32_t n_taps, float *dst, const float *src, const float vol, uint32_t n_samples) { - __m128 t1; + __m128 t2; const __m128 v = _mm_set1_ps(vol); uint32_t i; uint32_t w = *pos; - uint32_t o = n_buffer - delay - n_taps-1; + uint32_t o = n_buffer - delay - (n_taps-1); uint32_t n, unrolled; if (SPA_IS_ALIGNED(src, 16) && @@ -295,47 +288,47 @@ if (n_taps == 1) { for(n = 0; n < unrolled; n += 4) { + t1 = _mm_loadu_ps(&bufferw+o); t0 = _mm_load_ps(&srcn); _mm_storeu_ps(&bufferw, t0); _mm_storeu_ps(&bufferw+n_buffer, t0); - t0 = _mm_loadu_ps(&bufferw+o); - t0 = _mm_mul_ps(t0, v); + t0 = _mm_mul_ps(t1, v); _mm_store_ps(&dstn, t0); w += 4; if (w >= n_buffer) { w -= n_buffer; - t0 = _mm_load_ps(&buffern_buffer); + t0 = _mm_loadu_ps(&buffern_buffer); _mm_store_ps(&buffer0, t0); } } for(; n < n_samples; n++) { + t1 = _mm_load_ss(&bufferw+o); t0 = _mm_load_ss(&srcn); _mm_store_ss(&bufferw, t0); _mm_store_ss(&bufferw+n_buffer, t0); - t0 = _mm_load_ss(&bufferw+o); - t0 = _mm_mul_ss(t0, v); + t0 = _mm_mul_ss(t1, v); _mm_store_ss(&dstn, t0); w = w + 1 >= n_buffer ? 0 : w + 1; } } else { for(n = 0; n < unrolled; n += 4) { t0 = _mm_load_ps(&srcn); - _mm_storeu_ps(&bufferw, t0); - _mm_storeu_ps(&bufferw+n_buffer, t0); for(i = 0; i < 4; i++) convolver_run(&bufferw+o+i, &dstn+i, taps, n_taps, v); + _mm_storeu_ps(&bufferw, t0); + _mm_storeu_ps(&bufferw+n_buffer, t0); w += 4; if (w >= n_buffer) { w -= n_buffer; - t0 = _mm_load_ps(&buffern_buffer); + t0 = _mm_loadu_ps(&buffern_buffer); _mm_store_ps(&buffer0, t0); } } for(; n < n_samples; n++) { t0 = _mm_load_ss(&srcn); + convolver_run(&bufferw+o, &dstn, taps, n_taps, v); _mm_store_ss(&bufferw, t0); _mm_store_ss(&bufferw+n_buffer, t0); - convolver_run(&bufferw+o, &dstn, taps, n_taps, v); w = w + 1 >= n_buffer ? 0 : w + 1; } } @@ -393,7 +386,7 @@ if (mix->widen == 0.0f) { vol_sse(d0, s0, v0, n_samples); vol_sse(d1, s1, v1, n_samples); - avg_sse(d2, s0, s1, n_samples); + add_sse(d2, s0, s1, n_samples); } else { const __m128 mv0 = _mm_set1_ps(mix->matrix00); const __m128 mv1 = _mm_set1_ps(mix->matrix11);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audioconvert/resample-native.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audioconvert/resample-native.c
Changed
@@ -36,19 +36,19 @@ struct window_info window_info; static const struct quality blackman_qualities = { - { 8, 0.58, 0.58, { 0.16, }}, - { 16, 0.70, 0.70, { 0.20, }}, - { 24, 0.77, 0.77, { 0.16, }}, - { 32, 0.82, 0.82, { 0.16, }}, - { 48, 0.87, 0.87, { 0.16, }}, /* default */ - { 64, 0.895, 0.895, { 0.16, }}, - { 80, 0.910, 0.910, { 0.16, }}, - { 96, 0.925, 0.925, { 0.16, }}, - { 128, 0.942, 0.942, { 0.16, }}, - { 144, 0.950, 0.950, { 0.16, }}, - { 160, 0.958, 0.958, { 0.16, }}, - { 192, 0.966, 0.966, { 0.16, }}, - { 256, 0.975, 0.975, { 0.16, }}, + { 8, 0.667, 0.58, { 0.16, }}, + { 16, 0.80, 0.70, { 0.20, }}, + { 24, 0.857, 0.77, { 0.16, }}, + { 32, 0.889, 0.82, { 0.16, }}, + { 48, 0.923, 0.87, { 0.16, }}, /* default */ + { 64, 0.941, 0.895, { 0.16, }}, + { 80, 0.952, 0.910, { 0.16, }}, + { 96, 0.960, 0.925, { 0.16, }}, + { 128, 0.970, 0.942, { 0.16, }}, + { 144, 0.973, 0.950, { 0.16, }}, + { 160, 0.976, 0.958, { 0.16, }}, + { 192, 0.980, 0.966, { 0.16, }}, + { 256, 0.985, 0.975, { 0.16, }}, { 896, 0.988, 0.988, { 0.16, }}, { 1024, 0.990, 0.990, { 0.16, }}, }; @@ -70,19 +70,19 @@ } static const struct quality exp_qualities = { - { 8, 0.58, 0.58, { 16.97789, }}, - { 16, 0.70, 0.70, { 16.97789, }}, - { 24, 0.77, 0.77, { 16.97789, }}, - { 32, 0.82, 0.82, { 16.97789, }}, - { 48, 0.87, 0.87, { 16.97789, }}, /* default */ - { 64, 0.895, 0.895, { 16.97789, }}, - { 80, 0.910, 0.910, { 16.97789, }}, - { 96, 0.925, 0.925, { 16.97789, }}, - { 128, 0.942, 0.942, { 16.97789, }}, - { 144, 0.950, 0.950, { 16.97789, }}, - { 160, 0.958, 0.958, { 16.97789, }}, - { 192, 0.966, 0.966, { 16.97789, }}, - { 256, 0.975, 0.975, { 16.97789, }}, + { 8, 0.667, 0.58, { 16.97789, }}, + { 16, 0.80, 0.70, { 16.97789, }}, + { 24, 0.857, 0.77, { 16.97789, }}, + { 32, 0.889, 0.82, { 16.97789, }}, + { 48, 0.923, 0.87, { 16.97789, }}, /* default */ + { 64, 0.941, 0.895, { 16.97789, }}, + { 80, 0.952, 0.910, { 16.97789, }}, + { 96, 0.960, 0.925, { 16.97789, }}, + { 128, 0.970, 0.942, { 16.97789, }}, + { 144, 0.973, 0.950, { 16.97789, }}, + { 160, 0.976, 0.958, { 16.97789, }}, + { 192, 0.980, 0.966, { 16.97789, }}, + { 256, 0.985, 0.975, { 16.97789, }}, { 896, 0.988, 0.988, { 16.97789, }}, { 1024, 0.990, 0.990, { 16.97789, }}, }; @@ -107,21 +107,21 @@ #include "dbesi0.c" static const struct quality kaiser_qualities = { - { 8, 0.620000, 0.620000, { 3.553376, 110.000000, 0.888064 }}, - { 16, 0.780000, 0.780000, { 3.553376, 110.000000, 0.444032 }}, - { 24, 0.820000, 0.820000, { 3.904154, 120.000000, 0.325043 }}, - { 32, 0.865000, 0.865000, { 4.254931, 130.000000, 0.265548 }}, - { 48, 0.895000, 0.895000, { 4.254931, 130.000000, 0.177032 }}, - { 64, 0.915000, 0.915000, { 4.254931, 130.000000, 0.132774 }}, - { 80, 0.928000, 0.928000, { 4.254931, 130.000000, 0.106219 }}, - { 96, 0.942000, 0.942000, { 4.254931, 130.000000, 0.088516 }}, - { 128, 0.952000, 0.952000, { 4.254931, 130.000000, 0.066387 }}, - { 160, 0.960000, 0.960000, { 4.254931, 130.000000, 0.053110 }}, - { 192, 0.968000, 0.968000, { 4.254931, 130.000000, 0.044258 }}, - { 256, 0.976000, 0.976000, { 4.605709, 140.000000, 0.035914 }}, - { 512, 0.985000, 0.985000, { 4.781097, 145.000000, 0.018637 }}, - { 768, 0.990000, 0.990000, { 4.956486, 150.000000, 0.012878 }}, - { 1024, 0.993000, 0.993000, { 5.131875, 155.000000, 0.009999 }}, + { 8, 0.727, 0.62, { 3.553376, 110.0, 0.888064 }}, + { 16, 0.842, 0.78, { 3.553376, 110.0, 0.444032 }}, + { 24, 0.889, 0.82, { 3.904154, 120.0, 0.325043 }}, + { 32, 0.914, 0.865, { 4.254931, 130.0, 0.265548 }}, + { 48, 0.941, 0.895, { 4.254931, 130.0, 0.177032 }}, + { 64, 0.955, 0.915, { 4.254931, 130.0, 0.132774 }}, + { 80, 0.964, 0.928, { 4.254931, 130.0, 0.106219 }}, + { 96, 0.970, 0.942, { 4.254931, 130.0, 0.088516 }}, + { 128, 0.977, 0.952, { 4.254931, 130.0, 0.066387 }}, + { 160, 0.982, 0.960, { 4.254931, 130.0, 0.053110 }}, + { 192, 0.985, 0.968, { 4.254931, 130.0, 0.044258 }}, + { 256, 0.988, 0.976, { 4.605709, 140.0, 0.035914 }}, + { 512, 0.985, 0.985, { 4.781097, 145.0, 0.018637 }}, + { 768, 0.990, 0.990, { 4.956486, 150.0, 0.012878 }}, + { 1024, 0.993, 0.993, { 5.131875, 155.0, 0.009999 }}, }; static inline void kaiser_window(struct resample *r, double *w, double t, uint32_t n_taps) @@ -508,6 +508,17 @@ n_taps = SPA_ROUND_UP_N((uint32_t)ceil(n_taps / scale), 8); n_taps = SPA_MIN(n_taps, MAX_TAPS); + /* When upsampling with default cutoff, rounding n_taps up may + * give extra taps. Use them for a higher cutoff: + * cutoff = n_taps / (n_taps + K) + * K=3 for kaiser (better sidelobe control), K=4 for others. */ + if (out_rate >= in_rate && c->cutoff == cutoff) { + double k = c->window == RESAMPLE_WINDOW_KAISER ? 3.0 : 4.0; + double max_cutoff = SPA_MIN((double)n_taps / (n_taps + k), 0.99); + if (max_cutoff > scale) + scale = max_cutoff; + } + /* try to get at least 256 phases so that interpolation is * accurate enough when activated */ n_phases = SPA_MIN(MAX_PHASES, out_rate);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/audiomixer/mixer-dsp.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/audiomixer/mixer-dsp.c
Changed
@@ -81,7 +81,6 @@ uint32_t n_buffers; struct spa_list queue; - size_t queued_bytes; struct spa_list mix_link; bool active:1;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/avb/avb-pcm.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/avb/avb-pcm.c
Changed
@@ -359,14 +359,20 @@ const char *name; struct spa_pod *pod; char value512; + int res; if (spa_pod_parser_get_string(&prs, &name) < 0) break; if (spa_pod_parser_get_pod(&prs, &pod) < 0) break; + if (spa_pod_is_string(pod)) { - spa_pod_copy_string(pod, sizeof(value), value); + if ((res = spa_pod_copy_string(pod, sizeof(value), value)) < 0) { + spa_log_error(state->log, "can't copy value for '%s' (max %zu bytes): %s", + name, sizeof(value)-1, spa_strerror(res)); + continue; + } } else if (spa_pod_is_int(pod)) { snprintf(value, sizeof(value), "%d", SPA_POD_VALUE(struct spa_pod_int, pod));
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/bluez5/bluez-hardware.conf -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/bluez5/bluez-hardware.conf
Changed
@@ -85,10 +85,10 @@ { bus-type = "usb", vendor-id = "usb:0bda" }, # Mediatek MT7925, #pipewire-5213 - { bus-type = "usb", vendor-id = "usb:0e8d", product-id = "~(e025)", no-features = lc3-a127 }, - { bus-type = "usb", vendor-id = "usb:0489", product-id = "~(e111|e113|e118|e11e|e124|e139|e14e|e14f|e150|e151)", no-features = lc3-a127 }, - { bus-type = "usb", vendor-id = "usb:13d3", product-id = "~(3602|3603|3604|3608|3613|3627|3628|3630)", no-features = lc3-a127 }, - { bus-type = "usb", vendor-id = "usb:2c7c", product-id = "~(7009)", no-features = lc3-a127 }, + { bus-type = "usb", vendor-id = "usb:0e8d", no-features = lc3-a127, msbc-alt1-rtl }, + { bus-type = "usb", vendor-id = "usb:0489", no-features = lc3-a127, msbc-alt1-rtl }, + { bus-type = "usb", vendor-id = "usb:13d3", no-features = lc3-a127, msbc-alt1-rtl }, + { bus-type = "usb", vendor-id = "usb:2c7c", no-features = lc3-a127, msbc-alt1-rtl }, # Generic USB adapters { bus-type = "usb", no-features = msbc-alt1-rtl },
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/bluez5/media-source.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/bluez5/media-source.c
Changed
@@ -1001,8 +1001,10 @@ &port->current_format, this->codec_props, this->transport->read_mtu); - if (this->codec_data == NULL) - return -EIO; + if (this->codec_data == NULL) { + res = -EIO; + goto fail; + } spa_log_info(this->log, "%p: using %s codec %s", this, media_codec_kind_str(this->codec), this->codec->description); @@ -1012,8 +1014,10 @@ * and this won't work properly with epoll. Always dup to avoid problems. */ this->fd = dup(this->transport->fd); - if (this->fd < 0) - return -errno; + if (this->fd < 0) { + res = -errno; + goto fail; + } val = 6; if (setsockopt(this->fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)) < 0) @@ -1025,7 +1029,7 @@ if ((res = spa_bt_decode_buffer_init(&port->buffer, this->log, port->frame_size, port->current_format.info.raw.rate, this->quantum_limit, this->quantum_limit)) < 0) - return res; + goto fail; spa_bt_decode_buffer_set_target_latency(&port->buffer, (int32_t) this->decode_buffer_target); @@ -1066,8 +1070,10 @@ spa_strerror(res)); } else { spa_zero(this->source); - if (spa_bt_transport_ensure_sco_io(this->transport, this->data_loop, this->data_system) < 0) + if (spa_bt_transport_ensure_sco_io(this->transport, this->data_loop, this->data_system) < 0) { + res = -EIO; goto fail; + } spa_loop_locked(this->data_loop, do_start_sco_iso_io, 0, NULL, 0, this); } @@ -1079,11 +1085,20 @@ return 0; fail: + if (this->update_delay_event) { + spa_loop_utils_destroy_source(this->loop_utils, this->update_delay_event); + this->update_delay_event = NULL; + } + if (this->fd >= 0) { + close(this->fd); + this->fd = -1; + } + spa_bt_decode_buffer_clear(&port->buffer); if (this->codec_data) { this->codec->deinit(this->codec_data); this->codec_data = NULL; } - return -EIO; + return res; } static int do_start(struct impl *this) @@ -1139,10 +1154,6 @@ if (this->timer_source.loop) spa_loop_remove_source(this->data_loop, &this->timer_source); - if (this->transport && this->transport->iso_io) { - spa_bt_iso_io_set_cb(this->transport->iso_io, NULL, NULL); - spa_bt_iso_io_set_source_buffer(this->transport->iso_io, NULL); - } if (this->transport && this->transport->sco_io) spa_bt_sco_io_set_source_cb(this->transport->sco_io, NULL, NULL); set_timeout(this, 0);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/filter-graph/filter-graph.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/filter-graph/filter-graph.c
Changed
@@ -617,11 +617,13 @@ get_ranges(impl, p, &def, &min, &max); v = SPA_CLAMP(value ? *value : def, min, max); + if (!port->control_initialized || port->control_current != v) + count++; port->control_current = v; port->control_initialized = true; for (i = 0; i < node->n_hndl; i++) - count += port_id_set_control_value(port, i, v); + port_id_set_control_value(port, i, v); return count; }
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/libcamera/libcamera-device.cpp -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/libcamera/libcamera-device.cpp
Changed
@@ -24,6 +24,8 @@ #include "libcamera.h" #include "libcamera-manager.hpp" +#include <libcamera/base/span.h> + #include <libcamera/camera.h> #include <libcamera/property_ids.h>
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/libcamera/libcamera-source.cpp -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -8,6 +8,7 @@ #include <cstddef> #include <limits> #include <optional> +#include <span> #include <type_traits> #include <utility> @@ -303,7 +304,7 @@ } nodiscard -std::size_t count_unique_fds(libcamera::Span<const libcamera::FrameBuffer::Plane> planes) +std::size_t count_unique_fds(std::span<const libcamera::FrameBuffer::Plane> planes) { std::size_t c = 0; int fd = -1;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/v4l2/v4l2-utils.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
@@ -653,6 +653,36 @@ #define FOURCC_ARGS(f) (f)&0x7f,((f)>>8)&0x7f,((f)>>16)&0x7f,((f)>>24)&0x7f +/* The frame sizes a device enumerates are what its scaler can emit, which on a + * device that has one says nothing about how much detail reaches it: vivid + * offers up to 16384x8640 from a 720x576 source. V4L2 reports the source + * rectangle separately, so ask for that, and leave the default where it is + * today for a device that does not answer. */ +static void spa_v4l2_native_size(struct spa_v4l2_device *dev, + const struct v4l2_frmsize_stepwise *s, + uint32_t *width, uint32_t *height) +{ + struct v4l2_selection sel; + uint32_t sw, sh; + + *width = s->min_width; + *height = s->min_height; + + spa_zero(sel); + sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + sel.target = V4L2_SEL_TGT_CROP_BOUNDS; + if (xioctl(dev->fd, VIDIOC_G_SELECTION, &sel) < 0) + return; + if (sel.r.width < s->min_width || sel.r.width > s->max_width || + sel.r.height < s->min_height || sel.r.height > s->max_height) + return; + + sw = s->step_width ? s->step_width : 1; + sh = s->step_height ? s->step_height : 1; + *width = s->min_width + (sel.r.width - s->min_width) / sw * sw; + *height = s->min_height + (sel.r.height - s->min_height) / sh * sh; +} + static int spa_v4l2_enum_format(struct impl *this, int seq, uint32_t start, uint32_t num, @@ -671,6 +701,7 @@ struct spa_result_node_params result; struct v4l2_format fmt; uint32_t count = 0, try_width = 0, try_height = 0; + uint32_t def_width = 0, def_height = 0; bool with_modifier; if ((res = spa_v4l2_open(dev, this->props.device)) < 0) @@ -759,6 +790,18 @@ this->props.device); goto exit; } + /* This enumerates every pixel format of the device, so a + * filter that constrains the media type but not the pixel + * format is only applied here. */ + if (filter) { + const struct format_info *fi = + fourcc_to_format_info(port->fmtdesc.pixelformat); + + if (fi == NULL || + fi->media_type != filter_media_type || + fi->media_subtype != filter_media_subtype) + goto next_fmtdesc; + } } port->next_fmtdesc = false; port->frmsize.index = 0; @@ -907,9 +950,11 @@ spa_pod_builder_push_choice(&b.b, &f1, SPA_CHOICE_None, 0); choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b.b, &f1); - spa_pod_builder_rectangle(&b.b, - port->frmsize.stepwise.min_width, - port->frmsize.stepwise.min_height); + /* The default is what a client gets when it expresses no preference of + * its own, so offer the frame the device natively produces rather than + * the smallest one it can be asked for. */ + spa_v4l2_native_size(dev, &port->frmsize.stepwise, &def_width, &def_height); + spa_pod_builder_rectangle(&b.b, def_width, def_height); spa_pod_builder_rectangle(&b.b, port->frmsize.stepwise.min_width, port->frmsize.stepwise.min_height); @@ -1552,20 +1597,20 @@ spa_zero(control); control.id = c->ctrl_id; if (xioctl(dev->fd, VIDIOC_G_CTRL, &control) < 0) { - /* Write only controls like relative pan/tilt return EACCES */ - if (errno == EACCES) { - c->value = 0; - continue; - } - res = -errno; - goto done; + /* One control that cannot be read must not hide every other + * property of the node. Write only controls like relative + * pan/tilt return EACCES, and a volatile control returns + * whatever its g_volatile_ctrl handler returns. Keep the value + * from the last successful read, or the default that + * spa_v4l2_enum_controls() stored. */ + spa_log_debug(this->log, "'%s' VIDIOC_G_CTRL %08x: %m", + this->props.device, c->ctrl_id); + continue; } c->value = control.value; } - res = 0; -done: spa_v4l2_close(dev); - return res; + return 0; } static int
View file
_service:download_files:pipewire-1.6.8.tar.bz2/spa/plugins/videoconvert/videoconvert-ffmpeg.c -> _service:download_files:pipewire-1.6.9.tar.bz2/spa/plugins/videoconvert/videoconvert-ffmpeg.c
Changed
@@ -675,6 +675,7 @@ const char *name; struct spa_pod *pod; char value512; + int res; if (spa_pod_parser_get_string(&prs, &name) < 0) break; @@ -683,7 +684,11 @@ break; if (spa_pod_is_string(pod)) { - spa_pod_copy_string(pod, sizeof(value), value); + if ((res = spa_pod_copy_string(pod, sizeof(value), value)) < 0) { + spa_log_error(this->log, "can't copy value for '%s' (max %zu bytes): %s", + name, sizeof(value)-1, spa_strerror(res)); + continue; + } } else if (spa_pod_is_float(pod)) { spa_dtoa(value, sizeof(value), SPA_POD_VALUE(struct spa_pod_float, pod));
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/gst/gstpipewiresrc.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/gst/gstpipewiresrc.c
Changed
@@ -1074,10 +1074,6 @@ GST_DEBUG_OBJECT (this, "waiting for NEGOTIATED, now %s", pw_stream_state_as_string (state)); if (state == PW_STREAM_STATE_ERROR) break; - if (this->flushing) { - state = PW_STREAM_STATE_ERROR; - break; - } if (this->negotiated) break; @@ -1779,8 +1775,11 @@ * be moved from idle to suspended, which would mean format cleared via * handle_format_change. Wait for new format to avoid basesrc calling * create() and get not-negotiated error as response. */ - if (wait_negotiated(this) == PW_STREAM_STATE_ERROR) + if (wait_negotiated(this) == PW_STREAM_STATE_ERROR) { + pw_thread_loop_unlock (this->stream->core->loop); goto open_failed; + } + pw_thread_loop_unlock (this->stream->core->loop); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/flatpak-utils.h -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/flatpak-utils.h
Changed
@@ -65,7 +65,7 @@ static int pw_check_flatpak(pid_t pid, char **app_id, char **instance_id, char **devices) { -#if defined(__linux__) +#if defined(HAVE_GLIB2) && defined(__linux__) char root_path2048; struct stat stat_buf; int res;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-avb/stream.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-avb/stream.c
Changed
@@ -272,6 +272,7 @@ PW_KEY_NODE_NAME, "avb.source", PW_KEY_NODE_DESCRIPTION, "AVB Source", PW_KEY_NODE_WANT_DRIVER, "true", + PW_KEY_NODE_NETWORK, "true", NULL)); } else { stream->stream = pw_stream_new(server->impl->core, "sink", @@ -280,6 +281,7 @@ PW_KEY_NODE_NAME, "avb.sink", PW_KEY_NODE_DESCRIPTION, "AVB Sink", PW_KEY_NODE_WANT_DRIVER, "true", + PW_KEY_NODE_NETWORK, "true", NULL)); } if (stream->stream == NULL)
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-client-node/remote-node.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-client-node/remote-node.c
Changed
@@ -701,6 +701,11 @@ j, bm->id, bm->fd, d->maxsize, d->flags); } else if (d->type == SPA_DATA_MemPtr) { int offs = SPA_PTR_TO_INT(d->data); + if (offs < 0 || (uint32_t)offs > mm->size || + d->maxsize > mm->size - (uint32_t)offs) { + res = -EINVAL; + goto error_exit_cleanup; + } d->data = SPA_PTROFF(mm->ptr, offs, void); d->fd = -1; pw_log_debug(" data %d id:%u -> mem:%p offs:%d maxsize:%d flags:%08x",
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-echo-cancel.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-echo-cancel.c
Changed
@@ -703,6 +703,7 @@ const char *name; struct spa_pod *pod; char value512; + int res; if (spa_pod_parser_get_string(&prs, &name) < 0) break; @@ -711,7 +712,11 @@ break; if (spa_pod_is_string(pod)) { - spa_pod_copy_string(pod, sizeof(value), value); + if ((res = spa_pod_copy_string(pod, sizeof(value), value)) < 0) { + pw_log_error("can't copy value for '%s' (max %zu bytes): %s", + name, sizeof(value)-1, spa_strerror(res)); + continue; + } } else if (spa_pod_is_none(pod)) { spa_zero(value); } else
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-metadata/metadata.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-metadata/metadata.c
Changed
@@ -102,10 +102,19 @@ .clear = metadata_clear, }; +static void remove_pending(struct resource_data *d) +{ + if (d->pong_seq != 0) { + pw_impl_client_set_busy(pw_resource_get_client(d->resource), false); + d->pong_seq = 0; + d->impl->pending--; + } +} static void global_unbind(void *data) { struct resource_data *d = data; + remove_pending(d); if (d->resource) { spa_hook_remove(&d->resource_listener); spa_hook_remove(&d->object_listener); @@ -119,15 +128,6 @@ .destroy = global_unbind, }; -static void remove_pending(struct resource_data *d) -{ - if (d->pong_seq != 0) { - pw_impl_client_set_busy(pw_resource_get_client(d->resource), false); - d->pong_seq = 0; - d->impl->pending--; - } -} - static void impl_resource_destroy(void *data) { struct resource_data *d = data;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-netjack2-driver.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-netjack2-driver.c
Changed
@@ -1154,6 +1154,7 @@ } send_follower_available(impl); } + update_timer(impl, FOLLOWER_INIT_TIMEOUT); } static void core_error(void *data, uint32_t id, int seq, int res, const char *message)
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-pulse/client.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-pulse/client.c
Changed
@@ -223,7 +223,8 @@ { pw_log_trace("client %p: flushing", client); - spa_assert(!client->disconnect); + if (client->disconnect) + return -ENOTCONN; while (!spa_list_is_empty(&client->out_messages)) { struct message *m = spa_list_first(&client->out_messages, struct message, link);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-pulse/collect.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-pulse/collect.c
Changed
@@ -233,7 +233,6 @@ struct device_info *dev_info, bool monitor, struct defs *defs) { struct pw_manager_param *p; - dev_info->active_port_name = NULL; if (card) { spa_list_for_each(p, &card->param_list, link) { @@ -257,30 +256,6 @@ dev_info->have_volume = true; } } - - /* Look up the port name for the active port */ - if (dev_info->active_port != SPA_ID_INVALID) { - spa_list_for_each(p, &card->param_list, link) { - uint32_t index, direction; - const char *name = NULL; - - if (p->id != SPA_PARAM_EnumRoute) - continue; - - if (spa_pod_parse_object(p->param, - SPA_TYPE_OBJECT_ParamRoute, NULL, - SPA_PARAM_ROUTE_index, SPA_POD_Int(&index), - SPA_PARAM_ROUTE_direction, SPA_POD_Id(&direction), - SPA_PARAM_ROUTE_name, SPA_POD_String(&name)) < 0) - continue; - - if (index == dev_info->active_port && - direction == dev_info->direction) { - dev_info->active_port_name = name; - break; - } - } - } } spa_list_for_each(p, &device->param_list, link) { @@ -384,10 +359,12 @@ } uint32_t collect_port_info(struct pw_manager_object *card, struct card_info *card_info, - struct device_info *dev_info, struct port_info *port_info) + struct device_info *dev_info, struct port_info *port_info, + const char **active_port_name) { struct pw_manager_param *p; uint32_t n; + const char *aport_name = NULL; if (card == NULL) return 0; @@ -441,7 +418,7 @@ if (!array_contains(pi->devices, pi->n_devices, dev_info->device)) continue; if (pi->index == dev_info->active_port) - dev_info->active_port_name = pi->name; + aport_name = pi->name; } while (pi->info != NULL) { @@ -471,8 +448,11 @@ } n++; } - if (dev_info != NULL && dev_info->active_port_name == NULL && n > 0) - dev_info->active_port_name = port_info0.name; + if (aport_name == NULL && n > 0) + aport_name = port_info0.name; + + if (active_port_name) + *active_port_name = aport_name; return n; }
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-pulse/collect.h -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-pulse/collect.h
Changed
@@ -53,7 +53,6 @@ uint32_t card_id; uint32_t device; uint32_t active_port; - const char *active_port_name; }; @@ -127,7 +126,8 @@ }; uint32_t collect_port_info(struct pw_manager_object *card, struct card_info *card_info, - struct device_info *dev_info, struct port_info *port_info); + struct device_info *dev_info, struct port_info *port_info, + const char **active_port_name); /* ========================================================================== */
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-pulse/modules/module-alsa-source.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-pulse/modules/module-alsa-source.c
Changed
@@ -193,11 +193,11 @@ pw_properties_set(props, "source_name", NULL); } else if ((str = pw_properties_get(props, "name")) != NULL) { - pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", str); + pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_input.%s", str); pw_properties_set(props, "name", NULL); } else { - pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_output.%s", dev_id); + pw_properties_setf(props, PW_KEY_NODE_NAME, "alsa_input.%s", dev_id); } if ((str = pw_properties_get(props, "source_properties")) != NULL) {
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1357,9 +1357,20 @@ avail = spa_ringbuffer_get_read_index(&stream->ring, &index); if (!spa_list_is_empty(&client->out_messages)) { - pw_log_debug("%p: %s pending read:%u avail:%d", - stream, client->name, index, avail); - return 0; + /* Try to flush the pending messages first. A control + * message queued for a sibling stream in this same + * cycle (a playback stream's REQUEST) would otherwise + * make us skip this cycle, and when one is queued + * every cycle it starves this capture stream + * persistently while the connection itself keeps + * flowing. Only skip when the messages really cannot + * be flushed (socket backed up). */ + if (client_flush_messages(client) < 0 || + !spa_list_is_empty(&client->out_messages)) { + pw_log_debug("%p: %s pending read:%u avail:%d", + stream, client->name, index, avail); + return 0; + } } if (avail <= 0) { @@ -3178,7 +3189,7 @@ return -ENOMEM; port_info = alloca(card_info.n_ports * sizeof(*port_info)); card_info.active_profile = SPA_ID_INVALID; - n_ports = collect_port_info(card, &card_info, NULL, port_info); + n_ports = collect_port_info(card, &card_info, NULL, port_info, NULL); /* Set offset on all devices of the port */ res = -ENOENT; @@ -3637,7 +3648,7 @@ return -ENOMEM; port_info = alloca(card_info.n_ports * sizeof(*port_info)); card_info.active_profile = SPA_ID_INVALID; - n_ports = collect_port_info(o, &card_info, NULL, port_info); + n_ports = collect_port_info(o, &card_info, NULL, port_info, NULL); message_put(m, TAG_U32, n_ports, /* n_ports */ @@ -3838,11 +3849,12 @@ if (client->version >= 16) { uint32_t n_ports, n; struct port_info *port_info, *pi; + const char *active_port_name = NULL; if (card_info.n_ports > MAX_ALLOCA_SIZE / sizeof(*port_info)) return -ENOMEM; port_info = alloca(card_info.n_ports * sizeof(*port_info)); - n_ports = collect_port_info(card, &card_info, &dev_info, port_info); + n_ports = collect_port_info(card, &card_info, &dev_info, port_info, &active_port_name); message_put(m, TAG_U32, n_ports, /* n_ports */ @@ -3867,7 +3879,7 @@ } } message_put(m, - TAG_STRING, dev_info.active_port_name, /* active port name */ + TAG_STRING, active_port_name, /* active port name */ TAG_INVALID); } if (client->version >= 21) { @@ -4036,11 +4048,12 @@ if (client->version >= 16) { uint32_t n_ports, n; struct port_info *port_info, *pi; + const char *active_port_name = NULL; if (card_info.n_ports > MAX_ALLOCA_SIZE / sizeof(*port_info)) return -ENOMEM; port_info = alloca(card_info.n_ports * sizeof(*port_info)); - n_ports = collect_port_info(card, &card_info, &dev_info, port_info); + n_ports = collect_port_info(card, &card_info, &dev_info, port_info, &active_port_name); message_put(m, TAG_U32, n_ports, /* n_ports */ @@ -4065,7 +4078,7 @@ } } message_put(m, - TAG_STRING, dev_info.active_port_name, /* active port name */ + TAG_STRING, active_port_name, /* active port name */ TAG_INVALID); } if (client->version >= 21) {
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-protocol-simple.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-protocol-simple.c
Changed
@@ -78,6 +78,8 @@ * - \ref PW_KEY_NODE_RATE * - \ref PW_KEY_STREAM_CAPTURE_SINK * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_TARGET_OBJECT * * By default the server will work with stereo 16 bits samples at 44.1KHz.
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-pulse-tunnel.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-pulse-tunnel.c
Changed
@@ -79,6 +79,7 @@ * - \ref PW_KEY_NODE_DESCRIPTION * - \ref PW_KEY_NODE_GROUP * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_MEDIA_CLASS * - \ref PW_KEY_TARGET_OBJECT to specify the remote node.name or serial.id to link to *
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-raop-sink.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-raop-sink.c
Changed
@@ -89,6 +89,7 @@ * - \ref PW_KEY_NODE_GROUP * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_MEDIA_CLASS * * ## Example configuration @@ -403,14 +404,22 @@ return res; } -static int write_codec_pcm(void *dst, void *frames, uint32_t n_frames) +static int write_codec_pcm(void *dst, size_t max, const struct iovec *iov, size_t iovlen) { - uint8_t *bp, *b, *d = frames; + uint8_t *bp, *b; int bpos = 0; - uint32_t i; + uint32_t i, n_frames; + size_t j; b = bp = dst; + n_frames = 0; + for (j = 0; j < iovlen; j++) + n_frames += iovj.iov_len / 4; + + if (n_frames*4 + 8 > max) + return -ENOSPC; + bit_writer(&bp, &bpos, 1, 3); /* channel=1, stereo */ bit_writer(&bp, &bpos, 0, 4); /* Unknown */ bit_writer(&bp, &bpos, 0, 8); /* Unknown */ @@ -423,12 +432,15 @@ bit_writer(&bp, &bpos, (n_frames >> 8) & 0xff, 8); bit_writer(&bp, &bpos, (n_frames) & 0xff, 8); - for (i = 0; i < n_frames; i++) { - bit_writer(&bp, &bpos, *(d + 1), 8); - bit_writer(&bp, &bpos, *(d + 0), 8); - bit_writer(&bp, &bpos, *(d + 3), 8); - bit_writer(&bp, &bpos, *(d + 2), 8); - d += 4; + for (j = 0; j < iovlen; j++) { + const uint8_t *d = iovj.iov_base; + for (i = 0; i < iovj.iov_len / 4; i++) { + bit_writer(&bp, &bpos, *(d + 1), 8); + bit_writer(&bp, &bpos, *(d + 0), 8); + bit_writer(&bp, &bpos, *(d + 3), 8); + bit_writer(&bp, &bpos, *(d + 2), 8); + d += 4; + } } bit_writer(&bp, &bpos, 7, 3); /* end tag */ return bp - b + 1; @@ -447,11 +459,12 @@ { struct impl *impl = data; const size_t max = 8 + impl->mtu; - uint32_t tcp_pkt1, outmax, len, n_frames, rtptime; + uint32_t tcp_pkt1, outmax, len, rtptime; struct iovec out_vec3; struct rtp_header *header; struct msghdr msg; uint8_t *dst; + int res; if (!impl->recording) return; @@ -467,8 +480,6 @@ impl->sync = 0; } - n_frames = iov1.iov_len / impl->stride; - msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = out_vec; @@ -482,7 +493,12 @@ switch (impl->codec) { case CODEC_PCM: case CODEC_ALAC: - len = write_codec_pcm(dst, (void *)iov1.iov_base, n_frames); + res = write_codec_pcm(dst, max, &iov1, iovlen - 1); + if (res < 0) { + pw_log_warn("can't write data: %d (%s)", res, spa_strerror(res)); + return; + } + len = res; break; default: len = 8 + impl->mtu; @@ -493,9 +509,8 @@ aes_encrypt(impl, dst, len); if (impl->protocol == PROTO_TCP) { - out0 |= htonl((uint32_t) len + 12); - tcp_pkt0 = htonl(0x24000000); - out_vecmsg.msg_iovlen++ = (struct iovec) { tcp_pkt, 4 }; + tcp_pkt0 = htonl(0x24000000 | (len + 12)); + out_vecmsg.msg_iovlen++ = (struct iovec) { tcp_pkt, 4 }; } out_vecmsg.msg_iovlen++ = (struct iovec) { header, 12 }; @@ -1109,7 +1124,7 @@ SPA_SWAP(datai, dataj); } -static int rsa_encrypt(uint8_t *data, int len, uint8_t *enc) +static int rsa_encrypt(uint8_t *data, int len, uint8_t *enc, size_t enc_max) { uint8_t modulus256; uint8_t exponent8; @@ -1132,7 +1147,7 @@ EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM params5; int err = 0; - size_t size; + size_t size = enc_max; #if __BYTE_ORDER == __LITTLE_ENDIAN swap_bytes(modulus, msize); @@ -1254,7 +1269,7 @@ base64_encode(rac, sizeof(rac), sac, '\0'); pw_properties_set(impl->headers, "Apple-Challenge", sac); - rsa_len = rsa_encrypt(impl->aes_key, 16, rsakey); + rsa_len = rsa_encrypt(impl->aes_key, 16, rsakey, sizeof(rsakey)); if (rsa_len < 0) return -rsa_len; @@ -1871,6 +1886,8 @@ impl->psamples, impl->rate); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); + if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL) + pw_properties_set(props, PW_KEY_NODE_NETWORK, "true"); if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL) pw_properties_set(props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); if (pw_properties_get(props, "net.mtu") == NULL) @@ -1898,6 +1915,7 @@ copy_props(impl, props, PW_KEY_NODE_GROUP); copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); + copy_props(impl, props, PW_KEY_NODE_NETWORK); copy_props(impl, props, PW_KEY_MEDIA_CLASS); copy_props(impl, props, PW_KEY_MEDIA_FORMAT); copy_props(impl, props, PW_KEY_MEDIA_NAME);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-roc-sink.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-roc-sink.c
Changed
@@ -57,6 +57,7 @@ * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_MEDIA_CLASS * - \ref SPA_KEY_AUDIO_POSITION
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-roc-source.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-roc-source.c
Changed
@@ -67,6 +67,7 @@ * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_MEDIA_CLASS * - \ref SPA_KEY_AUDIO_POSITION *
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-rtp-sink.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-rtp-sink.c
Changed
@@ -85,6 +85,7 @@ * - \ref PW_KEY_NODE_GROUP * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * - \ref PW_KEY_MEDIA_CLASS * * ## Example configuration
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/modules/module-rtp-source.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/modules/module-rtp-source.c
Changed
@@ -81,6 +81,7 @@ * - \ref PW_KEY_NODE_GROUP * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_NODE_NETWORK * * ## Example configuration *\code{.unparsed}
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/tools/pw-cat.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/tools/pw-cat.c
Changed
@@ -206,7 +206,7 @@ uint32_t flags; } format_info = { { "ulaw", SF_FORMAT_ULAW, 1, "ulaw", SPA_AUDIO_FORMAT_ULAW, 1, 0 }, - { "alaw", SF_FORMAT_ULAW, 1, "alaw", SPA_AUDIO_FORMAT_ALAW, 1, 0 }, + { "alaw", SF_FORMAT_ALAW, 1, "alaw", SPA_AUDIO_FORMAT_ALAW, 1, 0 }, { "s8", SF_FORMAT_PCM_S8, 1, "s8", SPA_AUDIO_FORMAT_S8, 1, 0 }, { "u8", SF_FORMAT_PCM_U8, 1, "u8", SPA_AUDIO_FORMAT_U8, 1, 0 }, { "s16", SF_FORMAT_PCM_16, 2, "s16", SPA_AUDIO_FORMAT_S16, 2, 0 }, @@ -382,8 +382,8 @@ * interested in. This is relevant when playing data that contains * several multiplexed streams. */ while (true) { - if ((ret = av_read_frame(d->encoded.format_context, packet) < 0)) - break; + if ((ret = av_read_frame(d->encoded.format_context, packet)) < 0) + return dest_ptr - (uint8_t *)dest; if (packet->stream_index == d->encoded.stream_index) break; @@ -1775,7 +1775,6 @@ else extension = filename; - fprintf(stderr, "%s\n", filename); if (sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)) != 0) count = 0; @@ -2035,11 +2034,12 @@ } } fill_properties(data); - - /* try native format first, else decode to float */ - if ((fi = format_info_by_sf_format(info.format)) == NULL) - fi = format_info_by_sf_format(SF_FORMAT_FLOAT); } + + /* try native format first, else decode to float */ + if ((fi = format_info_by_sf_format(info.format)) == NULL) + fi = format_info_by_sf_format(SF_FORMAT_FLOAT); + if (fi == NULL) return -EIO;
View file
_service:download_files:pipewire-1.6.8.tar.bz2/src/tools/pw-loopback.c -> _service:download_files:pipewire-1.6.9.tar.bz2/src/tools/pw-loopback.c
Changed
@@ -228,10 +228,6 @@ if (data.delay != 0.0f) fprintf(f, " target.delay.sec = %s", spa_json_format_float(value, sizeof(value), data.delay)); - if (data.channels != 0) - fprintf(f, " audio.channels = %u", data.channels); - if (data.opt_channel_map != NULL) - fprintf(f, " audio.position = %s", data.opt_channel_map); if (data.opt_node_name != NULL) fprintf(f, " node.name = %s", data.opt_node_name); @@ -239,6 +235,16 @@ pw_properties_set(data.capture_props, PW_KEY_NODE_GROUP, data.opt_group_name); pw_properties_set(data.playback_props, PW_KEY_NODE_GROUP, data.opt_group_name); } + if (pw_properties_get(data.capture_props, SPA_KEY_AUDIO_CHANNELS) == NULL && + pw_properties_get(data.capture_props, SPA_KEY_AUDIO_POSITION) == NULL) { + pw_properties_setf(data.capture_props, SPA_KEY_AUDIO_CHANNELS, "%u", data.channels); + pw_properties_set(data.capture_props, SPA_KEY_AUDIO_POSITION, data.opt_channel_map); + } + if (pw_properties_get(data.playback_props, SPA_KEY_AUDIO_CHANNELS) == NULL && + pw_properties_get(data.playback_props, SPA_KEY_AUDIO_POSITION) == NULL) { + pw_properties_setf(data.playback_props, SPA_KEY_AUDIO_CHANNELS, "%u", data.channels); + pw_properties_set(data.playback_props, SPA_KEY_AUDIO_POSITION, data.opt_channel_map); + } fprintf(f, " capture.props = {"); pw_properties_serialize_dict(f, &data.capture_props->dict, 0);
View file
_service:download_files:pipewire-1.6.8.tar.bz2/test/test-spa-pod.c -> _service:download_files:pipewire-1.6.9.tar.bz2/test/test-spa-pod.c
Changed
@@ -288,6 +288,17 @@ spa_assert_se(SPA_POD_BODY_SIZE(&pod) == 6); spa_assert_se(spa_pod_is_string(&pod.pod.pod)); spa_assert_se(spa_pod_copy_string(&pod.pod.pod, sizeof(val), val) < 0); + + /* a valid string that does not fit in dest is rejected, not + * silently truncated */ + pod.pod = SPA_POD_INIT_String(9); + strncpy(pod.str, "test", 9); + + spa_assert_se(spa_pod_copy_string(&pod.pod.pod, 4, val) == -ENOSPC); + spa_assert_se(spa_streq(val, "")); + /* an exact fit is still accepted */ + spa_assert_se(spa_pod_copy_string(&pod.pod.pod, 9, val) == 0); + spa_assert_se(spa_streq(val, "test")); } { struct spa_pod_rectangle pod = SPA_POD_INIT_Rectangle(SPA_RECTANGLE(320,240));
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
.