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 36
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Oct 18 08:54:11 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.82 + +------------------------------------------------------------------- Sun Oct 8 16:26:36 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.81
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.81 +Version: 0.3.82 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.81.tar.gz/.gitlab/ci/check_missing_headers.sh -> pipewire-0.3.82.tar.gz/.gitlab/ci/check_missing_headers.sh
Changed
@@ -5,7 +5,7 @@ LIST="" -for i in $(find spa/include -name '*.h' -a -not -path 'spa/include/spa/utils/cleanup.h' | sed s#spa/include/##); +for i in $(find spa/include -name '*.h' | sed s#spa/include/##); do -f "$PREFIX/include/spa-0.2/$i" || LIST="$i $LIST" done
View file
pipewire-0.3.81.tar.gz/NEWS -> pipewire-0.3.82.tar.gz/NEWS
Changed
@@ -1,3 +1,68 @@ +# PipeWire 0.3.82 (2023-10-13) + +This is the second 1.0 release candidate that is API and ABI compatible +with previous 0.3.x releases. + +## Highlights + - Fix a regression in some devices when the Pro-Audio profile was selected. + Only enable the IRQ based scheduling and device linking in specific + safe cases. (#3556) + - Improve rate switching. In some cases the graph rate would not switch + correctly. (#2929) + - Fix regression in alsa wakeups that would cause silence in VMs. + - Fix a leak in the SBC codecs for SCO. + - More improvements to the RAOP module. + - Other small improvements and fixes. + + +## PipeWire + - Improve client property checks. + - Allow non-power-of-2 quantums when forced. + - Improve rate switching. In some cases the graph rate would not switch + correctly. (#2929) + - The PIPEWIRE_QUANTUM env variable now forces the size and rate in the + graph for the duration of the application. The softer PIPEWIRE_LATENCY + and PIPEWIRE_RATE can still be used to merely suggest a maximum latency + and a rate. + +## modules + - Remove the RTSP FLUSH request in RAOP because it does not seem necessary. + - The RAOP module now uses the common RTP stream functions. + - Add sockets option to protocol-native to make pipewire listen on multiple + sockets. + +## SPA + - Clean up some of the log functions. + - Add an option in ALSA to disable linking devices together. + - Only link pcms together when 1 capture and 1 playback pcm. For more complex + devices we can't be sure which ones can be linked. (#3556) + - disable tsched only when using linked devices. + - Add some extra checks in ALSA to avoid segfaults. (#3554) + - Add Tag support to alsa-sink and alsa-source. + - Use dynamic pod builder when we can. + - Set priority.driver on midi-bridge to allow it as a fallback driver. (#3562) + - Fix regression in alsa wakeups. (#3565) + - The PTP clock can now be found from the interface in node-driver. + +## pulse-server + - Some small cleanups and internal improvements. + - Add some memory debugging messages. + - Add Tag messages to streams. + +## Bluetooth + - Fix a leak in the SBC codecs for SCO. + +## JACK + - Patch up midi events in the destination buffer instead of writing to the + source buffer. (#3580) + - Group all jack clients together to avoid transport issues. (#3562) + +## ALSA-plugins + - Add also.deny option to block alsa clients from opening the PCM. + +Older versions: + + # PipeWire 0.3.81 (2023-10-06) This is the first 1.0 release candidate that is API and ABI compatible @@ -80,9 +145,6 @@ - jack_property now always manages to actually change the metadata because it waits for a roundtrip before exiting. -Older versions: - - # PipeWire 0.3.80 (2023-09-14) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.81.tar.gz/README.md -> pipewire-0.3.82.tar.gz/README.md
Changed
@@ -52,9 +52,8 @@ the samplerate. * `PIPEWIRE_RATE=<num/denom>` to configure a rate for the graph. * `PIPEWIRE_QUANTUM=<num/denom>` to configure latency as a fraction and a - samplerate. This function will attempt to change - the graph samplerate to `denom` and use the - specified `num` as the buffer size. + samplerate. This function will force the graph samplerate to + `denom` and force the specified `num` as the buffer size. * `PIPEWIRE_NODE=<id>` to request a link to the specified node. The id can be a node.name or object.serial of the target node.
View file
pipewire-0.3.81.tar.gz/meson.build -> pipewire-0.3.82.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.81', + version : '0.3.82', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3', @@ -232,6 +232,7 @@ 'sys/random.h', 'HAVE_SYS_RANDOM_H', 'sys/vfs.h', 'HAVE_SYS_VFS_H', 'pwd.h', 'HAVE_PWD_H', + 'grp.h', 'HAVE_GRP_H', foreach h : check_headers @@ -247,6 +248,10 @@ summary({'libsystemd': systemd_dep.found()}, bool_yn: true) cdata.set('HAVE_SYSTEMD', systemd.found() and systemd_dep.found()) +selinux_dep = dependency('libselinux', required: get_option('selinux')) +summary({'libselinux': selinux_dep.found()}, bool_yn: true) +cdata.set('HAVE_SELINUX', selinux_dep.found()) + configinc = include_directories('.') includes_inc = include_directories('include') pipewire_inc = include_directories('src') @@ -436,6 +441,7 @@ 'sigabbrev_np', '#include <string.h>', '-D_GNU_SOURCE', , 'XSetIOErrorExitHandler', '#include <X11/Xlib.h>', , x11_dep, 'malloc_trim', '#include <malloc.h>', , , + 'malloc_info', '#include <malloc.h>', , , foreach f : check_functions
View file
pipewire-0.3.81.tar.gz/meson_options.txt -> pipewire-0.3.82.tar.gz/meson_options.txt
Changed
@@ -42,6 +42,10 @@ description: 'Install systemd user service file (ignored without systemd)', type: 'feature', value: 'enabled') +option('selinux', + description: 'Enable SELinux integration', + type: 'feature', + value: 'auto') option('pipewire-alsa', description: 'Enable pipewire-alsa integration', type: 'feature',
View file
pipewire-0.3.81.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.82.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -1238,6 +1238,12 @@ if (str != NULL) pw_properties_update_string(pw->props, str, strlen(str)); + if ((str = pw_properties_get(pw->props, "alsa.deny")) != NULL && + spa_atob(str)) { + err = -EACCES; + goto error; + } + str = getenv("PIPEWIRE_NODE"); if (str != NULL && str0) pw_properties_set(pw->props, PW_KEY_TARGET_OBJECT, str);
View file
pipewire-0.3.81.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.82.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -1332,15 +1332,6 @@ return b.state.offset; } -static inline void fix_midi_event(uint8_t *data, size_t size) -{ - /* fixup NoteOn with vel 0 */ - if (size > 2 && (data0 & 0xF0) == 0x90 && data2 == 0x00) { - data0 = 0x80 + (data0 & 0x0F); - data2 = 0x40; - } -} - static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *b) { if (a->offset < b->offset) @@ -1373,6 +1364,29 @@ } } +static inline void fix_midi_event(uint8_t *data, size_t size) +{ + /* fixup NoteOn with vel 0 */ + if (size > 2 && (data0 & 0xF0) == 0x90 && data2 == 0x00) { + data0 = 0x80 + (data0 & 0x0F); + data2 = 0x40; + } +} + +static inline int midi_event_write(void *port_buffer, + jack_nframes_t time, + const jack_midi_data_t *data, + size_t data_size, bool fix) +{ + jack_midi_data_t *retbuf = jack_midi_event_reserve (port_buffer, time, data_size); + if (SPA_UNLIKELY(retbuf == NULL)) + return -ENOBUFS; + memcpy (retbuf, data, data_size); + if (fix) + fix_midi_event(retbuf, data_size); + return 0; +} + static void convert_to_midi(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi, bool fix) { struct spa_pod_control *cn_seq; @@ -1405,10 +1419,7 @@ uint8_t *data = SPA_POD_BODY(&next->value); size_t size = SPA_POD_BODY_SIZE(&next->value); - if (fix) - fix_midi_event(data, size); - - if ((res = jack_midi_event_write(midi, next->offset, data, size)) < 0) + if ((res = midi_event_write(midi, next->offset, data, size, fix)) < 0) pw_log_warn("midi %p: can't write event: %s", midi, spa_strerror(res)); break; @@ -3804,10 +3815,10 @@ if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { - pw_properties_setf(client->props, PW_KEY_NODE_RATE, + pw_properties_setf(client->props, PW_KEY_NODE_FORCE_RATE, "1/%u", q.denom); - pw_properties_setf(client->props, PW_KEY_NODE_LATENCY, - "%u/%u", q.num, q.denom); + pw_properties_setf(client->props, PW_KEY_NODE_FORCE_QUANTUM, + "%u", q.num); } else { pw_log_warn("invalid PIPEWIRE_QUANTUM: %s", str); } @@ -3828,7 +3839,7 @@ if (pw_properties_get(client->props, PW_KEY_NODE_NAME) == NULL) pw_properties_set(client->props, PW_KEY_NODE_NAME, client_name); if (pw_properties_get(client->props, PW_KEY_NODE_GROUP) == NULL) - pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "jack-%d", getpid()); + pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "group.dsp.0"); if (pw_properties_get(client->props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(client->props, PW_KEY_NODE_DESCRIPTION, client_name); if (pw_properties_get(client->props, PW_KEY_MEDIA_TYPE) == NULL) @@ -6924,11 +6935,7 @@ const jack_midi_data_t *data, size_t data_size) { - jack_midi_data_t *retbuf = jack_midi_event_reserve (port_buffer, time, data_size); - if (SPA_UNLIKELY(retbuf == NULL)) - return -ENOBUFS; - memcpy (retbuf, data, data_size); - return 0; + return midi_event_write(port_buffer, time, data, data_size, false); } SPA_EXPORT
View file
pipewire-0.3.81.tar.gz/spa/include/meson.build -> pipewire-0.3.82.tar.gz/spa/include/meson.build
Changed
@@ -15,7 +15,4 @@ spa_headers = 'spa' # used by doxygen install_subdir('spa', install_dir : get_option('includedir') / spa_name, - exclude_files : - 'utils/cleanup.h', - , )
View file
pipewire-0.3.81.tar.gz/spa/include/spa/pod/dynamic.h -> pipewire-0.3.82.tar.gz/spa/include/spa/pod/dynamic.h
Changed
@@ -10,6 +10,7 @@ #endif #include <spa/pod/builder.h> +#include <spa/utils/cleanup.h> struct spa_pod_dynamic_builder { struct spa_pod_builder b; @@ -23,14 +24,15 @@ struct spa_pod_dynamic_builder *d = (struct spa_pod_dynamic_builder*)data; int32_t old_size = d->b.size; int32_t new_size = SPA_ROUND_UP_N(size, d->extend); - void *old_data = d->b.data; + void *old_data = d->b.data, *new_data; if (old_data == d->data) d->b.data = NULL; - if ((d->b.data = realloc(d->b.data, new_size)) == NULL) + if ((new_data = realloc(d->b.data, new_size)) == NULL) return -errno; - if (old_data == d->data && d->b.data != old_data && old_size > 0) - memcpy(d->b.data, old_data, old_size); + if (old_data == d->data && new_data != old_data && old_size > 0) + memcpy(new_data, old_data, old_size); + d->b.data = new_data; d->b.size = new_size; return 0; } @@ -54,6 +56,10 @@ free(builder->b.data); } +SPA_DEFINE_AUTO_CLEANUP(spa_pod_dynamic_builder, struct spa_pod_dynamic_builder, { + spa_pod_dynamic_builder_clean(thing); +}) + #ifdef __cplusplus } /* extern "C" */ #endif
View file
pipewire-0.3.81.tar.gz/spa/include/spa/support/log.h -> pipewire-0.3.82.tar.gz/spa/include/spa/support/log.h
Changed
@@ -194,28 +194,29 @@ #define SPA_LOG_TOPIC(v, t) \ (struct spa_log_topic){ .version = (v), .topic = (t)} -#define spa_log_topic_init(l, topic) \ -do { \ - struct spa_log *_l = l; \ - if (SPA_LIKELY(_l)) { \ - struct spa_interface *_if = &_l->iface; \ - spa_interface_call(_if, struct spa_log_methods, \ - topic_init, 1, topic); \ - } \ -} while(0) - -/* Unused, left for backwards compat */ -#define spa_log_level_enabled(l,lev) ((l) && (l)->level >= (lev)) - -#define spa_log_level_topic_enabled(l,topic,lev) \ -({ \ - struct spa_log *_log = l; \ - enum spa_log_level _lev = _log ? _log->level : SPA_LOG_LEVEL_NONE; \ - struct spa_log_topic *_t = (struct spa_log_topic *)(topic); \ - if (_t && _t->has_custom_level) \ - _lev = _t->level; \ - _lev >= (lev); \ -}) +static inline void spa_log_topic_init(struct spa_log *log, struct spa_log_topic *topic) +{ + if (SPA_UNLIKELY(!log)) + return; + + spa_interface_call(&log->iface, struct spa_log_methods, topic_init, 1, topic); +} + +static inline bool spa_log_level_topic_enabled(const struct spa_log *log, + const struct spa_log_topic *topic, + enum spa_log_level level) +{ + enum spa_log_level max_level; + + if (topic && topic->has_custom_level) + max_level = topic->level; + else if (log) + max_level = log->level; + else + max_level = SPA_LOG_LEVEL_NONE; + + return level <= max_level; +} /* Transparently calls to version 0 log if v1 is not supported */ #define spa_log_logt(l,lev,topic,...) \
View file
pipewire-0.3.81.tar.gz/spa/include/spa/utils/cleanup.h -> pipewire-0.3.82.tar.gz/spa/include/spa/utils/cleanup.h
Changed
@@ -5,10 +5,48 @@ #ifndef SPA_UTILS_CLEANUP_H #define SPA_UTILS_CLEANUP_H -#if !defined(__has_attribute) || !__has_attribute(__cleanup__) -#error "attribute `cleanup` is required" +#define spa_exchange(var, new_value) \ +__extension__ ({ \ + __typeof__(var) *_ptr = &(var); \ + __typeof__(var) _old_value = *_ptr; \ + *_ptr = (new_value); \ + _old_value; \ +}) + +/* ========================================================================== */ + +#if __GNUC__ >= 10 || defined(__clang__) +#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) +#else +#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL) #endif +#define spa_clear_ptr(ptr, destructor) \ +__extension__ ({ \ + __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ + if (_old_value) \ + destructor(_old_value); \ + (void) 0; \ +}) + +/* ========================================================================== */ + +#include <unistd.h> + +#define spa_steal_fd(fd) spa_exchange((fd), -1) + +#define spa_clear_fd(fd) \ +__extension__ ({ \ + int _old_value = spa_steal_fd(fd), _res = 0; \ + if (_old_value >= 0) \ + _res = close(_old_value); \ + _res; \ +}) + +/* ========================================================================== */ + +#if defined(__has_attribute) && __has_attribute(__cleanup__) + #define spa_cleanup(func) __attribute__((__cleanup__(func))) #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ @@ -33,34 +71,10 @@ spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ _spa_autoptr_cleanup_type_ ## name -#define spa_exchange(var, new_value) \ -__extension__ ({ \ - __typeof__(var) *_ptr = &(var); \ - __typeof__(var) _old_value = *_ptr; \ - *_ptr = (new_value); \ - _old_value; \ -}) - -#if __GNUC__ >= 10 || defined(__clang__) -#define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) -#else -#define spa_steal_ptr(ptr) spa_exchange((ptr), NULL) -#endif - -#define spa_steal_fd(fd) spa_exchange((fd), -1) - /* ========================================================================== */ #include <stdlib.h> -#define spa_clear_ptr(ptr, destructor) \ -__extension__ ({ \ - __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ - if (_old_value) \ - destructor(_old_value); \ - (void) 0; \ -}) - static inline void _spa_autofree_cleanup_func(void *p) { free(*(void **) p); @@ -69,16 +83,6 @@ /* ========================================================================== */ -#include <unistd.h> - -#define spa_clear_fd(fd) \ -__extension__ ({ \ - int _old_value = spa_steal_fd(fd), _res = 0; \ - if (_old_value >= 0) \ - _res = close(_old_value); \ - _res; \ -}) - static inline void _spa_autoclose_cleanup_func(int *fd) { spa_clear_fd(*fd); @@ -101,4 +105,11 @@ spa_clear_ptr(*thing, closedir); }) +#else + +#define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) +#define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) + +#endif + #endif /* SPA_UTILS_CLEANUP_H */
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
@@ -296,7 +296,7 @@ static int add_pro_profile(pa_card *impl, uint32_t index) { snd_ctl_t *ctl_hndl; - int err, dev, count = 0; + int err, dev, count = 0, n_capture = 0, n_playback = 0; pa_alsa_profile *ap; pa_alsa_profile_set *ps = impl->profile_set; pa_alsa_mapping *m; @@ -304,6 +304,7 @@ snd_pcm_info_t *pcminfo; pa_sample_spec ss; snd_pcm_uframes_t try_period_size, try_buffer_size; + uint32_t idx; if (impl->use_ucm) { const char *verb = find_best_verb(impl); @@ -388,11 +389,10 @@ pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm); pa_proplist_setf(m->output_proplist, "clock.name", "api.alsa.%u", index); pa_proplist_setf(m->output_proplist, "device.profile.pro", "true"); - pa_proplist_setf(m->output_proplist, "node.group", "pro-audio-%u", index); - pa_proplist_setf(m->output_proplist, "node.link-group", "pro-audio-%u", index); pa_alsa_close(&m->output_pcm); m->supported = true; pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX); + n_playback++; } pa_idxset_put(ap->output_mappings, m, NULL); free(name); @@ -421,11 +421,10 @@ pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm); pa_proplist_setf(m->input_proplist, "clock.name", "api.alsa.%u", index); pa_proplist_setf(m->input_proplist, "device.profile.pro", "true"); - pa_proplist_setf(m->input_proplist, "node.group", "pro-audio-%u", index); - pa_proplist_setf(m->input_proplist, "node.link-group", "pro-audio-%u", index); pa_alsa_close(&m->input_pcm); m->supported = true; pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX); + n_capture++; } pa_idxset_put(ap->input_mappings, m, NULL); free(name); @@ -433,6 +432,20 @@ } snd_ctl_close(ctl_hndl); + if (n_capture == 1 && n_playback == 1) { + PA_IDXSET_FOREACH(m, ap->output_mappings, idx) { + pa_proplist_setf(m->output_proplist, "node.group", "pro-audio-%u", index); + pa_proplist_setf(m->output_proplist, "node.link-group", "pro-audio-%u", index); + pa_proplist_setf(m->output_proplist, "api.alsa.auto-link", "true"); + pa_proplist_setf(m->output_proplist, "api.alsa.disable-tsched", "true"); + } + PA_IDXSET_FOREACH(m, ap->input_mappings, idx) { + pa_proplist_setf(m->input_proplist, "node.group", "pro-audio-%u", index); + pa_proplist_setf(m->input_proplist, "node.link-group", "pro-audio-%u", index); + pa_proplist_setf(m->input_proplist, "api.alsa.auto-link", "true"); + pa_proplist_setf(m->input_proplist, "api.alsa.disable-tsched", "true"); + } + } return 0; }
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-acp-device.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-acp-device.c
Changed
@@ -26,6 +26,7 @@ #include <spa/param/param.h> #include <spa/pod/filter.h> #include <spa/pod/parser.h> +#include <spa/pod/dynamic.h> #include <spa/debug/pod.h> #include <spa/debug/log.h> @@ -484,7 +485,8 @@ { struct impl *this = object; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; uint8_t buffer4096; struct spa_result_device_params result; uint32_t count = 0; @@ -496,6 +498,9 @@ spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + card = this->card; result.id = id; @@ -503,7 +508,7 @@ next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_EnumProfile: @@ -511,7 +516,7 @@ return 0; pr = card->profilesresult.index; - param = build_profile(&b, id, pr, false); + param = build_profile(&b.b, id, pr, false); break; case SPA_PARAM_Profile: @@ -519,7 +524,7 @@ return 0; pr = card->profilescard->active_profile_index; - param = build_profile(&b, id, pr, true); + param = build_profile(&b.b, id, pr, true); break; case SPA_PARAM_EnumRoute: @@ -527,7 +532,7 @@ return 0; p = card->portsresult.index; - param = build_route(&b, id, p, NULL, SPA_ID_INVALID); + param = build_route(&b.b, id, p, NULL, SPA_ID_INVALID); break; case SPA_PARAM_Route: @@ -543,7 +548,7 @@ result.index++; } result.next = result.index + 1; - param = build_route(&b, id, p, dev, card->active_profile_index); + param = build_route(&b.b, id, p, dev, card->active_profile_index); if (param == NULL) return -errno; break; @@ -552,7 +557,7 @@ return -ENOENT; } - if (spa_pod_filter(&b, &result.param, param, filter) < 0) + if (spa_pod_filter(&b.b, &result.param, param, filter) < 0) goto next; spa_device_emit_result(&this->hooks, seq, 0,
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
@@ -15,6 +15,7 @@ #include <spa/utils/string.h> #include <spa/param/audio/format.h> #include <spa/pod/filter.h> +#include <spa/pod/dynamic.h> #include <spa/debug/log.h> #include <spa/debug/pod.h> @@ -100,7 +101,8 @@ { struct state *this = object; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; uint8_t buffer4096; struct spa_result_node_params result; uint32_t count = 0; @@ -108,12 +110,15 @@ spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + result.id = id; result.next = start; - next: +next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_PropInfo: @@ -122,7 +127,7 @@ switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device), SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH), @@ -130,21 +135,21 @@ SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device))); break; case 1: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName), SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"), SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name))); break; case 2: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName), SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"), SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name))); break; case 3: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec), SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"), @@ -153,7 +158,7 @@ case 4: if (!this->is_iec958 && !this->is_hdmi) goto next; - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_iec958Codecs), SPA_PROP_INFO_name, SPA_POD_String("iec958.codecs"), @@ -163,7 +168,7 @@ SPA_PROP_INFO_container, SPA_POD_Id(SPA_TYPE_Array)); break; default: - param = spa_alsa_enum_propinfo(this, result.index - 5, &b); + param = spa_alsa_enum_propinfo(this, result.index - 5, &b.b); if (param == NULL) return 0; } @@ -177,9 +182,9 @@ switch (result.index) { case 0: - spa_pod_builder_push_object(&b, &f, + spa_pod_builder_push_object(&b.b, &f, SPA_TYPE_OBJECT_Props, id); - spa_pod_builder_add(&b, + spa_pod_builder_add(&b.b, SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)), SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)), SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)), @@ -188,12 +193,12 @@ if (this->is_iec958 || this->is_hdmi) { n_codecs = spa_alsa_get_iec958_codecs(this, codecs, SPA_N_ELEMENTS(codecs)); - spa_pod_builder_prop(&b, SPA_PROP_iec958Codecs, 0); - spa_pod_builder_array(&b, sizeof(uint32_t), SPA_TYPE_Id, + spa_pod_builder_prop(&b.b, SPA_PROP_iec958Codecs, 0); + spa_pod_builder_array(&b.b, sizeof(uint32_t), SPA_TYPE_Id, n_codecs, codecs); } - spa_alsa_add_prop_params(this, &b); - param = spa_pod_builder_pop(&b, &f); + spa_alsa_add_prop_params(this, &b.b); + param = spa_pod_builder_pop(&b.b, &f); break; default: return 0; @@ -203,13 +208,13 @@ case SPA_PARAM_IO: switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamIO, id, SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock), SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock))); break; case 1: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamIO, id, SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position), SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position))); @@ -222,7 +227,7 @@ case SPA_PARAM_ProcessLatency: switch (result.index) { case 0: - param = spa_process_latency_build(&b, id, &this->process_latency); + param = spa_process_latency_build(&b.b, id, &this->process_latency); break; default: return 0; @@ -233,7 +238,7 @@ return -ENOENT; } - if (spa_pod_filter(&b, &result.param, param, filter) < 0) + if (spa_pod_filter(&b.b, &result.param, param, filter) < 0) goto next; spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); @@ -469,7 +474,8 @@ struct state *this = object; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; uint8_t buffer1024; struct spa_result_node_params result; uint32_t count = 0; @@ -479,12 +485,15 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + result.id = id; result.next = start; next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_EnumFormat: @@ -498,15 +507,15 @@ switch (this->current_format.media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - param = spa_format_audio_raw_build(&b, id, + param = spa_format_audio_raw_build(&b.b, id, &this->current_format.info.raw); break; case SPA_MEDIA_SUBTYPE_iec958: - param = spa_format_audio_iec958_build(&b, id, + param = spa_format_audio_iec958_build(&b.b, id, &this->current_format.info.iec958); break; case SPA_MEDIA_SUBTYPE_dsd: - param = spa_format_audio_dsd_build(&b, id, + param = spa_format_audio_dsd_build(&b.b, id, &this->current_format.info.dsd); break; default: @@ -520,7 +529,7 @@ if (result.index > 0) return 0;
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
@@ -16,6 +16,7 @@ #include <spa/monitor/device.h> #include <spa/param/audio/format.h> #include <spa/pod/filter.h> +#include <spa/pod/dynamic.h> #include "alsa.h" @@ -100,7 +101,8 @@ struct state *this = object; struct spa_pod *param; uint8_t buffer4096; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; struct props *p; struct spa_result_node_params result; uint32_t count = 0; @@ -108,6 +110,9 @@ spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + p = &this->props; result.id = id; @@ -115,13 +120,13 @@ next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_PropInfo: switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_device), SPA_PROP_INFO_name, SPA_POD_String(SPA_KEY_API_ALSA_PATH), @@ -129,28 +134,28 @@ SPA_PROP_INFO_type, SPA_POD_Stringn(p->device, sizeof(p->device))); break; case 1: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_deviceName), SPA_PROP_INFO_description, SPA_POD_String("The ALSA device name"), SPA_PROP_INFO_type, SPA_POD_Stringn(p->device_name, sizeof(p->device_name))); break; case 2: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_cardName), SPA_PROP_INFO_description, SPA_POD_String("The ALSA card name"), SPA_PROP_INFO_type, SPA_POD_Stringn(p->card_name, sizeof(p->card_name))); break; case 3: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec), SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"), SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, 0LL, 2 * SPA_NSEC_PER_SEC)); break; default: - param = spa_alsa_enum_propinfo(this, result.index - 4, &b); + param = spa_alsa_enum_propinfo(this, result.index - 4, &b.b); if (param == NULL) return 0; } @@ -162,16 +167,16 @@ switch (result.index) { case 0: - spa_pod_builder_push_object(&b, &f, + spa_pod_builder_push_object(&b.b, &f, SPA_TYPE_OBJECT_Props, id); - spa_pod_builder_add(&b, + spa_pod_builder_add(&b.b, SPA_PROP_device, SPA_POD_Stringn(p->device, sizeof(p->device)), SPA_PROP_deviceName, SPA_POD_Stringn(p->device_name, sizeof(p->device_name)), SPA_PROP_cardName, SPA_POD_Stringn(p->card_name, sizeof(p->card_name)), SPA_PROP_latencyOffsetNsec, SPA_POD_Long(this->process_latency.ns), 0); - spa_alsa_add_prop_params(this, &b); - param = spa_pod_builder_pop(&b, &f); + spa_alsa_add_prop_params(this, &b.b); + param = spa_pod_builder_pop(&b.b, &f); break; default: return 0; @@ -181,13 +186,13 @@ case SPA_PARAM_IO: switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamIO, id, SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Clock), SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_clock))); break; case 1: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamIO, id, SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Position), SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_position))); @@ -200,7 +205,7 @@ case SPA_PARAM_ProcessLatency: switch (result.index) { case 0: - param = spa_process_latency_build(&b, id, &this->process_latency); + param = spa_process_latency_build(&b.b, id, &this->process_latency); break; default: return 0; @@ -211,7 +216,7 @@ return -ENOENT; } - if (spa_pod_filter(&b, &result.param, param, filter) < 0) + if (spa_pod_filter(&b.b, &result.param, param, filter) < 0) goto next; spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); @@ -431,22 +436,25 @@ { struct state *this = object; struct spa_pod *param; - struct spa_pod_builder b = { 0 }; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; uint8_t buffer1024; struct spa_result_node_params result; uint32_t count = 0; spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); - spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + result.id = id; result.next = start; next: result.index = result.next++; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_EnumFormat: @@ -458,7 +466,7 @@ if (result.index > 0) return 0; - param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); + param = spa_format_audio_raw_build(&b.b, id, &this->current_format.info.raw); break; case SPA_PARAM_Buffers: @@ -467,7 +475,7 @@ if (result.index > 0) return 0; - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamBuffers, id, SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(this->blocks), @@ -481,7 +489,7 @@ case SPA_PARAM_Meta: switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamMeta, id, SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))); @@ -494,13 +502,13 @@ case SPA_PARAM_IO: switch (result.index) { case 0: - param = spa_pod_builder_add_object(&b, + param = spa_pod_builder_add_object(&b.b, SPA_TYPE_OBJECT_ParamIO, id, SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers), SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers))); break; case 1: - param = spa_pod_builder_add_object(&b,
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -131,6 +131,8 @@ state->multi_rate = spa_atob(s); } else if (spa_streq(k, "api.alsa.htimestamp")) { state->htimestamp = spa_atob(s); + } else if (spa_streq(k, "api.alsa.auto-link")) { + state->auto_link = spa_atob(s); } else if (spa_streq(k, "latency.internal.rate")) { state->process_latency.rate = atoi(s); } else if (spa_streq(k, "latency.internal.ns")) { @@ -512,7 +514,6 @@ state->multi_rate = true; state->htimestamp = false; - state->disable_tsched = state->is_pro; for (i = 0; info && i < info->n_items; i++) { const char *k = info->itemsi.key; const char *s = info->itemsi.value; @@ -574,6 +575,9 @@ spa_log_warn(state->log, "output close failed: %s", snd_strerror(err)); fclose(state->log_file); + free(state->tag0); + free(state->tag1); + return err; } @@ -1991,7 +1995,7 @@ CHECK(set_swparams(state), "swparams"); - if ((err = snd_pcm_prepare(state->hndl)) < 0 && err != -EBUSY) { + if ((!state->linked) && (err = snd_pcm_prepare(state->hndl)) < 0 && err != -EBUSY) { spa_log_error(state->log, "%s: snd_pcm_prepare error: %s", state->name, snd_strerror(err)); return err; @@ -2398,10 +2402,13 @@ if (SPA_UNLIKELY((res = check_position_config(state)) < 0)) return res; - if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) + if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) { + spa_log_error(state->log, "get_status error"); + state->next_time += state->threshold * 1e9 / state->rate; return res; + } - if (SPA_UNLIKELY(!following && delay > target + state->max_error)) { + if (SPA_UNLIKELY(!following && state->alsa_started && delay > target + state->max_error)) { spa_log_trace(state->log, "%p: early wakeup %ld %lu %lu", state, avail, delay, target); if (delay > target * 3) @@ -2412,7 +2419,7 @@ if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, following)) < 0)) return res; - if (following && !state->linked) { + if (following && state->alsa_started && !state->linked) { if (SPA_UNLIKELY(state->alsa_sync)) { enum spa_log_level lev; @@ -2553,11 +2560,9 @@ int spa_alsa_write(struct state *state) { - int res = 0; if (state->following && state->rt.driver == NULL) { uint64_t current_time = state->position->clock.nsec; - if ((res = alsa_write_sync(state, current_time)) < 0) - return res; + alsa_write_sync(state, current_time); } return alsa_write_frames(state); } @@ -2656,8 +2661,11 @@ if (SPA_UNLIKELY((res = check_position_config(state)) < 0)) return res; - if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) + if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) { + spa_log_error(state->log, "get_status error"); + state->next_time += state->threshold * 1e9 / state->rate; return res; + } if (SPA_UNLIKELY(!following && avail < state->read_size)) { spa_log_trace(state->log, "%p: early wakeup %ld %ld %ld %d", state, @@ -2671,7 +2679,7 @@ return res; max_read = state->buffer_frames; - if (following) { + if (following && !state->linked) { if (state->alsa_sync) { enum spa_log_level lev; @@ -2767,11 +2775,9 @@ int spa_alsa_read(struct state *state) { - int res; if (state->following && state->rt.driver == NULL) { uint64_t current_time = state->position->clock.nsec; - if ((res = alsa_read_sync(state, current_time)) < 0) - return res; + alsa_read_sync(state, current_time); } return alsa_read_frames(state); } @@ -3019,6 +3025,9 @@ struct state *follower; int err; + if (!state->opened) + return -EIO; + spa_alsa_pause(state); if (state->prepared) @@ -3034,7 +3043,7 @@ spa_list_for_each(follower, &state->followers, driver_link) { if (follower != state && !follower->matching) { spa_alsa_prepare(follower); - if (!follower->linked) + if (!follower->linked && state->auto_link) do_link(state, follower); } } @@ -3051,6 +3060,8 @@ if (state->started) return 0; + else if (!state->opened) + return -EIO; spa_alsa_prepare(state);
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -30,6 +30,7 @@ #include <spa/param/param.h> #include <spa/param/latency-utils.h> #include <spa/param/audio/format-utils.h> +#include <spa/param/tag-utils.h> #include "alsa.h" @@ -165,7 +166,8 @@ #define PORT_Format 3 #define PORT_Buffers 4 #define PORT_Latency 5 -#define N_PORT_PARAMS 6 +#define PORT_Tag 6 +#define N_PORT_PARAMS 7 struct spa_param_info port_paramsN_PORT_PARAMS; enum spa_direction port_direction; struct spa_io_buffers *io; @@ -214,6 +216,7 @@ unsigned int htimestamp:1; unsigned int is_pro:1; unsigned int sources_added:1; + unsigned int auto_link:1; unsigned int linked:1; uint64_t iec958_codecs; @@ -233,6 +236,8 @@ struct spa_latency_info latency2; struct spa_process_latency_info process_latency; + struct spa_pod *tag2; + /* Rate match via an ALSA ctl */ snd_ctl_t *ctl; snd_ctl_elem_value_t *pitch_elem;
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c
Changed
@@ -195,6 +195,7 @@ { SPA_KEY_DEVICE_API, "alsa" }, { SPA_KEY_MEDIA_CLASS, "Midi/Bridge" }, { SPA_KEY_NODE_DRIVER, "true" }, + { "priority.driver", "1" }, }; static void emit_node_info(struct seq_state *this, bool full)
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa.c -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa.c
Changed
@@ -9,6 +9,8 @@ #include <spa/support/plugin.h> #include <spa/support/log.h> +#include "alsa.h" + extern const struct spa_handle_factory spa_alsa_source_factory; extern const struct spa_handle_factory spa_alsa_sink_factory; extern const struct spa_handle_factory spa_alsa_udev_factory; @@ -20,8 +22,7 @@ extern const struct spa_handle_factory spa_alsa_compress_offload_device_factory; #endif -struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.alsa"); -struct spa_log_topic *alsa_log_topic = &log_topic; +struct spa_log_topic alsa_log_topic = SPA_LOG_TOPIC(0, "spa.alsa"); SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
View file
pipewire-0.3.81.tar.gz/spa/plugins/alsa/alsa.h -> pipewire-0.3.82.tar.gz/spa/plugins/alsa/alsa.h
Changed
@@ -8,12 +8,12 @@ #include <spa/support/log.h> #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT alsa_log_topic -extern struct spa_log_topic *alsa_log_topic; +#define SPA_LOG_TOPIC_DEFAULT &alsa_log_topic +extern struct spa_log_topic alsa_log_topic; static inline void alsa_log_topic_init(struct spa_log *log) { - spa_log_topic_init(log, alsa_log_topic); + spa_log_topic_init(log, &alsa_log_topic); } #endif /* SPA_ALSA_H */
View file
pipewire-0.3.81.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -26,8 +26,8 @@ #include <spa/debug/log.h> #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT log_topic -static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audioadapter"); +#define SPA_LOG_TOPIC_DEFAULT &log_topic +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audioadapter"); #define DEFAULT_ALIGN 16 @@ -153,7 +153,8 @@ { struct impl *this = object; uint8_t buffer4096; - struct spa_pod_dynamic_builder b; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; struct spa_result_node_params result; uint32_t count = 0; int res; @@ -161,6 +162,9 @@ spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_get_state(&b.b, &state); + result.id = id; result.next = start; next: @@ -168,7 +172,7 @@ spa_log_debug(this->log, "%p: %d id:%u", this, seq, id); - spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_EnumPortConfig: @@ -215,16 +219,12 @@ default: return -ENOENT; } - - if (res == 1) { - spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); - count++; - } - spa_pod_dynamic_builder_clean(&b); - if (res != 1) return res; + spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); + count++; + if (count != num) goto next; @@ -580,8 +580,9 @@ static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_direction direction, uint32_t port_id, struct spa_node *dst) { - struct spa_pod_builder b = { 0 }; - uint8_t buffer1024; + spa_auto(spa_pod_dynamic_builder) b = { 0 }; + struct spa_pod_builder_state state; + uint8_t buffer2048; struct spa_pod *param; uint32_t index = 0; struct spa_tag_info info; @@ -592,26 +593,25 @@ if (this->target == this->follower) return 0; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 2048); + spa_pod_builder_get_state(&b.b, &state); + while (true) { - void *state = NULL; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + void *tag_state = NULL; + spa_pod_builder_reset(&b.b, &state); if ((res = spa_node_port_enum_params_sync(src, direction, port_id, SPA_PARAM_Tag, - &index, NULL, ¶m, &b)) != 1) { + &index, NULL, ¶m, &b.b)) != 1) { param = NULL; break; } - if ((res = spa_tag_parse(param, &info, &state)) < 0) + if ((res = spa_tag_parse(param, &info, &tag_state)) < 0) return res; if (info.direction == direction) break; } - if ((res = spa_node_port_set_param(dst, - SPA_DIRECTION_REVERSE(direction), 0, - SPA_PARAM_Tag, 0, param)) < 0) - return res; - - return 0; + return spa_node_port_set_param(dst, SPA_DIRECTION_REVERSE(direction), 0, + SPA_PARAM_Tag, 0, param); } @@ -1755,7 +1755,7 @@ this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - spa_log_topic_init(this->log, log_topic); + spa_log_topic_init(this->log, &log_topic); this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
View file
pipewire-0.3.81.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.82.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -36,8 +36,8 @@ #include "wavfile.h" #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT log_topic -static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audioconvert"); +#define SPA_LOG_TOPIC_DEFAULT &log_topic +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audioconvert"); #define DEFAULT_RATE 48000 #define DEFAULT_CHANNELS 2 @@ -3354,7 +3354,7 @@ this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - spa_log_topic_init(this->log, log_topic); + spa_log_topic_init(this->log, &log_topic); this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); if (this->cpu) {
View file
pipewire-0.3.81.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
@@ -23,8 +23,8 @@ #include "mix-ops.h" #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT log_topic -static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.audiomixer"); +#define SPA_LOG_TOPIC_DEFAULT &log_topic +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.audiomixer"); #define DEFAULT_RATE 48000 #define DEFAULT_CHANNELS 2 @@ -918,7 +918,7 @@ this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - spa_log_topic_init(this->log, log_topic); + spa_log_topic_init(this->log, &log_topic); this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop); if (this->data_loop == NULL) {
View file
pipewire-0.3.81.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.82.tar.gz/spa/plugins/audiomixer/mixer-dsp.c
Changed
@@ -23,8 +23,8 @@ #include "mix-ops.h" #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT log_topic -static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.mixer-dsp"); +#define SPA_LOG_TOPIC_DEFAULT &log_topic +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.mixer-dsp"); #define MAX_BUFFERS 64 #define MAX_PORTS 512 @@ -855,7 +855,7 @@ this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - spa_log_topic_init(this->log, log_topic); + spa_log_topic_init(this->log, &log_topic); this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop); if (this->data_loop == NULL) {
View file
pipewire-0.3.81.tar.gz/spa/plugins/avb/avb.c -> pipewire-0.3.82.tar.gz/spa/plugins/avb/avb.c
Changed
@@ -7,11 +7,12 @@ #include <spa/support/plugin.h> #include <spa/support/log.h> +#include "avb.h" + extern const struct spa_handle_factory spa_avb_sink_factory; extern const struct spa_handle_factory spa_avb_source_factory; -struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.avb"); -struct spa_log_topic *avb_log_topic = &log_topic; +struct spa_log_topic avb_log_topic = SPA_LOG_TOPIC(0, "spa.avb"); SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index)
View file
pipewire-0.3.81.tar.gz/spa/plugins/avb/avb.h -> pipewire-0.3.82.tar.gz/spa/plugins/avb/avb.h
Changed
@@ -8,12 +8,12 @@ #include <spa/support/log.h> #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT avb_log_topic -extern struct spa_log_topic *avb_log_topic; +#define SPA_LOG_TOPIC_DEFAULT &avb_log_topic +extern struct spa_log_topic avb_log_topic; static inline void avb_log_topic_init(struct spa_log *log) { - spa_log_topic_init(log, avb_log_topic); + spa_log_topic_init(log, &avb_log_topic); } #endif /* SPA_AVB_H */
View file
pipewire-0.3.81.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.82.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
@@ -662,7 +662,9 @@ /* Init mSBC if needed */ if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) { - sbc_init_msbc(&this->msbc, 0); + res = sbc_init_msbc(&this->msbc, 0); + if (res < 0) + return res; /* Libsbc expects audio samples by default in host endianness, mSBC requires little endian */ this->msbc.endian = SBC_LE; @@ -705,6 +707,7 @@ fail: free(this->buffer); this->buffer = NULL; + sbc_finish(&this->msbc); return res; } @@ -819,6 +822,8 @@ this->buffer = NULL; this->buffer_head = this->buffer_next = this->buffer; } + + sbc_finish(&this->msbc); } static int do_stop(struct impl *this)
View file
pipewire-0.3.81.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.82.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
@@ -687,7 +687,10 @@ /* Init mSBC if needed */ if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) { - sbc_init_msbc(&this->msbc, 0); + res = sbc_init_msbc(&this->msbc, 0); + if (res < 0) + return res; + /* Libsbc expects audio samples by default in host endianness, mSBC requires little endian */ this->msbc.endian = SBC_LE; this->msbc_seq_initialized = false; @@ -708,6 +711,7 @@ return 0; fail: + sbc_finish(&this->msbc); return res; } @@ -798,6 +802,8 @@ spa_loop_invoke(this->data_loop, do_remove_transport_source, 0, NULL, 0, true, this); spa_bt_decode_buffer_clear(&port->buffer); + + sbc_finish(&this->msbc); } static int do_stop(struct impl *this)
View file
pipewire-0.3.81.tar.gz/spa/plugins/libcamera/libcamera.c -> pipewire-0.3.82.tar.gz/spa/plugins/libcamera/libcamera.c
Changed
@@ -9,8 +9,7 @@ #include "libcamera.h" -struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.libcamera"); -struct spa_log_topic *libcamera_log_topic = &log_topic; +struct spa_log_topic libcamera_log_topic = SPA_LOG_TOPIC(0, "spa.libcamera"); SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory,
View file
pipewire-0.3.81.tar.gz/spa/plugins/libcamera/libcamera.h -> pipewire-0.3.82.tar.gz/spa/plugins/libcamera/libcamera.h
Changed
@@ -18,12 +18,12 @@ extern const struct spa_handle_factory spa_libcamera_device_factory; #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT libcamera_log_topic -extern struct spa_log_topic *libcamera_log_topic; +#define SPA_LOG_TOPIC_DEFAULT &libcamera_log_topic +extern struct spa_log_topic libcamera_log_topic; static inline void libcamera_log_topic_init(struct spa_log *log) { - spa_log_topic_init(log, libcamera_log_topic); + spa_log_topic_init(log, &libcamera_log_topic); } #ifdef __cplusplus
View file
pipewire-0.3.81.tar.gz/spa/plugins/support/log-patterns.c -> pipewire-0.3.82.tar.gz/spa/plugins/support/log-patterns.c
Changed
@@ -22,6 +22,7 @@ struct spa_log_topic *t) { enum spa_log_level level = default_level; + bool has_custom_level = false; const char *topic = t->topic; struct support_log_pattern *pattern; @@ -29,10 +30,11 @@ if (fnmatch(pattern->pattern, topic, 0) != 0) continue; level = pattern->level; - t->has_custom_level = true; + has_custom_level = true; } t->level = level; + t->has_custom_level = has_custom_level; } int
View file
pipewire-0.3.81.tar.gz/spa/plugins/support/node-driver.c -> pipewire-0.3.82.tar.gz/spa/plugins/support/node-driver.c
Changed
@@ -8,6 +8,11 @@ #include <string.h> #include <stdio.h> #include <fcntl.h> +#if !defined(__FreeBSD__) && !defined(__MidnightBSD__) +#include <linux/ethtool.h> +#include <linux/sockios.h> +#endif +#include <net/if.h> #include <spa/support/plugin.h> #include <spa/support/log.h> @@ -485,6 +490,33 @@ return sizeof(struct impl); } +int get_phc_index(struct spa_system *s, const char *name) { +#ifdef ETHTOOL_GET_TS_INFO + struct ethtool_ts_info info = {0}; + struct ifreq ifr = {0}; + int fd, err; + + info.cmd = ETHTOOL_GET_TS_INFO; + strncpy(ifr.ifr_name, name, IFNAMSIZ - 1); + ifr.ifr_data = (char *) &info; + fd = socket(AF_INET, SOCK_DGRAM, 0); + + if (fd < 0) { + return -1; + } + + err = spa_system_ioctl(s, fd, SIOCETHTOOL, &ifr); + close(fd); + if (err < 0) { + return err; + } + + return info.phc_index; +#else + return -1; +#endif +} + static int impl_init(const struct spa_handle_factory *factory, struct spa_handle *handle, @@ -553,9 +585,28 @@ this->props.clock_id = DEFAULT_CLOCK_ID; } } else if (spa_streq(k, "clock.device")) { + if (this->clock_fd >= 0) { + close(this->clock_fd); + } this->clock_fd = open(s, O_RDWR); + + if (this->clock_fd == -1) { + spa_log_warn(this->log, "failed to open clock device '%s'", s); + } else { + this->props.clock_id = FD_TO_CLOCKID(this->clock_fd); + } + } else if (spa_streq(k, "clock.interface") && this->clock_fd < 0) { + int phc_index = get_phc_index(this->data_system, s); + if (phc_index < 0) { + spa_log_warn(this->log, "failed to get phc device index for interface '%s'", s); + } else { + char dev19; + spa_scnprintf(dev, sizeof(dev), "/dev/ptp%d", phc_index); + this->clock_fd = open(dev, O_RDWR); + } + if (this->clock_fd == -1) { - spa_log_info(this->log, "failed to open clock device '%s'", s); + spa_log_warn(this->log, "failed to open clock device '%s'", s); } else { this->props.clock_id = FD_TO_CLOCKID(this->clock_fd); }
View file
pipewire-0.3.81.tar.gz/spa/plugins/v4l2/v4l2.c -> pipewire-0.3.82.tar.gz/spa/plugins/v4l2/v4l2.c
Changed
@@ -7,12 +7,13 @@ #include <spa/support/plugin.h> #include <spa/support/log.h> +#include "v4l2.h" + extern const struct spa_handle_factory spa_v4l2_source_factory; extern const struct spa_handle_factory spa_v4l2_udev_factory; extern const struct spa_handle_factory spa_v4l2_device_factory; -struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.v4l2"); -struct spa_log_topic *v4l2_log_topic = &log_topic; +struct spa_log_topic v4l2_log_topic = SPA_LOG_TOPIC(0, "spa.v4l2"); SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory,
View file
pipewire-0.3.81.tar.gz/spa/plugins/v4l2/v4l2.h -> pipewire-0.3.82.tar.gz/spa/plugins/v4l2/v4l2.h
Changed
@@ -4,15 +4,17 @@ #include <errno.h> +#include <linux/videodev2.h> + #include <spa/support/log.h> #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT v4l2_log_topic -extern struct spa_log_topic *v4l2_log_topic; +#define SPA_LOG_TOPIC_DEFAULT &v4l2_log_topic +extern struct spa_log_topic v4l2_log_topic; static inline void v4l2_log_topic_init(struct spa_log *log) { - spa_log_topic_init(log, v4l2_log_topic); + spa_log_topic_init(log, &v4l2_log_topic); } struct spa_v4l2_device {
View file
pipewire-0.3.81.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.82.tar.gz/spa/plugins/videoconvert/videoadapter.c
Changed
@@ -25,8 +25,8 @@ #include <spa/debug/log.h> #undef SPA_LOG_TOPIC_DEFAULT -#define SPA_LOG_TOPIC_DEFAULT log_topic -static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.videoadapter"); +#define SPA_LOG_TOPIC_DEFAULT &log_topic +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.videoadapter"); #define DEFAULT_ALIGN 16 @@ -1554,7 +1554,7 @@ this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); - spa_log_topic_init(this->log, log_topic); + spa_log_topic_init(this->log, &log_topic); this->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
View file
pipewire-0.3.81.tar.gz/src/daemon/client-rt.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/client-rt.conf.in
Changed
@@ -111,6 +111,7 @@ alsa.properties = { + #alsa.deny = false # ALSA params take a single value, an array of values # or a range { min=.. max=... } #alsa.access = MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED
View file
pipewire-0.3.81.tar.gz/src/daemon/pipewire-aes67.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/pipewire-aes67.conf.in
Changed
@@ -23,9 +23,11 @@ } context.objects = - # An example clock reading from /dev/ptp0. Another option is to sync the - # ptp clock to CLOCK_TAI and then set clock.id = tai. - # If both device and ID are given and available, device takes precedence + # An example clock reading from /dev/ptp0. You can also specify the network interface name, + # pipewire will query the interface for the current active PHC index. Another option is to + # sync the ptp clock to CLOCK_TAI and then set clock.id = tai, keep in mind that tai may + # also be synced by a NTP client. + # The precedence is: device, interface, id { factory = spa-node-factory args = { factory.name = support.node.driver @@ -34,8 +36,9 @@ # This driver should only be used for network nodes marked with group priority.driver = 0 clock.name = "clock.system.ptp0" + #clock.id = tai clock.device = "/dev/ptp0" - clock.id = tai + #clock.interface = "eth0" object.export = true } }
View file
pipewire-0.3.81.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.82.tar.gz/src/daemon/pipewire.conf.in
Changed
@@ -102,7 +102,12 @@ } # The native communication protocol. - { name = libpipewire-module-protocol-native } + { name = libpipewire-module-protocol-native + args = { + # List of server Unix sockets, and optionally permissions + #sockets = { name = "pipewire-0" }, { name = "pipewire-manager-0" } + } + } # The profile module. Allows application to access profiler # and performance data. It provides an interface that is used
View file
pipewire-0.3.81.tar.gz/src/modules/flatpak-utils.h -> pipewire-0.3.82.tar.gz/src/modules/flatpak-utils.h
Changed
@@ -76,20 +76,20 @@ spa_autoclose int root_fd = openat(AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); if (root_fd < 0) { res = -errno; + pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); + if (res == -EACCES) { - struct statfs buf; - /* Access to the root dir isn't allowed. This can happen if the root is on a fuse - * filesystem, such as in a toolbox container. We will never have a fuse rootfs - * in the flatpak case, so in that case its safe to ignore this and - * continue to detect other types of apps. */ - if (statfs(root_path, &buf) == 0 && - buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */ - return 0; + /* If we can't access the root filesystem, consider not sandboxed. + * This should not happen but for now it is a workaround for selinux + * where we can't access the gnome-shell root when it connects for + * screen sharing. + */ + return 0; } + /* Not able to open the root dir shouldn't happen. Probably the app died and * we're failing due to /proc/$pid not existing. In that case fail instead * of treating this as privileged. */ - pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); return res; }
View file
pipewire-0.3.81.tar.gz/src/modules/meson.build -> pipewire-0.3.82.tar.gz/src/modules/meson.build
Changed
@@ -313,6 +313,10 @@ pipewire_module_protocol_deps += systemd_dep endif +if selinux_dep.found() + pipewire_module_protocol_deps += selinux_dep +endif + pipewire_module_protocol_native = shared_library('pipewire-module-protocol-native', 'module-protocol-native.c', 'module-protocol-native/local-socket.c', @@ -607,12 +611,13 @@ if build_module_raop pipewire_module_raop_sink = shared_library('pipewire-module-raop-sink', 'module-raop-sink.c', - 'module-raop/rtsp-client.c' , + 'module-raop/rtsp-client.c', + 'module-rtp/stream.c' , include_directories : configinc, install : true, install_dir : modules_install_dir, install_rpath: modules_install_dir, - dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, openssl_lib, + dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, opus_dep, openssl_lib, ) endif summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules')
View file
pipewire-0.3.81.tar.gz/src/modules/module-access.c -> pipewire-0.3.82.tar.gz/src/modules/module-access.c
Changed
@@ -263,17 +263,11 @@ res = pw_check_flatpak(pid, &flatpak_app_id, NULL); if (res != 0) { - if (res < 0) { - if (res == -EACCES) { - access = "unrestricted"; - goto granted; - } + if (res < 0) pw_log_warn("%p: client %p sandbox check failed: %s", impl, client, spa_strerror(res)); - } - else if (res > 0) { + else pw_log_debug(" %p: flatpak client %p added", impl, client); - } access = "flatpak"; itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id", flatpak_app_id);
View file
pipewire-0.3.81.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.82.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -147,7 +147,9 @@ * * Normally the volume of the sink/source is handled by the stream software volume. * With the capture.volumes and playback.volumes properties this can be handled - * by a control port in the graph instead. + * by a control port in the graph instead. Use capture.volumes for the volume of the + * input of the filter (when for example used as a sink). Use playback,volumes for + * the volume of the output of the filter (when for example used as a source). * * The min and max values (defaults 0.0 and 1.0) respectively can be used to scale * and translate the volume min and max values. @@ -1947,7 +1949,7 @@ /** * { * control = name:portname - * min = <float, defaukt 0.0> + * min = <float, default 0.0> * max = <float, default 1.0> * scale = <string, default "linear", options "linear","cubic"> * }
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-native.c
Changed
@@ -15,9 +15,13 @@ #include <fcntl.h> #include <sys/file.h> #include <ctype.h> +#include <limits.h> #ifdef HAVE_PWD_H #include <pwd.h> #endif +#ifdef HAVE_GRP_H +#include <grp.h> +#endif #if defined(__FreeBSD__) || defined(__MidnightBSD__) #include <sys/ucred.h> #endif @@ -27,13 +31,19 @@ #include <spa/pod/builder.h> #include <spa/utils/result.h> #include <spa/utils/string.h> +#include <spa/utils/json.h> #ifdef HAVE_SYSTEMD #include <systemd/sd-daemon.h> #endif +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#endif + #include <pipewire/impl.h> #include <pipewire/extensions/protocol-native.h> +#include <pipewire/cleanup.h> #include "pipewire/private.h" @@ -63,7 +73,17 @@ * * ## Module Options * - * The module has no options. + * The module supports the following arguments: + * + * - `sockets`: ` { name = "socket-name", owner = "owner", group = "group", mode = "mode", selinux.context = "context" }, ... ` + * + * Array of Unix socket names and (optionally) owner/permissions to serve, + * if the context is a server. If not absolute paths, the sockets are created + * in the default runtime directory. If not specified, one socket with + * a default name is created. + * + * The permissions have no effect for sockets from Systemd socket activation. + * Those should be configured via the systemd.socket(5) mechanism. * * ## General Options * @@ -107,6 +127,13 @@ { name = libpipewire-module-protocol-native } * *\endcode + * + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-protocol-native, + * args = { sockets = { name = "pipewire-0" }, { name = "pipewire-1" } } } + * + *\endcode */ #ifndef UNIX_PATH_MAX @@ -165,12 +192,23 @@ free(impl); } +struct socket_info { + char *name; + uid_t uid; + gid_t gid; + int mode; + char *selinux_context; + unsigned int has_owner:1; + unsigned int has_mode:1; +}; + struct server { struct pw_protocol_server this; int fd_lock; struct sockaddr_un addr; char lock_addrUNIX_PATH_MAX + LOCK_SUFFIXLEN; + struct socket_info socket_info; struct pw_loop *loop; struct spa_source *source; @@ -540,6 +578,8 @@ if (props == NULL) goto exit; + pw_properties_set(props, PW_KEY_SEC_SOCKET, s->socket_info.name); + #if defined(__linux__) len = sizeof(ucred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) { @@ -789,6 +829,31 @@ return res; } +static int set_socket_permissions(struct server *s) +{ + struct socket_info *info = &s->socket_info; + const char *path = s->addr.sun_path; + + if (info->has_owner) + if (chown(path, info->uid, info->gid) < 0) + return -errno; + + if (info->has_mode) + if (chmod(path, info->mode) < 0) + return -errno; + + if (info->selinux_context) { +#ifdef HAVE_SELINUX + if (setfilecon(path, info->selinux_context) < 0) + return -errno; +#else + return -EOPNOTSUPP; +#endif + } + + return 0; +} + static int add_socket(struct pw_protocol *protocol, struct server *s) { socklen_t size; @@ -836,11 +901,22 @@ goto error_close; } + if ((res = set_socket_permissions(s)) < 0) { + errno = -res; + pw_log_error("server %p: failed to set socket %s permissions: %m", + s, s->socket_info.name); + goto error_close; + } + if (listen(fd, 128) < 0) { res = -errno; pw_log_error("server %p: listen() failed with error: %m", s); goto error_close; } + } else { + if (s->socket_info.has_owner || s->socket_info.has_mode || s->socket_info.selinux_context) + pw_log_info("server %p: permissions ignored for socket %s from systemd", + s, s->socket_info.name); } res = write_socket_address(s); @@ -1250,6 +1326,8 @@ unlink(s->lock_addr); if (s->fd_lock != -1) close(s->fd_lock); + free(s->socket_info.name); + free(s->socket_info.selinux_context); free(s); } @@ -1311,9 +1389,10 @@ } static struct pw_protocol_server * -impl_add_server(struct pw_protocol *protocol, +add_server(struct pw_protocol *protocol, struct pw_impl_core *core, - const struct spa_dict *props) + const struct spa_dict *props, + struct socket_info *socket_info) { struct pw_protocol_server *this; struct server *s; @@ -1325,7 +1404,16 @@ this = &s->this; - name = get_server_name(props); + if (socket_info) { + s->socket_info = *socket_info; + s->socket_info.name = strdup(socket_info->name); + s->socket_info.selinux_context = socket_info->selinux_context ? + strdup(socket_info->selinux_context) : NULL; + name = socket_info->name; + } else { + name = get_server_name(props); + s->socket_info.name = strdup(name); + } if ((res = init_socket_name(s, name)) < 0) goto error; @@ -1349,6 +1437,14 @@ return NULL; } +static struct pw_protocol_server *
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/manager.h
Changed
@@ -9,11 +9,14 @@ extern "C" { #endif +#include <stdio.h> + #include <spa/utils/defs.h> #include <spa/pod/pod.h> #include <pipewire/pipewire.h> +struct client; struct pw_manager_object; struct pw_manager_events { @@ -68,8 +71,8 @@ struct pw_properties *props; struct pw_proxy *proxy; char *message_object_path; - int (*message_handler)(struct pw_manager *m, struct pw_manager_object *o, - const char *message, const char *params, char **response); + int (*message_handler)(struct client *client, struct pw_manager_object *o, + const char *message, const char *params, FILE *response); void *info; struct spa_param_info *params;
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/message-handler.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/message-handler.c
Changed
@@ -3,8 +3,10 @@ /* SPDX-License-Identifier: MIT */ #include <stdint.h> +#include <stdio.h> #include <regex.h> +#include <malloc.h> #include <spa/param/props.h> #include <spa/pod/builder.h> @@ -15,12 +17,13 @@ #include <pipewire/pipewire.h> +#include "client.h" #include "collect.h" #include "log.h" #include "manager.h" #include "message-handler.h" -static int bluez_card_object_message_handler(struct pw_manager *m, struct pw_manager_object *o, const char *message, const char *params, char **response) +static int bluez_card_object_message_handler(struct client *client, struct pw_manager_object *o, const char *message, const char *params, FILE *response) { struct transport_codec_info codecs64; uint32_t n_codecs, active; @@ -60,66 +63,62 @@ pw_device_set_param((struct pw_device *)o->proxy, SPA_PARAM_Props, 0, param); - return 0; } else if (spa_streq(message, "list-codecs")) { uint32_t i; - FILE *r; - size_t size; bool first = true; - r = open_memstream(response, &size); - if (r == NULL) - return -errno; - - fputc('', r); + fputc('', response); for (i = 0; i < n_codecs; ++i) { const char *desc = codecsi.description; - fprintf(r, "%s{\"name\":\"%d\",\"description\":\"%s\"}", + fprintf(response, "%s{\"name\":\"%d\",\"description\":\"%s\"}", first ? "" : ",", (int)codecsi.id, desc ? desc : "Unknown"); first = false; } - fputc('', r); - - return fclose(r) ? -errno : 0; + fputc('', response); } else if (spa_streq(message, "get-codec")) { if (active == SPA_ID_INVALID) - *response = strdup("null"); + fputs("null", response); else - *response = spa_aprintf("\"%d\"", (int)codecsactive.id); - return *response ? 0 : -ENOMEM; + fprintf(response, "\"%d\"", (int) codecsactive.id); + } else { + return -ENOSYS; } - return -ENOSYS; + return 0; } -static int core_object_message_handler(struct pw_manager *m, struct pw_manager_object *o, const char *message, const char *params, char **response) +static int core_object_message_handler(struct client *client, struct pw_manager_object *o, const char *message, const char *params, FILE *response) { pw_log_debug(": core %p object message:'%s' params:'%s'", o, message, params); if (spa_streq(message, "list-handlers")) { - FILE *r; - size_t size; bool first = true; - r = open_memstream(response, &size); - if (r == NULL) - return -errno; - - fputc('', r); - spa_list_for_each(o, &m->object_list, link) { + fputc('', response); + spa_list_for_each(o, &client->manager->object_list, link) { if (o->message_object_path) { - fprintf(r, "%s{\"name\":\"%s\",\"description\":\"%s\"}", + fprintf(response, "%s{\"name\":\"%s\",\"description\":\"%s\"}", first ? "" : ",", o->message_object_path, o->type); first = false; } } - fputc('', r); - return fclose(r) ? -errno : 0; + fputc('', response); +#ifdef HAVE_MALLOC_INFO + } else if (spa_streq(message, "pipewire-pulse:malloc-info")) { + malloc_info(0, response); +#endif +#ifdef HAVE_MALLOC_TRIM + } else if (spa_streq(message, "pipewire-pulse:malloc-trim")) { + int res = malloc_trim(0); + fprintf(response, "%d", res); +#endif + } else { + return -ENOSYS; } - return -ENOSYS; + return 0; } void register_object_message_handlers(struct pw_manager_object *o)
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1820,6 +1820,8 @@ PW_STREAM_FLAG_MAP_BUFFERS, params, n_params); + stream_update_tag_param(stream); + return 0; error_errno: @@ -3215,7 +3217,8 @@ if (stream == NULL || stream->type == STREAM_TYPE_UPLOAD) return -ENOENT; - pw_stream_update_properties(stream->stream, &props->dict); + if (pw_stream_update_properties(stream->stream, &props->dict) > 0) + stream_update_tag_param(stream); } else { if (pw_properties_update(client->props, &props->dict) > 0) { client_update_quirks(client); @@ -5099,12 +5102,12 @@ { struct impl *impl = client->impl; struct pw_manager *manager = client->manager; - const char *object_path = NULL; - const char *message = NULL; - const char *params = NULL; - struct message *reply; + const char *object_path = NULL, *message = NULL, *params = NULL; struct pw_manager_object *o; - int len = 0; + spa_autofree char *response_str = NULL; + size_t path_len = 0, response_len = 0; + FILE *response; + int res = -ENOENT; if (message_get(m, TAG_STRING, &object_path, @@ -5120,36 +5123,42 @@ if (object_path == NULL || message == NULL) return -EINVAL; - len = strlen(object_path); - if (len > 0 && object_pathlen - 1 == '/') - --len; - - spa_autofree char *path = strndup(object_path, len); + path_len = strlen(object_path); + if (path_len > 0 && object_pathpath_len - 1 == '/') + --path_len; + spa_autofree char *path = strndup(object_path, path_len); if (path == NULL) return -ENOMEM; - spa_autofree char *response = NULL; - int res = -ENOENT; - spa_list_for_each(o, &manager->object_list, link) { - if (o->message_object_path && spa_streq(o->message_object_path, path)) { - if (o->message_handler) - res = o->message_handler(manager, o, message, params, &response); - else - res = -ENOSYS; + if (spa_streq(o->message_object_path, path)) break; - } } + if (spa_list_is_end(o, &manager->object_list, link)) + return -ENOENT; - if (res < 0) - return res; + if (o->message_handler == NULL) + return -ENOSYS; - pw_log_debug("%p: object message response:'%s'", impl, response ? response : "<null>"); + response = open_memstream(&response_str, &response_len); + if (response == NULL) + return -errno; - reply = reply_new(client, tag); - message_put(reply, TAG_STRING, response, TAG_INVALID); + res = o->message_handler(client, o, message, params, response); - return client_queue_message(client, reply); + if (fclose(response)) + return -errno; + + pw_log_debug("%p: object message response: (%d) '%s'", impl, res, response_str ? response_str : "<null>"); + + if (res >= 0) { + struct message *reply = reply_new(client, tag); + + message_put(reply, TAG_STRING, response_str, TAG_INVALID); + res = client_queue_message(client, reply); + } + + return res; } static int do_error_access(struct client *client, uint32_t command, uint32_t tag, struct message *m)
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/stream.c -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/stream.c
Changed
@@ -8,6 +8,9 @@ #include <spa/utils/hook.h> #include <spa/utils/ringbuffer.h> +#include <spa/pod/dynamic.h> +#include <spa/param/tag-utils.h> + #include <pipewire/log.h> #include <pipewire/loop.h> #include <pipewire/map.h> @@ -412,3 +415,36 @@ } return client_queue_message(client, reply); } + +int stream_update_tag_param(struct stream *stream) +{ + struct spa_pod_dynamic_builder b; + const struct pw_properties *props = pw_stream_get_properties(stream->stream); + const struct spa_pod *param1; + struct spa_dict_item items64; + uint32_t i, n_items = 0; + uint8_t buffer4096; + + if (props == NULL) + return -EIO; + + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + + for (i = 0; i < props->dict.n_items; i++) { + if (n_items < SPA_N_ELEMENTS(items) && + spa_strstartswith(props->dict.itemsi.key, "media.")) + itemsn_items++ = props->dict.itemsi; + } + if (n_items > 0) { + struct spa_pod_frame f; + spa_tag_build_start(&b.b, &f, SPA_PARAM_Tag, SPA_DIRECTION_OUTPUT); + spa_tag_build_add_dict(&b.b, &SPA_DICT_INIT(items, n_items)); + param0 = spa_tag_build_end(&b.b, &f); + } else { + param0 = NULL; + } + if (param0 != NULL) + pw_stream_update_params(stream->stream, param, 1); + spa_pod_dynamic_builder_clean(&b); + return 0; +}
View file
pipewire-0.3.81.tar.gz/src/modules/module-protocol-pulse/stream.h -> pipewire-0.3.82.tar.gz/src/modules/module-protocol-pulse/stream.h
Changed
@@ -116,5 +116,6 @@ int stream_send_request(struct stream *stream); int stream_update_minreq(struct stream *stream, uint32_t minreq); int stream_send_moved(struct stream *stream, uint32_t peer_index, const char *peer_name); +int stream_update_tag_param(struct stream *stream); #endif /* PULSER_SERVER_STREAM_H */
View file
pipewire-0.3.81.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.82.tar.gz/src/modules/module-raop-sink.c
Changed
@@ -45,6 +45,7 @@ #include "module-raop/rtsp-client.h" #include "module-rtp/rtp.h" +#include "module-rtp/stream.h" /** \page page_module_raop_sink PipeWire Module: AirPlay Sink * @@ -121,36 +122,37 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define FRAMES_PER_TCP_PACKET 4096 -#define FRAMES_PER_UDP_PACKET 352 +#define BUFFER_SIZE (1u<<22) +#define BUFFER_MASK (BUFFER_SIZE-1) +#define BUFFER_SIZE2 (BUFFER_SIZE>>1) +#define BUFFER_MASK2 (BUFFER_SIZE2-1) -#define RAOP_LATENCY_MIN 11025u -#define DEFAULT_LATENCY_MS "1500" +#define FRAMES_PER_TCP_PACKET 4096 +#define FRAMES_PER_UDP_PACKET 352 -#define DEFAULT_TCP_AUDIO_PORT 6000 -#define DEFAULT_UDP_AUDIO_PORT 6000 -#define DEFAULT_UDP_CONTROL_PORT 6001 -#define DEFAULT_UDP_TIMING_PORT 6002 +#define RAOP_AUDIO_PORT 6000 +#define RAOP_UDP_CONTROL_PORT 6001 +#define RAOP_UDP_TIMING_PORT 6002 #define AES_CHUNK_SIZE 16 #ifndef MD5_DIGEST_LENGTH #define MD5_DIGEST_LENGTH 16 #endif -#define MD5_HASH_LENGTH (2*MD5_DIGEST_LENGTH) +#define MD5_HASH_LENGTH (2*MD5_DIGEST_LENGTH) #define DEFAULT_USER_NAME "PipeWire" #define RAOP_AUTH_USER_NAME "iTunes" -#define MAX_PORT_RETRY 128 +#define MAX_PORT_RETRY 128 -#define DEFAULT_FORMAT "S16" -#define DEFAULT_RATE 44100 -#define DEFAULT_CHANNELS 2 -#define DEFAULT_POSITION " FL FR " +#define RAOP_FORMAT "S16LE" +#define RAOP_STRIDE (2*DEFAULT_CHANNELS) +#define RAOP_RATE 44100 +#define RAOP_LATENCY_MS 250 -#define VOLUME_MAX 0.0 -#define VOLUME_MIN -30.0 -#define VOLUME_MUTE -144.0 +#define VOLUME_MAX 0.0 +#define VOLUME_MIN -30.0 +#define VOLUME_MUTE -144.0 #define MODULE_USAGE "( raop.ip=<ip address of host> ) " \ "( raop.port=<remote port> ) " \ @@ -163,8 +165,8 @@ "( node.latency=<latency as fraction> ) " \ "( node.name=<name of the nodes> ) " \ "( node.description=<description of the nodes> ) " \ - "( audio.format=<format, default:"DEFAULT_FORMAT"> ) " \ - "( audio.rate=<sample rate, default: "SPA_STRINGIFY(DEFAULT_RATE)"> ) " \ + "( audio.format=<format, default:"RAOP_FORMAT"> ) " \ + "( audio.rate=<sample rate, default: "SPA_STRINGIFY(RAOP_RATE)"> ) " \ "( audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> ) " \ "( audio.position=<channel map, default:"DEFAULT_POSITION"> ) " \ "( stream.props=<properties> ) " @@ -212,10 +214,7 @@ struct spa_hook core_listener; struct pw_properties *stream_props; - struct pw_stream *stream; - struct spa_hook stream_listener; - struct spa_audio_info_raw info; - uint32_t frame_size; + struct rtp_stream *stream; struct pw_rtsp_client *rtsp; struct spa_hook rtsp_listener; @@ -246,15 +245,15 @@ int server_fd; struct spa_source *server_source; - uint32_t block_size; + uint32_t psamples; + uint64_t rate; + uint32_t mtu; + uint32_t stride; uint32_t latency; - uint16_t seq, cseq; - uint32_t rtptime; uint32_t ssrc; uint32_t sync; uint32_t sync_period; - unsigned int first:1; unsigned int connected:1; unsigned int ready:1; unsigned int recording:1; @@ -262,17 +261,14 @@ bool mute; float volume; - uint8_t bufferFRAMES_PER_TCP_PACKET * 4; + struct spa_ringbuffer ring; + uint8_t bufferBUFFER_SIZE; + + struct spa_io_position *io_position; + uint32_t filled; }; -static void stream_destroy(void *d) -{ - struct impl *impl = d; - spa_hook_remove(&impl->stream_listener); - impl->stream = NULL; -} - static inline void bit_writer(uint8_t **p, int *pos, uint8_t data, int len) { int rb = 8 - *pos - len; @@ -307,11 +303,9 @@ return timespec_to_ntp(&now); } -static int send_udp_sync_packet(struct impl *impl, - struct sockaddr *dest_addr, socklen_t addrlen) +static int send_udp_sync_packet(struct impl *impl, uint32_t rtptime, unsigned int first) { uint32_t out3; - uint32_t rtptime = impl->rtptime; uint32_t latency = impl->latency; uint64_t transmitted; struct rtp_header header; @@ -321,11 +315,11 @@ spa_zero(header); header.v = 2; - if (impl->first) + if (first) header.x = 1; header.m = 1; header.pt = 84; - header.sequence_number = htons(impl->cseq); + header.sequence_number = 7; header.timestamp = htonl(rtptime - latency); iov0.iov_base = &header; @@ -339,8 +333,8 @@ iov1.iov_base = out; iov1.iov_len = sizeof(out); - msg.msg_name = dest_addr; - msg.msg_namelen = addrlen; + msg.msg_name = NULL; + msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 2; msg.msg_control = NULL; @@ -353,10 +347,8 @@ pw_log_warn("error sending control packet: %d", res); } - impl->cseq = (impl->cseq + 1) & 0xffff; - - pw_log_debug("raop control sync: cseq:%d first:%d latency:%u now:%"PRIx64" rtptime:%u", - impl->cseq, impl->first, latency, transmitted, rtptime); + pw_log_debug("raop control sync: first:%d latency:%u now:%"PRIx64" rtptime:%u", + first, latency, transmitted, rtptime); return res; } @@ -440,194 +432,86 @@ return bp - b + 1; } -static int flush_to_udp_packet(struct impl *impl) +static ssize_t send_packet(int fd, struct msghdr *msg) { - const size_t max = 8 + impl->block_size; - uint32_t outmax, len, n_frames; - struct rtp_header header; - struct iovec iov2; + ssize_t n; + n = sendmsg(fd, msg, MSG_NOSIGNAL); + if (n < 0) + pw_log_debug("sendmsg() failed: %m"); + return n; +} + +static void stream_send_packet(void *data, struct iovec *iov, size_t iovlen) +{
View file
pipewire-0.3.81.tar.gz/src/modules/module-rt.c -> pipewire-0.3.82.tar.gz/src/modules/module-rt.c
Changed
@@ -36,7 +36,7 @@ #include <sys/thr.h> #endif #if defined(__GNU__) -#include <mach.h> +#include <hurd.h> #endif #include <fcntl.h> #include <unistd.h> @@ -225,7 +225,7 @@ thr_self(&pid); return (pid_t)pid; #elif defined(__GNU__) - mach_port_t thread = mach_thread_self(); + mach_port_t thread = hurd_thread_self(); return (pid_t)thread; #else #error "No gettid impl"
View file
pipewire-0.3.81.tar.gz/src/modules/module-rtp/audio.c -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/audio.c
Changed
@@ -226,6 +226,10 @@ iov0.iov_len = sizeof(header); while (avail >= tosend) { + if (impl->marker_on_first && impl->first) + header.m = 1; + else + header.m = 0; header.sequence_number = htons(impl->seq); header.timestamp = htonl(impl->ts_offset + timestamp); @@ -234,11 +238,12 @@ (timestamp * stride) & BUFFER_MASK, &iov1, tosend * stride); - pw_log_trace("sending %d timestamp:%d", tosend, timestamp); + pw_log_trace("sending %d avail:%d ts_offset:%d timestamp:%d", tosend, avail, impl->ts_offset, timestamp); rtp_stream_emit_send_packet(impl, iov, 3); impl->seq++; + impl->first = false; timestamp += tosend; avail -= tosend; }
View file
pipewire-0.3.81.tar.gz/src/modules/module-rtp/stream.c -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/stream.c
Changed
@@ -32,6 +32,7 @@ struct rtp_stream_events, m, v, ##__VA_ARGS__) #define rtp_stream_emit_destroy(s) rtp_stream_emit(s, destroy, 0) #define rtp_stream_emit_state_changed(s,n,e) rtp_stream_emit(s, state_changed,0,n,e) +#define rtp_stream_emit_param_changed(s,i,p) rtp_stream_emit(s, param_changed,0,i,p) #define rtp_stream_emit_send_packet(s,i,l) rtp_stream_emit(s, send_packet,0,i,l) #define rtp_stream_emit_send_feedback(s,seq) rtp_stream_emit(s, send_feedback,0,seq) @@ -58,6 +59,7 @@ unsigned have_ssrc:1; unsigned ignore_ssrc:1; unsigned have_seq:1; + unsigned marker_on_first:1; uint32_t ts_offset; uint32_t psamples; uint32_t mtu; @@ -102,6 +104,7 @@ { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_ALAW, 1, "PCMA", "audio" }, { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_ULAW, 1, "PCMU", "audio" }, { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S16_BE, 2, "L16", "audio" }, + { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S16_LE, 2, "L16", "audio" }, { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S24_BE, 3, "L24", "audio" }, { SPA_MEDIA_SUBTYPE_control, 0, 1, "rtp-midi", "audio" }, { SPA_MEDIA_SUBTYPE_opus, 0, 4, "opus", "audio" }, @@ -132,6 +135,8 @@ if (impl->started) return 0; + impl->first = true; + rtp_stream_emit_state_changed(impl, true, NULL); impl->started = true; @@ -176,10 +181,17 @@ } } +static void on_stream_param_changed (void *d, uint32_t id, const struct spa_pod *param) +{ + struct impl *impl = d; + rtp_stream_emit_param_changed(impl, id, param); +}; + static const struct pw_stream_events stream_events = { PW_VERSION_STREAM_EVENTS, .destroy = stream_destroy, .state_changed = on_stream_state_changed, + .param_changed = on_stream_param_changed, .io_changed = stream_io_changed, }; @@ -287,6 +299,12 @@ impl->info.media_subtype = SPA_MEDIA_SUBTYPE_raw; impl->payload = 127; } + else if (spa_streq(str, "raop")) { + impl->info.media_type = SPA_MEDIA_TYPE_audio; + impl->info.media_subtype = SPA_MEDIA_SUBTYPE_raw; + impl->payload = 0x60; + impl->marker_on_first = 1; + } else if (spa_streq(str, "midi")) { impl->info.media_type = SPA_MEDIA_TYPE_application; impl->info.media_subtype = SPA_MEDIA_SUBTYPE_control; @@ -364,6 +382,7 @@ if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL) pw_properties_set(props, PW_KEY_NODE_NETWORK, "true"); + impl->marker_on_first = pw_properties_get_bool(props, "sess.marker-on-first", false); impl->ignore_ssrc = pw_properties_get_bool(props, "sess.ignore-ssrc", false); impl->direct_timestamp = pw_properties_get_bool(props, "sess.ts-direct", false); @@ -530,3 +549,40 @@ return pos->clock.position * impl->rate * pos->clock.rate.num / pos->clock.rate.denom; } + +uint16_t rtp_stream_get_seq(struct rtp_stream *s) +{ + struct impl *impl = (struct impl*)s; + + return impl->seq; +} + +void rtp_stream_set_first(struct rtp_stream *s) +{ + struct impl *impl = (struct impl*)s; + + impl->first = true; +} + +enum pw_stream_state rtp_stream_get_state(struct rtp_stream *s, const char **error) +{ + struct impl *impl = (struct impl*)s; + + return pw_stream_get_state(impl->stream, error); +} + +int rtp_stream_set_param(struct rtp_stream *s, uint32_t id, const struct spa_pod *param) +{ + struct impl *impl = (struct impl*)s; + + return pw_stream_set_param(impl->stream, id, param); +} + +int rtp_stream_update_params(struct rtp_stream *s, + const struct spa_pod **params, + uint32_t n_params) +{ + struct impl *impl = (struct impl*)s; + + return pw_stream_update_params(impl->stream, params, n_params); +} \ No newline at end of file
View file
pipewire-0.3.81.tar.gz/src/modules/module-rtp/stream.h -> pipewire-0.3.82.tar.gz/src/modules/module-rtp/stream.h
Changed
@@ -31,9 +31,11 @@ void (*state_changed) (void *data, bool started, const char *error); + void (*param_changed) (void *data, uint32_t id, const struct spa_pod *param); + void (*send_packet) (void *data, struct iovec *iov, size_t iovlen); - void (*send_feedback) (void *data, uint32_t senum); + void (*send_feedback) (void *data, uint32_t seqnum); }; struct rtp_stream *rtp_stream_new(struct pw_core *core, @@ -46,6 +48,17 @@ uint64_t rtp_stream_get_time(struct rtp_stream *s, uint64_t *rate); +uint16_t rtp_stream_get_seq(struct rtp_stream *s); + +void rtp_stream_set_first(struct rtp_stream *s); + +enum pw_stream_state rtp_stream_get_state(struct rtp_stream *s, const char **error); + +int rtp_stream_set_param(struct rtp_stream *s, uint32_t id, const struct spa_pod *param); + +int rtp_stream_update_params(struct rtp_stream *stream, + const struct spa_pod **params, + uint32_t n_params); #ifdef __cplusplus }
View file
pipewire-0.3.81.tar.gz/src/pipewire/context.c -> pipewire-0.3.82.tar.gz/src/pipewire/context.c
Changed
@@ -1027,7 +1027,7 @@ context, n, n->name); if (n->info.state >= PW_NODE_STATE_IDLE) - n->reconfigure = true; + n->need_resume = !n->pause_on_idle; pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED); } @@ -1309,7 +1309,7 @@ uint32_t target_quantum, target_rate, current_rate, current_quantum; uint64_t quantum_stamp = 0, rate_stamp = 0; bool force_rate, force_quantum, restore_rate = false, restore_quantum = false; - bool do_reconfigure = false, was_target_pending; + bool do_reconfigure = false, need_resume, was_target_pending; const uint32_t *node_rates; uint32_t node_n_rates, node_def_rate; uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum; @@ -1399,13 +1399,22 @@ if (force_rate) lock_rate = false; - if (n->reconfigure) + need_resume = n->need_resume; + if (need_resume) { running = true; + n->need_resume = false; + } current_rate = n->target_rate.denom; if (!restore_rate && - (lock_rate || n->reconfigure || !running || - (!force_rate && (n->info.state > PW_NODE_STATE_IDLE)))) + (lock_rate || need_resume || !running || + (!force_rate && (n->info.state > PW_NODE_STATE_IDLE)))) { + pw_log_debug("%p: keep rate:1/%u restore:%u lock:%u resume:%u " + "running:%u force:%u state:%s", context, + current_rate, restore_rate, lock_rate, need_resume, + running, force_rate, + pw_node_state_as_string(n->info.state)); + /* when we don't need to restore or rate and * when someone wants us to lock the rate of this driver or * when we are in the process of reconfiguring the driver or @@ -1413,6 +1422,7 @@ * when the driver is busy and we don't need to force a rate, * keep the current rate */ target_rate = current_rate; + } else { /* Here we are allowed to change the rate of the driver. * Start with the default rate. If the desired rate is @@ -1464,9 +1474,15 @@ current_quantum = n->target_quantum; if (!restore_quantum && - (lock_quantum || n->reconfigure || !running || - (!force_quantum && (n->info.state > PW_NODE_STATE_IDLE)))) + (lock_quantum || need_resume || !running || + (!force_quantum && (n->info.state > PW_NODE_STATE_IDLE)))) { + pw_log_debug("%p: keep quantum:%u restore:%u lock:%u resume:%u " + "running:%u force:%u state:%s", context, + current_quantum, restore_quantum, lock_quantum, need_resume, + running, force_quantum, + pw_node_state_as_string(n->info.state)); target_quantum = current_quantum; + } else { target_quantum = node_def_quantum; if (latency.denom != 0) @@ -1474,7 +1490,7 @@ target_quantum = SPA_CLAMP(target_quantum, node_min_quantum, node_max_quantum); target_quantum = SPA_MIN(target_quantum, lim_quantum); - if (settings->clock_power_of_two_quantum) + if (settings->clock_power_of_two_quantum && !force_quantum) target_quantum = flp2(target_quantum); }
View file
pipewire-0.3.81.tar.gz/src/pipewire/filter.c -> pipewire-0.3.82.tar.gz/src/pipewire/filter.c
Changed
@@ -1659,10 +1659,10 @@ if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { - pw_properties_setf(filter->properties, PW_KEY_NODE_RATE, + pw_properties_setf(filter->properties, PW_KEY_NODE_FORCE_RATE, "1/%u", q.denom); - pw_properties_setf(filter->properties, PW_KEY_NODE_LATENCY, - "%u/%u", q.num, q.denom); + pw_properties_setf(filter->properties, PW_KEY_NODE_FORCE_QUANTUM, + "%u", q.num); } } if ((str = getenv("PIPEWIRE_LATENCY")) != NULL)
View file
pipewire-0.3.81.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.82.tar.gz/src/pipewire/impl-client.c
Changed
@@ -152,30 +152,53 @@ return false; } -static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter) +static bool check_client_property_update(struct pw_impl_client *client, + const char *key, const char *old, const char *new) { static const char * const ignored = { + PW_KEY_PROTOCOL, PW_KEY_OBJECT_ID, + PW_KEY_OBJECT_SERIAL, + PW_KEY_ACCESS, NULL }; + /* Refuse specific restricted keys */ + if (has_key(ignored, key)) + goto deny; + + /* Refuse all security keys */ + if (spa_strstartswith(key, "pipewire.sec.")) + goto deny; + + /* Restrict other pipewire.* keys */ + if (spa_strstartswith(key, "pipewire.")) { + /* Refuse changing existing values */ + if (old != NULL) + goto deny; + } + + return true; + +deny: + if (!spa_streq(old, new)) + pw_log_warn("%p: refuse property update '%s' from '%s' to '%s'", + client, key, old ? old : "<unset>", new ? new : "<unset>"); + return false; +} + +static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter) +{ struct pw_resource *resource; int changed = 0; uint32_t i; - const char *old; for (i = 0; i < dict->n_items; i++) { if (filter) { - if (spa_strstartswith(dict->itemsi.key, "pipewire.") && - (old = pw_properties_get(client->properties, dict->itemsi.key)) != NULL && - (dict->itemsi.value == NULL || !spa_streq(old, dict->itemsi.value))) { - pw_log_warn("%p: refuse property update '%s' from '%s' to '%s'", - client, dict->itemsi.key, old, - dict->itemsi.value); - continue; + const char *old = pw_properties_get(client->properties, dict->itemsi.key); + const char *new = dict->itemsi.value; - } - if (has_key(ignored, dict->itemsi.key)) + if (!check_client_property_update(client, dict->itemsi.key, old, new)) continue; } changed += pw_properties_set(client->properties, dict->itemsi.key, dict->itemsi.value); @@ -501,6 +524,7 @@ PW_KEY_SEC_UID, PW_KEY_SEC_GID, PW_KEY_SEC_LABEL, + PW_KEY_SEC_SOCKET, NULL };
View file
pipewire-0.3.81.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.82.tar.gz/src/pipewire/impl-node.c
Changed
@@ -418,14 +418,6 @@ spa_list_for_each(resource, &node->global->resource_list, link) pw_resource_error(resource, res, error); } - if (node->reconfigure) { - if (state == PW_NODE_STATE_SUSPENDED && - node->pause_on_idle) { - node->reconfigure = false; - } - if (state == PW_NODE_STATE_RUNNING) - node->reconfigure = false; - } if (old == PW_NODE_STATE_RUNNING && state == PW_NODE_STATE_IDLE && node->suspend_on_idle) {
View file
pipewire-0.3.81.tar.gz/src/pipewire/keys.h -> pipewire-0.3.82.tar.gz/src/pipewire/keys.h
Changed
@@ -38,6 +38,8 @@ #define PW_KEY_SEC_GID "pipewire.sec.gid" /**< client gid, set by protocol*/ #define PW_KEY_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ +#define PW_KEY_SEC_SOCKET "pipewire.sec.socket" /**< client socket name, set by protocol */ + #define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system" /**< name of the system library to use */ #define PW_KEY_LIBRARY_NAME_LOOP "library.name.loop" /**< name of the loop library to use */ #define PW_KEY_LIBRARY_NAME_DBUS "library.name.dbus" /**< name of the dbus library to use */
View file
pipewire-0.3.81.tar.gz/src/pipewire/log.c -> pipewire-0.3.82.tar.gz/src/pipewire/log.c
Changed
@@ -233,13 +233,6 @@ } } -SPA_EXPORT -void -_pw_log_topic_new(struct spa_log_topic *topic) -{ - spa_log_topic_init(global_log, topic); -} - void pw_log_init(void) {
View file
pipewire-0.3.81.tar.gz/src/pipewire/log.h -> pipewire-0.3.82.tar.gz/src/pipewire/log.h
Changed
@@ -72,17 +72,6 @@ int line, const char *func, const char *fmt, va_list args) SPA_PRINTF_FUNC(5, 0); -/** Initialize the log topic. The returned topic is owned by the pipewire - * context and the topic must not be modified or freed. - * Do not use this function directly, use one of PW_LOG_TOPIC_* instead. - * - * \see PW_LOG_TOPIC_STATIC - * \see PW_LOG_TOPIC_EXTERN - * \see PW_LOG_TOPIC - */ -void -_pw_log_topic_new(struct spa_log_topic *topic); - /** * Declare a static log topic named \a var. The usual usage is: * \code
View file
pipewire-0.3.81.tar.gz/src/pipewire/map.h -> pipewire-0.3.82.tar.gz/src/pipewire/map.h
Changed
@@ -189,7 +189,7 @@ * \param id the index to look at * \return the item at \a id or NULL when no such item exists */ -static inline void *pw_map_lookup(struct pw_map *map, uint32_t id) +static inline void *pw_map_lookup(const struct pw_map *map, uint32_t id) { if (SPA_LIKELY(pw_map_check_id(map, id))) { union pw_map_item *item = pw_map_get_item(map, id); @@ -207,8 +207,8 @@ * \param data data to pass to \a func * \return the result of the last call to \a func or 0 when all callbacks returned 0. */ -static inline int pw_map_for_each(struct pw_map *map, - int (*func) (void *item_data, void *data), void *data) +static inline int pw_map_for_each(const struct pw_map *map, + int (*func) (void *item_data, void *data), void *data) { union pw_map_item *item; int res = 0;
View file
pipewire-0.3.81.tar.gz/src/pipewire/private.h -> pipewire-0.3.82.tar.gz/src/pipewire/private.h
Changed
@@ -671,7 +671,7 @@ unsigned int added:1; /**< the node was add to graph */ unsigned int pause_on_idle:1; /**< Pause processing when IDLE */ unsigned int suspend_on_idle:1; - unsigned int reconfigure:1; + unsigned int need_resume:1; unsigned int forced_rate:1; unsigned int forced_quantum:1; unsigned int trigger:1; /**< has the TRIGGER property and needs an extra
View file
pipewire-0.3.81.tar.gz/src/pipewire/stream.c -> pipewire-0.3.82.tar.gz/src/pipewire/stream.c
Changed
@@ -2034,10 +2034,10 @@ if ((str = getenv("PIPEWIRE_QUANTUM")) != NULL) { struct spa_fraction q; if (sscanf(str, "%u/%u", &q.num, &q.denom) == 2 && q.denom != 0) { - pw_properties_setf(stream->properties, PW_KEY_NODE_RATE, + pw_properties_setf(stream->properties, PW_KEY_NODE_FORCE_RATE, "1/%u", q.denom); - pw_properties_setf(stream->properties, PW_KEY_NODE_LATENCY, - "%u/%u", q.num, q.denom); + pw_properties_setf(stream->properties, PW_KEY_NODE_FORCE_QUANTUM, + "%u", q.num); } } if ((str = getenv("PIPEWIRE_LATENCY")) != NULL)
View file
pipewire-0.3.81.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.82.tar.gz/src/tools/pw-cat.c
Changed
@@ -1977,7 +1977,8 @@ uint32_t i, n_items = 0; for (i = 0; i < data.props->dict.n_items; i++) { - if (spa_strstartswith(data.props->dict.itemsi.key, "media.")) + if (n_items < SPA_N_ELEMENTS(items) && + spa_strstartswith(data.props->dict.itemsi.key, "media.")) itemsn_items++ = data.props->dict.itemsi; } if (n_items > 0) {
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
.