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 19
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Fri Dec 16 18:14:30 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.62 + +------------------------------------------------------------------- Sat Dec 3 00:09:52 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.61
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.61 +Version: 0.3.62 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.61.tar.gz/NEWS -> pipewire-0.3.62.tar.gz/NEWS
Changed
@@ -1,3 +1,80 @@ +# PipeWire 0.3.62 (2022-12-09) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - A regression in screensharing was fixed. It was caused by a race when + activating links and driver nodes. + - Video transform metadata was added so that cameras and screen sharing + can report the video orientation and transformations. + - Support for the PulseAudio module-gsettings was added to make paprefs + work. + - Support for bluetooth offloading was added. This allows for the bluetooth + reception, decoding and playback to happen completely in hardware. + This also requires some support in WirePlumber. + - Many bugfixes and improvements. + + +## PipeWire + - More work on stopping nodes in a more controlled way. + - Fix a race in starting nodes and drivers. In some cases the driver + node would already be started while the link to the peer node was not + ready yet. This caused regressions in screen sharing. The driver is + now only started after all the followers and links completed. + - Fix a case where a slow capture stream would not recycle buffers + anymore and stall. (#2874) + - Fix a subtle bug in pw_loop_invoke that could cause callbacks to be + delayed and cause crashes in some cases. + - Fix a case where IPC was done from the data-thread and could cause + crashes. + +## Tools + - Silence some expected errors in the pw-top output. + +## modules + - The filter-chain has seen some optimizations in the copy plugin and + the convolver. + - The zeroconf plugin will now only unpublish services from the server + that was removed. + - Fix a potential crash when stopping pw-loopback. + - Some harmless errors were turned into info messages. + - Fix some cases where pw_stream methods were called from the data-thread + that could cause segfaults. (#2633) + +## SPA + - There is now a video transform metadata that indicates how a video + frame was transformed (rotated/flipped). libcamera and the GStreamer + elements now have support for this metadata. + - The SPA volume plugin is now disabled from the default build. + - Handle missing control info in libcamera. + - Handle errors from loop better, don't call the callbacks on errors. + - Somewhat improve performance in some audioconvert AVX2 code for format + conversion. + - Fix PortConfig and EnumPortConfig params in audioconvert and + audioadapter to reflect what is actually going on instead of using + hardcoded values. + - Pass ignore-dB property correctly in all cases. + - Probing is now done in 48KHz again. (#2857) + +## Pulse-server + - IPv4 addresses are now added first to the list and exposed first with + zeroconf discover. + - module-gsettings was added to make paprefs work. + - The pulse.idle.timeout option was disabled by default and only enabled + for selected apps (speech-dispatcher) because it caused some problems + for other apps. (#2880) + +## JACK + - Only process valid ports. Could fix some crashes. (#2863) + +## Bluetooth + - Support was added for offloading bluetooth handling. Some hardware can + receive, decode and play the bluetooth audio directly in hardware. + + +Older versions: + # PipeWire 0.3.61 (2022-11-24) This is a bugfix release that is API and ABI compatible with previous @@ -65,9 +142,6 @@ - Add option to set node.passive on jack clients. Make some quirks for qsynth to make it suspend and fade out better. - -Older versions: - # PipeWire 0.3.60 (2022-11-10) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.61.tar.gz/meson.build -> pipewire-0.3.62.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.61', + version : '0.3.62', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3', @@ -301,6 +301,9 @@ flatpak_support = glib2_dep.found() cdata.set('HAVE_GLIB2', flatpak_support) +gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : get_option('gsettings')) +summary({'GIO (GSettings)': gio_dep.found()}, bool_yn: true, section: 'Misc dependencies') + gst_option = get_option('gstreamer') gst_deps_def = { 'glib-2.0': {'version': '>=2.32.0'},
View file
pipewire-0.3.61.tar.gz/meson_options.txt -> pipewire-0.3.62.tar.gz/meson_options.txt
Changed
@@ -177,9 +177,9 @@ type: 'feature', value: 'enabled') option('volume', - description: 'Enable volume spa plugin integration', + description: 'Build the legacy volume spa plugin', type: 'feature', - value: 'enabled') + value: 'disabled') option('vulkan', description: 'Enable vulkan spa plugin integration', type: 'feature', @@ -269,3 +269,7 @@ description: 'Enable code that depends on libreadline', type: 'feature', value: 'auto') +option('gsettings', + description: 'Enable code that depends on gsettings', + type: 'feature', + value: 'auto')
View file
pipewire-0.3.61.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.62.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -1144,6 +1144,8 @@ if (pw_map_item_is_free(item)) continue; p = item->data; + if (!p->valid) + continue; spa_list_for_each(mix, &p->mix, port_link) { if (SPA_LIKELY(mix->io != NULL)) mix->io->status = SPA_STATUS_NEED_DATA; @@ -1153,6 +1155,8 @@ if (pw_map_item_is_free(item)) continue; p = item->data; + if (!p->valid) + continue; prepare_output(p, frames); p->io.status = SPA_STATUS_NEED_DATA; }
View file
pipewire-0.3.61.tar.gz/spa/include/spa/buffer/meta.h -> pipewire-0.3.62.tar.gz/spa/include/spa/buffer/meta.h
Changed
@@ -39,16 +39,17 @@ enum spa_meta_type { SPA_META_Invalid, - SPA_META_Header, /**< struct spa_meta_header */ - SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */ - SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */ - SPA_META_Bitmap, /**< struct spa_meta_bitmap */ - SPA_META_Cursor, /**< struct spa_meta_cursor */ - SPA_META_Control, /**< metadata contains a spa_meta_control - * associated with the data */ - SPA_META_Busy, /**< don't write to buffer when count > 0 */ - - _SPA_META_LAST, /**< not part of ABI/API */ + SPA_META_Header, /**< struct spa_meta_header */ + SPA_META_VideoCrop, /**< struct spa_meta_region with cropping data */ + SPA_META_VideoDamage, /**< array of struct spa_meta_region with damage, where an invalid entry or end-of-array marks the end. */ + SPA_META_Bitmap, /**< struct spa_meta_bitmap */ + SPA_META_Cursor, /**< struct spa_meta_cursor */ + SPA_META_Control, /**< metadata contains a spa_meta_control + * associated with the data */ + SPA_META_Busy, /**< don't write to buffer when count > 0 */ + SPA_META_VideoTransform, /**< struct spa_meta_transform */ + + _SPA_META_LAST, /**< not part of ABI/API */ }; /** @@ -161,6 +162,24 @@ uint32_t count; /**< number of users busy with the buffer */ }; +enum spa_meta_videotransform_value { + SPA_META_TRANSFORMATION_None = 0, /**< no transform */ + SPA_META_TRANSFORMATION_90, /**< 90 degree counter-clockwise */ + SPA_META_TRANSFORMATION_180, /**< 180 degree counter-clockwise */ + SPA_META_TRANSFORMATION_270, /**< 270 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped, /**< 180 degree flipped around the vertical axis. Equivalent + * to a reflexion through the vertical line splitting the + * bufffer in two equal sized parts */ + SPA_META_TRANSFORMATION_Flipped90, /**< flip then rotate around 90 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped180, /**< flip then rotate around 180 degree counter-clockwise */ + SPA_META_TRANSFORMATION_Flipped270, /**< flip then rotate around 270 degree counter-clockwise */ +}; + +/** a transformation of the buffer */ +struct spa_meta_videotransform { + uint32_t transform; /**< orientation transformation that was applied to the buffer */ +}; + /** * \} */
View file
pipewire-0.3.61.tar.gz/spa/include/spa/param/props.h -> pipewire-0.3.62.tar.gz/spa/include/spa/param/props.h
Changed
@@ -74,6 +74,7 @@ SPA_PROP_rate, SPA_PROP_quality, SPA_PROP_bluetoothAudioCodec, + SPA_PROP_bluetoothOffloadActive, SPA_PROP_START_Audio = 0x10000, /**< audio related properties */ SPA_PROP_waveType,
View file
pipewire-0.3.61.tar.gz/spa/include/spa/param/type-info.h -> pipewire-0.3.62.tar.gz/spa/include/spa/param/type-info.h
Changed
@@ -117,6 +117,7 @@ { SPA_PROP_rate, SPA_TYPE_Double, SPA_TYPE_INFO_PROPS_BASE "rate", NULL }, { SPA_PROP_quality, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "quality", NULL }, { SPA_PROP_bluetoothAudioCodec, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "bluetoothAudioCodec", spa_type_bluetooth_audio_codec }, + { SPA_PROP_bluetoothOffloadActive, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "bluetoothOffloadActive", NULL }, { SPA_PROP_waveType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL }, { SPA_PROP_frequency, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "frequency", NULL },
View file
pipewire-0.3.61.tar.gz/spa/plugins/aec/aec-webrtc.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/aec/aec-webrtc.cpp
Changed
@@ -100,7 +100,8 @@ } apm->high_pass_filter()->Enable(high_pass_filter); - // Always disable drift compensation since it requires drift sampling + // Always disable drift compensation since PipeWire will already do + // drift compensation on all sinks and sources linked to this echo-canceler apm->echo_cancellation()->enable_drift_compensation(false); apm->echo_cancellation()->Enable(true); // TODO: wire up supression levels to args
View file
pipewire-0.3.61.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.62.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
@@ -34,7 +34,7 @@ struct spa_i18n *acp_i18n; -#define DEFAULT_RATE 44100 +#define DEFAULT_RATE 48000 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100) /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */ @@ -1348,7 +1348,6 @@ static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device *dev) { const char *mod_name; - bool ignore_dB = false; uint32_t i, port_index; int res; @@ -1365,7 +1364,7 @@ dev->device.flags |= ACP_DEVICE_ACTIVE; - find_mixer(impl, dev, NULL, ignore_dB); + find_mixer(impl, dev, NULL, impl->ignore_dB); /* Synchronize priority values, as it may have changed when setting the profile */ for (i = 0; i < impl->card.n_ports; i++) { @@ -1386,7 +1385,7 @@ if (dev->active_port) dev->active_port->port.flags |= ACP_PORT_ACTIVE; - if ((res = setup_mixer(impl, dev, ignore_dB)) < 0) + if ((res = setup_mixer(impl, dev, impl->ignore_dB)) < 0) return res; if (dev->read_volume) @@ -1533,7 +1532,6 @@ struct acp_card *card; const char *s, *profile_set = NULL, *profile = NULL; char device_id16; - bool ignore_dB = false; uint32_t profile_index; int res; @@ -1554,6 +1552,7 @@ impl->use_ucm = true; impl->auto_profile = true; impl->auto_port = true; + impl->ignore_dB = false; if (props) { if ((s = acp_dict_lookup(props, "api.alsa.use-ucm")) != NULL) @@ -1561,7 +1560,7 @@ if ((s = acp_dict_lookup(props, "api.alsa.soft-mixer")) != NULL) impl->soft_mixer = spa_atob(s); if ((s = acp_dict_lookup(props, "api.alsa.ignore-dB")) != NULL) - ignore_dB = spa_atob(s); + impl->ignore_dB = spa_atob(s); if ((s = acp_dict_lookup(props, "device.profile-set")) != NULL) profile_set = s; if ((s = acp_dict_lookup(props, "device.profile")) != NULL) @@ -1609,7 +1608,7 @@ goto error; } - impl->profile_set->ignore_dB = ignore_dB; + impl->profile_set->ignore_dB = impl->ignore_dB; pa_alsa_profile_set_probe(impl->profile_set, impl->ucm.mixers, device_id,
View file
pipewire-0.3.61.tar.gz/spa/plugins/alsa/acp/card.h -> pipewire-0.3.62.tar.gz/spa/plugins/alsa/acp/card.h
Changed
@@ -46,6 +46,7 @@ bool soft_mixer; bool auto_profile; bool auto_port; + bool ignore_dB; pa_alsa_ucm_config ucm; pa_alsa_profile_set *profile_set;
View file
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -138,6 +138,27 @@ return 0; } +static int convert_enum_port_config(struct impl *this, + int seq, uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter, struct spa_pod_builder *builder) +{ + struct spa_pod *f1, *f2 = NULL; + int res; + + f1 = spa_pod_builder_add_object(builder, + SPA_TYPE_OBJECT_ParamPortConfig, id, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(this->direction)); + + if (filter) { + if ((res = spa_pod_filter(builder, &f2, f1, filter)) < 0) + return res; + } + else { + f2 = f1; + } + return spa_node_enum_params(this->convert, seq, id, start, num, f2); +} + static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter) @@ -163,9 +184,25 @@ switch (id) { case SPA_PARAM_EnumPortConfig: + return convert_enum_port_config(this, seq, id, start, num, filter, &b.b); case SPA_PARAM_PortConfig: - res = spa_node_enum_params(this->convert, seq, id, start, num, filter); - return res; + if (this->passthrough) { + switch (result.index) { + case 0: + result.param = spa_pod_builder_add_object(&b.b, + SPA_TYPE_OBJECT_ParamPortConfig, id, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(this->direction), + SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id( + SPA_PARAM_PORT_CONFIG_MODE_passthrough)); + result.next++; + break; + default: + return 0; + } + } else { + return convert_enum_port_config(this, seq, id, start, num, filter, &b.b); + } + break; case SPA_PARAM_PropInfo: res = follower_enum_params(this, id, IDX_PropInfo, &result, filter, &b.b); @@ -813,9 +850,11 @@ this->started = true; break; case SPA_NODE_COMMAND_Suspend: + this->started = false; spa_log_debug(this->log, "%p: suspending", this); break; case SPA_NODE_COMMAND_Pause: + this->started = false; spa_log_debug(this->log, "%p: pausing", this); break; case SPA_NODE_COMMAND_Flush: @@ -847,10 +886,10 @@ break; case SPA_NODE_COMMAND_Suspend: configure_format(this, 0, NULL); - SPA_FALLTHROUGH + spa_log_debug(this->log, "%p: suspended", this); + break; case SPA_NODE_COMMAND_Pause: - this->started = false; - spa_log_debug(this->log, "%p: stopped", this); + spa_log_debug(this->log, "%p: paused", this); break; case SPA_NODE_COMMAND_Flush: spa_log_debug(this->log, "%p: flushed", this); @@ -1164,7 +1203,7 @@ spa_log_trace_fp(this->log, "%p: ready %d", this, status); if (!this->started) { - spa_log_warn(this->log, "%p: ready stopped node", this); + spa_log_info(this->log, "%p: ready stopped node", this); return -EIO; }
View file
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -161,6 +161,7 @@ struct port *portsMAX_PORTS; uint32_t n_ports; + enum spa_direction direction; enum spa_param_port_config_mode mode; struct spa_audio_info format; @@ -378,55 +379,61 @@ switch (id) { case SPA_PARAM_EnumPortConfig: + { + struct dir *dir; switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp)); + dir = &this->dirSPA_DIRECTION_INPUT;; break; case 1: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp)); - break; - case 2: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert)); - break; - case 3: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert)); + dir = &this->dirSPA_DIRECTION_OUTPUT;; break; default: return 0; } + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_ParamPortConfig, id, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(dir->direction), + SPA_PARAM_PORT_CONFIG_mode, SPA_POD_CHOICE_ENUM_Id(4, + SPA_PARAM_PORT_CONFIG_MODE_none, + SPA_PARAM_PORT_CONFIG_MODE_none, + SPA_PARAM_PORT_CONFIG_MODE_dsp, + SPA_PARAM_PORT_CONFIG_MODE_convert), + SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_CHOICE_Bool(false), + SPA_PARAM_PORT_CONFIG_control, SPA_POD_CHOICE_Bool(false)); break; - + } case SPA_PARAM_PortConfig: + { + struct dir *dir; + struct spa_pod_frame f1; + switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_INPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(this->dirSPA_DIRECTION_INPUT.mode)); + dir = &this->dirSPA_DIRECTION_INPUT;; break; case 1: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_ParamPortConfig, id, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(this->dirSPA_DIRECTION_OUTPUT.mode)); + dir = &this->dirSPA_DIRECTION_OUTPUT;; break; default: return 0; } + spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_ParamPortConfig, id); + spa_pod_builder_add(&b, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(dir->direction), + SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(dir->mode), + SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_Bool(this->monitor), + SPA_PARAM_PORT_CONFIG_control, SPA_POD_Bool(dir->control), + 0); + + if (dir->have_format) { + spa_pod_builder_prop(&b, SPA_PARAM_PORT_CONFIG_format, 0); + spa_format_audio_raw_build(&b, SPA_PARAM_PORT_CONFIG_format, + &dir->format.info.raw); + } + param = spa_pod_builder_pop(&b, &f0); break; - + } case SPA_PARAM_PropInfo: { struct props *p = &this->props; @@ -1015,6 +1022,8 @@ init_port(this, direction, 0, 0, false, false, false); break; } + case SPA_PARAM_PORT_CONFIG_MODE_none: + break; default: return -ENOTSUP; } @@ -2906,7 +2915,9 @@ this->props.soft.n_volumes = this->props.n_channels; this->props.monitor.n_volumes = this->props.n_channels; + this->dirSPA_DIRECTION_INPUT.direction = SPA_DIRECTION_INPUT; this->dirSPA_DIRECTION_INPUT.latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); + this->dirSPA_DIRECTION_OUTPUT.direction = SPA_DIRECTION_OUTPUT; this->dirSPA_DIRECTION_OUTPUT.latency = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT); this->node.iface = SPA_INTERFACE_INIT(
View file
pipewire-0.3.61.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.62.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
@@ -156,11 +156,12 @@ conv_s24_to_f32d_1s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) { - const int24_t *s = src; + const int8_t *s = src; float *d0 = dst0; uint32_t n, unrolled; __m128i in; __m128 out, factor = _mm_set1_ps(1.0f / S24_SCALE); + __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels); if (SPA_IS_ALIGNED(d0, 16) && n_samples > 0) { unrolled = n_samples & ~3; @@ -171,23 +172,19 @@ unrolled = 0; 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)); + in = _mm_i32gather_epi32((int*)s, mask1, 1); in = _mm_slli_epi32(in, 8); in = _mm_srai_epi32(in, 8); out = _mm_cvtepi32_ps(in); out = _mm_mul_ps(out, factor); _mm_store_ps(&d0n, out); - s += 4 * n_channels; + s += 12 * n_channels; } for(; n < n_samples; n++) { - out = _mm_cvtsi32_ss(factor, s24_to_s32(*s)); + out = _mm_cvtsi32_ss(factor, s24_to_s32(*(int24_t*)s)); out = _mm_mul_ss(out, factor); _mm_store_ss(&d0n, out); - s += n_channels; + s += 3 * n_channels; } } @@ -195,11 +192,12 @@ conv_s24_to_f32d_2s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) { - const int24_t *s = src; + const int8_t *s = src; float *d0 = dst0, *d1 = dst1; uint32_t n, unrolled; __m128i in2; __m128 out2, factor = _mm_set1_ps(1.0f / S24_SCALE); + __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels); if (SPA_IS_ALIGNED(d0, 16) && SPA_IS_ALIGNED(d1, 16) && @@ -212,16 +210,8 @@ unrolled = 0; 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)); - 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)); + in0 = _mm_i32gather_epi32((int*)&s0, mask1, 1); + in1 = _mm_i32gather_epi32((int*)&s3, mask1, 1); in0 = _mm_slli_epi32(in0, 8); in1 = _mm_slli_epi32(in1, 8); @@ -238,27 +228,28 @@ _mm_store_ps(&d0n, out0); _mm_store_ps(&d1n, out1); - s += 4 * n_channels; + s += 12 * n_channels; } for(; n < n_samples; n++) { - out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*s)); - out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+1))); + out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+0))); + out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+1))); out0 = _mm_mul_ss(out0, factor); out1 = _mm_mul_ss(out1, factor); _mm_store_ss(&d0n, out0); _mm_store_ss(&d1n, out1); - s += n_channels; + s += 3 * n_channels; } } static void conv_s24_to_f32d_4s_avx2(void *data, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_channels, uint32_t n_samples) { - const int24_t *s = src; + const int8_t *s = src; float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3; uint32_t n, unrolled; __m128i in4; __m128 out4, factor = _mm_set1_ps(1.0f / S24_SCALE); + __m128i mask1 = _mm_setr_epi32(0*n_channels, 3*n_channels, 6*n_channels, 9*n_channels); if (SPA_IS_ALIGNED(d0, 16) && SPA_IS_ALIGNED(d1, 16) && @@ -273,26 +264,10 @@ unrolled = 0; 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)); - 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)); - 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)); - 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)); + in0 = _mm_i32gather_epi32((int*)&s0, mask1, 1); + in1 = _mm_i32gather_epi32((int*)&s3, mask1, 1); + in2 = _mm_i32gather_epi32((int*)&s6, mask1, 1); + in3 = _mm_i32gather_epi32((int*)&s9, mask1, 1); in0 = _mm_slli_epi32(in0, 8); in1 = _mm_slli_epi32(in1, 8); @@ -319,13 +294,13 @@ _mm_store_ps(&d2n, out2); _mm_store_ps(&d3n, out3); - s += 4 * n_channels; + s += 12 * n_channels; } for(; n < n_samples; n++) { - out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*s)); - out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+1))); - out2 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+2))); - out3 = _mm_cvtsi32_ss(factor, s24_to_s32(*(s+3))); + out0 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+0))); + out1 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+1))); + out2 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+2))); + out3 = _mm_cvtsi32_ss(factor, s24_to_s32(*((int24_t*)s+3))); out0 = _mm_mul_ss(out0, factor); out1 = _mm_mul_ss(out1, factor); out2 = _mm_mul_ss(out2, factor); @@ -334,7 +309,7 @@ _mm_store_ss(&d1n, out1); _mm_store_ss(&d2n, out2); _mm_store_ss(&d3n, out3); - s += n_channels; + s += 3 * n_channels; } } @@ -361,12 +336,10 @@ const int32_t *s = src; float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3; uint32_t n, unrolled; - __m256i in4, t4; + __m256i in4; __m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE); - __m256i mask1 = _mm256_setr_epi64x(0*n_channels, 0*n_channels+2, 4*n_channels, 4*n_channels+2); - __m256i mask2 = _mm256_setr_epi64x(1*n_channels, 1*n_channels+2, 5*n_channels, 5*n_channels+2); - __m256i mask3 = _mm256_setr_epi64x(2*n_channels, 2*n_channels+2, 6*n_channels, 6*n_channels+2); - __m256i mask4 = _mm256_setr_epi64x(3*n_channels, 3*n_channels+2, 7*n_channels, 7*n_channels+2); + __m256i mask1 = _mm256_setr_epi32(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels, + 3*n_channels, 5*n_channels, 6*n_channels, 7*n_channels); if (SPA_IS_ALIGNED(d0, 32) && SPA_IS_ALIGNED(d1, 32) && @@ -377,19 +350,10 @@ unrolled = 0; for(n = 0; n < unrolled; n += 8) { - in0 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask1, 4); - in1 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask2, 4); - in2 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask3, 4); - in3 = _mm256_i64gather_epi64((long long int *)&s0*n_channels, mask4, 4); - - t0 = _mm256_unpacklo_epi32(in0, in1); /* a0 a1 b0 b1 a4 a5 b4 b5 */ - t1 = _mm256_unpackhi_epi32(in0, in1); /* c0 c1 d0 d1 c4 c5 d4 d5 */ - t2 = _mm256_unpacklo_epi32(in2, in3); /* a2 a3 b2 b3 a6 a7 b6 b7 */ - t3 = _mm256_unpackhi_epi32(in2, in3); /* c2 c3 d2 d3 c6 c7 d6 d7 */ - in0 = _mm256_unpacklo_epi64(t0, t2); /* a0 a1 a2 a3 a4 a5 a6 a7 */ - in1 = _mm256_unpackhi_epi64(t0, t2); /* b0 b1 b2 b3 b4 b5 b6 b7 */ - in2 = _mm256_unpacklo_epi64(t1, t3); /* c0 c1 c2 c3 c4 c5 c6 c7 */
View file
pipewire-0.3.61.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.62.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -79,11 +79,13 @@ struct props { enum spa_bluetooth_audio_codec codec; + bool offload_active; }; static void reset_props(struct props *props) { props->codec = 0; + props->offload_active = false; } struct impl; @@ -97,6 +99,7 @@ unsigned int mute:1; unsigned int save:1; unsigned int a2dp_duplex:1; + unsigned int offload_acquired:1; uint32_t n_channels; int64_t latency_offset; uint32_t channelsSPA_AUDIO_MAX_CHANNELS; @@ -407,6 +410,24 @@ .volume_changed = volume_changed, }; +static int node_offload_set_active(struct node *node, bool active) +{ + int res = 0; + + if (node->transport == NULL || !node->active) + return -ENOTSUP; + + if (active && !node->offload_acquired) + res = spa_bt_transport_acquire(node->transport, false); + else if (!active && node->offload_acquired) + res = spa_bt_transport_release(node->transport); + + if (res >= 0) + node->offload_acquired = active; + + return res; +} + static void get_channels(struct spa_bt_transport *t, bool a2dp_duplex, uint32_t *n_channels, uint32_t *channels) { const struct media_codec *codec; @@ -480,6 +501,7 @@ this->nodesid.impl = this; this->nodesid.active = true; + this->nodesid.offload_acquired = false; this->nodesid.a2dp_duplex = a2dp_duplex; get_channels(t, a2dp_duplex, &this->nodesid.n_channels, this->nodesid.channels); if (this->nodesid.transport) @@ -804,6 +826,7 @@ for (uint32_t i = 0; i < 2; i++) { struct node * node = &this->nodesi; + node_offload_set_active(node, false); if (node->transport) { spa_hook_remove(&node->transport_listener); node->transport = NULL; @@ -813,6 +836,8 @@ node->active = false; } } + + this->props.offload_active = false; } static bool validate_profile(struct impl *this, uint32_t profile, @@ -1674,7 +1699,7 @@ return true; } -static struct spa_pod *build_prop_info(struct impl *this, struct spa_pod_builder *b, uint32_t id) +static struct spa_pod *build_prop_info_codec(struct impl *this, struct spa_pod_builder *b, uint32_t id) { struct spa_pod_frame f2; struct spa_pod_choice *choice; @@ -1748,7 +1773,8 @@ return spa_pod_builder_add_object(b, SPA_TYPE_OBJECT_Props, id, - SPA_PROP_bluetoothAudioCodec, SPA_POD_Id(p->codec)); + SPA_PROP_bluetoothAudioCodec, SPA_POD_Id(p->codec), + SPA_PROP_bluetoothOffloadActive, SPA_POD_Bool(p->offload_active)); } static int impl_enum_params(void *object, int seq, @@ -1841,7 +1867,14 @@ { switch (result.index) { case 0: - param = build_prop_info(this, &b, id); + param = build_prop_info_codec(this, &b, id); + break; + case 1: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_PropInfo, id, + SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_bluetoothOffloadActive), + SPA_PROP_INFO_description, SPA_POD_String("Bluetooth audio offload active"), + SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool(false)); break; default: return 0; @@ -2030,6 +2063,25 @@ return changed; } +static void apply_prop_offload_active(struct impl *this, bool active) +{ + bool old_value = this->props.offload_active; + + this->props.offload_active = active; + + for (int i = 0; i < 2; i++) { + node_offload_set_active(&this->nodesi, active); + if (!this->nodesi.offload_acquired) + this->props.offload_active = false; + } + + if (this->props.offload_active != old_value) { + this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS; + this->paramsIDX_Props.flags ^= SPA_PARAM_INFO_SERIAL; + emit_info(this, false); + } +} + static int impl_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) @@ -2104,19 +2156,23 @@ case SPA_PARAM_Props: { uint32_t codec_id = SPA_ID_INVALID; + bool offload_active = this->props.offload_active; if (param == NULL) return 0; if ((res = spa_pod_parse_object(param, SPA_TYPE_OBJECT_Props, NULL, - SPA_PROP_bluetoothAudioCodec, SPA_POD_OPT_Id(&codec_id))) < 0) { + SPA_PROP_bluetoothAudioCodec, SPA_POD_OPT_Id(&codec_id), + SPA_PROP_bluetoothOffloadActive, SPA_POD_OPT_Bool(&offload_active))) < 0) { spa_log_warn(this->log, "can't parse props"); spa_debug_pod(0, NULL, param); return res; } - spa_log_debug(this->log, "setting props codec:%d", codec_id); + spa_log_debug(this->log, "setting props codec:%d offload:%d", (int)codec_id, (int)offload_active); + + apply_prop_offload_active(this, offload_active); if (codec_id == SPA_ID_INVALID) return 0;
View file
pipewire-0.3.61.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.62.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
@@ -95,7 +95,6 @@ struct buffer buffersMAX_BUFFERS; uint32_t n_buffers; - struct spa_list free; struct spa_list ready; struct buffer *current_buffer;
View file
pipewire-0.3.61.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -78,6 +78,7 @@ struct spa_list link; struct spa_buffer *outbuf; struct spa_meta_header *h; + struct spa_meta_videotransform *videotransform; void *ptr; }; @@ -589,6 +590,12 @@ SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))); break; + case 1: + param = (struct spa_pod*)spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_ParamMeta, id, + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform), + SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_videotransform))); + break; default: return 0; }
View file
pipewire-0.3.61.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.62.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
@@ -74,7 +74,7 @@ return; StreamRoles roles; - roles.push_back(VideoRecording); + roles.push_back(StreamRole::VideoRecording); impl->config = impl->camera->generateConfiguration(roles); } @@ -500,28 +500,48 @@ 0); switch (ctrl_id->type()) { - case ControlTypeBool: + case ControlTypeBool: { + bool def; + if (ctrl_info.def().isNone()) + def = ctrl_info.min().get<bool>(); + else + def = ctrl_info.def().get<bool>(); + spa_pod_builder_add(&b, - SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool( - (bool)ctrl_info.def().get<bool>()), - 0); - break; - case ControlTypeFloat: + SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool( + def), + 0); + } break; + case ControlTypeFloat: { + float min = ctrl_info.min().get<float>(); + float max = ctrl_info.max().get<float>(); + float def; + + if (ctrl_info.def().isNone()) + def = (min + max) / 2; + else + def = ctrl_info.def().get<float>(); + spa_pod_builder_add(&b, SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float( - (float)ctrl_info.def().get<float>(), - (float)ctrl_info.min().get<float>(), - (float)ctrl_info.max().get<float>()), + def, min, max), 0); - break; - case ControlTypeInteger32: + } break; + case ControlTypeInteger32: { + int32_t min = ctrl_info.min().get<int32_t>(); + int32_t max = ctrl_info.max().get<int32_t>(); + int32_t def; + + if (ctrl_info.def().isNone()) + def = (min + max) / 2; + else + def = ctrl_info.def().get<int32_t>(); + spa_pod_builder_add(&b, SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int( - (int32_t)ctrl_info.def().get<int32_t>(), - (int32_t)ctrl_info.min().get<int32_t>(), - (int32_t)ctrl_info.max().get<int32_t>()), + def, min, max), 0); - break; + } break; default: goto next; } @@ -678,6 +698,31 @@ return -ENOTSUP; } +static const struct { + Transform libcamera_transform; + uint32_t spa_transform_value; +} transform_map = { + { Transform::Identity, SPA_META_TRANSFORMATION_None }, + { Transform::Rot0, SPA_META_TRANSFORMATION_None }, + { Transform::HFlip, SPA_META_TRANSFORMATION_Flipped }, + { Transform::VFlip, SPA_META_TRANSFORMATION_Flipped180 }, + { Transform::HVFlip, SPA_META_TRANSFORMATION_180 }, + { Transform::Rot180, SPA_META_TRANSFORMATION_180 }, + { Transform::Transpose, SPA_META_TRANSFORMATION_Flipped90 }, + { Transform::Rot90, SPA_META_TRANSFORMATION_90 }, + { Transform::Rot270, SPA_META_TRANSFORMATION_270 }, + { Transform::Rot180Transpose, SPA_META_TRANSFORMATION_Flipped270 }, +}; + +static uint32_t libcamera_transform_to_spa_transform_value(Transform transform) +{ + for (const auto& t : transform_map) { + if (t.libcamera_transform == transform) + return t.spa_transform_value; + } + return SPA_META_TRANSFORMATION_None; +} + static int mmap_init(struct impl *impl, struct port *port, struct spa_buffer **buffers, uint32_t n_buffers) @@ -722,6 +767,16 @@ b->flags = BUFFER_FLAG_OUTSTANDING; b->h = (struct spa_meta_header*)spa_buffer_find_meta_data(buffersi, SPA_META_Header, sizeof(*b->h)); + b->videotransform = (struct spa_meta_videotransform*)spa_buffer_find_meta_data( + buffersi, SPA_META_VideoTransform, sizeof(*b->videotransform)); + if (b->videotransform) { + b->videotransform->transform = + libcamera_transform_to_spa_transform_value(impl->config->transform); + spa_log_debug(impl->log, "Setting videotransform for buffer %d to %u (from %s)", + i, b->videotransform->transform, transformToString(impl->config->transform)); + + } + d = buffersi->datas; for(j = 0; j < buffersi->n_datas; ++j) { dj.type = port->memtype;
View file
pipewire-0.3.61.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.62.tar.gz/spa/plugins/support/loop.c
Changed
@@ -89,7 +89,7 @@ uint8_t *buffer_data; uint8_t buffer_memDATAS_SIZE + MAX_ALIGN; - unsigned int flushing:1; + uint32_t flush_count; unsigned int polling:1; }; @@ -166,23 +166,39 @@ static void flush_items(struct impl *impl) { - uint32_t index; + uint32_t index, flush_count; + int32_t avail; int res; - impl->flushing = true; - while (spa_ringbuffer_get_read_index(&impl->buffer, &index) > 0) { + flush_count = ++impl->flush_count; + avail = spa_ringbuffer_get_read_index(&impl->buffer, &index); + while (avail > 0) { struct invoke_item *item; bool block; + spa_invoke_func_t func; item = SPA_PTROFF(impl->buffer_data, index & (DATAS_SIZE - 1), struct invoke_item); block = item->block; + func = item->func; spa_log_trace_fp(impl->log, "%p: flush item %p", impl, item); - item->res = item->func ? item->func(&impl->loop, - true, item->seq, item->data, item->size, - item->user_data) : 0; - - spa_ringbuffer_read_update(&impl->buffer, index + item->item_size); + /* first we remove the function from the item so that recursive + * calls don't call the callback again. We can't update the + * read index before we call the function because then the item + * might get overwritten. */ + item->func = NULL; + if (func) + item->res = func(&impl->loop, true, item->seq, item->data, + item->size, item->user_data); + + /* if this function did a recursive invoke, it now flushed the + * ringbuffer and we can exit */ + if (flush_count != impl->flush_count) + break; + + index += item->item_size; + avail -= item->item_size; + spa_ringbuffer_read_update(&impl->buffer, index); if (block) { if ((res = spa_system_eventfd_write(impl->system, impl->ack_fd, 1)) < 0) @@ -190,20 +206,21 @@ impl, impl->ack_fd, spa_strerror(res)); } } - impl->flushing = false; } static int loop_invoke_inthread(struct impl *impl, - spa_invoke_func_t func, - uint32_t seq, - const void *data, - size_t size, - bool block, - void *user_data) + spa_invoke_func_t func, + uint32_t seq, + const void *data, + size_t size, + bool block, + void *user_data) { - if (!impl->flushing) - flush_items(impl); + /* we should probably have a second ringbuffer for the in-thread pending + * callbacks. A recursive callback when flushing will insert itself + * before this one. */ + flush_items(impl); return func ? func(&impl->loop, true, seq, data, size, user_data) : 0; } @@ -222,6 +239,9 @@ int32_t filled; uint32_t avail, idx, offset, l0; + /* the ringbuffer can only be written to from one thread, if we are + * in the same thread as the loop, don't write into the ringbuffer + * but try to emit the calback right away after flushing what we have */ if (impl->thread == 0 || pthread_equal(impl->thread, pthread_self())) return loop_invoke_inthread(impl, func, seq, data, size, block, user_data); @@ -247,6 +267,7 @@ item->size = size; item->block = block; item->user_data = user_data; + item->res = 0; item->item_size = SPA_ROUND_UP_N(sizeof(struct invoke_item) + size, ITEM_ALIGN); spa_log_trace_fp(impl->log, "%p: add item %p filled:%d", impl, item, filled); @@ -585,10 +606,12 @@ uint64_t count = 0; int res; - if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0) - spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s", - source, source->fd, spa_strerror(res)); - + if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0) { + if (res != -EAGAIN) + spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s", + source, source->fd, spa_strerror(res)); + return; + } s->func.event(source->data, count); } @@ -651,10 +674,12 @@ int res; if (SPA_UNLIKELY((res = spa_system_timerfd_read(s->impl->system, - source->fd, &expirations)) < 0)) - spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s", - source, source->fd, spa_strerror(res)); - + source->fd, &expirations)) < 0)) { + if (res != -EAGAIN) + spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s", + source, source->fd, spa_strerror(res)); + return; + } s->func.timer(source->data, expirations); } @@ -731,10 +756,12 @@ struct source_impl *s = SPA_CONTAINER_OF(source, struct source_impl, source); int res, signal_number = 0; - if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0) - spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s", - source, source->fd, spa_strerror(res)); - + if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0) { + if (res != -EAGAIN) + spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s", + source, source->fd, spa_strerror(res)); + return; + } s->func.signal(source->data, signal_number); }
View file
pipewire-0.3.61.tar.gz/src/daemon/pipewire-pulse.conf.in -> pipewire-0.3.62.tar.gz/src/daemon/pipewire-pulse.conf.in
Changed
@@ -90,7 +90,7 @@ #pulse.default.frag = 96000/48000 # 2 seconds #pulse.default.tlength = 96000/48000 # 2 seconds #pulse.min.quantum = 256/48000 # 5ms - #pulse.idle.timeout = 5 # pause after 5s of underruns + #pulse.idle.timeout = 0 # don't pause after underruns #pulse.default.format = F32 #pulse.default.position = FL FR # These overrides are only applied when running in a vm. @@ -137,12 +137,12 @@ } { # speech dispatcher asks for too small latency and then underruns. - matches = { application.name = "~speech-dispatcher*" } + matches = { application.name = "~speech-dispatcher.*" } actions = { update-props = { - pulse.min.req = 1024/48000 # 21ms - pulse.min.quantum = 1024/48000 # 21ms - #pulse.idle.timeout = 0 + pulse.min.req = 512/48000 # 10.6ms + pulse.min.quantum = 512/48000 # 10.6ms + pulse.idle.timeout = 5 # pause after 5 seconds of underrun } } }
View file
pipewire-0.3.61.tar.gz/src/examples/video-dsp-play.c -> pipewire-0.3.62.tar.gz/src/examples/video-dsp-play.c
Changed
@@ -139,6 +139,8 @@ /* copy video image in texture */ sstride = buf->datas0.chunk->stride; + if (sstride == 0) + sstride = buf->datas0.chunk->size / data->position->video.size.height; src = sdata; dst = ddata;
View file
pipewire-0.3.61.tar.gz/src/examples/video-play-fixate.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-fixate.c
Changed
@@ -257,6 +257,8 @@ /* copy video image in texture */ sstride = buf->datas0.chunk->stride; + if (sstride == 0) + sstride = buf->datas0.chunk->size / data->size.height; ostride = SPA_MIN(sstride, dstride); src = sdata;
View file
pipewire-0.3.61.tar.gz/src/examples/video-play-pull.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-pull.c
Changed
@@ -206,6 +206,8 @@ } sstride = buf->datas0.chunk->stride; + if (sstride == 0) + sstride = buf->datas0.chunk->size / data->size.height; ostride = SPA_MIN(sstride, dstride); src = sdata;
View file
pipewire-0.3.61.tar.gz/src/examples/video-play-reneg.c -> pipewire-0.3.62.tar.gz/src/examples/video-play-reneg.c
Changed
@@ -136,6 +136,8 @@ /* copy video image in texture */ sstride = buf->datas0.chunk->stride; + if (sstride == 0) + sstride = buf->datas0.chunk->size / data->size.height; ostride = SPA_MIN(sstride, dstride); src = sdata;
View file
pipewire-0.3.61.tar.gz/src/examples/video-play.c -> pipewire-0.3.62.tar.gz/src/examples/video-play.c
Changed
@@ -204,6 +204,8 @@ } sstride = buf->datas0.chunk->stride; + if (sstride == 0) + sstride = buf->datas0.chunk->size / data->size.height; ostride = SPA_MIN(sstride, dstride); src = sdata;
View file
pipewire-0.3.61.tar.gz/src/gst/gstpipewirepool.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewirepool.c
Changed
@@ -115,6 +115,8 @@ data->crop = spa_buffer_find_meta_data (b->buffer, SPA_META_VideoCrop, sizeof(*data->crop)); if (data->crop) gst_buffer_add_video_crop_meta(buf); + data->videotransform = + spa_buffer_find_meta_data (b->buffer, SPA_META_VideoTransform, sizeof(*data->videotransform)); gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf), pool_data_quark,
View file
pipewire-0.3.61.tar.gz/src/gst/gstpipewirepool.h -> pipewire-0.3.62.tar.gz/src/gst/gstpipewirepool.h
Changed
@@ -57,6 +57,7 @@ GstBuffer *buf; gboolean queued; struct spa_meta_region *crop; + struct spa_meta_videotransform *videotransform; }; struct _GstPipeWirePool {
View file
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresink.c
Changed
@@ -491,6 +491,7 @@ GstMemory *mem = gst_buffer_peek_memory (buffer, i); d->chunk->offset = mem->offset; d->chunk->size = mem->size; + d->chunk->stride = 0; } if ((res = pw_stream_queue_buffer (pwsink->stream, data->b)) < 0) {
View file
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresrc.c
Changed
@@ -514,6 +514,25 @@ } } +static const char * const transform_map = { + SPA_META_TRANSFORMATION_None = "rotate-0", + SPA_META_TRANSFORMATION_90 = "rotate-90", + SPA_META_TRANSFORMATION_180 = "rotate-180", + SPA_META_TRANSFORMATION_270 = "rotate-270", + SPA_META_TRANSFORMATION_Flipped = "flip-rotate-0", + SPA_META_TRANSFORMATION_Flipped90 = "flip-rotate-270", + SPA_META_TRANSFORMATION_Flipped180 = "flip-rotate-180", + SPA_META_TRANSFORMATION_Flipped270 = "flip-rotate-90", +}; + +static const char *spa_transform_value_to_gst_image_orientation(uint32_t transform_value) +{ + if (transform_value >= SPA_N_ELEMENTS(transform_map)) + transform_value = SPA_META_TRANSFORMATION_None; + + return transform_maptransform_value; +} + static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc) { struct pw_buffer *b; @@ -521,6 +540,7 @@ GstPipeWirePoolData *data; struct spa_meta_header *h; struct spa_meta_region *crop; + struct spa_meta_videotransform *videotransform; guint i; b = pw_stream_dequeue_buffer (pwsrc->stream); @@ -568,6 +588,27 @@ meta->height = crop->region.size.height; } } + + videotransform = data->videotransform; + if (videotransform) { + if (pwsrc->transform_value != videotransform->transform) { + GstEvent *tag_event; + const char* tag_string; + + tag_string = + spa_transform_value_to_gst_image_orientation(videotransform->transform); + + GST_LOG_OBJECT (pwsrc, "got new videotransform: %u / %s", + videotransform->transform, tag_string); + + tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION, + tag_string, NULL)); + gst_pad_push_event (GST_BASE_SRC_PAD (pwsrc), tag_event); + + pwsrc->transform_value = videotransform->transform; + } + } + for (i = 0; i < b->buffer->n_datas; i++) { struct spa_data *d = &b->buffer->datasi; GstMemory *pmem = gst_buffer_peek_memory (data->buf, i); @@ -913,7 +954,7 @@ pwsrc->negotiated = pwsrc->caps != NULL; if (pwsrc->negotiated) { - const struct spa_pod *params3; + const struct spa_pod *params4; struct spa_pod_builder b = { NULL }; uint8_t buffer512; uint32_t buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers); @@ -939,9 +980,13 @@ SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region))); + params3 = spa_pod_builder_add_object (&b, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform), + SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_videotransform))); GST_DEBUG_OBJECT (pwsrc, "doing finish format"); - pw_stream_update_params (pwsrc->stream, params, 3); + pw_stream_update_params (pwsrc->stream, params, SPA_N_ELEMENTS(params)); } else { GST_WARNING_OBJECT (pwsrc, "finish format with error"); pw_stream_set_error (pwsrc->stream, -EINVAL, "unhandled format");
View file
pipewire-0.3.61.tar.gz/src/gst/gstpipewiresrc.h -> pipewire-0.3.62.tar.gz/src/gst/gstpipewiresrc.h
Changed
@@ -95,6 +95,8 @@ GstPipeWirePool *pool; GstClock *clock; GstClockTime last_time; + + enum spa_meta_videotransform_value transform_value; }; struct _GstPipeWireSrcClass {
View file
pipewire-0.3.61.tar.gz/src/modules/meson.build -> pipewire-0.3.62.tar.gz/src/modules/meson.build
Changed
@@ -289,6 +289,14 @@ cdata.set('HAVE_AVAHI', true) endif +if gio_dep.found() + pipewire_module_protocol_pulse_sources += + 'module-protocol-pulse/modules/module-gsettings.c', + + pipewire_module_protocol_pulse_deps += gio_dep + cdata.set('HAVE_GIO', true) +endif + if flatpak_support pipewire_module_protocol_pulse_deps += glib2_dep endif
View file
pipewire-0.3.61.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.62.tar.gz/src/modules/module-client-node/remote-node.c
Changed
@@ -1186,7 +1186,7 @@ struct timespec ts; struct pw_impl_port *p; - pw_log_trace("node %p: ready driver:%d exported:%d status:%d", node, + pw_log_trace_fp("node %p: ready driver:%d exported:%d status:%d", node, node->driver, node->exported, status); if (status & SPA_STATUS_HAVE_DATA) {
View file
pipewire-0.3.61.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.62.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -936,8 +936,13 @@ { struct impl *impl = data; - pw_log_error("error id:%u seq:%d res:%d (%s): %s", - id, seq, res, spa_strerror(res), message); + if (res == -ENOENT) { + pw_log_info("id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } else { + pw_log_warn("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } if (id == PW_ID_CORE && res == -EPIPE) pw_impl_module_schedule_destroy(impl->module);
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -505,6 +505,7 @@ unsigned int n_deps; unsigned int visited:1; + unsigned int disabled:1; }; struct link { @@ -521,6 +522,7 @@ const struct fc_descriptor *desc; void **hndl; uint32_t port; + unsigned next:1; }; struct graph_hndl { @@ -599,7 +601,7 @@ struct impl *impl = d; struct pw_buffer *in, *out; struct graph *graph = &impl->graph; - uint32_t i, insize = 0, outsize = 0, n_hndl = graph->n_hndl; + uint32_t i, j, insize = 0, outsize = 0, n_hndl = graph->n_hndl; int32_t stride = 0; struct graph_port *port; struct spa_data *bd; @@ -613,7 +615,7 @@ if (in == NULL || out == NULL) goto done; - for (i = 0; i < in->buffer->n_datas; i++) { + for (i = 0, j = 0; i < in->buffer->n_datas; i++) { uint32_t offs, size; bd = &in->buffer->datasi; @@ -621,12 +623,15 @@ offs = SPA_MIN(bd->chunk->offset, bd->maxsize); size = SPA_MIN(bd->chunk->size, bd->maxsize - offs); - port = i < graph->n_input ? &graph->inputi : NULL; - - if (port && port->desc) - port->desc->connect_port(*port->hndl, port->port, - SPA_PTROFF(bd->data, offs, void)); + while (j < graph->n_input) { + port = &graph->inputj++; + if (port->desc) + port->desc->connect_port(*port->hndl, port->port, + SPA_PTROFF(bd->data, offs, void)); + if (!port->next) + break; + } insize = i == 0 ? size : SPA_MIN(insize, size); stride = SPA_MAX(stride, bd->chunk->stride); } @@ -1849,7 +1854,7 @@ n_nodes++; } graph->n_input = 0; - graph->input = calloc(n_input * n_hndl, sizeof(struct graph_port)); + graph->input = calloc(n_input * 16 * n_hndl, sizeof(struct graph_port)); graph->n_output = 0; graph->output = calloc(n_output * n_hndl, sizeof(struct graph_port)); @@ -1869,8 +1874,8 @@ } else { struct spa_json it = *inputs; while (spa_json_get_string(&it, v, sizeof(v)) > 0) { - gp = &graph->inputgraph->n_input; if (spa_streq(v, "null")) { + gp = &graph->inputgraph->n_input++; gp->desc = NULL; pw_log_info("ignore input port %d", graph->n_input); } else if ((port = find_port(first, v, FC_PORT_INPUT)) == NULL) { @@ -1893,14 +1898,41 @@ res = -EBUSY; goto error; } - pw_log_info("input port %s%d:%s", + + if (d->flags & FC_DESCRIPTOR_COPY) { + for (j = 0; j < desc->n_output; j++) { + struct port *p = &port->node->output_portj; + struct link *link; + + gp = NULL; + spa_list_for_each(link, &p->link_list, output_link) { + struct port *peer = link->input; + + pw_log_info("copy input port %s%d:%s", + port->node->name, i, + d->portsport->p.name); + peer->external = graph->n_input; + gp = &graph->inputgraph->n_input++; + gp->desc = peer->node->desc->desc; + gp->hndl = &peer->node->hndli; + gp->port = peer->p; + gp->next = true; + } + if (gp != NULL) + gp->next = false; + } + port->node->disabled = true; + } else { + pw_log_info("input port %s%d:%s", port->node->name, i, d->portsport->p.name); - port->external = graph->n_input; - gp->desc = d; - gp->hndl = &port->node->hndli; - gp->port = port->p; + port->external = graph->n_input; + gp = &graph->inputgraph->n_input++; + gp->desc = d; + gp->hndl = &port->node->hndli; + gp->port = port->p; + gp->next = false; + } } - graph->n_input++; } } if (outputs == NULL) { @@ -1965,11 +1997,12 @@ desc = node->desc; d = desc->desc; - for (i = 0; i < n_hndl; i++) { - gh = &graph->hndlgraph->n_hndl++; - gh->hndl = &node->hndli; - gh->desc = d; - + if (!node->disabled) { + for (i = 0; i < n_hndl; i++) { + gh = &graph->hndlgraph->n_hndl++; + gh->hndl = &node->hndli; + gh->desc = d; + } } for (i = 0; i < desc->n_output; i++) { spa_list_for_each(link, &node->output_porti.link_list, output_link) @@ -2088,8 +2121,13 @@ { struct impl *impl = data; - pw_log_error("error id:%u seq:%d res:%d (%s): %s", - id, seq, res, spa_strerror(res), message); + if (res == -ENOENT) { + pw_log_info("message id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } else { + pw_log_warn("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } if (id == PW_ID_CORE && res == -EPIPE) pw_impl_module_schedule_destroy(impl->module);
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -101,6 +101,7 @@ static const struct fc_descriptor copy_desc = { .name = "copy", + .flags = FC_DESCRIPTOR_COPY, .n_ports = 2, .ports = copy_ports, @@ -260,14 +261,11 @@ static void bq_run(struct builtin *impl, unsigned long samples, int type) { struct biquad *bq = &impl->bq; - unsigned long i; float *out = impl->port0; float *in = impl->port1; float freq = impl->port20; float Q = impl->port30; float gain = impl->port40; - float x1, x2, y1, y2; - float b0, b1, b2, a1, a2; if (impl->freq != freq || impl->Q != Q || impl->gain != gain) { impl->freq = freq; @@ -275,30 +273,7 @@ impl->gain = gain; biquad_set(bq, type, freq * 2 / impl->rate, Q, gain); } - x1 = bq->x1; - x2 = bq->x2; - y1 = bq->y1; - y2 = bq->y2; - b0 = bq->b0; - b1 = bq->b1; - b2 = bq->b2; - a1 = bq->a1; - a2 = bq->a2; - for (i = 0; i < samples; i++) { - float x = ini; - float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; - outi = y; - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - } -#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x)) - bq->x1 = F(x1); - bq->x2 = F(x2); - bq->y1 = F(y1); - bq->y2 = F(y2); -#undef F + dsp_ops_biquad_run(&dsp_ops, bq, out, in, samples); } /** bq_lowpass */
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
@@ -420,8 +420,6 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int length) { - int i; - convolver1_run(conv->headConvolver, input, output, length); if (conv->tailInput) { @@ -431,24 +429,14 @@ int remaining = length - processed; int processing = SPA_MIN(remaining, conv->headBlockSize - (conv->tailInputFill % conv->headBlockSize)); - const int sumBegin = processed; - const int sumEnd = processed + processing; - - if (conv->tailPrecalculated0) { - int precalculatedPos = conv->precalculatedPos; - for (i = sumBegin; i < sumEnd; i++) { - outputi += conv->tailPrecalculated0precalculatedPos; - precalculatedPos++; - } - } - - if (conv->tailPrecalculated) { - int precalculatedPos = conv->precalculatedPos; - for (i = sumBegin; i < sumEnd; i++) { - outputi += conv->tailPrecalculatedprecalculatedPos; - precalculatedPos++; - } - } + if (conv->tailPrecalculated0) + fft_sum(&outputprocessed, &outputprocessed, + &conv->tailPrecalculated0conv->precalculatedPos, + processing); + if (conv->tailPrecalculated) + fft_sum(&outputprocessed, &outputprocessed, + &conv->tailPrecalculatedconv->precalculatedPos, + processing); conv->precalculatedPos += processing; fft_copy(conv->tailInput + conv->tailInputFill, input + processed, processing); @@ -467,7 +455,8 @@ if (conv->tailPrecalculated && conv->tailInputFill == conv->tailBlockSize) { SPA_SWAP(conv->tailPrecalculated, conv->tailOutput); - convolver1_run(conv->tailConvolver, conv->tailInput, conv->tailOutput, conv->tailBlockSize); + convolver1_run(conv->tailConvolver, conv->tailInput, + conv->tailOutput, conv->tailBlockSize); } if (conv->tailInputFill == conv->tailBlockSize) { conv->tailInputFill = 0;
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
@@ -25,6 +25,7 @@ #include <string.h> #include <stdio.h> #include <math.h> +#include <float.h> #include <spa/utils/defs.h> @@ -98,3 +99,37 @@ } } } + +void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples) +{ + float x1, x2, y1, y2; + float b0, b1, b2, a1, a2; + uint32_t i; + + x1 = bq->x1; + x2 = bq->x2; + y1 = bq->y1; + y2 = bq->y2; + b0 = bq->b0; + b1 = bq->b1; + b2 = bq->b2; + a1 = bq->a1; + a2 = bq->a2; + for (i = 0; i < n_samples; i++) { + float x = ini; + float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; + outi = y; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } +#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x)) + bq->x1 = F(x1); + bq->x2 = F(x2); + bq->y1 = F(y1); + bq->y2 = F(y2); +#undef F +} +
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops.c -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops.c
Changed
@@ -42,6 +42,8 @@ void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, float gain, uint32_t n_src, uint32_t n_samples); + void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples); }; static struct dsp_info dsp_table = @@ -50,11 +52,13 @@ { SPA_CPU_FLAG_SSE, .copy = dsp_copy_c, .mix_gain = dsp_mix_gain_sse, + .biquad_run = dsp_biquad_run_c, }, #endif { 0, .copy = dsp_copy_c, .mix_gain = dsp_mix_gain_c, + .biquad_run = dsp_biquad_run_c, }, }; @@ -86,6 +90,7 @@ ops->cpu_flags = info->cpu_flags; ops->copy = info->copy; ops->mix_gain = info->mix_gain; + ops->biquad_run = info->biquad_run; ops->free = impl_dsp_ops_free; return 0;
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/dsp-ops.h -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/dsp-ops.h
Changed
@@ -24,6 +24,8 @@ #include <spa/utils/defs.h> +#include "biquad.h" + struct dsp_ops { uint32_t cpu_flags; @@ -35,6 +37,8 @@ void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, float gain, uint32_t n_src, uint32_t n_samples); + void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples); void (*free) (struct dsp_ops *ops); const void *priv; @@ -44,19 +48,24 @@ #define dsp_ops_copy(ops,...) (ops)->copy(ops, __VA_ARGS__) #define dsp_ops_mix_gain(ops,...) (ops)->mix_gain(ops, __VA_ARGS__) +#define dsp_ops_biquad_run(ops,...) (ops)->biquad_run(ops, __VA_ARGS__) #define dsp_ops_free(ops) (ops)->free(ops) #define MAKE_COPY_FUNC(arch) \ void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ - const void * SPA_RESTRICT src, uint32_t n_samples) + const void * SPA_RESTRICT src, uint32_t n_samples) #define MAKE_MIX_GAIN_FUNC(arch) \ void dsp_mix_gain_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src, float gain, uint32_t n_src, uint32_t n_samples) +#define MAKE_BIQUAD_RUN_FUNC(arch) \ +void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \ + float *out, const float *in, uint32_t n_samples) MAKE_COPY_FUNC(c); MAKE_MIX_GAIN_FUNC(c); +MAKE_BIQUAD_RUN_FUNC(c); #if defined (HAVE_SSE) MAKE_MIX_GAIN_FUNC(sse); #endif
View file
pipewire-0.3.61.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.62.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
@@ -64,6 +64,7 @@ struct fc_descriptor { const char *name; #define FC_DESCRIPTOR_SUPPORTS_NULL_DATA (1ULL << 0) +#define FC_DESCRIPTOR_COPY (1ULL << 1) uint64_t flags; void (*free) (const struct fc_descriptor *desc);
View file
pipewire-0.3.61.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.62.tar.gz/src/modules/module-loopback.c
Changed
@@ -451,32 +451,31 @@ &impl->playback_listener, &out_stream_events, impl); + /* connect playback first to activate it before capture triggers it */ n_params = 0; spa_pod_builder_init(&b, buffer, sizeof(buffer)); paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, - &impl->capture_info); - - if ((res = pw_stream_connect(impl->capture, - PW_DIRECTION_INPUT, + &impl->playback_info); + if ((res = pw_stream_connect(impl->playback, + PW_DIRECTION_OUTPUT, PW_ID_ANY, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | - PW_STREAM_FLAG_RT_PROCESS, + PW_STREAM_FLAG_RT_PROCESS | + PW_STREAM_FLAG_TRIGGER, params, n_params)) < 0) return res; n_params = 0; spa_pod_builder_init(&b, buffer, sizeof(buffer)); paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, - &impl->playback_info); - - if ((res = pw_stream_connect(impl->playback, - PW_DIRECTION_OUTPUT, + &impl->capture_info); + if ((res = pw_stream_connect(impl->capture, + PW_DIRECTION_INPUT, PW_ID_ANY, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | - PW_STREAM_FLAG_RT_PROCESS | - PW_STREAM_FLAG_TRIGGER, + PW_STREAM_FLAG_RT_PROCESS, params, n_params)) < 0) return res; @@ -487,8 +486,13 @@ { struct impl *impl = data; - pw_log_error("error id:%u seq:%d res:%d (%s): %s", - id, seq, res, spa_strerror(res), message); + if (res == -ENOENT) { + pw_log_info("message id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } else { + pw_log_warn("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } if (id == PW_ID_CORE && res == -EPIPE) pw_impl_module_schedule_destroy(impl->module); @@ -513,11 +517,11 @@ static void impl_destroy(struct impl *impl) { - /* disconnect both streams before destroying any of them */ + /* deactivate both streams before destroying any of them */ if (impl->capture) - pw_stream_disconnect(impl->capture); + pw_stream_set_active(impl->capture, false); if (impl->playback) - pw_stream_disconnect(impl->playback); + pw_stream_set_active(impl->playback, false); if (impl->capture) pw_stream_destroy(impl->capture);
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/module.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/module.c
Changed
@@ -36,7 +36,6 @@ #include <pipewire/properties.h> #include <pipewire/work-queue.h> -#include "client.h" #include "defs.h" #include "format.h" #include "internal.h" @@ -84,14 +83,14 @@ spa_hook_list_append(&module->listener_list, listener, events, data); } -int module_load(struct client *client, struct module *module) +int module_load(struct module *module) { pw_log_info("load module index:%u name:%s", module->index, module->info->name); if (module->info->load == NULL) return -ENOTSUP; /* subscription event is sent when the module does a * module_emit_loaded() */ - return module->info->load(client, module); + return module->info->load(module); } void module_free(struct module *module) @@ -119,9 +118,6 @@ struct impl *impl = module->impl; int res = 0; - /* Note that client can be NULL (when the module is being unloaded - * internally and not by a client request */ - pw_log_info("unload module index:%u name:%s", module->index, module->info->name); if (module->info->unload) @@ -283,9 +279,8 @@ return spa_streq(module->info->name, name) ? 1 : 0; } -struct module *module_create(struct client *client, const char *name, const char *args) +struct module *module_create(struct impl *impl, const char *name, const char *args) { - struct impl *impl = client->impl; const struct module_info *info; struct module *module;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/module.h -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/module.h
Changed
@@ -29,7 +29,6 @@ #include <spa/param/audio/raw.h> #include <spa/utils/hook.h> -#include "client.h" #include "internal.h" struct module; @@ -41,7 +40,7 @@ unsigned int load_once:1; int (*prepare) (struct module *module); - int (*load) (struct client *client, struct module *module); + int (*load) (struct module *module); int (*unload) (struct module *module); const struct spa_dict *properties; @@ -78,9 +77,9 @@ #define module_emit_loaded(m,r) spa_hook_list_call(&m->listener_list, struct module_events, loaded, 0, r) #define module_emit_destroy(m) spa_hook_list_call(&(m)->listener_list, struct module_events, destroy, 0) -struct module *module_create(struct client *client, const char *name, const char *args); +struct module *module_create(struct impl *impl, const char *name, const char *args); void module_free(struct module *module); -int module_load(struct client *client, struct module *module); +int module_load(struct module *module); int module_unload(struct module *module); void module_schedule_unload(struct module *module);
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-always-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-always-sink.c
Changed
@@ -51,7 +51,7 @@ .destroy = module_destroy }; -static int module_always_sink_load(struct client *client, struct module *module) +static int module_always_sink_load(struct module *module) { struct module_always_sink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c
Changed
@@ -391,7 +391,7 @@ check_initialized(data); } -static int module_combine_sink_load(struct client *client, struct module *module) +static int module_combine_sink_load(struct module *module) { struct module_combine_sink_data *data = module->user_data; struct pw_properties *props; @@ -402,9 +402,7 @@ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); const char *str; - data->core = pw_context_connect(module->impl->context, - pw_properties_copy(client->props), - 0); + data->core = pw_context_connect(module->impl->context, NULL, 0); if (data->core == NULL) return -errno;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c
Changed
@@ -63,7 +63,7 @@ .destroy = module_destroy }; -static int module_echo_cancel_load(struct client *client, struct module *module) +static int module_echo_cancel_load(struct module *module) { struct module_echo_cancel_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-gsettings.c
Added
@@ -0,0 +1,298 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <gio/gio.h> +#include <glib.h> + +#include <spa/debug/mem.h> +#include <pipewire/pipewire.h> +#include <pipewire/thread.h> + +#include "../module.h" + +#define NAME "gsettings" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +#define PA_GSETTINGS_MODULE_GROUP_SCHEMA "org.freedesktop.pulseaudio.module-group" +#define PA_GSETTINGS_MODULE_GROUPS_SCHEMA "org.freedesktop.pulseaudio.module-groups" +#define PA_GSETTINGS_MODULE_GROUPS_PATH "/org/freedesktop/pulseaudio/module-groups/" + +#define MAX_MODULES 10 + +struct module_gsettings_data { + struct module *module; + + GMainContext *context; + GMainLoop *loop; + struct spa_thread *thr; + + GSettings *settings; + gchar **group_names; + + struct spa_list groups; +}; + +struct group { + struct spa_list link; + char *name; + struct module *module; + struct spa_hook module_listener; +}; + +struct info { + bool enabled; + char *name; + char *moduleMAX_MODULES; + char *argsMAX_MODULES; +}; + +static void clean_info(const struct info *info) +{ + int i; + for (i = 0; i < MAX_MODULES; i++) { + g_free(info->modulei); + g_free(info->argsi); + } + g_free(info->name); +} + +static void unload_module(struct module_gsettings_data *d, struct group *g) +{ + spa_list_remove(&g->link); + g_free(g->name); + if (g->module) + module_unload(g->module); + free(g); +} + +static void unload_group(struct module_gsettings_data *d, const char *name) +{ + struct group *g, *t; + spa_list_for_each_safe(g, t, &d->groups, link) { + if (spa_streq(g->name, name)) + unload_module(d, g); + } +} +static void module_destroy(void *data) +{ + struct group *g = data; + if (g->module) { + spa_hook_remove(&g->module_listener); + g->module = NULL; + } +} + +static const struct module_events module_gsettings_events = { + VERSION_MODULE_EVENTS, + .destroy = module_destroy +}; + +static int load_group(struct module_gsettings_data *d, const struct info *info) +{ + struct group *g; + int i, res; + + for (i = 0; i < MAX_MODULES; i++) { + if (info->modulei == NULL || strlen(info->modulei) <= 0) + break; + + g = calloc(1, sizeof(struct group)); + if (g == NULL) + return -errno; + + g->name = strdup(info->name); + g->module = module_create(d->module->impl, info->modulei, info->argsi); + if (g->module == NULL) { + pw_log_info("can't create module:%s args:%s: %m", + info->modulei, info->argsi); + } else { + module_add_listener(g->module, &g->module_listener, + &module_gsettings_events, g); + if ((res = module_load(g->module)) < 0) { + pw_log_warn("can't load module:%s args:%s: %s", + info->modulei, info->argsi, + spa_strerror(res)); + } + } + spa_list_append(&d->groups, &g->link); + } + return 0; +} + +static int +do_handle_info(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct module_gsettings_data *d = user_data; + const struct info *info = data; + + unload_group(d, info->name); + if (info->enabled) + load_group(d, info); + + clean_info(info); + return 0; +} + +static void handle_module_group(struct module_gsettings_data *d, gchar *name) +{ + struct impl *impl = d->module->impl; + GSettings *settings; + gchar p1024; + struct info info; + int i; + + snprintf(p, sizeof(p), PA_GSETTINGS_MODULE_GROUPS_PATH"%s/", name); + + settings = g_settings_new_with_path(PA_GSETTINGS_MODULE_GROUP_SCHEMA, p); + if (settings == NULL) + return; + + spa_zero(info); + info.name = strdup(p); + info.enabled = g_settings_get_boolean(settings, "enabled"); + + for (i = 0; i < MAX_MODULES; i++) { + snprintf(p, sizeof(p), "name%d", i); + info.modulei = g_settings_get_string(settings, p); + + snprintf(p, sizeof(p), "args%i", i); + info.argsi = g_settings_get_string(settings, p); + } + pw_loop_invoke(impl->loop, do_handle_info, 0, + &info, sizeof(info), false, d); + + g_object_unref(G_OBJECT(settings)); +} + +static void module_group_callback(GSettings *settings, gchar *key, gpointer user_data) +{ + struct module_gsettings_data *d = g_object_get_data(G_OBJECT(settings), "module-data"); + handle_module_group(d, user_data); +} + +static void *do_loop(void *user_data) +{ + struct module_gsettings_data *d = user_data;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c
Changed
@@ -59,7 +59,7 @@ .destroy = module_destroy }; -static int module_ladspa_sink_load(struct client *client, struct module *module) +static int module_ladspa_sink_load(struct module *module) { struct module_ladspa_sink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c
Changed
@@ -59,7 +59,7 @@ .destroy = module_destroy }; -static int module_ladspa_source_load(struct client *client, struct module *module) +static int module_ladspa_source_load(struct module *module) { struct module_ladspa_source_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
@@ -63,7 +63,7 @@ .destroy = module_destroy }; -static int module_loopback_load(struct client *client, struct module *module) +static int module_loopback_load(struct module *module) { struct module_loopback_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c
Changed
@@ -38,10 +38,10 @@ struct pw_array servers; }; -static int module_native_protocol_tcp_load(struct client *client, struct module *module) +static int module_native_protocol_tcp_load(struct module *module) { struct module_native_protocol_tcp_data *data = module->user_data; - struct impl *impl = client->impl; + struct impl *impl = module->impl; const char *address; int res;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-null-sink.c
Changed
@@ -104,11 +104,11 @@ .error = module_null_sink_core_error, }; -static int module_null_sink_load(struct client *client, struct module *module) +static int module_null_sink_load(struct module *module) { struct module_null_sink_data *d = module->user_data; - d->core = pw_context_connect(module->impl->context, pw_properties_copy(client->props), 0); + d->core = pw_context_connect(module->impl->context, NULL, 0); if (d->core == NULL) return -errno;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-sink.c
Changed
@@ -64,7 +64,7 @@ .destroy = module_destroy }; -static int module_pipe_sink_load(struct client *client, struct module *module) +static int module_pipe_sink_load(struct module *module) { struct module_pipesink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-pipe-source.c
Changed
@@ -64,7 +64,7 @@ .destroy = module_destroy }; -static int module_pipe_source_load(struct client *client, struct module *module) +static int module_pipe_source_load(struct module *module) { struct module_pipesrc_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-raop-discover.c
Changed
@@ -55,7 +55,7 @@ .destroy = module_destroy }; -static int module_raop_discover_load(struct client *client, struct module *module) +static int module_raop_discover_load(struct module *module) { struct module_raop_discover_data *data = module->user_data;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c
Changed
@@ -59,7 +59,7 @@ .destroy = module_destroy }; -static int module_remap_sink_load(struct client *client, struct module *module) +static int module_remap_sink_load(struct module *module) { struct module_remap_sink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c
Changed
@@ -59,7 +59,7 @@ .destroy = module_destroy }; -static int module_remap_source_load(struct client *client, struct module *module) +static int module_remap_source_load(struct module *module) { struct module_remap_source_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink-input.c
Changed
@@ -58,7 +58,7 @@ .destroy = module_destroy }; -static int module_roc_sink_input_load(struct client *client, struct module *module) +static int module_roc_sink_input_load(struct module *module) { struct module_roc_sink_input_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c
Changed
@@ -58,7 +58,7 @@ .destroy = module_destroy }; -static int module_roc_sink_load(struct client *client, struct module *module) +static int module_roc_sink_load(struct module *module) { struct module_roc_sink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-source.c
Changed
@@ -58,7 +58,7 @@ .destroy = module_destroy }; -static int module_roc_source_load(struct client *client, struct module *module) +static int module_roc_source_load(struct module *module) { struct module_roc_source_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c
Changed
@@ -57,7 +57,7 @@ .destroy = module_destroy }; -static int module_rtp_recv_load(struct client *client, struct module *module) +static int module_rtp_recv_load(struct module *module) { struct module_rtp_recv_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c
Changed
@@ -58,7 +58,7 @@ .destroy = module_destroy }; -static int module_rtp_send_load(struct client *client, struct module *module) +static int module_rtp_send_load(struct module *module) { struct module_rtp_send_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-simple-protocol-tcp.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-simple-protocol-tcp.c
Changed
@@ -58,10 +58,10 @@ .destroy = module_destroy }; -static int module_simple_protocol_tcp_load(struct client *client, struct module *module) +static int module_simple_protocol_tcp_load(struct module *module) { struct module_simple_protocol_tcp_data *data = module->user_data; - struct impl *impl = client->impl; + struct impl *impl = module->impl; char *args; size_t size; uint32_t i;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-switch-on-connect.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-switch-on-connect.c
Changed
@@ -175,13 +175,13 @@ .done = on_core_done, }; -static int module_switch_on_connect_load(struct client *client, struct module *module) +static int module_switch_on_connect_load(struct module *module) { - struct impl *impl = client->impl; + struct impl *impl = module->impl; struct module_switch_on_connect_data *d = module->user_data; int res; - d->core = pw_context_connect(impl->context, pw_properties_copy(client->props), 0); + d->core = pw_context_connect(impl->context, NULL, 0); if (d->core == NULL) { res = -errno; goto error;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c
Changed
@@ -62,7 +62,7 @@ .destroy = module_destroy }; -static int module_tunnel_sink_load(struct client *client, struct module *module) +static int module_tunnel_sink_load(struct module *module) { struct module_tunnel_sink_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c
Changed
@@ -62,7 +62,7 @@ .destroy = module_destroy }; -static int module_tunnel_source_load(struct client *client, struct module *module) +static int module_tunnel_source_load(struct module *module) { struct module_tunnel_source_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-x11-bell.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-x11-bell.c
Changed
@@ -51,7 +51,7 @@ .destroy = module_destroy }; -static int module_x11_bell_load(struct client *client, struct module *module) +static int module_x11_bell_load(struct module *module) { struct module_x11_bell_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c
Changed
@@ -57,7 +57,7 @@ .destroy = module_destroy }; -static int module_zeroconf_discover_load(struct client *client, struct module *module) +static int module_zeroconf_discover_load(struct module *module) { struct module_zeroconf_discover_data *data = module->user_data; FILE *f;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
@@ -73,6 +73,7 @@ AvahiEntryGroup *entry_group; AvahiStringList *txt; + struct server *server; const char *service_type; enum service_subtype subtype; @@ -154,6 +155,7 @@ spa_list_remove(&s->link); spa_list_append(&s->userdata->pending, &s->link); s->published = false; + s->server = NULL; } static void unpublish_all_services(struct module_zeroconf_publish_data *d) @@ -397,7 +399,7 @@ return txt; } -static int find_port(struct service *s, int *proto, uint16_t *port) +static struct server *find_server(struct service *s, int *proto, uint16_t *port) { struct module_zeroconf_publish_data *d = s->userdata; struct impl *impl = d->module->impl; @@ -407,14 +409,15 @@ if (server->addr.ss_family == AF_INET) { *proto = AVAHI_PROTO_INET; *port = ntohs(((struct sockaddr_in*) &server->addr)->sin_port); - return 0; + return server; } else if (server->addr.ss_family == AF_INET6) { *proto = AVAHI_PROTO_INET6; *port = ntohs(((struct sockaddr_in6*) &server->addr)->sin6_port); - return 0; + return server; } } - return -ENODEV; + + return NULL; } static void publish_service(struct service *s) @@ -423,10 +426,11 @@ int proto; uint16_t port; - if (find_port(s, &proto, &port) < 0) + struct server *server = find_server(s, &proto, &port); + if (!server) return; - pw_log_debug("found proto:%d port:%d", proto, port); + pw_log_debug("found server:%p proto:%d port:%d", server, proto, port); if (!d->client || avahi_client_get_state(d->client) != AVAHI_CLIENT_S_RUNNING) return; @@ -499,6 +503,7 @@ spa_list_remove(&s->link); spa_list_append(&d->published, &s->link); + s->server = server; pw_log_info("created service: %s", s->service_name); return; @@ -626,7 +631,13 @@ { struct module_zeroconf_publish_data *d = data; pw_log_info("a server stopped, try republish"); - unpublish_all_services(d); + + struct service *s, *tmp; + spa_list_for_each_safe(s, tmp, &d->published, link) { + if (s->server == server) + unpublish_service(s); + } + publish_pending(d); } @@ -636,14 +647,13 @@ .server_stopped = impl_server_stopped, }; -static int module_zeroconf_publish_load(struct client *client, struct module *module) +static int module_zeroconf_publish_load(struct module *module) { struct module_zeroconf_publish_data *data = module->user_data; struct pw_loop *loop; int error; - data->core = pw_context_connect(module->impl->context, - pw_properties_copy(client->props), 0); + data->core = pw_context_connect(module->impl->context, NULL, 0); if (data->core == NULL) { pw_log_error("failed to connect to pipewire: %m"); return -errno;
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -85,7 +85,7 @@ #define DEFAULT_MIN_QUANTUM "256/48000" #define DEFAULT_FORMAT "F32" #define DEFAULT_POSITION " FL FR " -#define DEFAULT_IDLE_TIMEOUT "5" +#define DEFAULT_IDLE_TIMEOUT "0" #define MAX_FORMATS 32 /* The max amount of data we send in one block when capturing. In PulseAudio this @@ -5131,6 +5131,7 @@ .sync = on_load_module_manager_sync, }; + struct impl *impl = client->impl; const char *name, *argument; struct module *module; struct pending_module *pm; @@ -5145,7 +5146,7 @@ pw_log_info("%s %s name:%s argument:%s", client->name, commandscommand.name, name, argument); - module = module_create(client, name, argument); + module = module_create(impl, name, argument); if (module == NULL) return -errno; @@ -5159,7 +5160,7 @@ pw_log_debug("pending module %p: start tag:%d", pm, tag); - r = module_load(client, module); + r = module_load(module); module_add_listener(module, &pm->module_listener, &module_events, pm); client_add_listener(client, &pm->client_listener, &client_events, pm);
View file
pipewire-0.3.61.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.62.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
@@ -823,13 +823,14 @@ if (len < 2) return -ENOSPC; - snprintf(ip, sizeof(ip), ":::%d", res); - spa_assert_se(parse_ipv6_address(ip, (struct sockaddr_in6 *) &addr) == 0); - addrs0 = addr; - snprintf(ip, sizeof(ip), "0.0.0.0:%d", res); spa_assert_se(parse_ipv4_address(ip, (struct sockaddr_in *) &addr) == 0); + addrs0 = addr; + + snprintf(ip, sizeof(ip), ":::%d", res); + spa_assert_se(parse_ipv6_address(ip, (struct sockaddr_in6 *) &addr) == 0); addrs1 = addr; + return 2; }
View file
pipewire-0.3.61.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.62.tar.gz/src/modules/module-pulse-tunnel.c
Changed
@@ -189,6 +189,7 @@ uint32_t target_latency; uint32_t current_latency; uint32_t target_buffer; + struct spa_io_rate_match *rate_match; struct spa_dll dll; float max_error; unsigned resync:1; @@ -250,6 +251,28 @@ } } +static void update_rate(struct impl *impl, bool playback) +{ + float error, corr; + + if (impl->rate_match == NULL) + return; + + if (playback) + error = (float)impl->target_latency - (float)impl->current_latency; + else + error = (float)impl->current_latency - (float)impl->target_latency; + error = SPA_CLAMP(error, -impl->max_error, impl->max_error); + + corr = spa_dll_update(&impl->dll, error); + pw_log_debug("error:%f corr:%f current:%u target:%u", + error, corr, + impl->current_latency, impl->target_latency); + + SPA_FLAG_SET(impl->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE); + impl->rate_match->rate = corr; +} + static void playback_stream_process(void *d) { struct impl *impl = d; @@ -279,17 +302,7 @@ size, RINGBUFFER_SIZE); impl->resync = true; } else { - float error, corr; - - error = (float)impl->target_latency - (float)impl->current_latency; - error = SPA_CLAMP(error, -impl->max_error, impl->max_error); - - corr = spa_dll_update(&impl->dll, error); - pw_log_debug("filled:%u target:%u error:%f corr:%f %u %u", filled, - impl->target_buffer, error, corr, - impl->current_latency, impl->target_latency); - pw_stream_set_control(impl->stream, - SPA_PROP_rate, 1, &corr, NULL); + update_rate(impl, true); } spa_ringbuffer_write_data(&impl->ring, impl->buffer, RINGBUFFER_SIZE, @@ -326,24 +339,12 @@ if (avail < (int32_t)size) { memset(bd->data, 0, size); } else { - float error, corr; - if (avail > (int32_t)RINGBUFFER_SIZE) { avail = impl->target_buffer; index += avail - impl->target_buffer; } else { - error = (float)(impl->current_latency) - (float)impl->target_latency; - error = SPA_CLAMP(error, -impl->max_error, impl->max_error); - - corr = spa_dll_update(&impl->dll, error); - - pw_log_debug("avail:%u target:%u error:%f corr:%f %u %u", avail, - impl->target_buffer, error, corr, - impl->current_latency, impl->target_latency); - pw_stream_set_control(impl->stream, - SPA_PROP_rate, 1, &corr, NULL); + update_rate(impl, false); } - spa_ringbuffer_read_data(&impl->ring, impl->buffer, RINGBUFFER_SIZE, index & RINGBUFFER_MASK, @@ -359,10 +360,21 @@ pw_stream_queue_buffer(impl->stream, buf); } +static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size) +{ + struct impl *impl = data; + switch (id) { + case SPA_IO_RateMatch: + impl->rate_match = area; + break; + } +} + static const struct pw_stream_events playback_stream_events = { PW_VERSION_STREAM_EVENTS, .destroy = stream_destroy, .state_changed = stream_state_changed, + .io_changed = stream_io_changed, .process = playback_stream_process }; @@ -370,6 +382,7 @@ PW_VERSION_STREAM_EVENTS, .destroy = stream_destroy, .state_changed = stream_state_changed, + .io_changed = stream_io_changed, .process = capture_stream_process };
View file
pipewire-0.3.61.tar.gz/src/modules/module-rtp-sink.c -> pipewire-0.3.62.tar.gz/src/modules/module-rtp-sink.c
Changed
@@ -306,8 +306,17 @@ &iov1, tosend); n = sendmsg(impl->rtp_fd, &msg, MSG_NOSIGNAL); - if (n < 0) - pw_log_warn("sendmsg() failed: %m"); + if (n < 0) { + switch (errno) { + case ECONNREFUSED: + case ECONNRESET: + pw_log_debug("remote end not listening"); + break; + default: + pw_log_warn("sendmsg() failed: %m"); + break; + } + } impl->seq++; impl->timestamp += tosend / impl->frame_size;
View file
pipewire-0.3.61.tar.gz/src/modules/module-rtp-source.c -> pipewire-0.3.62.tar.gz/src/modules/module-rtp-source.c
Changed
@@ -214,6 +214,7 @@ struct spa_ringbuffer ring; uint8_t bufferBUFFER_SIZE; + struct spa_io_rate_match *rate_match; struct spa_dll dll; uint32_t target_buffer; float max_error; @@ -269,8 +270,10 @@ pw_log_debug("avail:%u target:%u error:%f corr:%f", avail, sess->target_buffer, error, corr); - pw_stream_set_control(sess->stream, - SPA_PROP_rate, 1, &corr, NULL); + if (sess->rate_match) { + SPA_FLAG_SET(sess->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE); + sess->rate_match->rate = corr; + } } spa_ringbuffer_read_data(&sess->ring, sess->buffer, @@ -308,10 +311,21 @@ } } +static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size) +{ + struct session *sess = data; + switch (id) { + case SPA_IO_RateMatch: + sess->rate_match = area; + break; + } +} + static const struct pw_stream_events out_stream_events = { PW_VERSION_STREAM_EVENTS, .destroy = stream_destroy, .state_changed = on_stream_state_changed, + .io_changed = stream_io_changed, .process = stream_process };
View file
pipewire-0.3.61.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.62.tar.gz/src/pipewire/impl-link.c
Changed
@@ -622,8 +622,8 @@ pw_log_debug("%p: activate activated:%d state:%s", this, impl->activated, pw_link_state_as_string(this->info.state)); - if (impl->activated || !this->prepared || !impl->inode->active || - !impl->inode->added || !impl->onode->active) + if (impl->activated || !this->prepared || + !impl->inode->active || !impl->onode->active) return 0; if (!impl->io_set) { @@ -812,7 +812,7 @@ spa_list_remove(&this->rt.out_mix.rt_link); spa_list_remove(&this->rt.in_mix.rt_link); - if (this->input->node != this->output->node) { + if (impl->inode != impl->onode) { struct pw_node_activation_state *state; spa_list_remove(&this->rt.target.link);
View file
pipewire-0.3.61.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.62.tar.gz/src/pipewire/impl-node.c
Changed
@@ -158,12 +158,51 @@ this->rt.driver_target.node = NULL; } +static int +do_node_add(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_impl_node *this = user_data; + struct pw_impl_node *driver = this->driver_node; + + this->added = true; + if (this->source.loop == NULL) { + struct spa_system *data_system = this->context->data_system; + uint64_t dummy; + int res; + + /* clear the eventfd in case it was written to while the node was stopped */ + res = spa_system_eventfd_read(data_system, this->source.fd, &dummy); + if (SPA_UNLIKELY(res != -EAGAIN && res != 0)) + pw_log_warn("%p: read failed %m", this); + + spa_loop_add_source(loop, &this->source); + add_node(this, driver); + } + return 0; +} + +static int +do_node_remove(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_impl_node *this = user_data; + if (this->source.loop != NULL) { + spa_loop_remove_source(loop, &this->source); + remove_node(this); + } + this->added = false; + return 0; +} + static void node_deactivate(struct pw_impl_node *this) { struct pw_impl_port *port; struct pw_impl_link *link; pw_log_debug("%p: deactivate", this); + + /* make sure the node doesn't get woken up while not active */ + pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this); + spa_list_for_each(port, &this->input_ports, link) { spa_list_for_each(link, &port->links, input_link) pw_impl_link_deactivate(link); @@ -200,7 +239,7 @@ return res; } -static void node_activate_outputs(struct pw_impl_node *this) +static void node_activate(struct pw_impl_node *this) { struct pw_impl_port *port; @@ -210,13 +249,6 @@ spa_list_for_each(link, &port->links, output_link) pw_impl_link_activate(link); } -} - -static void node_activate_inputs(struct pw_impl_node *this) -{ - struct pw_impl_port *port; - - pw_log_debug("%p: activate", this); spa_list_for_each(port, &this->input_ports, link) { struct pw_impl_link *link; spa_list_for_each(link, &port->links, input_link) @@ -229,9 +261,7 @@ struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); int res = 0; - /* First activate the outputs so that when the node starts pushing, - * we can process the outputs */ - node_activate_outputs(this); + node_activate(this); if (impl->pending_state >= PW_NODE_STATE_RUNNING) return 0; @@ -243,6 +273,10 @@ impl->pending_play = true; res = spa_node_send_command(this->node, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start)); + } else { + /* driver nodes will wait until all other nodes are started before + * they are started */ + res = EBUSY; } if (res < 0) @@ -325,34 +359,6 @@ } } -static int -do_node_add(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) -{ - struct pw_impl_node *this = user_data; - struct pw_impl_node *driver = this->driver_node; - - if (this->source.loop == NULL) { - spa_loop_add_source(loop, &this->source); - add_node(this, driver); - } - this->added = true; - return 0; -} - -static int -do_node_remove(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) -{ - struct pw_impl_node *this = user_data; - if (this->source.loop != NULL) { - spa_loop_remove_source(loop, &this->source); - remove_node(this); - } - this->added = false; - return 0; -} - static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error) { struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); @@ -375,10 +381,6 @@ pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node); } } - if (res >= 0) { - /* now activate the inputs */ - node_activate_inputs(node); - } break; case PW_NODE_STATE_IDLE: case PW_NODE_STATE_SUSPENDED: @@ -807,17 +809,9 @@ struct impl *impl = user_data; struct pw_impl_node *driver = *(struct pw_impl_node **)data; struct pw_impl_node *node = &impl->this; - int res; pw_log_trace("%p: driver:%p->%p", node, node->driver_node, driver); - if ((res = spa_node_set_io(node->node, - SPA_IO_Position, - &driver->rt.activation->position, - sizeof(struct spa_io_position))) < 0) { - pw_log_debug("%p: set position: %s", node, spa_strerror(res)); - } - pw_log_trace("%p: set position %p", node, &driver->rt.activation->position); node->rt.position = &driver->rt.activation->position; @@ -843,6 +837,8 @@ { struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); struct pw_impl_node *old = node->driver_node; + int res; + bool was_driving; if (driver == NULL) driver = node; @@ -865,8 +861,16 @@ old->name, old->info.id, driver->name, driver->info.id); } + was_driving = node->driving; node->driving = node->driver && driver == node; + /* When a node was driver (and is waiting for all nodes to complete + * the Start command) cancel the pending state and let the new driver + * calculate a new state so that the Start command is sent to the + * node */ + if (was_driving && !node->driving) + impl->pending_state = node->info.state; + pw_log_debug("%p: driver %p driving:%u", node, driver, node->driving); pw_log_info("(%s-%u) -> change driver (%s-%d -> %s-%d)", @@ -876,6 +880,13 @@ node->driver_node = driver; node->moved = true; + if ((res = spa_node_set_io(node->node, + SPA_IO_Position, + &driver->rt.activation->position, + sizeof(struct spa_io_position))) < 0) { + pw_log_debug("%p: set position: %s", node, spa_strerror(res)); + } + pw_loop_invoke(node->data_loop, do_move_nodes, SPA_ID_INVALID, &driver, sizeof(struct pw_impl_node *),
View file
pipewire-0.3.61.tar.gz/src/pipewire/stream.c -> pipewire-0.3.62.tar.gz/src/pipewire/stream.c
Changed
@@ -324,7 +324,8 @@ { uint32_t index; - if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED)) + if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED) || + buffer->id >= stream->n_buffers) return -EINVAL; SPA_FLAG_SET(buffer->flags, BUFFER_FLAG_QUEUED); @@ -921,6 +922,9 @@ if (impl->disconnecting && n_buffers > 0) return -EIO; + if (n_buffers > MAX_BUFFERS) + return -EINVAL; + prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0); clear_buffers(stream); @@ -956,6 +960,7 @@ pw_log_debug("%p: got buffer id:%d datas:%d, mapped size %d", stream, i, buffersi->n_datas, size); } + impl->n_buffers = n_buffers; for (i = 0; i < n_buffers; i++) { struct buffer *b = &impl->buffersi; @@ -972,9 +977,6 @@ pw_stream_emit_add_buffer(stream, &b->this); } - - impl->n_buffers = n_buffers; - return 0; } @@ -1000,6 +1002,7 @@ if (io->status == SPA_STATUS_HAVE_DATA && (b = get_buffer(stream, io->buffer_id)) != NULL) { /* push new buffer */ + pw_log_trace_fp("%p: push %d %p", stream, b->id, io); if (queue_push(impl, &impl->dequeued, b) == 0) { copy_position(impl, impl->dequeued.incount); if (b->busy) @@ -1007,13 +1010,15 @@ call_process(impl); } } - if (io->status != SPA_STATUS_NEED_DATA) { + if (io->status != SPA_STATUS_NEED_DATA || io->buffer_id == SPA_ID_INVALID) { /* pop buffer to recycle */ if ((b = queue_pop(impl, &impl->queued))) { pw_log_trace_fp("%p: recycle buffer %d", stream, b->id); - } else if (io->status == -EPIPE) - return io->status; - io->buffer_id = b ? b->id : SPA_ID_INVALID; + io->buffer_id = b->id; + } else { + pw_log_trace_fp("%p: no buffers to recycle", stream); + io->buffer_id = SPA_ID_INVALID; + } io->status = SPA_STATUS_NEED_DATA; } if (impl->driving && impl->using_trigger)
View file
pipewire-0.3.61.tar.gz/src/tools/pw-top.c -> pipewire-0.3.62.tar.gz/src/tools/pw-top.c
Changed
@@ -663,11 +663,20 @@ { struct data *data = _data; - pw_log_error("error id:%u seq:%d res:%d (%s): %s", - id, seq, res, spa_strerror(res), message); - - if (id == PW_ID_CORE && res == -EPIPE) - pw_main_loop_quit(data->loop); + if (id == PW_ID_CORE) { + switch (res) { + case -EPIPE: + pw_main_loop_quit(data->loop); + break; + default: + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + break; + } + } else { + pw_log_info("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); + } } static void on_core_done(void *_data, uint32_t id, int seq)
View file
pipewire-0.3.61.tar.gz/test/test-spa-buffer.c -> pipewire-0.3.62.tar.gz/test/test-spa-buffer.c
Changed
@@ -47,7 +47,8 @@ pwtest_int_eq(SPA_META_Cursor, 5); pwtest_int_eq(SPA_META_Control, 6); pwtest_int_eq(SPA_META_Busy, 7); - pwtest_int_eq(_SPA_META_LAST, 8); + pwtest_int_eq(SPA_META_VideoTransform, 8); + pwtest_int_eq(_SPA_META_LAST, 9); return PWTEST_PASS; } @@ -64,6 +65,7 @@ pwtest_int_eq(sizeof(struct spa_meta_region), 16U); pwtest_int_eq(sizeof(struct spa_meta_bitmap), 20U); pwtest_int_eq(sizeof(struct spa_meta_cursor), 28U); + pwtest_int_eq(sizeof(struct spa_meta_videotransform), 4U); return PWTEST_PASS; #else @@ -75,6 +77,7 @@ fprintf(stderr, "%zd\n", sizeof(struct spa_meta_region)); fprintf(stderr, "%zd\n", sizeof(struct spa_meta_bitmap)); fprintf(stderr, "%zd\n", sizeof(struct spa_meta_cursor)); + fprintf(stderr, "%zd\n", sizeof(struct spa_meta_videotransform)); return PWTEST_SKIP; #endif }
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
.