Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Problem getting expanded diff: bad link: could not apply patch 'project.diff'
×
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
.