Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 38
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Fri Nov 3 13:41:27 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.84 + +------------------------------------------------------------------- Mon Oct 23 15:00:54 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.83
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.83 +Version: 0.3.84 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.83.tar.gz/NEWS -> pipewire-0.3.84.tar.gz/NEWS
Changed
@@ -1,3 +1,64 @@ +# PipeWire 0.3.84 (2023-11-02) + +This is the fourth 1.0 release candidate that is API and ABI compatible +with previous 0.3.x releases. + +## Highlights + - Fix a regression with openal because the queued buffers in the stream + were not reported correctly. + - Fix a bug in port busy counters that could cause random silent links. + - Fix a regression in echo-cancel because it was not reporting its + streams as ASYNC. + - Fix a JACK regression where not all ports were enumerated in all cases. + - Many more fixes and improvements. + + +## PipeWire + - pw_stream now reports the queued buffers more accurately. This fixes + a regression when using openal. (#3592) + - The port busy counters were not updated correctly in some cases. This + could lead to negotiation errors and silent links. (#3547) + - Ignore latency maximum when forcing rate/quantum. (#3613) + - Nodes can now be added to multiple groups and link-groups. (#3612) + +## Modules + - The filter-chain now also handles notify port dependencies + correctly. (#3596) + - Filter-chain has support for new linear, clamp, recip, exp, log, mult, + sine builtin plugins. + - The echo-cancel module now correctly reports its playback and capture + streams as ASYNC to avoid running out of buffers. (#3593) + - It is now possible to specify an array of remote names to connect to + with the native protocol. + - module-rtp-sap and module-rtp-sink now try to bind to the specified + interface. + +## SPA + - The alsa plugin now removes the runtime properties such as period-num, + period-size and max-latency when suspended. (#3613) + +## Bluetooth + - BAP Locations/Context is now set on endpoints as required by new bluez. + - Improve selection of BAP leader. + +## JACK + - Add a jack_set_sample_rate() extension function. + - Make sure we get the info of all nodes/ports before completing the + jack_client_open() operation so that we can enumerate the ports + correctly in all cases. (#3618) + +## GStreamer + - Fix types of metadata in pipewiresink. + - Also copy metadata in buffers in all cases. + - Fix size allocation in bufferpool for compressed formats. + - Don't stop streaming thread when unlinked. (#3620) + +## ALSA + - The ALSA plugin now handles NULL values from mmap_areas. (#3600) + +Older versions: + + # PipeWire 0.3.83 (2023-10-19) This is the third 1.0 release candidate that is API and ABI compatible @@ -52,9 +113,6 @@ (#3585) - Potentially fix silent export in ardour in some cases. (#3514) -Older versions: - - # PipeWire 0.3.82 (2023-10-13) This is the second 1.0 release candidate that is API and ABI compatible
View file
pipewire-0.3.83.tar.gz/meson.build -> pipewire-0.3.84.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.83', + version : '0.3.84', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3',
View file
pipewire-0.3.83.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.84.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -309,21 +309,21 @@ xfer = nframes; if (xfer > 0) { const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io); - const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size; - - if (io->stream == SND_PCM_STREAM_PLAYBACK) - snd_pcm_areas_copy_wrap(pwareas, 0, nframes, - areas, offset, - io->buffer_size, - io->channels, xfer, - io->format); - else - snd_pcm_areas_copy_wrap(areas, offset, - io->buffer_size, - pwareas, 0, nframes, - io->channels, xfer, - io->format); - + if (areas != NULL) { + const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size; + if (io->stream == SND_PCM_STREAM_PLAYBACK) + snd_pcm_areas_copy_wrap(pwareas, 0, nframes, + areas, offset, + io->buffer_size, + io->channels, xfer, + io->format); + else + snd_pcm_areas_copy_wrap(areas, offset, + io->buffer_size, + pwareas, 0, nframes, + io->channels, xfer, + io->format); + } hw_ptr += xfer; if (hw_ptr >= pw->boundary) hw_ptr -= pw->boundary;
View file
pipewire-0.3.83.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h -> pipewire-0.3.84.tar.gz/pipewire-jack/src/pipewire-jack-extensions.h
Changed
@@ -23,6 +23,8 @@ int jack_get_video_image_size(jack_client_t *client, jack_image_size_t *size); +int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes); + #ifdef __cplusplus } #endif
View file
pipewire-0.3.83.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.84.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -426,6 +426,7 @@ int rt_max; unsigned int fix_midi_events:1; unsigned int global_buffer_size:1; + unsigned int global_sample_rate:1; unsigned int passive_links:1; unsigned int graph_callback_pending:1; unsigned int pending_callbacks:1; @@ -1519,13 +1520,17 @@ static void prepare_output(struct port *p, uint32_t frames) { struct mix *mix; + struct spa_io_buffers *io; if (SPA_UNLIKELY(p->empty_out || p->tied)) process_empty(p, frames); + if (p->global_mix == NULL || (io = p->global_mix->io) == NULL) + return; + spa_list_for_each(mix, &p->mix, port_link) { if (SPA_LIKELY(mix->io != NULL)) - *mix->io = p->io; + *mix->io = *io; } } @@ -3261,7 +3266,7 @@ struct client *c = (struct client *) data; struct object *o, *ot, *op; const char *str; - bool do_emit = true; + bool do_emit = true, do_sync = false; uint32_t serial; if (props == NULL) @@ -3343,6 +3348,7 @@ &o->proxy_listener, &proxy_events, o); pw_proxy_add_object_listener(o->proxy, &o->object_listener, &node_events, o); + do_sync = true; } } pthread_mutex_lock(&c->context.lock); @@ -3437,6 +3443,7 @@ pw_port_subscribe_params((struct pw_port*)o->proxy, ids, 1); + do_sync = true; } pthread_mutex_lock(&c->context.lock); spa_list_append(&c->context.objects, &o->link); @@ -3558,6 +3565,7 @@ pw_metadata_add_listener(proxy, &c->metadata->listener, &metadata_events, c); + do_sync = true; } else if (spa_streq(str, "settings")) { proxy = pw_registry_bind(c->registry, id, type, PW_VERSION_METADATA, sizeof(struct metadata)); @@ -3567,6 +3575,7 @@ pw_proxy_add_listener(proxy, &c->settings->proxy_listener, &settings_proxy_events, c); + do_sync = true; } goto exit; } @@ -3601,6 +3610,9 @@ } exit: + if (do_sync) + c->pending_sync = pw_proxy_sync((struct pw_proxy*)c->core, + c->pending_sync); return; exit_free: free_object(c, o); @@ -3932,6 +3944,7 @@ client->default_as_system = pw_properties_get_bool(client->props, "jack.default-as-system", false); client->fix_midi_events = pw_properties_get_bool(client->props, "jack.fix-midi-events", true); client->global_buffer_size = pw_properties_get_bool(client->props, "jack.global-buffer-size", false); + client->global_sample_rate = pw_properties_get_bool(client->props, "jack.global-sample-rate", false); client->max_ports = pw_properties_get_uint32(client->props, "jack.max-client-ports", MAX_CLIENT_PORTS); client->fill_aliases = pw_properties_get_bool(client->props, "jack.fill-aliases", false); client->writable_input = pw_properties_get_bool(client->props, "jack.writable-input", true); @@ -3952,13 +3965,15 @@ if (status) *status = 0; + client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync); + while (true) { pw_thread_loop_wait(client->context.loop); if (client->last_res < 0) goto init_failed; - if (client->has_transport) + if (client->pending_sync == client->last_sync) break; } @@ -4720,6 +4735,37 @@ } SPA_EXPORT +int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes) +{ + struct client *c = (struct client *) client; + + return_val_if_fail(c != NULL, -EINVAL); + + pw_log_info("%p: sample-size %u", client, nframes); + + pw_thread_loop_lock(c->context.loop); + if (c->global_sample_rate && c->settings && c->settings->proxy) { + char val256; + snprintf(val, sizeof(val), "%u", nframes); + pw_metadata_set_property(c->settings->proxy, 0, + "clock.force-rate", "", val); + } else { + pw_properties_setf(c->props, PW_KEY_NODE_FORCE_RATE, "%u", nframes); + + c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; + c->info.props = &c->props->dict; + + pw_client_node_update(c->node, + PW_CLIENT_NODE_UPDATE_INFO, + 0, NULL, &c->info); + c->info.change_mask = 0; + } + pw_thread_loop_unlock(c->context.loop); + + return 0; +} + +SPA_EXPORT jack_nframes_t jack_get_sample_rate (jack_client_t *client) { struct client *c = (struct client *) client; @@ -5045,6 +5091,19 @@ return &mix->buffersio->buffer_id; } +static inline void *get_buffer_data(struct buffer *b, jack_nframes_t frames) +{ + struct spa_data *d; + uint32_t offset, size; + + d = &b->datas0; + offset = SPA_MIN(d->chunk->offset, d->maxsize); + size = SPA_MIN(d->chunk->size, d->maxsize - offset); + if (size / sizeof(float) < frames) + return NULL; + return SPA_PTROFF(d->data, offset, void); +} + static void *get_buffer_input_float(struct port *p, jack_nframes_t frames) { struct mix *mix; @@ -5055,8 +5114,8 @@ bool ptr_aligned = true; spa_list_for_each(mix, &p->mix, port_link) { - struct spa_data *d; - uint32_t offset, size; + if (mix->id == SPA_ID_INVALID) + continue; pw_log_trace_fp("%p: port %s mix %d.%d get buffer %d", p->client, p->object->port.name, p->port_id, mix->id, frames); @@ -5064,13 +5123,9 @@ if ((b = get_mix_buffer(mix, frames)) == NULL) continue; - d = &b->datas0; - offset = SPA_MIN(d->chunk->offset, d->maxsize); - size = SPA_MIN(d->chunk->size, d->maxsize - offset); - if (size / sizeof(float) < frames) + if ((np = get_buffer_data(b, frames)) == NULL) continue; - np = SPA_PTROFF(d->data, offset, float); if (!SPA_IS_ALIGNED(np, 16)) ptr_aligned = false; @@ -5104,6 +5159,9 @@ struct buffer *b; void *pod; + if (mix->id == SPA_ID_INVALID) + continue; + pw_log_trace_fp("%p: port %p mix %d.%d get buffer %d", p->client, p, p->port_id, mix->id, frames); @@ -5168,8 +5226,6 @@ if ((p = o->port.port) == NULL) { struct mix *mix; struct buffer *b; - struct spa_data *d; - uint32_t offset, size; if ((mix = find_mix_peer(o->client, o->id)) == NULL) return NULL; @@ -5179,13 +5235,7 @@ if ((b = get_mix_buffer(mix, frames)) == NULL) return NULL; - d = &b->datas0; - offset = SPA_MIN(d->chunk->offset, d->maxsize); - size = SPA_MIN(d->chunk->size, d->maxsize - offset); - if (size / sizeof(float) < frames) - return NULL; - - return SPA_PTROFF(d->data, offset, void); + return get_buffer_data(b, frames); } if (!p->valid) return NULL;
View file
pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
@@ -55,6 +55,11 @@ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods); snprintf(headroom, sizeof(headroom), "%u", this->headroom); itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom); + } else { + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL); } this->info.props = &SPA_DICT_INIT(items, n_items);
View file
pipewire-0.3.83.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.84.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
@@ -55,6 +55,11 @@ itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods); snprintf(headroom, sizeof(headroom), "%u", this->headroom); itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", headroom); + } else { + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-size", NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", NULL); + itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.headroom", NULL); } this->info.props = &SPA_DICT_INIT(items, n_items);
View file
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bap-codec-caps.h -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bap-codec-caps.h
Changed
@@ -51,38 +51,56 @@ #define LC3_CONFIG_DURATION_7_5 0x00 #define LC3_CONFIG_DURATION_10 0x01 -#define LC3_CONFIG_CHNL_NOT_ALLOWED 0x00000000 -#define LC3_CONFIG_CHNL_FL 0x00000001 /* front left */ -#define LC3_CONFIG_CHNL_FR 0x00000002 /* front right */ -#define LC3_CONFIG_CHNL_FC 0x00000004 /* front center */ -#define LC3_CONFIG_CHNL_LFE 0x00000008 /* LFE */ -#define LC3_CONFIG_CHNL_BL 0x00000010 /* back left */ -#define LC3_CONFIG_CHNL_BR 0x00000020 /* back right */ -#define LC3_CONFIG_CHNL_FLC 0x00000040 /* front left center */ -#define LC3_CONFIG_CHNL_FRC 0x00000080 /* front right center */ -#define LC3_CONFIG_CHNL_BC 0x00000100 /* back center */ -#define LC3_CONFIG_CHNL_LFE2 0x00000200 /* LFE 2 */ -#define LC3_CONFIG_CHNL_SL 0x00000400 /* side left */ -#define LC3_CONFIG_CHNL_SR 0x00000800 /* side right */ -#define LC3_CONFIG_CHNL_TFL 0x00001000 /* top front left */ -#define LC3_CONFIG_CHNL_TFR 0x00002000 /* top front right */ -#define LC3_CONFIG_CHNL_TFC 0x00004000 /* top front center */ -#define LC3_CONFIG_CHNL_TC 0x00008000 /* top center */ -#define LC3_CONFIG_CHNL_TBL 0x00010000 /* top back left */ -#define LC3_CONFIG_CHNL_TBR 0x00020000 /* top back right */ -#define LC3_CONFIG_CHNL_TSL 0x00040000 /* top side left */ -#define LC3_CONFIG_CHNL_TSR 0x00080000 /* top side right */ -#define LC3_CONFIG_CHNL_TBC 0x00100000 /* top back center */ -#define LC3_CONFIG_CHNL_BFC 0x00200000 /* bottom front center */ -#define LC3_CONFIG_CHNL_BFL 0x00400000 /* bottom front left */ -#define LC3_CONFIG_CHNL_BFR 0x00800000 /* bottom front right */ -#define LC3_CONFIG_CHNL_FLW 0x01000000 /* front left wide */ -#define LC3_CONFIG_CHNL_FRW 0x02000000 /* front right wide */ -#define LC3_CONFIG_CHNL_LS 0x04000000 /* left surround */ -#define LC3_CONFIG_CHNL_RS 0x08000000 /* right surround */ - #define LC3_MAX_CHANNELS 28 +#define BAP_CHANNEL_NOT_ALLOWED 0x00000000 +#define BAP_CHANNEL_FL 0x00000001 /* front left */ +#define BAP_CHANNEL_FR 0x00000002 /* front right */ +#define BAP_CHANNEL_FC 0x00000004 /* front center */ +#define BAP_CHANNEL_LFE 0x00000008 /* LFE */ +#define BAP_CHANNEL_BL 0x00000010 /* back left */ +#define BAP_CHANNEL_BR 0x00000020 /* back right */ +#define BAP_CHANNEL_FLC 0x00000040 /* front left center */ +#define BAP_CHANNEL_FRC 0x00000080 /* front right center */ +#define BAP_CHANNEL_BC 0x00000100 /* back center */ +#define BAP_CHANNEL_LFE2 0x00000200 /* LFE 2 */ +#define BAP_CHANNEL_SL 0x00000400 /* side left */ +#define BAP_CHANNEL_SR 0x00000800 /* side right */ +#define BAP_CHANNEL_TFL 0x00001000 /* top front left */ +#define BAP_CHANNEL_TFR 0x00002000 /* top front right */ +#define BAP_CHANNEL_TFC 0x00004000 /* top front center */ +#define BAP_CHANNEL_TC 0x00008000 /* top center */ +#define BAP_CHANNEL_TBL 0x00010000 /* top back left */ +#define BAP_CHANNEL_TBR 0x00020000 /* top back right */ +#define BAP_CHANNEL_TSL 0x00040000 /* top side left */ +#define BAP_CHANNEL_TSR 0x00080000 /* top side right */ +#define BAP_CHANNEL_TBC 0x00100000 /* top back center */ +#define BAP_CHANNEL_BFC 0x00200000 /* bottom front center */ +#define BAP_CHANNEL_BFL 0x00400000 /* bottom front left */ +#define BAP_CHANNEL_BFR 0x00800000 /* bottom front right */ +#define BAP_CHANNEL_FLW 0x01000000 /* front left wide */ +#define BAP_CHANNEL_FRW 0x02000000 /* front right wide */ +#define BAP_CHANNEL_LS 0x04000000 /* left surround */ +#define BAP_CHANNEL_RS 0x08000000 /* right surround */ + +#define BAP_CHANNEL_ALL 0x0fffffff /* mask of all */ + +#define BAP_CONTEXT_PROHIBITED 0x0000 /* Prohibited */ +#define BAP_CONTEXT_UNSPECIFIED 0x0001 /* Unspecified */ +#define BAP_CONTEXT_CONVERSATIONAL 0x0002 /* Telephony, video calls, ... */ +#define BAP_CONTEXT_MEDIA 0x0004 /* Music, radio, podcast, movie soundtrack, TV */ +#define BAP_CONTEXT_GAME 0x0008 /* Gaming media, game effects, music, in-game voice chat */ +#define BAP_CONTEXT_INSTRUCTIONAL 0x0010 /* Instructional audio, navigation, announcements, user guidance */ +#define BAP_CONTEXT_VOICE 0x0020 /* Man-machine communication, voice recognition, virtual assistants */ +#define BAP_CONTEXT_LIVE 0x0040 /* Live audio, perceived both via direct acoustic path and via BAP */ +#define BAP_CONTEXT_SOUND_EFFECTS 0x0080 /* Keyboard and touch feedback, menu, UI, other system sounds */ +#define BAP_CONTEXT_NOTIFICATIONS 0x0100 /* Attention-seeking, message arrival, reminders */ +#define BAP_CONTEXT_RINGTONE 0x0200 /* Incoming call alert audio */ +#define BAP_CONTEXT_ALERTS 0x0400 /* Alarms and timers, critical battery, alarm clock, toaster */ +#define BAP_CONTEXT_EMERGENCY 0x0800 /* Fire alarm, other urgent alerts */ + +#define BAP_CONTEXT_ALL 0x0fff + #define BT_ISO_QOS_CIG_UNSET 0xff #define BT_ISO_QOS_CIS_UNSET 0xff
View file
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Changed
@@ -53,34 +53,34 @@ uint32_t bit; enum spa_audio_channel channel; } channel_bits = { - { LC3_CONFIG_CHNL_FL, SPA_AUDIO_CHANNEL_FL }, - { LC3_CONFIG_CHNL_FR, SPA_AUDIO_CHANNEL_FR }, - { LC3_CONFIG_CHNL_FC, SPA_AUDIO_CHANNEL_FC }, - { LC3_CONFIG_CHNL_LFE, SPA_AUDIO_CHANNEL_LFE }, - { LC3_CONFIG_CHNL_BL, SPA_AUDIO_CHANNEL_RL }, - { LC3_CONFIG_CHNL_BR, SPA_AUDIO_CHANNEL_RR }, - { LC3_CONFIG_CHNL_FLC, SPA_AUDIO_CHANNEL_FLC }, - { LC3_CONFIG_CHNL_FRC, SPA_AUDIO_CHANNEL_FRC }, - { LC3_CONFIG_CHNL_BC, SPA_AUDIO_CHANNEL_BC }, - { LC3_CONFIG_CHNL_LFE2, SPA_AUDIO_CHANNEL_LFE2 }, - { LC3_CONFIG_CHNL_SL, SPA_AUDIO_CHANNEL_SL }, - { LC3_CONFIG_CHNL_SR, SPA_AUDIO_CHANNEL_SR }, - { LC3_CONFIG_CHNL_TFL, SPA_AUDIO_CHANNEL_TFL }, - { LC3_CONFIG_CHNL_TFR, SPA_AUDIO_CHANNEL_TFR }, - { LC3_CONFIG_CHNL_TFC, SPA_AUDIO_CHANNEL_TFC }, - { LC3_CONFIG_CHNL_TC, SPA_AUDIO_CHANNEL_TC }, - { LC3_CONFIG_CHNL_TBL, SPA_AUDIO_CHANNEL_TRL }, - { LC3_CONFIG_CHNL_TBR, SPA_AUDIO_CHANNEL_TRR }, - { LC3_CONFIG_CHNL_TSL, SPA_AUDIO_CHANNEL_TSL }, - { LC3_CONFIG_CHNL_TSR, SPA_AUDIO_CHANNEL_TSR }, - { LC3_CONFIG_CHNL_TBC, SPA_AUDIO_CHANNEL_TRC }, - { LC3_CONFIG_CHNL_BFC, SPA_AUDIO_CHANNEL_BC }, - { LC3_CONFIG_CHNL_BFL, SPA_AUDIO_CHANNEL_BLC }, - { LC3_CONFIG_CHNL_BFR, SPA_AUDIO_CHANNEL_BRC }, - { LC3_CONFIG_CHNL_FLW, SPA_AUDIO_CHANNEL_FLW }, - { LC3_CONFIG_CHNL_FRW, SPA_AUDIO_CHANNEL_FRW }, - { LC3_CONFIG_CHNL_LS, SPA_AUDIO_CHANNEL_SL }, /* is it the right mapping? */ - { LC3_CONFIG_CHNL_RS, SPA_AUDIO_CHANNEL_SR }, /* is it the right mapping? */ + { BAP_CHANNEL_FL, SPA_AUDIO_CHANNEL_FL }, + { BAP_CHANNEL_FR, SPA_AUDIO_CHANNEL_FR }, + { BAP_CHANNEL_FC, SPA_AUDIO_CHANNEL_FC }, + { BAP_CHANNEL_LFE, SPA_AUDIO_CHANNEL_LFE }, + { BAP_CHANNEL_BL, SPA_AUDIO_CHANNEL_RL }, + { BAP_CHANNEL_BR, SPA_AUDIO_CHANNEL_RR }, + { BAP_CHANNEL_FLC, SPA_AUDIO_CHANNEL_FLC }, + { BAP_CHANNEL_FRC, SPA_AUDIO_CHANNEL_FRC }, + { BAP_CHANNEL_BC, SPA_AUDIO_CHANNEL_BC }, + { BAP_CHANNEL_LFE2, SPA_AUDIO_CHANNEL_LFE2 }, + { BAP_CHANNEL_SL, SPA_AUDIO_CHANNEL_SL }, + { BAP_CHANNEL_SR, SPA_AUDIO_CHANNEL_SR }, + { BAP_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFL }, + { BAP_CHANNEL_TFR, SPA_AUDIO_CHANNEL_TFR }, + { BAP_CHANNEL_TFC, SPA_AUDIO_CHANNEL_TFC }, + { BAP_CHANNEL_TC, SPA_AUDIO_CHANNEL_TC }, + { BAP_CHANNEL_TBL, SPA_AUDIO_CHANNEL_TRL }, + { BAP_CHANNEL_TBR, SPA_AUDIO_CHANNEL_TRR }, + { BAP_CHANNEL_TSL, SPA_AUDIO_CHANNEL_TSL }, + { BAP_CHANNEL_TSR, SPA_AUDIO_CHANNEL_TSR }, + { BAP_CHANNEL_TBC, SPA_AUDIO_CHANNEL_TRC }, + { BAP_CHANNEL_BFC, SPA_AUDIO_CHANNEL_BC }, + { BAP_CHANNEL_BFL, SPA_AUDIO_CHANNEL_BLC }, + { BAP_CHANNEL_BFR, SPA_AUDIO_CHANNEL_BRC }, + { BAP_CHANNEL_FLW, SPA_AUDIO_CHANNEL_FLW }, + { BAP_CHANNEL_FRW, SPA_AUDIO_CHANNEL_FRW }, + { BAP_CHANNEL_LS, SPA_AUDIO_CHANNEL_SL }, /* is it the right mapping? */ + { BAP_CHANNEL_RS, SPA_AUDIO_CHANNEL_SR }, /* is it the right mapping? */ }; static int write_ltv(uint8_t *dest, uint8_t type, void* value, size_t len)
View file
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -38,6 +38,7 @@ #include "dbus-helpers.h" #include "player.h" #include "iso-io.h" +#include "bap-codec-caps.h" #include "defs.h" static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5"); @@ -2017,41 +2018,31 @@ static bool device_set_update_leader(struct spa_bt_set_membership *set) { - struct spa_bt_set_membership *s, *leader; - int min_rank = INT_MAX; - int leader_rank = INT_MAX; - - leader = NULL; + struct spa_bt_set_membership *s, *leader = NULL; + /* Make minimum rank device the leader, so that device set nodes always + * appear under a specific device. + */ spa_bt_for_each_set_member(s, set) { if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX)) continue; - min_rank = SPA_MIN(min_rank, s->rank); - if (s->leader) { - leader_rank = s->rank; + + if (leader == NULL || s->rank < leader->rank || + (s->rank == leader->rank && s->leader)) leader = s; - } } - if (min_rank >= leader_rank && leader) + if (leader == NULL || (leader && leader->leader)) return false; - spa_bt_for_each_set_member(s, set) { - if (leader == NULL && s->rank == min_rank && - (s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX)) { - s->leader = true; - leader = s; - } else { - s->leader = false; - } - } + spa_bt_for_each_set_member(s, set) + s->leader = false; - if (leader) { - struct spa_bt_monitor *monitor = leader->device->monitor; + leader->leader = true; - spa_log_debug(monitor->log, "device set %s: leader is %s", - leader->path, leader->device->path); - } + spa_log_debug(leader->device->monitor->log, + "device set %p %s: leader is %s", + set, leader->path, leader->device->path); return true; } @@ -4684,7 +4675,6 @@ { const char *interface_name = BLUEZ_MEDIA_ENDPOINT_INTERFACE; DBusMessageIter object, array, entry, dict; - dbus_bool_t delay_reporting; dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &object); dbus_message_iter_append_basic(&object, DBUS_TYPE_OBJECT_PATH, &endpoint); @@ -4699,10 +4689,28 @@ append_basic_variant_dict_entry(&dict, "UUID", DBUS_TYPE_STRING, "s", &uuid); append_basic_variant_dict_entry(&dict, "Codec", DBUS_TYPE_BYTE, "y", &codec_id); append_basic_array_variant_dict_entry(&dict, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, caps, caps_size); + if (spa_bt_profile_from_uuid(uuid) & SPA_BT_PROFILE_A2DP_SOURCE) { - delay_reporting = TRUE; + dbus_bool_t delay_reporting = TRUE; + append_basic_variant_dict_entry(&dict, "DelayReporting", DBUS_TYPE_BOOLEAN, "b", &delay_reporting); } + if (spa_bt_profile_from_uuid(uuid) & (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE)) { + dbus_uint32_t locations; + dbus_uint16_t supported_context, context; + + locations = BAP_CHANNEL_ALL; + if (spa_bt_profile_from_uuid(uuid) & SPA_BT_PROFILE_BAP_SINK) { + supported_context = context = BAP_CONTEXT_ALL; + } else { + supported_context = context = (BAP_CONTEXT_UNSPECIFIED | BAP_CONTEXT_CONVERSATIONAL | + BAP_CONTEXT_MEDIA | BAP_CONTEXT_GAME); + } + + append_basic_variant_dict_entry(&dict, "Locations", DBUS_TYPE_UINT32, "u", &locations); + append_basic_variant_dict_entry(&dict, "Context", DBUS_TYPE_UINT16, "q", &context); + append_basic_variant_dict_entry(&dict, "SupportedContext", DBUS_TYPE_UINT16, "q", &supported_context); + } dbus_message_iter_close_container(&entry, &dict); dbus_message_iter_close_container(&array, &entry);
View file
pipewire-0.3.83.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.84.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -634,7 +634,7 @@ char transport32, str_id32, object_path512; bool is_dyn_node = SPA_FLAG_IS_SET(id, DYNAMIC_NODE_ID_FLAG); - spa_log_debug(this->log, "node, transport:%p id:%08x factory:%s", t, id, factory_name); + spa_log_debug(this->log, "%p: node, transport:%p id:%08x factory:%s", this, t, id, factory_name); snprintf(transport, sizeof(transport), "pointer:%p", t); items0 = SPA_DICT_ITEM_INIT(SPA_KEY_API_BLUEZ5_TRANSPORT, transport); @@ -838,8 +838,8 @@ static void emit_dynamic_node(struct dynamic_node *this, struct impl *impl, struct spa_bt_transport *t, uint32_t id, const char *factory_name, bool a2dp_duplex) { - spa_log_debug(impl->log, "dynamic node, transport: %p->%p id: %08x->%08x", - this->transport, t, this->id, id); + spa_log_debug(impl->log, "%p: dynamic node, transport: %p->%p id: %08x->%08x", + this, this->transport, t, this->id, id); if (this->transport) { /* Session manager don't really handles transport ptr changing. */ @@ -955,6 +955,9 @@ continue; } + spa_log_debug(this->log, "%p: %s belongs to set %s leader:%d", this, + device->path, set->path, set->leader); + dset->path = strdup(set->path); dset->leader = set->leader; break; @@ -1124,7 +1127,7 @@ static void emit_remove_nodes(struct impl *this) { - spa_log_debug(this->log, "remove nodes"); + spa_log_debug(this->log, "%p: remove nodes", this); remove_dynamic_node (&this->dyn_media_source); remove_dynamic_node (&this->dyn_media_sink);
View file
pipewire-0.3.83.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.84.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
@@ -89,6 +89,9 @@ struct spa_param_info params2; struct props props; + struct spa_io_clock *clock; + struct spa_io_position *position; + struct spa_hook_list hooks; struct spa_callbacks callbacks; @@ -196,7 +199,23 @@ static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size) { - return -ENOTSUP; + struct impl *this = object; + + spa_return_val_if_fail(this != NULL, -EINVAL); + + switch (id) { + case SPA_IO_Clock: + if (size > 0 && size < sizeof(struct spa_io_clock)) + return -EINVAL; + this->clock = data; + break; + case SPA_IO_Position: + this->position = data; + break; + default: + return -ENOENT; + } + return 0; } static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
View file
pipewire-0.3.83.tar.gz/src/daemon/minimal.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/minimal.conf.in
Changed
@@ -144,7 +144,7 @@ # Creates an object from a PipeWire factory with the given parameters. # If nofail is given, errors are ignored (and no object is created). # - #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } } + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } } #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail } #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
View file
pipewire-0.3.83.tar.gz/src/daemon/pipewire-vulkan.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/pipewire-vulkan.conf.in
Changed
@@ -88,11 +88,11 @@ # If condition is given, the object is created only when the context properties # all match the match rules. # - #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } } + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } } #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail } #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } } - #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } } + #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } } { factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = vulkan-compute-source object.export = true } } { factory = spa-node-factory args = { factory.name = api.vulkan.compute.filter node.name = vulkan-compute-filter object.export = true } }
View file
pipewire-0.3.83.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.84.tar.gz/src/daemon/pipewire.conf.in
Changed
@@ -178,7 +178,7 @@ condition = { module.x11.bell = true } } { name = libpipewire-module-jackdbus-detect - args { + args = { #jack.library = libjack.so.0 #jack.server = null #jack.client-name = PipeWire @@ -214,7 +214,7 @@ # If condition is given, the object is created only when the context properties # all match the match rules. # - #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } } + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } } #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = nofail } #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
View file
pipewire-0.3.83.tar.gz/src/examples/bluez-session.c -> pipewire-0.3.84.tar.gz/src/examples/bluez-session.c
Changed
@@ -71,6 +71,7 @@ struct spa_hook listener; struct spa_list device_list; + struct pw_properties *props; }; static struct node *find_node(struct object *obj, uint32_t id) @@ -266,7 +267,7 @@ spa_list_remove(&obj->link); spa_hook_remove(&obj->listener); pw_proxy_destroy(obj->proxy); - free(obj->handle); + pw_unload_spa_handle(obj->handle); free(obj); } @@ -302,7 +303,7 @@ int res; void *iface; - handle = pw_context_load_spa_handle(impl->context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, NULL); + handle = pw_context_load_spa_handle(impl->context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, &impl->props->dict); if (handle == NULL) { res = -errno; goto out; @@ -362,6 +363,10 @@ return -1; } + if ((impl.props = pw_properties_new(NULL, NULL)) == NULL) { + return -1; + } + pw_core_add_listener(impl.core, &impl.core_listener, &core_events, &impl);
View file
pipewire-0.3.83.tar.gz/src/gst/gstpipewirepool.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewirepool.c
Changed
@@ -228,7 +228,10 @@ p->add_metavideo = has_video && gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - gst_buffer_pool_config_set_params (config, caps, p->video_info.size, min_buffers, max_buffers); + if (p->video_info.size != 0) + size = p->video_info.size; + + gst_buffer_pool_config_set_params (config, caps, size, min_buffers, max_buffers); return GST_BUFFER_POOL_CLASS (gst_pipewire_pool_parent_class)->set_config (pool, config); }
View file
pipewire-0.3.83.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewiresink.c
Changed
@@ -267,12 +267,12 @@ port_params1 = spa_pod_builder_add_object (&b, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, - SPA_PARAM_META_type, SPA_POD_Int(SPA_META_Header), + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_header))); port_params2 = spa_pod_builder_add_object (&b, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, - SPA_PARAM_META_type, SPA_POD_Int(SPA_META_VideoCrop), + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region))); pw_thread_loop_lock (sink->core->loop); @@ -576,9 +576,10 @@ goto start_error; if (state == PW_STREAM_STATE_UNCONNECTED) { - enum pw_stream_flags flags = 0; + enum pw_stream_flags flags; uint32_t target_id; + flags = PW_STREAM_FLAG_ASYNC; if (pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE) flags |= PW_STREAM_FLAG_AUTOCONNECT; else @@ -676,7 +677,11 @@ config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pwsink->pool)); gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers); - size = (size == 0) ? gst_buffer_get_size (buffer) : size; + if (size == 0) { + gsize maxsize; + gst_buffer_get_sizes (buffer, NULL, &maxsize); + size = maxsize; + } gst_buffer_pool_config_set_params (config, caps, size, min_buffers, max_buffers); gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pwsink->pool), config); @@ -702,6 +707,7 @@ gst_buffer_extract (buffer, 0, info.data, info.maxsize); gst_buffer_unmap (b, &info); gst_buffer_resize (b, 0, gst_buffer_get_size (buffer)); + gst_buffer_copy_into(b, buffer, GST_BUFFER_COPY_METADATA, 0, -1); buffer = b; unref_buffer = TRUE;
View file
pipewire-0.3.83.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.84.tar.gz/src/gst/gstpipewiresrc.c
Changed
@@ -892,7 +892,9 @@ GST_DEBUG_OBJECT (basesrc, "connect capture with path %s, target-object %s", pwsrc->path, pwsrc->target_object); pwsrc->negotiated = FALSE; - enum pw_stream_flags flags = PW_STREAM_FLAG_DONT_RECONNECT; + enum pw_stream_flags flags; + flags = PW_STREAM_FLAG_DONT_RECONNECT | + PW_STREAM_FLAG_ASYNC; if (pwsrc->autoconnect) flags |= PW_STREAM_FLAG_AUTOCONNECT; pw_stream_connect (pwsrc->stream, @@ -1186,7 +1188,7 @@ if (state == PW_STREAM_STATE_ERROR) goto streaming_error; - if (state != PW_STREAM_STATE_STREAMING) + if (state == PW_STREAM_STATE_UNCONNECTED) goto streaming_stopped; if ((caps = pwsrc->caps) != NULL) {
View file
pipewire-0.3.83.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.84.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -1002,7 +1002,8 @@ PW_DIRECTION_OUTPUT, PW_ID_ANY, PW_STREAM_FLAG_MAP_BUFFERS | - PW_STREAM_FLAG_RT_PROCESS, + PW_STREAM_FLAG_RT_PROCESS | + PW_STREAM_FLAG_ASYNC, params, n_params)) < 0) { spa_pod_dynamic_builder_clean(&b); return res; @@ -1036,7 +1037,8 @@ 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_ASYNC, params, n_params)) < 0) { spa_pod_dynamic_builder_clean(&b); return res;
View file
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -203,8 +203,8 @@ * - `bq_notch` a notch filter. * - `bq_allpass` an allpass filter. * - `bq_raw` a raw biquad filter. You need a config section to specify coefficients - * per sample rate. The coefficients of the sample rate closest to the - * graph rate are selected: + * per sample rate. The coefficients of the sample rate closest to the + * graph rate are selected: * *\code{.unparsed} * filter.graph = { @@ -320,6 +320,73 @@ * * It has an input port "In" and an output port "Out". * + * ### Clamp + * + * The clamp plugin can be used to clamp samples between min and max values. + * + * It has an input port "In" and an output port "Out". It also has a "Control" + * and "Notify" port for the control values. + * + * The final result is clamped to the "Min" and "Max" control values. + * + * ### Linear + * + * The linear plugin can be used to apply a linear transformation on samples + * or control values. + * + * It has an input port "In" and an output port "Out". It also has a "Control" + * and "Notify" port for the control values. + * + * The control value "Mult" and "Add" are used to configure the linear transform. Each + * sample or control value will be calculated as: new = old * Mult + Add. + * + * ### Reciprocal + * + * The recip plugin can be used to calculate the reciprocal (1/x) of samples + * or control values. + * + * It has an input port "In" and an output port "Out". It also has a "Control" + * and "Notify" port for the control values. + * + * ### Exp + * + * The exp plugin can be used to calculate the exponential (base^x) of samples + * or control values. + * + * It has an input port "In" and an output port "Out". It also has a "Control" + * and "Notify" port for the control values. + * + * The control value "Base" is used to calculate base ^ x for each sample. + * + * ### Log + * + * The log plugin can be used to calculate the logarithm of samples + * or control values. + * + * It has an input port "In" and an output port "Out". It also has a "Control" + * and "Notify" port for the control values. + * + * The control value "Base", "M1" and "M2" are used to calculate + * out = M2 * log2f(fabsf(in * M1)) / log2f(Base) for each sample. + * + * ### Multiply + * + * The mult plugin can be used to multiply samples together. + * + * It has 8 input ports named "In 1" to "In 8" and an output port "Out". + * + * All input ports samples are multiplied together into the output. Unused input ports + * will be ignored and not cause overhead. + * + * ### Sine + * + * The sine plugin generates a sine wave. + * + * It has an output port "Out" and also a control output port "notify". + * + * "Freq", "Ampl", "Offset" and "Phase" can be used to control the sine wave + * frequence, amplitude, offset and phase. + * * ## SOFA filter * * There is an optional builtin SOFA filter available. @@ -391,7 +458,7 @@ * - \ref PW_KEY_NODE_LINK_GROUP * - \ref PW_KEY_NODE_VIRTUAL * - \ref PW_KEY_NODE_NAME: See notes below. If not specified, defaults to - * 'filter-chain-<pid>-<module-id>'. + * 'filter-chain-<pid>-<module-id>'. * * Stream only properties: * @@ -2591,6 +2658,10 @@ spa_list_for_each(link, &node->output_porti.link_list, output_link) link->input->node->n_deps--; } + for (i = 0; i < desc->n_notify; i++) { + spa_list_for_each(link, &node->notify_porti.link_list, output_link) + link->input->node->n_deps--; + } /* collect all control ports on the graph */ for (i = 0; i < desc->n_control; i++) {
View file
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -41,6 +41,7 @@ float gain; float b0, b1, b2; float a0, a1, a2; + float accum; }; static void *builtin_instantiate(const struct fc_descriptor * Descriptor, @@ -1234,6 +1235,443 @@ .cleanup = builtin_cleanup, }; +/* clamp */ +static void clamp_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float min = impl->port40, max = impl->port50; + float *in = impl->port1, *out = impl->port0; + float *ctrl = impl->port3, *notify = impl->port2; + + if (in != NULL && out != NULL) { + unsigned long n; + for (n = 0; n < SampleCount; n++) + outn = SPA_CLAMPF(inn, min, max); + } + if (ctrl != NULL && notify != NULL) + notify0 = SPA_CLAMPF(ctrl0, min, max); +} + +static struct fc_port clamp_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 3, + .name = "Control", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + }, + { .index = 4, + .name = "Min", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 0.0f, .min = -100.0f, .max = 100.0f + }, + { .index = 5, + .name = "Max", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 1.0f, .min = -100.0f, .max = 100.0f + }, +}; + +static const struct fc_descriptor clamp_desc = { + .name = "clamp", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(clamp_ports), + .ports = clamp_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = clamp_run, + .cleanup = builtin_cleanup, +}; + +/* linear */ +static void linear_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float mult = impl->port40, add = impl->port50; + float *in = impl->port1, *out = impl->port0; + float *ctrl = impl->port3, *notify = impl->port2; + + if (in != NULL && out != NULL) + dsp_ops_linear(dsp_ops, out, in, mult, add, SampleCount); + + if (ctrl != NULL && notify != NULL) + notify0 = ctrl0 * mult + add; +} + +static struct fc_port linear_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 3, + .name = "Control", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + }, + { .index = 4, + .name = "Mult", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 1.0f, .min = -10.0f, .max = 10.0f + }, + { .index = 5, + .name = "Add", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 0.0f, .min = -10.0f, .max = 10.0f + }, +}; + +static const struct fc_descriptor linear_desc = { + .name = "linear", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(linear_ports), + .ports = linear_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = linear_run, + .cleanup = builtin_cleanup, +}; + + +/* reciprocal */ +static void recip_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float *in = impl->port1, *out = impl->port0; + float *ctrl = impl->port3, *notify = impl->port2; + + if (in != NULL && out != NULL) { + unsigned long n; + for (n = 0; n < SampleCount; n++) { + if (in0 == 0.0f) + outn = 0.0f; + else + outn = 1.0f / inn; + } + } + if (ctrl != NULL && notify != NULL) { + if (ctrl0 == 0.0f) + notify0 = 0.0f; + else + notify0 = 1.0f / ctrl0; + } +} + +static struct fc_port recip_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 3, + .name = "Control", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + }, +}; + +static const struct fc_descriptor recip_desc = { + .name = "recip", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(recip_ports), + .ports = recip_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = recip_run, + .cleanup = builtin_cleanup, +}; + +/* exp */ +static void exp_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float base = impl->port40; + float *in = impl->port1, *out = impl->port0; + float *ctrl = impl->port3, *notify = impl->port2; + + if (in != NULL && out != NULL) { + unsigned long n; + for (n = 0; n < SampleCount; n++) + outn = powf(base, inn); + } + if (ctrl != NULL && notify != NULL) + notify0 = powf(base, ctrl0); +} + +static struct fc_port exp_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 3, + .name = "Control", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + }, + { .index = 4, + .name = "Base", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = M_E, .min = -10.0f, .max = 10.0f + }, +}; + +static const struct fc_descriptor exp_desc = { + .name = "exp", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(exp_ports), + .ports = exp_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = exp_run, + .cleanup = builtin_cleanup, +}; + +/* log */ +static void log_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float base = impl->port40; + float m1 = impl->port50; + float m2 = impl->port60; + float *in = impl->port1, *out = impl->port0; + float *ctrl = impl->port3, *notify = impl->port2; + float lb = log2f(base); + + if (in != NULL && out != NULL) { + unsigned long n; + for (n = 0; n < SampleCount; n++) + outn = m2 * log2f(fabsf(inn * m1)) / lb; + } + if (ctrl != NULL && notify != NULL) + notify0 = m2 * log2f(fabsf(ctrl0 * m1)) / lb; +} + +static struct fc_port log_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 3, + .name = "Control", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + }, + { .index = 4, + .name = "Base", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = M_E, .min = 2.0f, .max = 100.0f + }, + { .index = 5, + .name = "M1", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 1.0f, .min = -10.0f, .max = 10.0f + }, + { .index = 6, + .name = "M2", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 1.0f, .min = -10.0f, .max = 10.0f + }, +}; + +static const struct fc_descriptor log_desc = { + .name = "log", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(log_ports), + .ports = log_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = log_run, + .cleanup = builtin_cleanup, +}; + +/* mult */ +static void mult_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + int i, n_src = 0; + float *out = impl->port0; + const void *src8; + + if (out == NULL) + return; + + for (i = 0; i < 8; i++) { + float *in = impl->port1+i; + + if (in == NULL) + continue; + + srcn_src++ = in; + } + dsp_ops_mult(dsp_ops, out, src, n_src, SampleCount); +} + +static struct fc_port mult_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "In 1", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 2, + .name = "In 2", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 3, + .name = "In 3", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 4, + .name = "In 4", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 5, + .name = "In 5", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 6, + .name = "In 6", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 7, + .name = "In 7", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, + { .index = 8, + .name = "In 8", + .flags = FC_PORT_INPUT | FC_PORT_AUDIO, + }, +}; + +static const struct fc_descriptor mult_desc = { + .name = "mult", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(mult_ports), + .ports = mult_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = mult_run, + .cleanup = builtin_cleanup, +}; + +#define M_PI_M2 ( M_PI + M_PI ) + +/* sine */ +static void sine_run(void * Instance, unsigned long SampleCount) +{ + struct builtin *impl = Instance; + float *out = impl->port0; + float *notify = impl->port1; + float freq = impl->port20; + float ampl = impl->port30; + float offs = impl->port50; + unsigned long n; + + for (n = 0; n < SampleCount; n++) { + if (out != NULL) + outn = sin(impl->accum) * ampl + offs; + if (notify != NULL && n == 0) + notify0 = sin(impl->accum) * ampl + offs; + + impl->accum += M_PI_M2 * freq / impl->rate; + if (impl->accum >= M_PI_M2) + impl->accum -= M_PI_M2; + } +} + +static struct fc_port sine_ports = { + { .index = 0, + .name = "Out", + .flags = FC_PORT_OUTPUT | FC_PORT_AUDIO, + }, + { .index = 1, + .name = "Notify", + .flags = FC_PORT_OUTPUT | FC_PORT_CONTROL, + }, + { .index = 2, + .name = "Freq", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 440.0f, .min = 0.0f, .max = 1000000.0f + }, + { .index = 3, + .name = "Ampl", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 1.0, .min = 0.0f, .max = 10.0f + }, + { .index = 4, + .name = "Phase", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 0.0f, .min = -M_PI, .max = M_PI + }, + { .index = 5, + .name = "Offset", + .flags = FC_PORT_INPUT | FC_PORT_CONTROL, + .def = 0.0f, .min = -10.0f, .max = 10.0f + }, +}; + +static const struct fc_descriptor sine_desc = { + .name = "sine", + .flags = FC_DESCRIPTOR_SUPPORTS_NULL_DATA, + + .n_ports = SPA_N_ELEMENTS(sine_ports), + .ports = sine_ports, + + .instantiate = builtin_instantiate, + .connect_port = builtin_connect_port, + .run = sine_run, + .cleanup = builtin_cleanup, +}; + static const struct fc_descriptor * builtin_descriptor(unsigned long Index) { switch(Index) { @@ -1265,6 +1703,20 @@ return &invert_desc; case 13: return &bq_raw_desc; + case 14: + return &clamp_desc; + case 15: + return &linear_desc; + case 16: + return &recip_desc; + case 17: + return &exp_desc; + case 18: + return &log_desc; + case 19: + return &mult_desc; + case 20: + return &sine_desc; } return NULL; }
View file
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
@@ -33,8 +33,14 @@ uint32_t i; const float *s = src; float *d = dst; - for (i = 0; i < n_samples; i++) - di = si * gain; + if (gain == 0.0f) + dsp_clear_c(ops, dst, n_samples); + else if (gain == 1.0f) + dsp_copy_c(ops, dst, src, n_samples); + else { + for (i = 0; i < n_samples; i++) + di = si * gain; + } } static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, @@ -43,8 +49,15 @@ uint32_t i; const float *s = src; float *d = dst; - for (i = 0; i < n_samples; i++) - di += si * gain; + + if (gain == 0.0f) + return; + else if (gain == 1.0f) + dsp_add_c(ops, dst, src, n_samples); + else { + for (i = 0; i < n_samples; i++) + di += si * gain; + } } @@ -64,17 +77,34 @@ if (n_src == 0) { dsp_clear_c(ops, dst, n_samples); } else { - if (gain0 == 1.0f) - dsp_copy_c(ops, dst, src0, n_samples); - else - dsp_gain_c(ops, dst, src0, gain0, n_samples); - - for (i = 1; i < n_src; i++) { - if (gaini == 1.0f) - dsp_add_c(ops, dst, srci, n_samples); - else - dsp_gain_add_c(ops, dst, srci, gaini, n_samples); - } + dsp_gain_c(ops, dst, src0, gain0, n_samples); + for (i = 1; i < n_src; i++) + dsp_gain_add_c(ops, dst, srci, gaini, n_samples); + } +} + +static inline void dsp_mult1_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples) +{ + uint32_t i; + const float *s = src; + float *d = dst; + for (i = 0; i < n_samples; i++) + di *= si; +} + +void dsp_mult_c(struct dsp_ops *ops, + void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, + uint32_t n_src, uint32_t n_samples) +{ + uint32_t i; + if (n_src == 0) { + dsp_clear_c(ops, dst, n_samples); + } else { + dsp_copy_c(ops, dst, src0, n_samples); + for (i = 1; i < n_src; i++) + dsp_mult1_c(ops, dst, srci, n_samples); } } @@ -113,6 +143,27 @@ dsti = ai + bi; } +void dsp_linear_c(struct dsp_ops *ops, float * dst, + const float * SPA_RESTRICT src, const float mult, + const float add, uint32_t n_samples) +{ + uint32_t i; + if (add == 0.0f) { + dsp_gain_c(ops, dst, src, mult, n_samples); + } else { + if (mult == 0.0f) { + for (i = 0; i < n_samples; i++) + dsti = add; + } else if (mult == 1.0f) { + for (i = 0; i < n_samples; i++) + dsti = srci + add; + } else { + for (i = 0; i < n_samples; i++) + dsti = mult * srci + add; + } + } +} + void *dsp_fft_new_c(struct dsp_ops *ops, int32_t size, bool real) { return pffft_new_setup(size, real ? PFFFT_REAL : PFFFT_COMPLEX);
View file
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops.c -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops.c
Changed
@@ -27,6 +27,8 @@ .funcs.mix_gain = dsp_mix_gain_sse, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_avx, + .funcs.linear = dsp_linear_c, + .funcs.mult = dsp_mult_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c, @@ -41,6 +43,8 @@ .funcs.mix_gain = dsp_mix_gain_sse, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_sse, + .funcs.linear = dsp_linear_c, + .funcs.mult = dsp_mult_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c, @@ -54,6 +58,8 @@ .funcs.mix_gain = dsp_mix_gain_c, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_c, + .funcs.linear = dsp_linear_c, + .funcs.mult = dsp_mult_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c,
View file
pipewire-0.3.83.tar.gz/src/modules/module-filter-chain/dsp-ops.h -> pipewire-0.3.84.tar.gz/src/modules/module-filter-chain/dsp-ops.h
Changed
@@ -37,6 +37,12 @@ float * dst, const float * src, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale); + void (*linear) (struct dsp_ops *ops, + float * dst, const float * SPA_RESTRICT src, + const float mult, const float add, uint32_t n_samples); + void (*mult) (struct dsp_ops *ops, + void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_src, uint32_t n_samples); }; struct dsp_ops { @@ -58,6 +64,8 @@ #define dsp_ops_mix_gain(ops,...) (ops)->funcs.mix_gain(ops, __VA_ARGS__) #define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(ops, __VA_ARGS__) #define dsp_ops_sum(ops,...) (ops)->funcs.sum(ops, __VA_ARGS__) +#define dsp_ops_linear(ops,...) (ops)->funcs.linear(ops, __VA_ARGS__) +#define dsp_ops_mult(ops,...) (ops)->funcs.mult(ops, __VA_ARGS__) #define dsp_ops_fft_new(ops,...) (ops)->funcs.fft_new(ops, __VA_ARGS__) #define dsp_ops_fft_free(ops,...) (ops)->funcs.fft_free(ops, __VA_ARGS__) @@ -79,6 +87,12 @@ #define MAKE_SUM_FUNC(arch) \ void dsp_sum_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) +#define MAKE_LINEAR_FUNC(arch) \ +void dsp_linear_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ + const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples) +#define MAKE_MULT_FUNC(arch) \ +void dsp_mult_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ + const void * SPA_RESTRICT src, uint32_t n_src, uint32_t n_samples) #define MAKE_FFT_NEW_FUNC(arch) \ void *dsp_fft_new_##arch(struct dsp_ops *ops, int32_t size, bool real) @@ -102,6 +116,8 @@ MAKE_MIX_GAIN_FUNC(c); MAKE_BIQUAD_RUN_FUNC(c); MAKE_SUM_FUNC(c); +MAKE_LINEAR_FUNC(c); +MAKE_MULT_FUNC(c); MAKE_FFT_NEW_FUNC(c); MAKE_FFT_FREE_FUNC(c);
View file
pipewire-0.3.83.tar.gz/src/modules/module-protocol-native/local-socket.c -> pipewire-0.3.84.tar.gz/src/modules/module-protocol-native/local-socket.c
Changed
@@ -9,6 +9,7 @@ #include <stdio.h> #include <string.h> #include <errno.h> +#include <limits.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> @@ -20,6 +21,7 @@ #endif #include <pipewire/pipewire.h> +#include <spa/utils/json.h> #define DEFAULT_SYSTEM_RUNTIME_DIR "/run/pipewire" @@ -119,31 +121,56 @@ return res; } -int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, - const struct spa_dict *props, - void (*done_callback) (void *data, int res), - void *data) +static int try_connect_name(struct pw_protocol_client *client, + const char *name, + void (*done_callback) (void *data, int res), + void *data) { - const char *runtime_dir, *name; + const char *runtime_dir; int res; - name = get_remote(props); - if (name == NULL) - return -EINVAL; - if (name0 == '/') { - res = try_connect(client, NULL, name, done_callback, data); + return try_connect(client, NULL, name, done_callback, data); } else { runtime_dir = get_runtime_dir(); if (runtime_dir != NULL) { res = try_connect(client, runtime_dir, name, done_callback, data); if (res >= 0) - goto exit; + return res; } runtime_dir = get_system_dir(); if (runtime_dir != NULL) - res = try_connect(client, runtime_dir, name, done_callback, data); + return try_connect(client, runtime_dir, name, done_callback, data); + } + + return -EINVAL; +} + +int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, + const struct spa_dict *props, + void (*done_callback) (void *data, int res), + void *data) +{ + const char *name; + struct spa_json it2; + char pathPATH_MAX; + int res = -EINVAL; + + name = get_remote(props); + if (name == NULL) + return -EINVAL; + + spa_json_init(&it0, name, strlen(name)); + + if (spa_json_enter_array(&it0, &it1) < 0) + return try_connect_name(client, name, done_callback, data); + + while (spa_json_get_string(&it1, path, sizeof(path)) > 0) { + res = try_connect_name(client, path, done_callback, data); + if (res < 0) + continue; + break; } -exit: + return res; }
View file
pipewire-0.3.83.tar.gz/src/modules/module-rtp-sap.c -> pipewire-0.3.84.tar.gz/src/modules/module-rtp-sap.c
Changed
@@ -757,6 +757,11 @@ if ((str = pw_properties_get(props, "rtp.session")) != NULL) fprintf(f, "\"sess.name\" = \"%s\", ", str); + /* Use an interface if explicitly specified, else use the SAP interface if that was specified */ + if ((str = pw_properties_get(props, "local.ifname")) != NULL || (str = impl->ifname) != NULL) { + fprintf(f, "\"local.ifname\" = \"%s\", ", str); + } + if ((media = pw_properties_get(props, "sess.media")) == NULL) media = "audio"; @@ -1540,7 +1545,7 @@ pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_info)); - pw_log_info("Successfully loaded module-rtp-sink"); + pw_log_info("Successfully loaded module-rtp-sap"); return 0; out:
View file
pipewire-0.3.83.tar.gz/src/modules/module-rtp-sink.c -> pipewire-0.3.84.tar.gz/src/modules/module-rtp-sink.c
Changed
@@ -253,7 +253,7 @@ static int make_socket(struct sockaddr_storage *src, socklen_t src_len, struct sockaddr_storage *dst, socklen_t dst_len, - bool loop, int ttl, int dscp) + bool loop, int ttl, int dscp, char *ifname) { int af, fd, val, res; @@ -267,6 +267,13 @@ pw_log_error("bind() failed: %m"); goto error; } +#ifdef SO_BINDTODEVICE + if (ifname && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) { + res = -errno; + pw_log_error("setsockopt(SO_BINDTODEVICE) failed: %m"); + goto error; + } +#endif if (connect(fd, (struct sockaddr*)dst, dst_len) < 0) { res = -errno; pw_log_error("connect() failed: %m"); @@ -517,7 +524,8 @@ if ((res = make_socket(&impl->src_addr, impl->src_len, &impl->dst_addr, impl->dst_len, - impl->mcast_loop, impl->ttl, impl->dscp)) < 0) { + impl->mcast_loop, impl->ttl, impl->dscp, + impl->ifname)) < 0) { pw_log_error("can't make socket: %s", spa_strerror(res)); goto out; }
View file
pipewire-0.3.83.tar.gz/src/pipewire/context.c -> pipewire-0.3.84.tar.gz/src/pipewire/context.c
Changed
@@ -807,7 +807,8 @@ spa_list_for_each(l, &p->links, input_link) { t = l->output->node; - if (!t->active || !l->prepared || (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction))) + if (!t->active || !l->prepared || + (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction))) continue; pw_log_debug(" peer %p: '%s'", t, t->name); @@ -820,7 +821,8 @@ spa_list_for_each(l, &p->links, output_link) { t = l->input->node; - if (!t->active || !l->prepared || (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction))) + if (!t->active || !l->prepared || + (!t->driving && SPA_FLAG_IS_SET(t->checked, 1u<<direction))) continue; pw_log_debug(" peer %p: '%s'", t, t->name); @@ -834,12 +836,12 @@ * don't get included here. They were added to the same driver but * need to otherwise stay idle unless some non-passive link activates * them. */ - if (node->link_group != NULL) { + if (node->link_groups != NULL) { spa_list_for_each(t, nodes, sort_link) { if (t->exported || !t->active || SPA_FLAG_IS_SET(t->checked, 1u<<direction)) continue; - if (!spa_streq(t->link_group, node->link_group)) + if (pw_strv_find_common(t->link_groups, node->link_groups) < 0) continue; pw_log_debug(" group %p: '%s'", t, t->name); @@ -931,15 +933,15 @@ } /* now go through all the nodes that have the same group and * that are not yet visited */ - if (n->group != NULL || n->link_group != NULL) { + if (n->groups != NULL || n->link_groups != NULL) { spa_list_for_each(t, &context->node_list, link) { if (t->exported || !t->active || t->visited) continue; - if ((t->group == NULL || !spa_streq(t->group, n->group)) && - (t->link_group == NULL || !spa_streq(t->link_group, n->link_group))) + if (pw_strv_find_common(t->groups, n->groups) < 0 && + pw_strv_find_common(t->link_groups, n->link_groups) < 0) continue; - pw_log_debug("%p: %s join group:%s link-group:%s", - t, t->name, n->group, n->link_group); + pw_log_debug("%p: %s join group of %s", + t, t->name, n->name); t->visited = true; spa_list_append(&queue, &t->sort_link); } @@ -1465,8 +1467,9 @@ node_max_quantum = node_max_quantum * current_rate / node_rate_quantum; } - /* calculate desired quantum */ - if (max_latency.denom != 0) { + /* calculate desired quantum. Don't limit to the max_latency when we are + * going to force a quantum or rate and reconfigure the nodes. */ + if (max_latency.denom != 0 && !force_quantum && !force_rate) { uint32_t tmp = (max_latency.num * current_rate / max_latency.denom); if (tmp < node_max_quantum) node_max_quantum = tmp;
View file
pipewire-0.3.83.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.84.tar.gz/src/pipewire/impl-link.c
Changed
@@ -140,6 +140,30 @@ link->info.change_mask = 0; } +static inline void input_set_busy_id(struct pw_impl_link *link, uint32_t id) +{ + struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this); + if (impl->input_busy_id != SPA_ID_INVALID) + link->input->busy_count--; + if (id != SPA_ID_INVALID) + link->input->busy_count++; + impl->input_busy_id = id; + if (link->input->busy_count < 0) + pw_log_error("%s: invalid busy count:%d", link->name, link->input->busy_count); +} + +static inline void output_set_busy_id(struct pw_impl_link *link, uint32_t id) +{ + struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this); + if (impl->output_busy_id != SPA_ID_INVALID) + link->output->busy_count--; + if (id != SPA_ID_INVALID) + link->output->busy_count++; + impl->output_busy_id = id; + if (link->output->busy_count < 0) + pw_log_error("%s: invalid busy count:%d", link->name, link->output->busy_count); +} + static void link_update_state(struct pw_impl_link *link, enum pw_link_state state, int res, char *error) { struct impl *impl = SPA_CONTAINER_OF(link, struct impl, this); @@ -194,15 +218,11 @@ } else if (state == PW_LINK_STATE_INIT) { link->prepared = false; link->preparing = false; - if (impl->output_busy_id != SPA_ID_INVALID) { - impl->output_busy_id = SPA_ID_INVALID; - link->output->busy_count--; - } + + output_set_busy_id(link, SPA_ID_INVALID); pw_work_queue_cancel(impl->work, &link->output_link, SPA_ID_INVALID); - if (impl->input_busy_id != SPA_ID_INVALID) { - impl->input_busy_id = SPA_ID_INVALID; - link->input->busy_count--; - } + + input_set_busy_id(link, SPA_ID_INVALID); pw_work_queue_cancel(impl->work, &link->input_link, SPA_ID_INVALID); } } @@ -218,14 +238,15 @@ else port = this->output; - if (id == impl->input_busy_id) { - impl->input_busy_id = SPA_ID_INVALID; - port->busy_count--; - } else if (id == impl->output_busy_id) { - impl->output_busy_id = SPA_ID_INVALID; - port->busy_count--; - } else if (id != SPA_ID_INVALID) - return; + if (id != SPA_ID_INVALID) { + if (id == impl->input_busy_id) { + input_set_busy_id(this, SPA_ID_INVALID); + } else if (id == impl->output_busy_id) { + output_set_busy_id(this, SPA_ID_INVALID); + } else { + return; + } + } pw_log_debug("%p: obj:%p port %p complete state:%d: %s", this, obj, port, port->state, spa_strerror(res)); @@ -258,14 +279,15 @@ mix = &this->rt.out_mix; } - if (id == impl->input_busy_id) { - impl->input_busy_id = SPA_ID_INVALID; - port->busy_count--; - } else if (id == impl->output_busy_id) { - impl->output_busy_id = SPA_ID_INVALID; - port->busy_count--; - } else if (id != SPA_ID_INVALID) - return; + if (id != SPA_ID_INVALID) { + if (id == impl->input_busy_id) { + input_set_busy_id(this, SPA_ID_INVALID); + } else if (id == impl->output_busy_id) { + output_set_busy_id(this, SPA_ID_INVALID); + } else { + return; + } + } pw_log_debug("%p: obj:%p port %p complete state:%d: %s", this, obj, port, port->state, spa_strerror(res)); @@ -309,7 +331,7 @@ struct pw_impl_port *input, *output; uint8_t buffer4096; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - uint32_t index; + uint32_t index, busy_id; uint32_t in_state, out_state; if (this->info.state >= PW_LINK_STATE_NEGOTIATING) @@ -430,10 +452,10 @@ goto error; } if (SPA_RESULT_IS_ASYNC(res)) { - output->busy_count++; res = spa_node_sync(output->node->node, res); - impl->output_busy_id = pw_work_queue_add(impl->work, &this->output_link, res, + busy_id = pw_work_queue_add(impl->work, &this->output_link, res, complete_ready, this); + output_set_busy_id(this, busy_id); } else { complete_ready(&this->output_link, this, res, SPA_ID_INVALID); } @@ -449,10 +471,10 @@ goto error; } if (SPA_RESULT_IS_ASYNC(res2)) { - input->busy_count++; res2 = spa_node_sync(input->node->node, res2); - impl->input_busy_id = pw_work_queue_add(impl->work, &this->input_link, res2, + busy_id = pw_work_queue_add(impl->work, &this->input_link, res2, complete_ready, this); + input_set_busy_id(this, busy_id); if (res == 0) res = res2; } else { @@ -524,7 +546,7 @@ { struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); int res; - uint32_t in_flags, out_flags; + uint32_t in_flags, out_flags, busy_id; char *error = NULL; struct pw_impl_port *input, *output; @@ -597,10 +619,10 @@ goto error_clear; } if (SPA_RESULT_IS_ASYNC(res)) { - output->busy_count++; res = spa_node_sync(output->node->node, res); - impl->output_busy_id = pw_work_queue_add(impl->work, &this->output_link, res, + busy_id = pw_work_queue_add(impl->work, &this->output_link, res, complete_paused, this); + output_set_busy_id(this, busy_id); if (flags & SPA_NODE_BUFFERS_FLAG_ALLOC) return 0; } else { @@ -620,10 +642,10 @@ } if (SPA_RESULT_IS_ASYNC(res)) { - input->busy_count++; res = spa_node_sync(input->node->node, res); - impl->input_busy_id = pw_work_queue_add(impl->work, &this->input_link, res, + busy_id = pw_work_queue_add(impl->work, &this->input_link, res, complete_paused, this); + input_set_busy_id(this, busy_id); } else { complete_paused(&this->input_link, this, res, SPA_ID_INVALID); } @@ -726,13 +748,13 @@ } if (output->busy_count > 0) { - pw_log_debug("%p: output port %p was busy", this, output); + pw_log_debug("%p: output port %p was busy %d", this, output, output->busy_count); res = spa_node_sync(output->node->node, 0); pw_work_queue_add(impl->work, &this->output_link, res, complete_sync, this); goto exit; } else if (input->busy_count > 0) { - pw_log_debug("%p: input port %p was busy", this, input); + pw_log_debug("%p: input port %p was busy %d", this, input, input->busy_count); res = spa_node_sync(input->node->node, 0); pw_work_queue_add(impl->work, &this->input_link, res, complete_sync, this); goto exit; @@ -762,10 +784,8 @@ pw_log_debug("%p: remove input port %p", this, port); - if (impl->input_busy_id != SPA_ID_INVALID) { - impl->input_busy_id = SPA_ID_INVALID; - port->busy_count--; - } + input_set_busy_id(this, SPA_ID_INVALID); + spa_hook_remove(&impl->input_port_listener); spa_hook_remove(&impl->input_node_listener); spa_hook_remove(&impl->input_global_listener); @@ -792,10 +812,8 @@ pw_log_debug("%p: remove output port %p", this, port); - if (impl->output_busy_id != SPA_ID_INVALID) { - impl->output_busy_id = SPA_ID_INVALID; - port->busy_count--; - } + output_set_busy_id(this, SPA_ID_INVALID); + spa_hook_remove(&impl->output_port_listener); spa_hook_remove(&impl->output_node_listener); spa_hook_remove(&impl->output_global_listener);
View file
pipewire-0.3.83.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.84.tar.gz/src/pipewire/impl-node.c
Changed
@@ -9,6 +9,7 @@ #include <errno.h> #include <time.h> #include <malloc.h> +#include <limits.h> #include <spa/support/system.h> #include <spa/pod/parser.h> @@ -42,6 +43,9 @@ unsigned int cache_params:1; unsigned int pending_play:1; + + char *group; + char *link_group; }; #define pw_node_resource(r,m,v,...) pw_resource_call(r,struct pw_node_events,m,v,__VA_ARGS__) @@ -473,8 +477,8 @@ static void clear_info(struct pw_impl_node *this) { - free(this->group); - free(this->link_group); + pw_free_strv(this->groups); + pw_free_strv(this->link_groups); free(this->name); free((char*)this->info.error); } @@ -964,20 +968,26 @@ /* group defines what nodes are scheduled together */ str = pw_properties_get(node->properties, PW_KEY_NODE_GROUP); - if (!spa_streq(str, node->group)) { - pw_log_info("%p: group '%s'->'%s'", node, node->group, str); - free(node->group); - node->group = str ? strdup(str) : NULL; - node->freewheel = spa_streq(node->group, "pipewire.freewheel"); + if (!spa_streq(str, impl->group)) { + pw_log_info("%p: group '%s'->'%s'", node, impl->group, str); + free(impl->group); + impl->group = str ? strdup(str) : NULL; + pw_free_strv(node->groups); + node->groups = impl->group ? + pw_strv_parse(impl->group, strlen(impl->group), INT_MAX, NULL) : NULL; + node->freewheel = pw_strv_find(node->groups, "pipewire.freewheel") >= 0; recalc_reason = "group changed"; } /* link group defines what nodes are logically linked together */ str = pw_properties_get(node->properties, PW_KEY_NODE_LINK_GROUP); - if (!spa_streq(str, node->link_group)) { - pw_log_info("%p: link group '%s'->'%s'", node, node->link_group, str); - free(node->link_group); - node->link_group = str ? strdup(str) : NULL; + if (!spa_streq(str, impl->link_group)) { + pw_log_info("%p: link group '%s'->'%s'", node, impl->link_group, str); + free(impl->link_group); + impl->link_group = str ? strdup(str) : NULL; + pw_free_strv(node->link_groups); + node->link_groups = impl->link_group ? + pw_strv_parse(impl->link_group, strlen(impl->link_group), INT_MAX, NULL) : NULL; recalc_reason = "link group changed"; } @@ -2098,6 +2108,8 @@ clear_info(node); spa_system_close(node->data_system, node->source.fd); + free(impl->group); + free(impl->link_group); free(impl); #ifdef HAVE_MALLOC_TRIM
View file
pipewire-0.3.83.tar.gz/src/pipewire/keys.h -> pipewire-0.3.84.tar.gz/src/pipewire/keys.h
Changed
@@ -90,7 +90,9 @@ /* remote keys */ #define PW_KEY_REMOTE_NAME "remote.name" /**< The name of the remote to connect to, * default pipewire-0, overwritten by - * env(PIPEWIRE_REMOTE) */ + * env(PIPEWIRE_REMOTE). May also be + * a SPA-JSON array of sockets, to be tried + * in order. */ #define PW_KEY_REMOTE_INTENTION "remote.intention" /**< The intention of the remote connection, * "generic", "screencast" */ @@ -135,7 +137,8 @@ #define PW_KEY_NODE_SESSION "node.session" /**< the session id this node is part of */ #define PW_KEY_NODE_GROUP "node.group" /**< the group id this node is part of. Nodes * in the same group are always scheduled - * with the same driver. */ + * with the same driver. Can be an array of + * group names. */ #define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ #define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected * to a compatible node */ @@ -175,7 +178,8 @@ * on output/input/all ports when the value is * "out"/"in"/"true" respectively */ #define PW_KEY_NODE_LINK_GROUP "node.link-group" /**< the node is internally linked to - * nodes with the same link-group */ + * nodes with the same link-group. Can be an + * array of group names. */ #define PW_KEY_NODE_NETWORK "node.network" /**< the node is on a network */ #define PW_KEY_NODE_TRIGGER "node.trigger" /**< the node is not scheduled automatically * based on the dependencies in the graph
View file
pipewire-0.3.83.tar.gz/src/pipewire/private.h -> pipewire-0.3.84.tar.gz/src/pipewire/private.h
Changed
@@ -643,8 +643,8 @@ char *name; /** for debug */ uint32_t priority_driver; /** priority for being driver */ - char *group; /** group to schedule this node in */ - char *link_group; /** group this node is linked to */ + char **groups; /** groups to schedule this node in */ + char **link_groups; /** groups this node is linked to */ uint64_t spa_flags; unsigned int registered:1;
View file
pipewire-0.3.83.tar.gz/src/pipewire/stream.c -> pipewire-0.3.84.tar.gz/src/pipewire/stream.c
Changed
@@ -2340,6 +2340,7 @@ struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); uintptr_t seq1, seq2; uint32_t buffered, quantum, index; + int32_t avail_buffers; do { seq1 = SPA_SEQ_READ(impl->seq); @@ -2358,19 +2359,23 @@ time->delay += (impl->latency.min_rate + impl->latency.max_rate) / 2; time->delay += ((impl->latency.min_ns + impl->latency.max_ns) / 2) * time->rate.denom / SPA_NSEC_PER_SEC; + avail_buffers = spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index); + avail_buffers = SPA_CLAMP(avail_buffers, 0, (int32_t)impl->n_buffers); + if (size >= offsetof(struct pw_time, queued_buffers)) time->buffered = buffered; if (size >= offsetof(struct pw_time, avail_buffers)) - time->queued_buffers = spa_ringbuffer_get_read_index(&impl->queued.ring, &index); + time->queued_buffers = impl->n_buffers - avail_buffers; if (size >= sizeof(struct pw_time)) - time->avail_buffers = spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index); + time->avail_buffers = avail_buffers; pw_log_trace_fp("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d %"PRIu64" %" - PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, stream, + PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %d/%d", stream, time->now, time->delay, time->ticks, time->rate.num, time->rate.denom, time->queued, impl->dequeued.outcount, impl->dequeued.incount, - impl->queued.outcount, impl->queued.incount); + impl->queued.outcount, impl->queued.incount, + avail_buffers, impl->n_buffers); return 0; }
View file
pipewire-0.3.83.tar.gz/src/pipewire/utils.c -> pipewire-0.3.84.tar.gz/src/pipewire/utils.c
Changed
@@ -13,6 +13,8 @@ #include <string.h> #include <time.h> +#include <spa/utils/json.h> + #include <pipewire/array.h> #include <pipewire/log.h> #include <pipewire/utils.h> @@ -74,7 +76,8 @@ } pw_array_add_ptr(&arr, NULL); - *n_tokens = n; + if (n_tokens != NULL) + *n_tokens = n; return arr.data; } @@ -110,6 +113,89 @@ return n; } +/** Parse an array of strings + * \param val a string to parse + * \param len the length of \a val + * \param max_tokens the max number of tokens to split + * \paramout n_tokens the number of tokens, may be NULL + * \return a NULL terminated array of strings that should be + * freed with \ref pw_free_strv. + * + * \a val is parsed using relaxed json syntax. + * + * \since 0.3.84 + */ +SPA_EXPORT +char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens) +{ + struct pw_array arr; + struct spa_json it2; + char v256; + int n = 0; + + if (val == NULL) + return NULL; + + pw_array_init(&arr, 16); + + spa_json_init(&it0, val, len); + if (spa_json_enter_array(&it0, &it1) <= 0) + spa_json_init(&it1, val, len); + + while (spa_json_get_string(&it1, v, sizeof(v)) > 0 && n + 1 < max_tokens) { + pw_array_add_ptr(&arr, strdup(v)); + n++; + } + pw_array_add_ptr(&arr, NULL); + + if (n_tokens != NULL) + *n_tokens = n; + + return arr.data; +} + +/** Find a string in a NULL terminated array of strings. + * \param a a strv to check + * \param b the string to find + * \return the index in \a a where \a b is found or < 0 if not. + * + * \since 0.3.84 + */ +SPA_EXPORT +int pw_strv_find(char **a, char *b) +{ + int i; + if (a == NULL || b == NULL) + return -EINVAL; + for (i = 0; ai; i++) { + if (spa_streq(ai, b)) + return i; + } + return -ENOENT; +} + +/** Check if two NULL terminated arrays of strings have a common string. + * \param a a strv to check + * \param b another strv to check + * \return the index in \a a of the first common string or < 0 if not. + * + * \since 0.3.84 + */ +SPA_EXPORT +int pw_strv_find_common(char **a, char **b) +{ + int i; + + if (a == NULL || b == NULL) + return -EINVAL; + + for (i = 0; ai; i++) { + if (pw_strv_find(b, ai) >= 0) + return i; + } + return -ENOENT; +} + /** Free a NULL terminated array of strings * \param str a NULL terminated array of string *
View file
pipewire-0.3.83.tar.gz/src/pipewire/utils.h -> pipewire-0.3.84.tar.gz/src/pipewire/utils.h
Changed
@@ -46,6 +46,12 @@ int pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens); +char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens); + +int pw_strv_find(char **a, char *b); + +int pw_strv_find_common(char **a, char **b); + void pw_free_strv(char **str);
View file
pipewire-0.3.83.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.84.tar.gz/src/tools/pw-dump.c
Changed
@@ -1608,7 +1608,8 @@ data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote, + PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : + ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""), NULL), 0); if (data.core == NULL) {
View file
pipewire-0.3.83.tar.gz/src/tools/pw-mon.c -> pipewire-0.3.84.tar.gz/src/tools/pw-mon.c
Changed
@@ -860,7 +860,8 @@ data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote, + PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : + ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""), NULL), 0); if (data.core == NULL) {
View file
pipewire-0.3.83.tar.gz/src/tools/pw-top.c -> pipewire-0.3.84.tar.gz/src/tools/pw-top.c
Changed
@@ -836,7 +836,8 @@ data.core = pw_context_connect(data.context, pw_properties_new( - PW_KEY_REMOTE_NAME, opt_remote, + PW_KEY_REMOTE_NAME, opt_remote ? opt_remote : + ("" PW_DEFAULT_REMOTE "-manager," PW_DEFAULT_REMOTE ""), NULL), 0); if (data.core == NULL) {
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
.