Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 32
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Aug 9 15:43:07 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.77 + +------------------------------------------------------------------- Mon Jul 31 19:02:32 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.76
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.76 +Version: 0.3.77 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.76.tar.gz/NEWS -> pipewire-0.3.77.tar.gz/NEWS
Changed
@@ -1,3 +1,57 @@ +# PipeWire 0.3.77 (2023-08-04) + +This is a quick bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - Fix a bug in ALSA source where the available number of samples was miscaluclated + and resulted in xruns in some cases. + - A new L permission was added to make it possible to force a link between + nodes even when the nodes can't see eachother. + - The VBAN module now supports midi send and receive as well. + - Many cleanups and small fixes. + + +## PipeWire + - Global objects now only show permissions that apply to them. The permissions + required to perform various API calls are documented. + - A new L permission was added to make it possible to force a link between + nodes even when the nodes can't see eachother. + - Config files need to end with .conf. + - The client.api is added the to global properties of a node. + +## modules + - The VBAN module now supports midi send and receive as well. + - Fix module-profiler alignment and make sure we don't overrun our buffers with + many nodes. + - Protect libcanberra calls with a mutex because it is not thread safe. (#2834) + +## SPA + - Support older compilers for spa_clear_ptr(). + - Fix a bug in ALSA source where the available number of samples was miscaluclated + and resulted in xruns. (#3395) + - Don't set inotify on /dev but on the videoX devices directly. Setting inotify + on /dev would cause a lot of spurious wakeups and lock contention in the + fsnotify subsystem on some benchmarks. + - Audioconvert now rate limits the warnings when it runs out of buffers. (#3384) + +## pulse-server + - Some bugs and inconsistencies were fixed in device lookup. + - Improve subscribe event emission, detect changes to the sink or the monitor + and send the right sink/source event. (#3388) + +## JACK + - The libjack.so now has a minor version of 3 and a micro version of the pipewire + version. + - JACK clients will now see portregistration from other jack clients when they + activate/deactivate like real JACK. (#3260) + +## bluetooth + - Use some more autoptr cleanups, fix some leaks. + +Older versions: + + # PipeWire 0.3.76 (2023-07-28) This is a quick bugfix release that is API and ABI compatible with previous @@ -36,9 +90,6 @@ - LE Audio support is now enabled by default when liblc3 is available now that bluez has support for detecting the hardware features. -Older versions: - - # PipeWire 0.3.75 (2023-07-21) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.76.tar.gz/doc/dma-buf.dox -> pipewire-0.3.77.tar.gz/doc/dma-buf.dox
Changed
@@ -147,6 +147,18 @@ In cases where mapping a single plane is required the size should be obtained locally via the filedescriptor. +# SPA param video format helpers + +SPA offers helper functions to parse and build a spa_pod object to/from the spa_video_info_* +struct. The flags `SPA_VIDEO_FLAG_MODIFIER` and `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED` +are used to indicate modifier usage with the format. `SPA_VIDEO_FLAG_MODIFIER` declares the +parsed/provided spa_video_info_* struct contains valid modifier information. For legacy +reasons `spa_format_video_*_build` will announce any modifier != 0 even when this flag is +unused. `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED` is exclusive to the parse helpers and +declares that the parsed spa_pod contains modifier information which needs to be fixated as +described aboath. The list of available modifiers has to be parsed manually from the spa_pod +object. + # v4l2 Another use case for streaming via DMA-BUFs are exporting a camera feed from v4l2
View file
pipewire-0.3.76.tar.gz/meson.build -> pipewire-0.3.77.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.76', + version : '0.3.77', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3', @@ -25,6 +25,15 @@ soversion = 0 libversion = '@0@.@1@.0'.format(soversion, pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int()) +# LADI/jack +# 3, for PipeWire being the third JACK implementation, after JACK1 and jackdmp/JACK2) +jack_version_major = 3 +jack_version_minor = pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int() +# libjackserver version has 0 for major (for compatibility with other implementations), +# 3 for minor, and "100*pipewire_version_minor + pipewire_version_micro" +# as micro version (the minor libpipewire soversion number) +libjackversion = '@0@.@1@.@2@'.format(soversion, jack_version_major, jack_version_minor) + pipewire_name = 'pipewire-@0@'.format(apiversion) spa_name = 'spa-@0@'.format(spaversion)
View file
pipewire-0.3.76.tar.gz/pipewire-jack/src/meson.build -> pipewire-0.3.77.tar.gz/pipewire-jack/src/meson.build
Changed
@@ -36,7 +36,7 @@ pipewire_jack = shared_library('jack', pipewire_jack_sources, soversion : soversion, - version : libversion, + version : libjackversion, c_args : pipewire_jack_c_args, include_directories : configinc, jack_inc, dependencies : pipewire_dep, mathlib, @@ -47,7 +47,7 @@ pipewire_jackserver = shared_library('jackserver', pipewire_jackserver_sources, soversion : soversion, - version : libversion, + version : libjackversion, c_args : pipewire_jack_c_args, include_directories : configinc, jack_inc, dependencies : pipewire_dep, mathlib, @@ -58,7 +58,7 @@ pipewire_jacknet = shared_library('jacknet', pipewire_net_sources, soversion : soversion, - version : libversion, + version : libjackversion, c_args : pipewire_jack_c_args, include_directories : configinc, jack_inc, dependencies : pipewire_dep, mathlib,
View file
pipewire-0.3.76.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.77.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -137,6 +137,8 @@ char node_name512; int32_t priority; uint32_t client_id; + unsigned is_jack:1; + unsigned is_running:1; } node; struct { uint32_t src; @@ -926,6 +928,7 @@ int32_t avail; uint32_t index; struct notify *notify; + bool do_graph = false; if (c->frozen_callbacks != 0 || !c->pending_callbacks) return; @@ -976,11 +979,12 @@ o->port_link.dst_serial, notify->arg1, c->connect_arg); + + do_graph = true; break; case NOTIFY_TYPE_GRAPH: pw_log_debug("%p: graph", c); - recompute_latencies(c); - do_callback(c, graph_callback, c->active, c->graph_arg); + do_graph = true; break; case NOTIFY_TYPE_BUFFER_FRAMES: pw_log_debug("%p: buffer frames %d", c, notify->arg1); @@ -1031,6 +1035,10 @@ index += sizeof(struct notify); spa_ringbuffer_read_update(&c->notify_ring, index); } + if (do_graph) { + recompute_latencies(c); + do_callback(c, graph_callback, c->active, c->graph_arg); + } thaw_callbacks(c); pw_log_debug("%p: leave", c); } @@ -3061,6 +3069,35 @@ .destroy = proxy_destroy, }; +static void node_info(void *data, const struct pw_node_info *info) +{ + struct object *n = data; + struct client *c = n->client; + + pw_log_info("DSP node %d state change %s", info->id, + pw_node_state_as_string(info->state)); + + n->node.is_running = (info->state == PW_NODE_STATE_RUNNING); + + if (info->change_mask & PW_NODE_CHANGE_MASK_STATE) { + struct object *p; + spa_list_for_each(p, &c->context.objects, link) { + if (p->type != INTERFACE_Port || p->removed || + p->port.node_id != info->id) + continue; + if (n->node.is_running) + queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, p, 1, NULL); + else + queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, p, 0, NULL); + } + } +} + +static const struct pw_node_events node_events = { + PW_VERSION_NODE, + .info = node_info, +}; + static void port_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) @@ -3105,7 +3142,7 @@ struct client *c = (struct client *) data; struct object *o, *ot, *op; const char *str; - bool is_first = true; + bool do_emit = true; uint32_t serial; if (props == NULL) @@ -3162,7 +3199,7 @@ snprintf(o->node.name, sizeof(o->node.name), "%.*s-%d", (int)(sizeof(tmp)-11), tmp, id); } else { - is_first = ot == NULL; + do_emit = ot == NULL; snprintf(o->node.name, sizeof(o->node.name), "%s", tmp); } if (id == c->node_id) { @@ -3174,9 +3211,21 @@ if ((str = spa_dict_lookup(props, PW_KEY_PRIORITY_SESSION)) != NULL) o->node.priority = pw_properties_parse_int(str); + if ((str = spa_dict_lookup(props, PW_KEY_CLIENT_API)) != NULL) + o->node.is_jack = spa_streq(str, "jack"); pw_log_debug("%p: add node %d", c, id); + if (o->node.is_jack) { + o->proxy = pw_registry_bind(c->registry, + id, type, PW_VERSION_NODE, 0); + if (o->proxy) { + pw_proxy_add_listener(o->proxy, + &o->proxy_listener, &proxy_events, o); + pw_proxy_add_object_listener(o->proxy, + &o->object_listener, &node_events, o); + } + } pthread_mutex_lock(&c->context.lock); spa_list_append(&c->context.objects, &o->link); pthread_mutex_unlock(&c->context.lock); @@ -3255,6 +3304,8 @@ o->port.latencySPA_DIRECTION_INPUT = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); o->port.latencySPA_DIRECTION_OUTPUT = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT); + do_emit = !ot->node.is_jack || ot->node.is_running; + o->proxy = pw_registry_bind(c->registry, id, type, PW_VERSION_PORT, 0); if (o->proxy) { @@ -3409,23 +3460,24 @@ switch (o->type) { case INTERFACE_Node: - if (is_first) { - pw_log_info("%p: client added \"%s\"", c, o->node.name); + pw_log_info("%p: client added \"%s\" emit:%d", c, o->node.name, do_emit); + if (do_emit) queue_notify(c, NOTIFY_TYPE_REGISTRATION, o, 1, NULL); - } break; case INTERFACE_Port: - pw_log_info("%p: port added %u/%u \"%s\"", c, o->id, o->serial, o->port.name); - queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, o, 1, NULL); + pw_log_info("%p: port added %u/%u \"%s\" emit:%d", c, o->id, + o->serial, o->port.name, do_emit); + if (do_emit) + queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, o, 1, NULL); break; case INTERFACE_Link: pw_log_info("%p: link %u %u/%u -> %u/%u added", c, o->id, o->port_link.src, o->port_link.src_serial, o->port_link.dst, o->port_link.dst_serial); - queue_notify(c, NOTIFY_TYPE_CONNECT, o, 1, NULL); - queue_notify(c, NOTIFY_TYPE_GRAPH, NULL, 0, NULL); + if (do_emit) + queue_notify(c, NOTIFY_TYPE_CONNECT, o, 1, NULL); break; } emit_callbacks(c); @@ -3479,7 +3531,6 @@ o->port_link.src, o->port_link.src_serial, o->port_link.dst, o->port_link.dst_serial); queue_notify(c, NOTIFY_TYPE_CONNECT, o, 0, NULL); - queue_notify(c, NOTIFY_TYPE_GRAPH, NULL, 0, NULL); } else { pw_log_warn("unlink between unknown ports %d and %d", o->port_link.src, o->port_link.dst);
View file
pipewire-0.3.76.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.77.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c
Changed
@@ -985,7 +985,9 @@ MAKE_FORMAT(Y10, video, raw, 2, UNKNOWN), MAKE_FORMAT(Y12, video, raw, 2, UNKNOWN), MAKE_FORMAT(Y16, video, raw, 2, GRAY16_LE), +#ifdef V4L2_PIX_FMT_Y16_BE MAKE_FORMAT(Y16_BE, video, raw, 2, GRAY16_BE), +#endif MAKE_FORMAT(Y10BPACK, video, raw, 2, UNKNOWN), /* Palette formats */
View file
pipewire-0.3.76.tar.gz/spa/include/spa/utils/cleanup.h -> pipewire-0.3.77.tar.gz/spa/include/spa/utils/cleanup.h
Changed
@@ -40,13 +40,20 @@ _old_value; \ }) +#if __GNUC__ > 10 || defined(__clang__) #define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) +#else +#define spa_steal_ptr(ptr) ((__typeof__(ptr)) spa_exchange((ptr), NULL)) +#endif + #define spa_steal_fd(fd) spa_exchange((fd), -1) /* ========================================================================== */ #include <stdlib.h> + +#if __GNUC__ > 10 || defined(__clang__) #define spa_clear_ptr(ptr, destructor) \ __extension__ ({ \ __typeof__(*(ptr)) *_old_value = spa_steal_ptr(ptr); \ @@ -54,6 +61,15 @@ destructor(_old_value); \ (void) 0; \ }) +#else +#define spa_clear_ptr(ptr, destructor) \ +__extension__ ({ \ + __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ + if (_old_value) \ + destructor(_old_value); \ + (void) 0; \ +}) +#endif static inline void _spa_autofree_cleanup_func(void *p) {
View file
pipewire-0.3.76.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.77.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -2498,9 +2498,10 @@ if (avail < target) max_read = target - avail; - else if (avail > target) + else if (avail > target) { snd_pcm_forward(state->hndl, avail - target); - avail = target; + avail = target; + } state->alsa_sync = false; } else state->alsa_sync_warning = true;
View file
pipewire-0.3.76.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.77.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -9,12 +9,14 @@ #include <spa/support/plugin.h> #include <spa/support/cpu.h> +#include <spa/support/loop.h> #include <spa/support/log.h> #include <spa/utils/result.h> #include <spa/utils/list.h> #include <spa/utils/json.h> #include <spa/utils/names.h> #include <spa/utils/string.h> +#include <spa/utils/ratelimit.h> #include <spa/node/node.h> #include <spa/node/io.h> #include <spa/node/utils.h> @@ -190,6 +192,8 @@ uint32_t quantum_limit; enum spa_direction direction; + struct spa_ratelimit rate_limit; + struct props props; struct spa_io_position *io_position; @@ -2316,12 +2320,8 @@ { struct buffer *b; - if (spa_list_is_empty(&port->queue)) { - if (port->n_buffers > 0) - spa_log_warn(this->log, "%p: out of buffers on port %d %d", - this, port->id, port->n_buffers); + if (spa_list_is_empty(&port->queue)) return NULL; - } b = spa_list_first(&port->queue, struct buffer, link); spa_log_trace_fp(this->log, "%p: peek buffer %d/%d on port %d %u", @@ -2331,10 +2331,12 @@ static inline void dequeue_buffer(struct impl *this, struct port *port, struct buffer *b) { - spa_list_remove(&b->link); - SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED); spa_log_trace_fp(this->log, "%p: dequeue buffer %d on port %d %u", this, b->id, port->id, b->flags); + if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_QUEUED)) + return; + spa_list_remove(&b->link); + SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED); } static int @@ -2614,6 +2616,14 @@ return true; } +static uint64_t get_time_ns(struct impl *impl) +{ + struct timespec now; + if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) + return 0; + return SPA_TIMESPEC_TO_NSEC(&now); +} + static int impl_node_process(void *object) { struct impl *this = object; @@ -2626,12 +2636,13 @@ struct buffer *buf, *out_bufsMAX_PORTS; struct spa_data *bd; struct dir *dir; - int tmp = 0, res = 0; + int tmp = 0, res = 0, missed; bool in_passthrough, mix_passthrough, resample_passthrough, out_passthrough; bool in_avail = false, flush_in = false, flush_out = false; bool draining = false, in_empty = this->out_offset == 0; struct spa_io_buffers *io, *ctrlio = NULL; const struct spa_pod_sequence *ctrl = NULL; + uint64_t current_time; /* calculate quantum scale, this is how many samples we need to produce or * consume. Also update the rate scale, this is sent to the resampler to adjust @@ -2640,6 +2651,7 @@ if (SPA_LIKELY(this->io_position)) { double r = this->rate_scale; + current_time = this->io_position->clock.nsec; quant_samples = this->io_position->clock.duration; if (this->direction == SPA_DIRECTION_INPUT) { if (this->io_position->clock.rate.denom != this->resample.o_rate) @@ -2660,8 +2672,10 @@ this->rate_scale = r; } } - else + else { + current_time = get_time_ns(this); quant_samples = this->quantum_limit; + } dir = &this->dirSPA_DIRECTION_INPUT; in_passthrough = dir->conv.is_passthrough; @@ -2789,6 +2803,11 @@ queue_buffer(this, port, io->buffer_id); buf = peek_buffer(this, port); + if (buf == NULL && port->n_buffers > 0 && + (missed = spa_ratelimit_test(&this->rate_limit, current_time)) >= 0) { + spa_log_warn(this->log, "%p: (%d missed) out of buffers on port %d %d", + this, missed, port->id, port->n_buffers); + } } out_bufsi = buf; @@ -3195,9 +3214,11 @@ this->cpu_flags = spa_cpu_get_flags(this->cpu); this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu)); } - props_reset(&this->props); + this->rate_limit.interval = 2 * SPA_NSEC_PER_SEC; + this->rate_limit.burst = 1; + this->mix.options = CHANNELMIX_OPTION_UPMIX | CHANNELMIX_OPTION_MIX_LFE; this->mix.upmix = CHANNELMIX_UPMIX_NONE; this->mix.log = this->log;
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-hsphfpd.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-hsphfpd.c
Changed
@@ -170,10 +170,9 @@ { spa_list_remove(&endpoint->link); free(endpoint->path); - if (endpoint->local_address) - free(endpoint->local_address); - if (endpoint->remote_address) - free(endpoint->remote_address); + free(endpoint->local_address); + free(endpoint->remote_address); + free(endpoint); } static bool hsphfpd_cmp_transport_path(struct spa_bt_transport *t, const void *data) @@ -198,9 +197,9 @@ int type, void *value) { - DBusMessage *m, *r; + spa_autoptr(DBusMessage) m = NULL, r = NULL; DBusMessageIter iter; - DBusError err; + spa_auto(DBusError) err = DBUS_ERROR_INIT; m = dbus_message_new_method_call(HSPHFPD_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "Set"); if (m == NULL) @@ -209,15 +208,9 @@ dbus_message_iter_init_append(m, &iter); dbus_message_iter_append_basic(&iter, type, value); - dbus_error_init(&err); - r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err); - dbus_message_unref(m); - m = NULL; - if (r == NULL) { spa_log_error(backend->log, "Transport Set() failed for transport %s (%s)", path, err.message); - dbus_error_free(&err); return -EIO; } @@ -226,7 +219,6 @@ return -EIO; } - dbus_message_unref(r); return 0; } @@ -447,7 +439,7 @@ const char *interface; const char *property; const char *agent_codec; - DBusMessage *r = NULL; + spa_autoptr(DBusMessage) r = NULL; if (!check_signature(m, "ss")) { r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call"); @@ -488,7 +480,6 @@ if (!dbus_connection_send(conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } @@ -497,7 +488,7 @@ const char *interface; DBusMessageIter iter, array, dict, data; const char *agent_codec; - DBusMessage *r = NULL; + spa_autoptr(DBusMessage) r = NULL; if (!check_signature(m, "s")) { r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call"); @@ -538,7 +529,6 @@ if (!dbus_connection_send(conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } @@ -547,7 +537,6 @@ struct impl *backend = userdata; DBusMessageIter arg_i; const char *transport_path; - int fd; const char *sender; const char *endpoint_path = NULL; const char *air_codec = NULL; @@ -560,7 +549,8 @@ struct hsphfpd_endpoint *endpoint; struct spa_bt_transport *transport; struct hsphfpd_transport_data *transport_data; - DBusMessage *r = NULL; + spa_autoptr(DBusMessage) r = NULL; + spa_autoclose int fd = -1; if (!check_signature(m, "oha{sv}")) { r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call"); @@ -578,7 +568,6 @@ sender = dbus_message_get_sender(m); if (!spa_streq(sender, backend->hsphfpd_service_id)) { - close(fd); spa_log_error(backend->log, "Sender '%s' is not authorized", sender); r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Sender '%s' is not authorized", sender); goto fail; @@ -601,28 +590,24 @@ &mtu); if (!endpoint_path) { - close(fd); spa_log_error(backend->log, "Endpoint property was not specified"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "Endpoint property was not specified"); goto fail; } if (!air_codec) { - close(fd); spa_log_error(backend->log, "AirCodec property was not specified"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "AirCodec property was not specified"); goto fail; } if (!rx_volume_control) { - close(fd); spa_log_error(backend->log, "RxVolumeControl property was not specified"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeControl property was not specified"); goto fail; } if (!tx_volume_control) { - close(fd); spa_log_error(backend->log, "TxVolumeControl property was not specified"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeControl property was not specified"); goto fail; @@ -630,7 +615,6 @@ if (rx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) { if (rx_volume_gain == (uint16_t)-1) { - close(fd); spa_log_error(backend->log, "RxVolumeGain property was not specified, but VolumeControl is not none"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeGain property was not specified, but VolumeControl is not none"); goto fail; @@ -641,7 +625,6 @@ if (tx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) { if (tx_volume_gain == (uint16_t)-1) { - close(fd); spa_log_error(backend->log, "TxVolumeGain property was not specified, but VolumeControl is not none"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeGain property was not specified, but VolumeControl is not none"); goto fail; @@ -651,7 +634,6 @@ } if (!mtu) { - close(fd); spa_log_error(backend->log, "MTU property was not specified"); r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "MTU property was not specified"); goto fail; @@ -659,14 +641,12 @@ endpoint = endpoint_find(backend, endpoint_path); if (!endpoint) { - close(fd); spa_log_error(backend->log, "Endpoint %s does not exist", endpoint_path); r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s does not exist", endpoint_path); goto fail; } if (!endpoint->valid) { - close(fd); spa_log_error(backend->log, "Endpoint %s is not valid", endpoint_path); r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not valid", endpoint_path); goto fail; @@ -674,7 +654,6 @@ transport = spa_bt_transport_find(backend->monitor, endpoint_path); if (!transport) { - close(fd); spa_log_error(backend->log, "Endpoint %s is not connected", endpoint_path); r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not connected", endpoint_path); goto fail; @@ -684,7 +663,6 @@ spa_log_warn(backend->log, "Expecting codec to be %d, got %d", transport->codec, codec); if (transport->fd >= 0) { - close(fd); spa_log_error(backend->log, "Endpoint %s has already active transport", endpoint_path); r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s has already active transport", endpoint_path); goto fail; @@ -707,18 +685,15 @@ transport->read_mtu = mtu; transport->write_mtu = mtu; - transport->fd = fd; + transport->fd = spa_steal_fd(fd);
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
@@ -177,16 +177,9 @@ static DBusHandlerResult profile_release(DBusConnection *conn, DBusMessage *m, void *userdata) { - DBusMessage *r; - - r = dbus_message_new_error(m, BLUEZ_PROFILE_INTERFACE ".Error.NotImplemented", - "Method not implemented"); - if (r == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!dbus_connection_send(conn, r, NULL)) + if (!reply_with_error(conn, m, BLUEZ_PROFILE_INTERFACE ".Error.NotImplemented", "Method not implemented")) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } @@ -1390,12 +1383,11 @@ struct sockaddr_sco addr; socklen_t len; bdaddr_t src; - int sock = -1; - sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO); + spa_autoclose int sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO); if (sock < 0) { spa_log_error(backend->log, "socket(SEQPACKET, SCO) %s", strerror(errno)); - goto fail; + return -1; } str2ba(adapter->address, &src); @@ -1407,7 +1399,7 @@ if (bind(sock, (struct sockaddr *) &addr, len) < 0) { spa_log_error(backend->log, "bind(): %s", strerror(errno)); - goto fail; + return -1; } spa_log_debug(backend->log, "msbc=%d", (int)msbc); @@ -1418,16 +1410,11 @@ voice_config.setting = BT_VOICE_TRANSPARENT; if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &voice_config, sizeof(voice_config)) < 0) { spa_log_error(backend->log, "setsockopt(): %s", strerror(errno)); - goto fail; + return -1; } } - return sock; - -fail: - if (sock >= 0) - close(sock); - return -1; + return spa_steal_fd(sock); } static int sco_do_connect(struct spa_bt_transport *t) @@ -1436,11 +1423,7 @@ struct spa_bt_device *d = t->device; struct transport_data *td = t->user_data; struct sockaddr_sco addr; - socklen_t len; int err; - int sock; - bdaddr_t dst; - int retry = 2; spa_log_debug(backend->log, "transport %p: enter sco_do_connect, codec=%u", t, t->codec); @@ -1450,52 +1433,45 @@ if (d->adapter == NULL) return -EIO; - str2ba(d->address, &dst); - -again: - sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC)); - if (sock < 0) - return -1; - - len = sizeof(addr); - memset(&addr, 0, len); + spa_zero(addr); addr.sco_family = AF_BLUETOOTH; - bacpy(&addr.sco_bdaddr, &dst); - - spa_log_debug(backend->log, "transport %p: doing connect", t); - err = connect(sock, (struct sockaddr *) &addr, len); - if (err < 0 && errno == ECONNABORTED && retry-- > 0) { - spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d", - strerror(errno), retry); - close(sock); - goto again; - } else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { - spa_log_error(backend->log, "connect(): %s", strerror(errno)); + str2ba(d->address, &addr.sco_bdaddr); + + for (int retry = 2;;) { + spa_autoclose int sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC)); + if (sock < 0) + return -1; + + spa_log_debug(backend->log, "transport %p: doing connect", t); + err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); + if (err < 0 && errno == ECONNABORTED && retry-- > 0) { + spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d", + strerror(errno), retry); + continue; + } else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { + spa_log_error(backend->log, "connect(): %s", strerror(errno)); #ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE - if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC && - td->rfcomm->msbc_supported_by_hfp) { - /* Adapter doesn't support msbc. Renegotiate. */ - d->adapter->msbc_probed = true; - d->adapter->has_msbc = false; - td->rfcomm->msbc_supported_by_hfp = false; - if (t->profile == SPA_BT_PROFILE_HFP_HF) { - td->rfcomm->hfp_ag_switching_codec = true; - rfcomm_send_reply(td->rfcomm, "+BCS: 1"); - } else if (t->profile == SPA_BT_PROFILE_HFP_AG) { - rfcomm_send_cmd(td->rfcomm, "AT+BAC=1"); + if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC && + td->rfcomm->msbc_supported_by_hfp) { + /* Adapter doesn't support msbc. Renegotiate. */ + d->adapter->msbc_probed = true; + d->adapter->has_msbc = false; + td->rfcomm->msbc_supported_by_hfp = false; + if (t->profile == SPA_BT_PROFILE_HFP_HF) { + td->rfcomm->hfp_ag_switching_codec = true; + rfcomm_send_reply(td->rfcomm, "+BCS: 1"); + } else if (t->profile == SPA_BT_PROFILE_HFP_AG) { + rfcomm_send_cmd(td->rfcomm, "AT+BAC=1"); + } } - } #endif - goto fail_close; - } - - td->err = -EINPROGRESS; + return -1; + } - return sock; + td->err = -EINPROGRESS; -fail_close: - close(sock); - return -1; + return spa_steal_fd(sock); + } } static int rfcomm_ag_sync_volume(struct rfcomm *rfcomm, bool later); @@ -1726,25 +1702,24 @@ struct impl *backend = source->data; struct sockaddr_sco addr; socklen_t addrlen; - int sock = -1; char local_address18, remote_address18; struct rfcomm *rfcomm; struct spa_bt_transport *t = NULL; if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) { spa_log_error(backend->log, "error listening SCO connection: %s", strerror(errno)); - goto fail; + return; } memset(&addr, 0, sizeof(addr)); addrlen = sizeof(addr); spa_log_debug(backend->log, "doing accept"); - sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen); + spa_autoclose int sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen); if (sock < 0) { if (errno != EAGAIN) spa_log_error(backend->log, "SCO accept(): %s", strerror(errno)); - goto fail; + return; } ba2str(&addr.sco_bdaddr, remote_address); @@ -1754,7 +1729,7 @@ if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) { spa_log_error(backend->log, "SCO getsockname(): %s", strerror(errno)); - goto fail; + return; } ba2str(&addr.sco_bdaddr, local_address); @@ -1770,19 +1745,19 @@ if (!t) { spa_log_debug(backend->log, "No transport for adapter %s and remote %s",
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-ofono.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-ofono.c
Changed
@@ -140,8 +140,8 @@ static int _audio_acquire(struct impl *backend, const char *path, uint8_t *codec) { - DBusMessage *m, *r; - DBusError err; + spa_autoptr(DBusMessage) m = NULL, r = NULL; + spa_auto(DBusError) err = DBUS_ERROR_INIT; int ret = 0; m = dbus_message_new_method_call(OFONO_SERVICE, path, @@ -150,7 +150,6 @@ if (m == NULL) return -ENOMEM; - dbus_error_init(&err); /* * XXX: We assume here oFono replies. It however can happen that the headset does @@ -160,20 +159,15 @@ * XXX: do better here right now. */ r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err); - dbus_message_unref(m); - m = NULL; - if (r == NULL) { spa_log_error(backend->log, "Transport Acquire() failed for transport %s (%s)", path, err.message); - dbus_error_free(&err); return -EIO; } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(backend->log, "Acquire returned error: %s", dbus_message_get_error_name(r)); - ret = -EIO; - goto finish; + return -EIO; } if (!dbus_message_get_args(r, &err, @@ -181,13 +175,9 @@ DBUS_TYPE_BYTE, codec, DBUS_TYPE_INVALID)) { spa_log_error(backend->log, "Failed to parse Acquire() reply: %s", err.message); - dbus_error_free(&err); - ret = -EIO; - goto finish; + return -EIO; } -finish: - dbus_message_unref(r); return ret; } @@ -462,18 +452,12 @@ static DBusHandlerResult ofono_release(DBusConnection *conn, DBusMessage *m, void *userdata) { struct impl *backend = userdata; - DBusMessage *r; spa_log_warn(backend->log, "release"); - r = dbus_message_new_error(m, OFONO_HF_AUDIO_AGENT_INTERFACE ".Error.NotImplemented", - "Method not implemented"); - if (r == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!dbus_connection_send(conn, r, NULL)) + if (!reply_with_error(conn, m, OFONO_HF_AUDIO_AGENT_INTERFACE ".Error.NotImplemented", "Method not implemented")) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } @@ -532,7 +516,7 @@ uint8_t codec; struct spa_bt_transport *t; struct transport_data *td; - DBusMessage *r = NULL; + spa_autoptr(DBusMessage) r = NULL; if (dbus_message_get_args(m, NULL, DBUS_TYPE_OBJECT_PATH, &path, @@ -582,11 +566,9 @@ fail: if (r) { - DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED; if (!dbus_connection_send(backend->conn, r, NULL)) - res = DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); - return res; + return DBUS_HANDLER_RESULT_NEED_MEMORY; + return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_HANDLED; @@ -596,7 +578,6 @@ { struct impl *backend = userdata; const char *path, *interface, *member; - DBusMessage *r; DBusHandlerResult res; path = dbus_message_get_path(m); @@ -607,6 +588,7 @@ if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { const char *xml = OFONO_INTROSPECT_XML; + spa_autoptr(DBusMessage) r = NULL; if ((r = dbus_message_new_method_return(m)) == NULL) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -615,7 +597,6 @@ if (!dbus_connection_send(backend->conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); res = DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call(m, OFONO_HF_AUDIO_AGENT_INTERFACE, "Release")) @@ -631,22 +612,21 @@ static void ofono_getcards_reply(DBusPendingCall *pending, void *user_data) { struct impl *backend = user_data; - DBusMessage *r; DBusMessageIter i, array_i, struct_i, props_i; - r = steal_reply_and_unref(&pending); + spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending); if (r == NULL) return; if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(backend->log, "Failed to get a list of handsfree audio cards: %s", dbus_message_get_error_name(r)); - goto finish; + return; } if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "a(oa{sv})")) { spa_log_error(backend->log, "Invalid arguments in GetCards() reply"); - goto finish; + return; } dbus_message_iter_recurse(&i, &array_i); @@ -663,22 +643,16 @@ dbus_message_iter_next(&array_i); } - -finish: - dbus_message_unref(r); } -static int backend_ofono_register(void *data) +static int ofono_register(struct impl *backend) { - struct impl *backend = data; - - DBusMessage *m, *r; + spa_autoptr(DBusMessage) m = NULL, r = NULL; const char *path = OFONO_AUDIO_CLIENT; uint8_t codecs2; const uint8_t *pcodecs = codecs; - int ncodecs = 0, res; - DBusPendingCall *call; - DBusError err; + int ncodecs = 0; + spa_auto(DBusError) err = DBUS_ERROR_INIT; spa_log_debug(backend->log, "Registering"); @@ -695,72 +669,77 @@ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcodecs, ncodecs, DBUS_TYPE_INVALID); - dbus_error_init(&err); - r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err); - dbus_message_unref(m); - if (r == NULL) { if (dbus_error_has_name(&err, "org.freedesktop.DBus.Error.ServiceUnknown")) { spa_log_info(backend->log, "oFono not available: %s", err.message); - res = -ENOTSUP; + return -ENOTSUP; } else { spa_log_warn(backend->log, "Registering Profile %s failed: %s (%s)", path, err.message, err.name); - res = -EIO; + return -EIO; } - dbus_error_free(&err); - return res; }
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -221,9 +221,10 @@ } // Unregister virtual battery of device -static void battery_remove(struct spa_bt_device *device) { +static void battery_remove(struct spa_bt_device *device) +{ DBusMessageIter i, entry; - DBusMessage *m; + spa_autoptr(DBusMessage) m = NULL; const char *interface; cancel_and_unref(&device->battery_pending_call); @@ -252,8 +253,6 @@ spa_log_error(device->monitor->log, "sending " DBUS_SIGNAL_INTERFACES_REMOVED " failed"); } - dbus_message_unref(m); - device->has_battery = false; } @@ -292,7 +291,7 @@ { spa_log_debug(device->monitor->log, "updating battery: %s", device->battery_path); - DBusMessage *msg; + spa_autoptr(DBusMessage) msg = NULL; DBusMessageIter iter; msg = dbus_message_new_signal(device->battery_path, @@ -308,13 +307,12 @@ if (!dbus_connection_send(device->monitor->conn, msg, NULL)) spa_log_error(device->monitor->log, "Error updating battery"); - - dbus_message_unref(msg); } // Create new virtual battery with value stored in current device object -static void battery_create(struct spa_bt_device *device) { - DBusMessage *msg; +static void battery_create(struct spa_bt_device *device) +{ + spa_autoptr(DBusMessage) msg = NULL; DBusMessageIter iter, entry, dict; msg = dbus_message_new_signal(PIPEWIRE_BATTERY_PROVIDER, DBUS_INTERFACE_OBJECT_MANAGER, @@ -339,8 +337,6 @@ return; } - dbus_message_unref(msg); - spa_log_debug(device->monitor->log, "Created virtual battery for %s", device->address); device->has_battery = true; } @@ -348,17 +344,15 @@ static void on_battery_provider_registered(DBusPendingCall *pending_call, void *data) { - DBusMessage *reply; struct spa_bt_device *device = data; spa_assert(device->battery_pending_call == pending_call); - reply = steal_reply_and_unref(&device->battery_pending_call); + spa_autoptr(DBusMessage) reply = steal_reply_and_unref(&device->battery_pending_call); if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(device->monitor->log, "Failed to register battery provider. Error: %s", dbus_message_get_error_name(reply)); spa_log_error(device->monitor->log, "BlueZ Battery Provider is not available, won't retry to register it. Make sure you are running BlueZ 5.56+ with experimental features to use Battery Provider."); device->adapter->battery_provider_unavailable = true; - dbus_message_unref(reply); return; } @@ -368,14 +362,12 @@ if (!device->has_battery) battery_create(device); - - dbus_message_unref(reply); } // Register Battery Provider for adapter and then create virtual battery for device static void register_battery_provider(struct spa_bt_device *device) { - DBusMessage *method_call; + spa_autoptr(DBusMessage) method_call = NULL; DBusMessageIter message_iter; if (device->battery_pending_call) { @@ -398,26 +390,12 @@ dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH, &object_path); - if (!dbus_connection_send_with_reply(device->monitor->conn, method_call, &device->battery_pending_call, - DBUS_TIMEOUT_USE_DEFAULT)) { - dbus_message_unref(method_call); - spa_log_error(device->monitor->log, "Failed to register battery provider"); - return; - } - - dbus_message_unref(method_call); - + device->battery_pending_call = send_with_reply(device->monitor->conn, method_call, + on_battery_provider_registered, device); if (!device->battery_pending_call) { spa_log_error(device->monitor->log, "Failed to register battery provider"); return; } - - if (!dbus_pending_call_set_notify( - device->battery_pending_call, on_battery_provider_registered, - device, NULL)) { - spa_log_error(device->monitor->log, "Failed to register battery provider"); - cancel_and_unref(&device->battery_pending_call); - } } static int media_codec_to_endpoint(const struct media_codec *codec, @@ -546,20 +524,17 @@ const char *path; uint8_t *cap, configA2DP_MAX_CAPS_SIZE; uint8_t *pconf = (uint8_t *) config; - DBusMessage *r; - DBusError err; + spa_autoptr(DBusMessage) r = NULL; + spa_auto(DBusError) err = DBUS_ERROR_INIT; int size, res; const struct media_codec *codec; bool sink; - dbus_error_init(&err); - path = dbus_message_get_path(m); if (!dbus_message_get_args(m, &err, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) { spa_log_error(monitor->log, "Endpoint SelectConfiguration(): %s", err.message); - dbus_error_free(&err); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size); @@ -604,8 +579,6 @@ if (!dbus_connection_send(conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_unref(r); - return DBUS_HANDLER_RESULT_HANDLED; } @@ -618,7 +591,7 @@ struct spa_bt_monitor *monitor = userdata; const char *path; DBusMessageIter args, props, iter; - DBusMessage *r = NULL; + spa_autoptr(DBusMessage) r = NULL; int res; const struct media_codec *codec; bool sink; @@ -831,12 +804,8 @@ dbus_message_iter_close_container(&iter, &dict); - if (r) { - if (!dbus_connection_send(conn, r, NULL)) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_unref(r); - } + if (!dbus_connection_send(conn, r, NULL)) + return DBUS_HANDLER_RESULT_NEED_MEMORY; return DBUS_HANDLER_RESULT_HANDLED; @@ -845,15 +814,8 @@ goto error; error: - if (r) - dbus_message_unref(r); - if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", err_msg)) == NULL) + if (!reply_with_error(conn, m, "org.bluez.Error.InvalidArguments", err_msg)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!dbus_connection_send(conn, r, NULL)) { - dbus_message_unref(r); - return DBUS_HANDLER_RESULT_NEED_MEMORY; - } - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } @@ -1111,35 +1073,30 @@ static int adapter_init_modalias(struct spa_bt_monitor *monitor, struct spa_bt_adapter *d) { char path1024; - FILE *f = NULL; int vendor_id, product_id;
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/dbus-helpers.h -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/dbus-helpers.h
Changed
@@ -5,6 +5,8 @@ #ifndef SPA_BLUEZ5_DBUS_HELPERS_H #define SPA_BLUEZ5_DBUS_HELPERS_H +#include <stdbool.h> + #include <dbus/dbus.h> #include <spa/utils/cleanup.h> @@ -29,4 +31,42 @@ return reply; } +SPA_DEFINE_AUTOPTR_CLEANUP(DBusMessage, DBusMessage, { + spa_clear_ptr(*thing, dbus_message_unref); +}) + +static inline bool reply_with_error(DBusConnection *conn, + DBusMessage *reply_to, + const char *error_name, const char *error_message) +{ + spa_autoptr(DBusMessage) reply = dbus_message_new_error(reply_to, error_name, error_message); + + return reply && dbus_connection_send(conn, reply, NULL); +} + +static inline DBusPendingCall *send_with_reply(DBusConnection *conn, + DBusMessage *m, + DBusPendingCallNotifyFunction callback, void *user_data) +{ + DBusPendingCall *pending_call; + + if (!dbus_connection_send_with_reply(conn, m, &pending_call, DBUS_TIMEOUT_USE_DEFAULT)) + return NULL; + + if (!pending_call) + return NULL; + + if (!dbus_pending_call_set_notify(pending_call, callback, user_data, NULL)) { + dbus_pending_call_cancel(pending_call); + dbus_pending_call_unref(pending_call); + return NULL; + } + + return pending_call; +} + +SPA_DEFINE_AUTO_CLEANUP(DBusError, DBusError, { + dbus_error_free(thing); +}) + #endif /* SPA_BLUEZ5_DBUS_HELPERS_H */
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/hci.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/hci.c
Changed
@@ -29,10 +29,12 @@ #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> +#include <spa/utils/cleanup.h> + int spa_bt_adapter_has_msbc(struct spa_bt_adapter *adapter) { - int hci_id, res; - int sock = -1; + int hci_id; + spa_autoclose int sock = -1; uint8_t features8, max_page = 0; struct sockaddr_hci a; const char *str; @@ -46,28 +48,20 @@ sock = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI); if (sock < 0) - goto error; + return -errno; memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = hci_id; if (bind(sock, (struct sockaddr *) &a, sizeof(a)) < 0) - goto error; + return -errno; if (hci_read_local_ext_features(sock, 0, &max_page, features, 1000) < 0) - goto error; - - close(sock); + return -errno; adapter->msbc_probed = true; adapter->has_msbc = ((features2 & LMP_TRSP_SCO) && (features3 & LMP_ESCO)) ? 1 : 0; return adapter->has_msbc; - -error: - res = -errno; - if (sock >= 0) - close(sock); - return res; } #endif
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/media-codecs.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/media-codecs.c
Changed
@@ -9,6 +9,7 @@ */ #include <spa/utils/string.h> +#include <spa/utils/cleanup.h> #include "media-codecs.h" @@ -16,7 +17,8 @@ uint32_t cap, int preferred_value) { size_t i; - int *scores, res; + spa_autofree int *scores = NULL; + int res; unsigned int max_priority; if (n == 0) @@ -54,9 +56,8 @@ } if (scoresres < 0) - res = -EINVAL; + return -EINVAL; - free(scores); return res; }
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/modemmanager.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/modemmanager.c
Changed
@@ -40,35 +40,6 @@ void *user_data; }; -static bool mm_dbus_connection_send_with_reply(struct impl *this, DBusMessage *m, DBusPendingCall **pending_return, - DBusPendingCallNotifyFunction function, void *user_data) -{ - spa_assert(*pending_return == NULL); - - DBusPendingCall *pending_call; - bool ret = dbus_connection_send_with_reply(this->conn, m, &pending_call, -1); - if (!ret) { - spa_log_debug(this->log, "dbus call failure"); - goto out; - } - - spa_assert(pending_call); - - ret = dbus_pending_call_set_notify(pending_call, function, user_data, NULL); - if (!ret) { - spa_log_debug(this->log, "dbus set notify failure"); - cancel_and_unref(&pending_call); - goto out; - } - - *pending_return = pending_call; - -out: - dbus_message_unref(m); - - return ret; -} - static int mm_state_to_clcc(struct impl *this, MMCallState state) { switch (state) { @@ -119,28 +90,27 @@ { struct call *call = user_data; struct impl *this = call->this; - DBusMessage *r; DBusMessageIter arg_i, element_i; MMCallDirection direction; MMCallState state; spa_assert(call->pending == pending); - r = steal_reply_and_unref(&call->pending); + spa_autoptr(DBusMessage) r = steal_reply_and_unref(&call->pending); if (r == NULL) return; if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) { spa_log_warn(this->log, "ModemManager D-Bus Call not available"); - goto finish; + return; } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(this->log, "GetAll() failed: %s", dbus_message_get_error_name(r)); - goto finish; + return; } if (!dbus_message_iter_init(r, &arg_i) || !spa_streq(dbus_message_get_signature(r), "a{sv}")) { spa_log_error(this->log, "Invalid arguments in GetAll() reply"); - goto finish; + return; } spa_log_debug(this->log, "Call path: %s", call->path); @@ -184,9 +154,6 @@ dbus_message_iter_next(&element_i); } - -finish: - dbus_message_unref(r); } static DBusHandlerResult mm_parse_voice_properties(struct impl *this, DBusMessageIter *props_i) @@ -417,23 +384,22 @@ static void mm_get_managed_objects_reply(DBusPendingCall *pending, void *user_data) { struct impl *this = user_data; - DBusMessage *r; DBusMessageIter i, array_i; spa_assert(this->pending == pending); - r = steal_reply_and_unref(&this->pending); + spa_autoptr(DBusMessage) r = steal_reply_and_unref(&this->pending); if (r == NULL) return; if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(this->log, "Failed to get a list of endpoints from ModemManager: %s", dbus_message_get_error_name(r)); - goto finish; + return; } if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) { spa_log_error(this->log, "Invalid arguments in GetManagedObjects() reply"); - goto finish; + return; } dbus_message_iter_recurse(&i, &array_i); @@ -444,9 +410,6 @@ mm_parse_interfaces(this, &dict_i); dbus_message_iter_next(&array_i); } - -finish: - dbus_message_unref(r); } static void call_free(struct call *call) @@ -501,12 +464,10 @@ static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data) { struct impl *this = user_data; - DBusError err; - - dbus_error_init(&err); if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) { const char *name, *old_owner, *new_owner; + spa_auto(DBusError) err = DBUS_ERROR_INIT; spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m)); @@ -609,6 +570,7 @@ const char *path; struct call *call_object; const char *mm_call_interface = MM_DBUS_INTERFACE_CALL; + spa_autoptr(DBusMessage) m = NULL; if (!spa_streq(this->modem.path, dbus_message_get_path(m))) goto finish; @@ -632,7 +594,9 @@ if (m == NULL) goto finish; dbus_message_append_args(m, DBUS_TYPE_STRING, &mm_call_interface, DBUS_TYPE_INVALID); - if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_properties_reply, call_object)) { + + call_object->pending = send_with_reply(this->conn, m, mm_get_call_properties_reply, call_object); + if (!call_object->pending) { spa_log_error(this->log, "dbus call failure"); goto finish; } @@ -707,18 +671,16 @@ static int add_filters(struct impl *this) { - DBusError err; - if (this->filters_added) return 0; - dbus_error_init(&err); - if (!dbus_connection_add_filter(this->conn, mm_filter_cb, this, NULL)) { spa_log_error(this->log, "failed to add filter function"); - goto fail; + return -EIO; } + spa_auto(DBusError) err = DBUS_ERROR_INIT; + dbus_bus_add_match(this->conn, "type='signal',sender='org.freedesktop.DBus'," "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" MM_DBUS_SERVICE "'", &err); @@ -744,10 +706,6 @@ this->filters_added = true; return 0; - -fail: - dbus_error_free(&err); - return -EIO; } bool mm_is_available(void *modemmanager) @@ -771,12 +729,11 @@ struct impl *this = dbus_cmd_data->this; struct call *call = dbus_cmd_data->call; void *user_data = dbus_cmd_data->user_data; - DBusMessage *r; free(data); spa_assert(call->pending == pending); - r = steal_reply_and_unref(&call->pending); + spa_autoptr(DBusMessage) r = steal_reply_and_unref(&call->pending); if (r == NULL) return; @@ -801,12 +758,11 @@ struct dbus_cmd_data *dbus_cmd_data = data; struct impl *this = dbus_cmd_data->this; void *user_data = dbus_cmd_data->user_data;
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/player.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/player.c
Changed
@@ -9,6 +9,7 @@ #include <spa/utils/string.h> #include "defs.h" +#include "dbus-helpers.h" #include "player.h" #define PLAYER_OBJECT_PATH_BASE "/media_player" @@ -167,18 +168,18 @@ static DBusMessage *introspect(struct impl *impl, DBusMessage *m) { const char *xml = PLAYER_INTROSPECT_XML; - DBusMessage *r; + spa_autoptr(DBusMessage) r = NULL; if ((r = dbus_message_new_method_return(m)) == NULL) return NULL; if (!dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)) return NULL; - return r; + return spa_steal_ptr(r); } static DBusHandlerResult player_handler(DBusConnection *c, DBusMessage *m, void *userdata) { struct impl *impl = userdata; - DBusMessage *r; + spa_autoptr(DBusMessage) r = NULL; if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) { r = introspect(impl, m); @@ -194,20 +195,16 @@ if (r == NULL) return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!dbus_connection_send(impl->conn, r, NULL)) { - dbus_message_unref(r); + if (!dbus_connection_send(impl->conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - } - dbus_message_unref(r); return DBUS_HANDLER_RESULT_HANDLED; } static int send_update_signal(struct impl *impl) { - DBusMessage *m; + spa_autoptr(DBusMessage) m = NULL; const char *iface = PLAYER_INTERFACE; DBusMessageIter i, a; - int res = 0; m = dbus_message_new_signal(impl->path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged"); if (m == NULL) @@ -223,11 +220,9 @@ dbus_message_iter_close_container(&i, &a); if (!dbus_connection_send(impl->conn, m, NULL)) - res = -EIO; - - dbus_message_unref(m); + return -EIO; - return res; + return 0; } static void update_properties(struct impl *impl, bool send_signal) @@ -330,10 +325,9 @@ { struct impl *impl = SPA_CONTAINER_OF(player, struct impl, this); - DBusError err; + spa_auto(DBusError) err = DBUS_ERROR_INIT; DBusMessageIter i; - DBusMessage *m, *r; - int res = 0; + spa_autoptr(DBusMessage) m = NULL, r = NULL; spa_log_debug(impl->log, "RegisterPlayer() for dummy AVRCP player %s for %s", impl->path, adapter_path); @@ -347,34 +341,27 @@ dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &impl->path); append_properties(impl, &i); - dbus_error_init(&err); r = dbus_connection_send_with_reply_and_block(impl->conn, m, -1, &err); - dbus_message_unref(m); - if (r == NULL) { spa_log_error(impl->log, "RegisterPlayer() failed (%s)", err.message); - dbus_error_free(&err); return -EIO; } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(impl->log, "RegisterPlayer() failed"); - res = -EIO; + return -EIO; } - dbus_message_unref(r); - - return res; + return 0; } int spa_bt_player_unregister(struct spa_bt_player *player, const char *adapter_path) { struct impl *impl = SPA_CONTAINER_OF(player, struct impl, this); - DBusError err; + spa_auto(DBusError) err = DBUS_ERROR_INIT; DBusMessageIter i; - DBusMessage *m, *r; - int res = 0; + spa_autoptr(DBusMessage) m = NULL, r = NULL; spa_log_debug(impl->log, "UnregisterPlayer() for dummy AVRCP player %s for %s", impl->path, adapter_path); @@ -387,22 +374,16 @@ dbus_message_iter_init_append(m, &i); dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &impl->path); - dbus_error_init(&err); r = dbus_connection_send_with_reply_and_block(impl->conn, m, -1, &err); - dbus_message_unref(m); - if (r == NULL) { spa_log_error(impl->log, "UnregisterPlayer() failed (%s)", err.message); - dbus_error_free(&err); return -EIO; } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(impl->log, "UnregisterPlayer() failed"); - res = -EIO; + return -EIO; } - dbus_message_unref(r); - - return res; + return 0; }
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/quirks.c
Changed
@@ -28,6 +28,7 @@ #include <spa/support/plugin.h> #include <spa/monitor/device.h> #include <spa/monitor/utils.h> +#include <spa/utils/cleanup.h> #include <spa/utils/hook.h> #include <spa/utils/type.h> #include <spa/utils/keys.h> @@ -187,27 +188,21 @@ { char *data; struct stat sbuf; - int fd = -1; + spa_autoclose int fd = -1; spa_log_debug(this->log, "loading %s", path); if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0) - goto fail; + return -errno; if (fstat(fd, &sbuf) < 0) - goto fail; + return -errno; if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) - goto fail; - close(fd); + return -errno; load_quirks(this, data, sbuf.st_size); munmap(data, sbuf.st_size); return 0; - -fail: - if (fd >= 0) - close(fd); - return -errno; } struct spa_bt_quirks *spa_bt_quirks_create(const struct spa_dict *info, struct spa_log *log)
View file
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/upower.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/upower.c
Changed
@@ -43,40 +43,36 @@ static void upower_get_percentage_properties_reply(DBusPendingCall *pending, void *user_data) { struct impl *backend = user_data; - DBusMessage *r; DBusMessageIter i, variant_i; spa_assert(backend->pending_get_call == pending); - r = steal_reply_and_unref(&backend->pending_get_call); + spa_autoptr(DBusMessage) r = steal_reply_and_unref(&backend->pending_get_call); if (r == NULL) return; if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(backend->log, "Failed to get percentage from UPower: %s", dbus_message_get_error_name(r)); - goto finish; + return; } if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "v")) { spa_log_error(backend->log, "Invalid arguments in Get() reply"); - goto finish; + return; } dbus_message_iter_recurse(&i, &variant_i); upower_parse_percentage(backend, &variant_i); - -finish: - dbus_message_unref(r); } static int update_battery_percentage(struct impl *this) { cancel_and_unref(&this->pending_get_call); - DBusMessage *m = dbus_message_new_method_call(UPOWER_SERVICE, - UPOWER_DISPLAY_DEVICE_OBJECT, - DBUS_INTERFACE_PROPERTIES, - "Get"); + spa_autoptr(DBusMessage) m = dbus_message_new_method_call(UPOWER_SERVICE, + UPOWER_DISPLAY_DEVICE_OBJECT, + DBUS_INTERFACE_PROPERTIES, + "Get"); if (!m) return -ENOMEM; @@ -86,10 +82,9 @@ DBUS_TYPE_INVALID); dbus_message_set_auto_start(m, false); - dbus_connection_send_with_reply(this->conn, m, &this->pending_get_call, -1); - dbus_pending_call_set_notify(this->pending_get_call, upower_get_percentage_properties_reply, this, NULL); - - dbus_message_unref(m); + this->pending_get_call = send_with_reply(this->conn, m, upower_get_percentage_properties_reply, this); + if (!this->pending_get_call) + return -EIO; return 0; } @@ -102,12 +97,10 @@ static DBusHandlerResult upower_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data) { struct impl *this = user_data; - DBusError err; - - dbus_error_init(&err); if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) { const char *name, *old_owner, *new_owner; + spa_auto(DBusError) err = DBUS_ERROR_INIT; spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m)); @@ -176,18 +169,16 @@ static int add_filters(struct impl *this) { - DBusError err; - if (this->filters_added) return 0; - dbus_error_init(&err); - if (!dbus_connection_add_filter(this->conn, upower_filter_cb, this, NULL)) { spa_log_error(this->log, "failed to add filter function"); - goto fail; + return -EIO; } + spa_auto(DBusError) err = DBUS_ERROR_INIT; + dbus_bus_add_match(this->conn, "type='signal',sender='org.freedesktop.DBus'," "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" UPOWER_SERVICE "'", &err); @@ -199,10 +190,6 @@ this->filters_added = true; return 0; - -fail: - dbus_error_free(&err); - return -EIO; } void *upower_register(struct spa_log *log,
View file
pipewire-0.3.76.tar.gz/spa/plugins/v4l2/v4l2-udev.c -> pipewire-0.3.77.tar.gz/spa/plugins/v4l2/v4l2-udev.c
Changed
@@ -33,8 +33,10 @@ #define ACTION_DISABLE 2 struct device { + struct impl *impl; uint32_t id; struct udev_device *dev; + struct spa_source notify; unsigned int accessible:1; unsigned int ignored:1; unsigned int emitted:1; @@ -59,66 +61,79 @@ uint32_t n_devices; struct spa_source source; - struct spa_source notify; }; -static int impl_udev_open(struct impl *this) +static int stop_inotify(struct device *dev); +static int start_inotify(struct device *dev); + +static int impl_udev_open(struct impl *impl) { - if (this->udev == NULL) { - this->udev = udev_new(); - if (this->udev == NULL) + if (impl->udev == NULL) { + impl->udev = udev_new(); + if (impl->udev == NULL) return -ENOMEM; } return 0; } -static int impl_udev_close(struct impl *this) +static int impl_udev_close(struct impl *impl) { - if (this->udev != NULL) - udev_unref(this->udev); - this->udev = NULL; + if (impl->udev != NULL) + udev_unref(impl->udev); + impl->udev = NULL; return 0; } -static struct device *add_device(struct impl *this, uint32_t id, struct udev_device *dev) +static struct device *add_device(struct impl *impl, uint32_t id, struct udev_device *dev) { struct device *device; - if (this->n_devices >= MAX_DEVICES) + if (impl->n_devices >= MAX_DEVICES) return NULL; - device = &this->devicesthis->n_devices++; + device = &impl->devicesimpl->n_devices++; spa_zero(*device); + device->impl = impl; + device->notify.fd = -1; device->id = id; udev_device_ref(dev); device->dev = dev; + start_inotify(device); return device; } -static struct device *find_device(struct impl *this, uint32_t id) +static struct device *find_device(struct impl *impl, uint32_t id) { uint32_t i; - for (i = 0; i < this->n_devices; i++) { - if (this->devicesi.id == id) - return &this->devicesi; + for (i = 0; i < impl->n_devices; i++) { + if (impl->devicesi.id == id) + return &impl->devicesi; } return NULL; } -static void remove_device(struct impl *this, struct device *device) +static void clear_device(struct device *device) +{ + stop_inotify(device); + if (device->dev) + udev_device_unref(device->dev); +} + +static void remove_device(struct device *device) { - udev_device_unref(device->dev); - *device = this->devices--this->n_devices; + struct impl *impl = device->impl; + clear_device(device); + *device = impl->devices--impl->n_devices; } -static void clear_devices(struct impl *this) +static void clear_devices(struct impl *impl) { uint32_t i; - for (i = 0; i < this->n_devices; i++) - udev_device_unref(this->devicesi.dev); - this->n_devices = 0; + for (i = 0; i < impl->n_devices; i++) + clear_device(&impl->devicesi); + impl->n_devices = 0; } -static uint32_t get_device_id(struct impl *this, struct udev_device *dev) +static uint32_t get_device_id(struct impl *impl, struct udev_device *dev) { const char *str; @@ -214,8 +229,9 @@ *d = 0; } -static int emit_object_info(struct impl *this, struct device *device) +static int emit_object_info(struct device *device) { + struct impl *impl = device->impl; struct spa_device_object_info info; uint32_t id = device->id; struct udev_device *dev = device->dev; @@ -315,54 +331,55 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_CAPABILITIES, str); } info.props = &SPA_DICT_INIT(items, n_items); - spa_device_emit_object_info(&this->hooks, id, &info); + spa_device_emit_object_info(&impl->hooks, id, &info); device->emitted = true; return 1; } -static bool check_access(struct impl *this, struct device *device) +static bool check_access(struct device *device) { char path128; snprintf(path, sizeof(path), "/dev/video%u", device->id); device->accessible = access(path, R_OK|W_OK) >= 0; - spa_log_debug(this->log, "%s accessible:%u", path, device->accessible); + spa_log_debug(device->impl->log, "%s accessible:%u", path, device->accessible); return device->accessible; } -static void process_device(struct impl *this, uint32_t action, struct udev_device *dev) +static void process_device(struct impl *impl, uint32_t action, struct udev_device *dev) { uint32_t id; struct device *device; bool emitted; - if ((id = get_device_id(this, dev)) == SPA_ID_INVALID) + if ((id = get_device_id(impl, dev)) == SPA_ID_INVALID) return; - device = find_device(this, id); + device = find_device(impl, id); if (device && device->ignored) return; switch (action) { case ACTION_ADD: if (device == NULL) - device = add_device(this, id, dev); + device = add_device(impl, id, dev); if (device == NULL) return; - if (!check_access(this, device)) + if (!check_access(device)) return; - emit_object_info(this, device); + else + emit_object_info(device); break; case ACTION_REMOVE: if (device == NULL) return; emitted = device->emitted; - remove_device(this, device); + remove_device(device); if (emitted) - spa_device_emit_object_info(&this->hooks, id, NULL); + spa_device_emit_object_info(&impl->hooks, id, NULL); break; case ACTION_DISABLE: @@ -370,27 +387,16 @@ return; if (device->emitted) { device->emitted = false; - spa_device_emit_object_info(&this->hooks, id, NULL); + spa_device_emit_object_info(&impl->hooks, id, NULL); }
View file
pipewire-0.3.76.tar.gz/src/modules/module-metadata/metadata.c -> pipewire-0.3.77.tar.gz/src/modules/module-metadata/metadata.c
Changed
@@ -265,6 +265,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_Metadata, PW_VERSION_METADATA, + PW_METADATA_PERM_MASK, properties, global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.77.tar.gz/src/modules/module-profiler.c
Changed
@@ -4,6 +4,7 @@ #include <string.h> #include <stdio.h> +#include <stdalign.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> @@ -103,6 +104,7 @@ struct spa_source *flush_event; unsigned int listening:1; + alignas(max_align_t) uint8_t flushFLUSH_BUFFER + sizeof(struct spa_pod_struct); }; @@ -132,12 +134,14 @@ pw_log_trace("%p avail %d", impl, avail); if (avail > 0) { - spa_ringbuffer_read_data(&n->buffer, n->data, DATA_BUFFER, - idx % DATA_BUFFER, - SPA_PTROFF(p, sizeof(struct spa_pod_struct) + total, void), - avail); + if (total + avail < FLUSH_BUFFER) { + spa_ringbuffer_read_data(&n->buffer, n->data, DATA_BUFFER, + idx % DATA_BUFFER, + SPA_PTROFF(p, sizeof(struct spa_pod_struct) + total, void), + avail); + total += avail; + } spa_ringbuffer_read_update(&n->buffer, idx + avail); - total += avail; } } @@ -458,6 +462,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_Profiler, PW_VERSION_PROFILER, + PW_PROFILER_PERM_MASK, pw_properties_copy(props), global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/collect.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/collect.c
Changed
@@ -6,6 +6,9 @@ #include <spa/pod/builder.h> #include <spa/pod/parser.h> #include <spa/utils/string.h> + +#include <spa/param/audio/format-utils.h> + #include <pipewire/pipewire.h> #include "collect.h" @@ -226,7 +229,7 @@ return SPA_ID_INVALID; } -void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, +static void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, struct device_info *dev_info, bool monitor, struct defs *defs) { struct pw_manager_param *p; @@ -287,6 +290,57 @@ dev_info->volume_info.volume.channels = dev_info->map.channels; } +static void update_device_info(struct pw_manager *manager, struct pw_manager_object *o, + enum pw_direction direction, bool monitor, struct defs *defs) +{ + const char *str; + const char *key = monitor ? "device.info.monitor" : "device.info"; + struct pw_manager_object *card = NULL; + struct pw_node_info *info = o->info; + struct device_info *dev_info, di; + + if (info == NULL) + return; + + di = DEVICE_INFO_INIT(direction); + if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) + di.card_id = (uint32_t)atoi(str); + if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) + di.device = (uint32_t)atoi(str); + if (di.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = di.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } + collect_device_info(o, card, &di, monitor, defs); + + dev_info = pw_manager_object_get_data(o, key); + if (dev_info) { + if (memcmp(dev_info, &di, sizeof(di)) != 0) { + if (monitor || direction == PW_DIRECTION_INPUT) + o->change_mask |= PW_MANAGER_OBJECT_FLAG_SOURCE; + else + o->change_mask |= PW_MANAGER_OBJECT_FLAG_SINK; + } + } else { + o->change_mask = ~0; + dev_info = pw_manager_object_add_data(o, key, sizeof(*dev_info)); + } + if (dev_info != NULL) + *dev_info = di; +} + +void get_device_info(struct pw_manager_object *o, struct device_info *info, + enum pw_direction direction, bool monitor) +{ + const char *key = monitor ? "device.info.monitor" : "device.info"; + struct device_info *di; + di = pw_manager_object_get_data(o, key); + if (di != NULL) + *info = *di; + else + *info = DEVICE_INFO_INIT(direction); +} + static bool array_contains(uint32_t *vals, uint32_t n_vals, uint32_t val) { uint32_t n; @@ -527,3 +581,21 @@ return n_codecs; } + +void update_object_info(struct pw_manager *manager, struct pw_manager_object *o, + struct defs *defs) +{ + if (pw_manager_object_is_sink(o)) { + update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs); + update_device_info(manager, o, PW_DIRECTION_OUTPUT, true, defs); + } + if (pw_manager_object_is_source(o)) { + update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs); + } + if (pw_manager_object_is_source_output(o)) { + update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs); + } + if (pw_manager_object_is_sink_input(o)) { + update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs); + } +}
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/collect.h -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/collect.h
Changed
@@ -35,6 +35,8 @@ struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s); uint32_t id_to_index(struct pw_manager *m, uint32_t id); void select_best(struct selector *s, struct pw_manager_object *o); +void update_object_info(struct pw_manager *manager, struct pw_manager_object *o, + struct defs *defs); /* ========================================================================== */ @@ -47,9 +49,11 @@ unsigned int have_volume:1; unsigned int have_iec958codecs:1; + uint32_t card_id; uint32_t device; uint32_t active_port; const char *active_port_name; + }; #define DEVICE_INFO_INIT(_dir) \ @@ -58,12 +62,13 @@ .ss = SAMPLE_SPEC_INIT, \ .map = CHANNEL_MAP_INIT, \ .volume_info = VOLUME_INFO_INIT, \ + .card_id = SPA_ID_INVALID, \ .device = SPA_ID_INVALID, \ .active_port = SPA_ID_INVALID, \ } -void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, - struct device_info *dev_info, bool monitor, struct defs *defs); +void get_device_info(struct pw_manager_object *device, struct device_info *info, + enum pw_direction direction, bool monitor); /* ========================================================================== */
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c
Changed
@@ -220,17 +220,15 @@ static int do_extension_device_restore_save_formats(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct selector sel; struct pw_manager_object *o, *card = NULL; struct pw_node_info *info; int res; - uint32_t type, sink_index, card_id = SPA_ID_INVALID; + uint32_t type, sink_index; uint8_t i, n_formats; uint32_t n_codecs = 0, codec, iec958codecs32; struct device_info dev_info; - const char *str; if ((res = message_get(m, TAG_U32, &type, @@ -269,18 +267,12 @@ if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(SPA_DIRECTION_INPUT); + get_device_info(o, &dev_info, SPA_DIRECTION_INPUT, false); - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; card = select_object(manager, &sel); } - collect_device_info(o, card, &dev_info, false, &impl->defs); - if (card != NULL && dev_info.active_port != SPA_ID_INVALID) { res = set_card_codecs(card, dev_info.active_port, dev_info.device, n_codecs, iec958codecs);
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
@@ -58,6 +58,7 @@ const struct object_info *info; + int changed; struct spa_list pending_list; struct spa_hook proxy_listener; @@ -210,7 +211,7 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); - info = o->this.info = pw_client_info_merge(o->this.info, info, o->this.changed == 0); + info = o->this.info = pw_client_info_merge(o->this.info, info, o->changed == 0); if (info == NULL) return; @@ -218,7 +219,7 @@ changed++; if (changed) { - o->this.changed += changed; + o->changed += changed; core_sync(o->manager); } } @@ -251,7 +252,7 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); - info = o->this.info = pw_module_info_merge(o->this.info, info, o->this.changed == 0); + info = o->this.info = pw_module_info_merge(o->this.info, info, o->changed == 0); if (info == NULL) return; @@ -259,7 +260,7 @@ changed++; if (changed) { - o->this.changed += changed; + o->changed += changed; core_sync(o->manager); } } @@ -292,7 +293,7 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); - info = o->this.info = pw_device_info_merge(o->this.info, info, o->this.changed == 0); + info = o->this.info = pw_device_info_merge(o->this.info, info, o->changed == 0); if (info == NULL) return; @@ -331,7 +332,7 @@ } } if (changed) { - o->this.changed += changed; + o->changed += changed; core_sync(o->manager); } } @@ -377,7 +378,7 @@ return; if ((dev = find_device(m, o->this.id, device)) != NULL) { - dev->this.changed++; + dev->changed++; core_sync(o->manager); } } @@ -412,7 +413,7 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); - info = o->this.info = pw_node_info_merge(o->this.info, info, o->this.changed == 0); + info = o->this.info = pw_node_info_merge(o->this.info, info, o->changed == 0); if (info == NULL) return; @@ -446,7 +447,7 @@ } } if (changed) { - o->this.changed += changed; + o->changed += changed; core_sync(o->manager); } } @@ -678,10 +679,10 @@ if (o->this.creating) { o->this.creating = false; manager_emit_added(m, &o->this); - o->this.changed = 0; - } else if (o->this.changed > 0) { + o->changed = 0; + } else if (o->changed > 0) { manager_emit_updated(m, &o->this); - o->this.changed = 0; + o->changed = 0; } } }
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/manager.h
Changed
@@ -71,11 +71,13 @@ int (*message_handler)(struct pw_manager *m, struct pw_manager_object *o, const char *message, const char *params, char **response); - int changed; void *info; struct spa_param_info *params; uint32_t n_params; +#define PW_MANAGER_OBJECT_FLAG_SOURCE (1<<0) +#define PW_MANAGER_OBJECT_FLAG_SINK (1<<1) + uint64_t change_mask; /* object specific params change mask */ struct spa_list param_list; unsigned int creating:1; unsigned int removing:1;
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
@@ -180,17 +180,14 @@ static void fill_service_data(struct module_zeroconf_publish_data *d, struct service *s, struct pw_manager_object *o) { - struct impl *impl = d->module->impl; bool is_sink = pw_manager_object_is_sink(o); bool is_source = pw_manager_object_is_source(o); struct pw_node_info *info = o->info; - const char *name, *desc, *str; - uint32_t card_id = SPA_ID_INVALID; + const char *name, *desc; struct pw_manager *manager = d->manager; struct pw_manager_object *card = NULL; struct card_info card_info = CARD_INFO_INIT; - struct device_info dev_info = is_sink ? - DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT) : DEVICE_INFO_INIT(PW_DIRECTION_INPUT); + struct device_info dev_info; uint32_t flags = 0; if (info == NULL || info->props == NULL) @@ -202,19 +199,15 @@ if (name == NULL) name = "unknown"; - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; + get_device_info(o, &dev_info, is_sink ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT, false); + + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; card = select_object(manager, &sel); } if (card) collect_card_info(card, &card_info); - collect_device_info(o, card, &dev_info, false, &impl->defs); - if (!pw_manager_object_is_virtual(o)) { if (is_sink) flags |= SINK_HARDWARE;
View file
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -208,13 +208,15 @@ { uint32_t event = 0, mask = 0, res_index = o->index; - if (pw_manager_object_is_sink(o)) { + pw_log_debug("index:%d id:%d %08lx type:%u", o->index, o->id, o->change_mask, type); + + if (pw_manager_object_is_sink(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SINK) { client_queue_subscribe_event(client, SUBSCRIPTION_MASK_SINK, SUBSCRIPTION_EVENT_SINK | type, res_index); } - if (pw_manager_object_is_source_or_monitor(o)) { + if (pw_manager_object_is_source_or_monitor(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SOURCE) { mask = SUBSCRIPTION_MASK_SOURCE; event = SUBSCRIPTION_EVENT_SOURCE; } @@ -808,6 +810,7 @@ { struct client *client = data; struct pw_manager *manager = client->manager; + struct impl *impl = client->impl; const char *str; register_object_message_handlers(o); @@ -869,8 +872,12 @@ } } + update_object_info(manager, o, &impl->defs); + send_object_event(client, o, SUBSCRIPTION_EVENT_NEW); + o->change_mask = 0; + /* Adding sinks etc. may also change defaults */ send_default_change_subscribe_event(client, pw_manager_object_is_sink(o), pw_manager_object_is_source_or_monitor(o)); } @@ -878,9 +885,15 @@ static void manager_updated(void *data, struct pw_manager_object *o) { struct client *client = data; + struct pw_manager *manager = client->manager; + struct impl *impl = client->impl; + + update_object_info(manager, o, &impl->defs); send_object_event(client, o, SUBSCRIPTION_EVENT_CHANGE); + o->change_mask = 0; + set_temporary_move_target(client, o, SPA_ID_INVALID); send_latency_offset_subscribe_event(client, o); @@ -1646,8 +1659,8 @@ spa_zero(fix_ss); spa_zero(fix_map); if ((fix_format || fix_rate || fix_channels) && o != NULL) { - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT); - collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs); + struct device_info dev_info; + get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, is_monitor); fix_ss.format = fix_format ? dev_info.ss.format : 0; fix_ss.rate = fix_rate ? dev_info.ss.rate : 0; fix_ss.channels = fix_channels ? dev_info.ss.channels : 0; @@ -1936,8 +1949,8 @@ spa_zero(fix_ss); spa_zero(fix_map); if ((fix_format || fix_rate || fix_channels) && o != NULL) { - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT); - collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs); + struct device_info dev_info; + get_device_info(o, &dev_info, PW_DIRECTION_INPUT, is_monitor); fix_ss.format = fix_format ? dev_info.ss.format : 0; fix_ss.rate = fix_rate ? dev_info.ss.rate : 0; fix_ss.channels = fix_channels ? dev_info.ss.channels : 0; @@ -2453,7 +2466,7 @@ uint32_t index, const char *name, bool sink, bool *is_monitor) { struct selector sel; - bool monitor = false, find_default = false; + bool monitor = false, find_default = false, allow_monitor = false; struct pw_manager_object *o; if (name != NULL) { @@ -2463,10 +2476,12 @@ sink = true; find_default = true; monitor = true; + allow_monitor = true; } else if (spa_streq(name, DEFAULT_SOURCE)) { if (sink) return NULL; find_default = true; + allow_monitor = true; } else if (spa_streq(name, DEFAULT_SINK)) { if (!sink) return NULL; @@ -2485,8 +2500,10 @@ if (name != NULL) { if (spa_strendswith(name, ".monitor")) { - name = strndupa(name, strlen(name)-8); - monitor = true; + if (!sink) { + name = strndupa(name, strlen(name)-8); + allow_monitor = true; + } } } else if (index == SPA_ID_INVALID) return NULL; @@ -2502,8 +2519,18 @@ o = select_object(client->manager, &sel); if (o != NULL) { - if (!sink && pw_manager_object_is_monitor(o)) - monitor = true; + if (!sink) { + if (pw_manager_object_is_monitor(o)) { + if (!allow_monitor) + return NULL; + monitor = true; + } + else if (!pw_manager_object_is_source(o)) + return NULL; + } else { + if (!pw_manager_object_is_sink(o)) + return NULL; + } } if (is_monitor) *is_monitor = monitor; @@ -2876,11 +2903,10 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct pw_node_info *info; - uint32_t index, card_id = SPA_ID_INVALID; - const char *name, *str; + uint32_t index; + const char *name; struct volume volume; struct pw_manager_object *o, *card = NULL; int res; @@ -2916,22 +2942,16 @@ if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(direction); - - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; - card = select_object(manager, &sel); - } - collect_device_info(o, card, &dev_info, is_monitor, &impl->defs); + get_device_info(o, &dev_info, direction, is_monitor); if (dev_info.have_volume && volume_compare(&dev_info.volume_info.volume, &volume) == 0) goto done; + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } if (card != NULL && !is_monitor && dev_info.active_port != SPA_ID_INVALID) res = set_card_volume_mute_delay(card, dev_info.active_port, dev_info.device, &volume, NULL, NULL); @@ -2947,11 +2967,10 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct pw_node_info *info; - uint32_t index, card_id = SPA_ID_INVALID; - const char *name, *str; + uint32_t index; + const char *name; bool mute; struct pw_manager_object *o, *card = NULL; int res; @@ -2982,22 +3001,17 @@ if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(direction); - - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c
Changed
@@ -292,6 +292,7 @@ this->global = pw_global_new (context, PW_TYPE_INTERFACE_EndpointStream, PW_VERSION_ENDPOINT_STREAM, + PW_ENDPOINT_STREAM_PERM_MASK, properties, endpoint_stream_bind, this); if (!this->global) goto no_mem;
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c
Changed
@@ -322,6 +322,7 @@ this->global = pw_global_new (context, PW_TYPE_INTERFACE_Endpoint, PW_VERSION_ENDPOINT, + PW_ENDPOINT_PERM_MASK, NULL, endpoint_bind, this); if (!this->global) goto no_mem;
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c
Changed
@@ -310,6 +310,7 @@ this->global = pw_global_new(context, PW_TYPE_INTERFACE_EndpointLink, PW_VERSION_ENDPOINT_LINK, + PW_ENDPOINT_LINK_PERM_MASK, properties, endpoint_link_bind, this); if (!this->global) goto no_mem;
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-session/session.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-session/session.c
Changed
@@ -283,6 +283,7 @@ this->global = pw_global_new (context, PW_TYPE_INTERFACE_Session, PW_VERSION_SESSION, + PW_SESSION_PERM_MASK, NULL, session_bind, this); if (!this->global) goto no_mem;
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint-link.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint-link.c
Changed
@@ -390,6 +390,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_EndpointLink, PW_VERSION_ENDPOINT_LINK, + PW_ENDPOINT_LINK_PERM_MASK, properties, global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint-stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint-stream.c
Changed
@@ -381,6 +381,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_EndpointStream, PW_VERSION_ENDPOINT_STREAM, + PW_ENDPOINT_STREAM_PERM_MASK, properties, global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint.c
Changed
@@ -390,6 +390,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_Endpoint, PW_VERSION_ENDPOINT, + PW_ENDPOINT_PERM_MASK, properties, global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/session.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/session.c
Changed
@@ -379,6 +379,7 @@ impl->global = pw_global_new(context, PW_TYPE_INTERFACE_Session, PW_VERSION_SESSION, + PW_SESSION_PERM_MASK, properties, global_bind, impl); if (impl->global == NULL) {
View file
pipewire-0.3.76.tar.gz/src/modules/module-vban/audio.c -> pipewire-0.3.77.tar.gz/src/modules/module-vban/audio.c
Changed
@@ -209,8 +209,9 @@ timestamp += tosend; avail -= tosend; - impl->header.n_frames++; + header.n_frames++; } + impl->header.n_frames = header.n_frames; spa_ringbuffer_read_update(&impl->ring, timestamp); }
View file
pipewire-0.3.77.tar.gz/src/modules/module-vban/midi.c
Added
@@ -0,0 +1,327 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans <wim.taymans@gmail.com> */ +/* SPDX-License-Identifier: MIT */ + +static void vban_midi_process_playback(void *data) +{ + struct impl *impl = data; + struct pw_buffer *buf; + struct spa_data *d; + uint32_t timestamp, duration, maxsize, read; + struct spa_pod_builder b; + struct spa_pod_frame f1; + void *ptr; + struct spa_pod *pod; + struct spa_pod_control *c; + + if ((buf = pw_stream_dequeue_buffer(impl->stream)) == NULL) { + pw_log_debug("Out of stream buffers: %m"); + return; + } + d = buf->buffer->datas; + + maxsize = d0.maxsize; + + /* we always use the graph position to select events */ + if (impl->io_position) { + duration = impl->io_position->clock.duration; + timestamp = impl->io_position->clock.position; + } else { + duration = 8192; + timestamp = 0; + } + + /* we copy events into the buffer as they are available. */ + spa_pod_builder_init(&b, d0.data, maxsize); + spa_pod_builder_push_sequence(&b, &f0, 0); + + while (true) { + int32_t avail = spa_ringbuffer_get_read_index(&impl->ring, &read); + if (avail <= 0) + break; + + ptr = SPA_PTROFF(impl->buffer, read & BUFFER_MASK2, void); + + if ((pod = spa_pod_from_data(ptr, avail, 0, avail)) == NULL) + goto done; + if (!spa_pod_is_sequence(pod)) + goto done; + + /* the ringbuffer contains series of sequences, one for each + * received packet */ + SPA_POD_SEQUENCE_FOREACH((struct spa_pod_sequence*)pod, c) { +#if 0 + /* try to render with given delay */ + uint32_t target = c->offset + impl->target_buffer; + target = (uint64_t)target * rate / impl->rate; +#else + uint32_t target = timestamp; +#endif + if (timestamp != 0) { + /* skip old packets */ + if (target < timestamp) + continue; + /* event for next cycle */ + if (target >= timestamp + duration) + goto complete; + } else { + timestamp = target; + } + spa_pod_builder_control(&b, target - timestamp, SPA_CONTROL_Midi); + spa_pod_builder_bytes(&b, + SPA_POD_BODY(&c->value), + SPA_POD_BODY_SIZE(&c->value)); + } + /* we completed a sequence (one RTP packet), advance ringbuffer + * and go to the next packet */ + read += SPA_PTRDIFF(c, ptr); + spa_ringbuffer_read_update(&impl->ring, read); + } +complete: + spa_pod_builder_pop(&b, &f0); + + if (b.state.offset > maxsize) { + pw_log_warn("overflow buffer %u %u", b.state.offset, maxsize); + b.state.offset = 0; + } + d0.chunk->size = b.state.offset; + d0.chunk->stride = 1; + d0.chunk->offset = 0; +done: + pw_stream_queue_buffer(impl->stream, buf); +} + +static int parse_varlen(uint8_t *p, uint32_t avail, uint32_t *result) +{ + uint32_t value = 0, offs = 0; + while (offs < avail) { + uint8_t b = poffs++; + value = (value << 7) | (b & 0x7f); + if ((b & 0x80) == 0) + break; + } + *result = value; + return offs; +} + +static int get_midi_size(uint8_t *p, uint32_t avail) +{ + int size; + uint32_t offs = 0, value; + + switch (poffs++) { + case 0xc0 ... 0xdf: + size = 2; + break; + case 0x80 ... 0xbf: + case 0xe0 ... 0xef: + size = 3; + break; + case 0xff: + case 0xf0: + case 0xf7: + size = parse_varlen(&poffs, avail - offs, &value); + size += value + 1; + break; + default: + return -EINVAL; + } + return size; +} + +static int vban_midi_receive_midi(struct impl *impl, uint8_t *packet, + uint32_t payload_offset, uint32_t plen) +{ + uint32_t write; + int32_t filled; + struct spa_pod_builder b; + struct spa_pod_frame f1; + void *ptr; + uint32_t offs = payload_offset; + uint32_t timestamp = 0; + + /* no sync, resync */ + if (!impl->have_sync) { + pw_log_info("sync to timestamp:%u", timestamp); + impl->have_sync = true; + impl->ring.readindex = impl->ring.writeindex; + } + + filled = spa_ringbuffer_get_write_index(&impl->ring, &write); + if (filled > (int32_t)BUFFER_SIZE2) { + pw_log_warn("overflow"); + return -ENOSPC; + } + + ptr = SPA_PTROFF(impl->buffer, write & BUFFER_MASK2, void); + + /* each packet is written as a sequence of events. The offset is + * the receive timestamp */ + spa_pod_builder_init(&b, ptr, BUFFER_SIZE2 - filled); + spa_pod_builder_push_sequence(&b, &f0, 0); + + while (offs < plen) { + int size; + + spa_pod_builder_control(&b, timestamp, SPA_CONTROL_Midi); + + size = get_midi_size(&packetoffs, plen - offs); + + if (size <= 0 || offs + size > plen) { + pw_log_warn("invalid size (%08x) %d (%u %u)", + packetoffs, size, offs, plen); + break; + } + + spa_pod_builder_bytes(&b, &packetoffs, size); + + offs += size; + } + spa_pod_builder_pop(&b, &f0); + + write += b.state.offset; + spa_ringbuffer_write_update(&impl->ring, write); + + return 0; +} + +static int vban_midi_receive(struct impl *impl, uint8_t *buffer, ssize_t len) +{ + struct vban_header *hdr; + ssize_t hlen; + uint32_t n_frames; + + if (len < VBAN_HEADER_SIZE) + goto short_packet; + + hdr = (struct vban_header*)buffer; + if (strncmp(hdr->vban, "VBAN", 3)) + goto invalid_version;
View file
pipewire-0.3.76.tar.gz/src/modules/module-vban/stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-vban/stream.c
Changed
@@ -81,7 +81,7 @@ }; #include "module-vban/audio.c" -//#include "module-vban/midi.c" +#include "module-vban/midi.c" struct format_info { uint32_t media_subtype; @@ -97,7 +97,7 @@ { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S32_LE, 4, VBAN_DATATYPE_INT32, }, { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_F32_LE, 4, VBAN_DATATYPE_FLOAT32, }, { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_F64_LE, 8, VBAN_DATATYPE_FLOAT64, }, - { SPA_MEDIA_SUBTYPE_control, 0, 1, }, + { SPA_MEDIA_SUBTYPE_control, 0, 1, VBAN_SERIAL_MIDI | VBAN_DATATYPE_U8, }, }; static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size) @@ -289,9 +289,6 @@ goto out; } memcpy(impl->header.vban, "VBAN", 4); - if ((str = pw_properties_get(props, "sess.name")) == NULL) - str = "Stream1"; - strcpy(impl->header.stream_name, str); switch (impl->info.media_subtype) { case SPA_MEDIA_SUBTYPE_raw: @@ -307,6 +304,7 @@ } impl->stride = impl->format_info->size * impl->stream_info.info.raw.channels; impl->rate = impl->stream_info.info.raw.rate; + impl->header.format_SR = vban_sr_index(impl->rate); if (impl->header.format_SR == VBAN_SR_MAXNUMBER) { pw_log_error("unsupported audio rate:%u", impl->rate); @@ -314,6 +312,9 @@ goto out; } impl->header.format_bit = impl->format_info->format_bit; + if ((str = pw_properties_get(props, "sess.name")) == NULL) + str = "Stream1"; + strcpy(impl->header.stream_name, str); break; case SPA_MEDIA_SUBTYPE_control: impl->stream_info = impl->info; @@ -327,6 +328,14 @@ impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); if (impl->rate == 0) impl->rate = 10000; + + impl->header.format_SR = (0x1 << 5) | 14; /* 115200 */ + impl->header.format_nbs = 0; + impl->header.format_nbc = 0; + impl->header.format_bit = impl->format_info->format_bit; + if ((str = pw_properties_get(props, "sess.name")) == NULL) + str = "Midi1"; + strcpy(impl->header.stream_name, str); break; default: spa_assert_not_reached(); @@ -413,7 +422,7 @@ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); -// vban_midi_init(impl, direction); + vban_midi_init(impl, direction); break; default: res = -EINVAL;
View file
pipewire-0.3.76.tar.gz/src/modules/module-vban/vban.h -> pipewire-0.3.77.tar.gz/src/modules/module-vban/vban.h
Changed
@@ -53,6 +53,10 @@ #define VBAN_DATATYPE_12BITS 0x06 #define VBAN_DATATYPE_10BITS 0x07 +#define VBAN_SERIAL_GENERIC 0x00 +#define VBAN_SERIAL_MIDI 0x10 +#define VBAN_SERIAL_USER 0xf0 + #ifdef __cplusplus } #endif
View file
pipewire-0.3.76.tar.gz/src/modules/module-x11-bell.c -> pipewire-0.3.77.tar.gz/src/modules/module-x11-bell.c
Changed
@@ -62,6 +62,10 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic +/* libcanberra is not thread safe when doing ca_context_create() + * and so we need a global lock */ +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + struct impl { struct pw_context *context; struct pw_thread_loop *thread_loop; @@ -83,6 +87,7 @@ ca_context *ca; int res; + pthread_mutex_lock(&lock); if (impl->properties) sample = pw_properties_get(impl->properties, "sample.name"); if (sample == NULL) @@ -113,6 +118,7 @@ exit_destroy: ca_context_destroy(ca); exit: + pthread_mutex_unlock(&lock); return res; }
View file
pipewire-0.3.76.tar.gz/src/pipewire/client.h -> pipewire-0.3.77.tar.gz/src/pipewire/client.h
Changed
@@ -25,6 +25,8 @@ */ #define PW_TYPE_INTERFACE_Client PW_TYPE_INFO_INTERFACE_BASE "Client" +#define PW_CLIENT_PERM_MASK PW_PERM_RWXM + #define PW_VERSION_CLIENT 3 struct pw_client; @@ -105,12 +107,16 @@ * \param id the global id to report the error on * \param res an errno style error code * \param message an error string + * + * This requires W and X permissions on the client. */ int (*error) (void *object, uint32_t id, int res, const char *message); /** * Update client properties * * \param props new properties + * + * This requires W and X permissions on the client. */ int (*update_properties) (void *object, const struct spa_dict *props); @@ -121,6 +127,8 @@ * * \param index the first index to query, 0 for first * \param num the maximum number of items to get + * + * This requires W and X permissions on the client. */ int (*get_permissions) (void *object, uint32_t index, uint32_t num); /** @@ -135,6 +143,8 @@ * * \param n_permissions number of permissions * \param permissions array of permissions + * + * This requires W and X permissions on the client. */ int (*update_permissions) (void *object, uint32_t n_permissions, const struct pw_permission *permissions);
View file
pipewire-0.3.76.tar.gz/src/pipewire/conf.c -> pipewire-0.3.77.tar.gz/src/pipewire/conf.c
Changed
@@ -984,6 +984,11 @@ return res == 0 ? data.count : res; } +static bool valid_conf_name(const char *str) +{ + return spa_streq(str, "null") || spa_strendswith(str, ".conf"); +} + static int try_load_conf(const char *conf_prefix, const char *conf_name, struct pw_properties *conf) { @@ -1018,6 +1023,11 @@ conf_name = pw_properties_get(props, PW_KEY_CONFIG_NAME); if (conf_name == NULL) conf_name = "client.conf"; + else if (!valid_conf_name(conf_name)) { + pw_log_error("%s '%s' does not end with .conf", + PW_KEY_CONFIG_NAME, conf_name); + return -EINVAL; + } if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) { pw_log_error("can't load config %s: %s", conf_name, spa_strerror(res)); @@ -1030,6 +1040,12 @@ struct pw_properties *override; const char *path, *name; + if (!valid_conf_name(conf_name)) { + pw_log_error("%s '%s' does not end with .conf", + PW_KEY_CONFIG_OVERRIDE_NAME, conf_name); + return -EINVAL; + } + override = pw_properties_new(NULL, NULL); if (override == NULL) { res = -errno;
View file
pipewire-0.3.76.tar.gz/src/pipewire/core.h -> pipewire-0.3.77.tar.gz/src/pipewire/core.h
Changed
@@ -34,6 +34,8 @@ #define PW_TYPE_INTERFACE_Core PW_TYPE_INFO_INTERFACE_BASE "Core" #define PW_TYPE_INTERFACE_Registry PW_TYPE_INFO_INTERFACE_BASE "Registry" +#define PW_CORE_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + #define PW_VERSION_CORE 4 struct pw_core; #define PW_VERSION_REGISTRY 3 @@ -223,6 +225,8 @@ * Start a conversation with the server. This will send * the core info and will destroy all resources for the client * (except the core and client resource). + * + * This requires X permissions on the core. */ int (*hello) (void *object, uint32_t version); /** @@ -235,6 +239,8 @@ * methods and the resulting events have been handled. * * \param seq the seq number passed to the done event + * + * This requires X permissions on the core. */ int (*sync) (void *object, uint32_t id, int seq); /** @@ -243,6 +249,8 @@ * Reply to the server ping event with the same seq. * * \param seq the seq number received in the ping event + * + * This requires X permissions on the core. */ int (*pong) (void *object, uint32_t id, int seq); /** @@ -257,9 +265,11 @@ * This method is usually also emitted on the resource object with * \a id. * - * \param id object where the error occurred + * \param id resource id where the error occurred * \param res error code * \param message error description + * + * This requires X permissions on the core. */ int (*error) (void *object, uint32_t id, int seq, int res, const char *message); /** @@ -269,6 +279,8 @@ * the global objects available from the PipeWire server * \param version the client version * \param user_data_size extra size + * + * This requires X permissions on the core. */ struct pw_registry * (*get_registry) (void *object, uint32_t version, size_t user_data_size); @@ -281,6 +293,8 @@ * \param version the version of the interface * \param props extra properties * \param user_data_size extra size + * + * This requires X permissions on the core. */ void * (*create_object) (void *object, const char *factory_name, @@ -294,6 +308,8 @@ * Destroy the server resource for the given proxy. * * \param obj the proxy to destroy + * + * This requires X permissions on the core. */ int (*destroy) (void *object, void *proxy); }; @@ -474,7 +490,8 @@ * * Try to destroy the global object. * - * \param id the global id to destroy + * \param id the global id to destroy. The client needs X permissions + * on the global. */ int (*destroy) (void *object, uint32_t id); };
View file
pipewire-0.3.76.tar.gz/src/pipewire/device.h -> pipewire-0.3.77.tar.gz/src/pipewire/device.h
Changed
@@ -25,6 +25,8 @@ #define PW_TYPE_INTERFACE_Device PW_TYPE_INFO_INTERFACE_BASE "Device" +#define PW_DEVICE_PERM_MASK PW_PERM_RWXM + #define PW_VERSION_DEVICE 3 struct pw_device; @@ -105,6 +107,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the device. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -119,6 +123,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions on the device. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); @@ -128,6 +134,8 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires W and X permissions on the device. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param);
View file
pipewire-0.3.76.tar.gz/src/pipewire/extensions/metadata.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/metadata.h
Changed
@@ -21,6 +21,8 @@ */ #define PW_TYPE_INTERFACE_Metadata PW_TYPE_INFO_INTERFACE_BASE "Metadata" +#define PW_METADATA_PERM_MASK PW_PERM_RWX + #define PW_VERSION_METADATA 3 struct pw_metadata; @@ -29,6 +31,7 @@ #define PW_METADATA_EVENT_PROPERTY 0 #define PW_METADATA_EVENT_NUM 1 + /** \ref pw_metadata events */ struct pw_metadata_events { #define PW_VERSION_METADATA_EVENTS 0 @@ -56,12 +59,33 @@ const struct pw_metadata_events *events, void *data); + /** + * Set a metadata property + * + * Automatically emit property events for the subject and key + * when they are changed. + * + * \param subject the id of the global to associate the metadata + * with. + * \param key the key of the metadata, NULL clears all metadata for + * the subject. + * \param type the type of the metadata, this can be blank + * \param value the metadata value. NULL clears the metadata. + * + * This requires X and W permissions on the metadata. It also + * requires M permissions on the subject global. + */ int (*set_property) (void *object, uint32_t subject, const char *key, const char *type, const char *value); + /** + * Clear all metadata + * + * This requires X and W permissions on the metadata. + */ int (*clear) (void *object); };
View file
pipewire-0.3.76.tar.gz/src/pipewire/extensions/profiler.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/profiler.h
Changed
@@ -26,6 +26,8 @@ #define PW_EXTENSION_MODULE_PROFILER PIPEWIRE_MODULE_PREFIX "module-profiler" +#define PW_PROFILER_PERM_MASK PW_PERM_R + #define PW_PROFILER_EVENT_PROFILE 0 #define PW_PROFILER_EVENT_NUM 1
View file
pipewire-0.3.76.tar.gz/src/pipewire/extensions/session-manager/interfaces.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/session-manager/interfaces.h
Changed
@@ -21,18 +21,22 @@ */ #define PW_TYPE_INTERFACE_Session PW_TYPE_INFO_INTERFACE_BASE "Session" +#define PW_SESSION_PERM_MASK PW_PERM_RWX #define PW_VERSION_SESSION 0 struct pw_session; #define PW_TYPE_INTERFACE_Endpoint PW_TYPE_INFO_INTERFACE_BASE "Endpoint" +#define PW_ENDPOINT_PERM_MASK PW_PERM_RWX #define PW_VERSION_ENDPOINT 0 struct pw_endpoint; #define PW_TYPE_INTERFACE_EndpointStream PW_TYPE_INFO_INTERFACE_BASE "EndpointStream" +#define PW_ENDPOINT_STREAM_PERM_MASK PW_PERM_RWX #define PW_VERSION_ENDPOINT_STREAM 0 struct pw_endpoint_stream; #define PW_TYPE_INTERFACE_EndpointLink PW_TYPE_INFO_INTERFACE_BASE "EndpointLink" +#define PW_ENDPOINT_LINK_PERM_MASK PW_PERM_RWX #define PW_VERSION_ENDPOINT_LINK 0 struct pw_endpoint_link; @@ -93,6 +97,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -107,6 +113,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -118,6 +126,8 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires X and W permissions. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -195,6 +205,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -209,6 +221,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -220,10 +234,17 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires X and W permissions. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); + /** + * Create a link + * + * This requires X permissions. + */ int (*create_link) (void *object, const struct spa_dict *props); }; @@ -298,6 +319,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -312,6 +335,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -323,6 +348,8 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires X and W permissions. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -400,6 +427,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -414,6 +443,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -425,10 +456,17 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires X and W permissions. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); + /** + * Request a state on the link. + * + * This requires X and W permissions. + */ int (*request_state) (void *object, enum pw_endpoint_link_state state); };
View file
pipewire-0.3.76.tar.gz/src/pipewire/factory.h -> pipewire-0.3.77.tar.gz/src/pipewire/factory.h
Changed
@@ -27,6 +27,8 @@ */ #define PW_TYPE_INTERFACE_Factory PW_TYPE_INFO_INTERFACE_BASE "Factory" +#define PW_FACTORY_PERM_MASK PW_PERM_R|PW_PERM_M + #define PW_VERSION_FACTORY 3 struct pw_factory;
View file
pipewire-0.3.76.tar.gz/src/pipewire/global.c -> pipewire-0.3.77.tar.gz/src/pipewire/global.c
Changed
@@ -25,10 +25,10 @@ SPA_EXPORT uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_impl_client *client) { - if (client->permission_func == NULL) - return PW_PERM_ALL; - - return client->permission_func(global, client, client->permission_data); + uint32_t permissions = global->permission_mask; + if (client->permission_func != NULL) + permissions &= client->permission_func(global, client, client->permission_data); + return permissions; } /** Create a new global @@ -47,6 +47,7 @@ pw_global_new(struct pw_context *context, const char *type, uint32_t version, + uint32_t permission_mask, struct pw_properties *properties, pw_global_bind_func_t func, void *object) @@ -71,6 +72,7 @@ this->context = context; this->type = type; this->version = version; + this->permission_mask = permission_mask; this->func = func; this->object = object; this->properties = properties;
View file
pipewire-0.3.76.tar.gz/src/pipewire/global.h -> pipewire-0.3.77.tar.gz/src/pipewire/global.h
Changed
@@ -65,6 +65,7 @@ pw_global_new(struct pw_context *context, /**< the context */ const char *type, /**< the interface type of the global */ uint32_t version, /**< the interface version of the global */ + uint32_t permission_mask, /**< mask of valid permissions */ struct pw_properties *properties, /**< extra properties */ pw_global_bind_func_t func, /**< function to bind */ void *object /**< global object */);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-client.c
Changed
@@ -514,6 +514,7 @@ client->global = pw_global_new(context, PW_TYPE_INTERFACE_Client, PW_VERSION_CLIENT, + PW_CLIENT_PERM_MASK, properties, global_bind, client);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-core.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-core.c
Changed
@@ -588,6 +588,7 @@ core->global = pw_global_new(context, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE, + PW_CORE_PERM_MASK, properties, global_bind, core);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-device.c
Changed
@@ -560,6 +560,7 @@ device->global = pw_global_new(context, PW_TYPE_INTERFACE_Device, PW_VERSION_DEVICE, + PW_DEVICE_PERM_MASK, properties, global_bind, device);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-factory.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-factory.c
Changed
@@ -174,6 +174,7 @@ factory->global = pw_global_new(context, PW_TYPE_INTERFACE_Factory, PW_VERSION_FACTORY, + PW_FACTORY_PERM_MASK, properties, global_bind, factory);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-link.c
Changed
@@ -1131,7 +1131,7 @@ } static int check_owner_permissions(struct pw_context *context, - struct pw_impl_node *node, uint32_t id, uint32_t permissions) + struct pw_impl_node *node, struct pw_global *other, uint32_t permissions) { const char *str; struct pw_impl_client *client; @@ -1155,11 +1155,7 @@ /* not the right object, something wrong */ return -EIO; - if ((global = pw_context_find_global(context, id)) == NULL) - /* current client can't see node id */ - return -errno; - - perms = pw_global_get_permissions(global, client); + perms = pw_global_get_permissions(other, client); if ((perms & permissions) != permissions) /* owner client can't see other node */ return -EPERM; @@ -1174,12 +1170,37 @@ struct pw_properties *properties) { int res; + uint32_t in_perms, out_perms; + struct pw_global *in_global, *out_global; + + if ((in_global = input->node->global) == NULL) + return -ENOENT; + if ((out_global = output->node->global) == NULL) + return -ENOENT; + + in_perms = out_perms = PW_PERM_R | PW_PERM_L; + if (context->current_client != NULL) { + in_perms = pw_global_get_permissions(in_global, context->current_client); + out_perms = pw_global_get_permissions(out_global, context->current_client); + } + /* current client can't see input node or output node */ + if (!PW_PERM_IS_R(in_perms) || !PW_PERM_IS_R(out_perms)) + return -ENOENT; + if ((res = check_owner_permissions(context, output->node, - input->node->info.id, PW_PERM_R)) < 0) - return res; + in_global, PW_PERM_R)) < 0) { + /* output node owner can't see input node, check if the current + * client has universal link permissions for the output node */ + if (!PW_PERM_IS_L(out_perms)) + return res; + } if ((res = check_owner_permissions(context, input->node, - output->node->info.id, PW_PERM_R)) < 0) - return res; + out_global, PW_PERM_R)) < 0) { + /* input node owner can't see output node, check if the current + * client has universal link permissions for the input node */ + if (!PW_PERM_IS_L(in_perms)) + return res; + } return 0; } @@ -1462,6 +1483,7 @@ link->global = pw_global_new(context, PW_TYPE_INTERFACE_Link, PW_VERSION_LINK, + PW_LINK_PERM_MASK, properties, global_bind, link);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-metadata.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-metadata.c
Changed
@@ -519,6 +519,7 @@ metadata->global = pw_global_new(context, PW_TYPE_INTERFACE_Metadata, PW_VERSION_METADATA, + PW_METADATA_PERM_MASK, properties, global_bind, metadata);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-module.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-module.c
Changed
@@ -222,6 +222,7 @@ this->global = pw_global_new(context, PW_TYPE_INTERFACE_Module, PW_VERSION_MODULE, + PW_MODULE_PERM_MASK, NULL, global_bind, this);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-node.c
Changed
@@ -747,6 +747,7 @@ PW_KEY_MODULE_ID, PW_KEY_FACTORY_ID, PW_KEY_CLIENT_ID, + PW_KEY_CLIENT_API, PW_KEY_DEVICE_ID, PW_KEY_PRIORITY_SESSION, PW_KEY_PRIORITY_DRIVER, @@ -773,6 +774,7 @@ this->global = pw_global_new(context, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, + PW_NODE_PERM_MASK, properties, global_bind, this);
View file
pipewire-0.3.76.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-port.c
Changed
@@ -1000,6 +1000,7 @@ port->global = pw_global_new(node->context, PW_TYPE_INTERFACE_Port, PW_VERSION_PORT, + PW_PORT_PERM_MASK, properties, global_bind, port);
View file
pipewire-0.3.76.tar.gz/src/pipewire/link.h -> pipewire-0.3.77.tar.gz/src/pipewire/link.h
Changed
@@ -31,6 +31,8 @@ #define PW_TYPE_INTERFACE_Link PW_TYPE_INFO_INTERFACE_BASE "Link" +#define PW_LINK_PERM_MASK PW_PERM_R | PW_PERM_X + #define PW_VERSION_LINK 3 struct pw_link;
View file
pipewire-0.3.76.tar.gz/src/pipewire/module.h -> pipewire-0.3.77.tar.gz/src/pipewire/module.h
Changed
@@ -24,6 +24,8 @@ */ #define PW_TYPE_INTERFACE_Module PW_TYPE_INFO_INTERFACE_BASE "Module" +#define PW_MODULE_PERM_MASK PW_PERM_R|PW_PERM_M + #define PW_VERSION_MODULE 3 struct pw_module;
View file
pipewire-0.3.76.tar.gz/src/pipewire/node.h -> pipewire-0.3.77.tar.gz/src/pipewire/node.h
Changed
@@ -29,6 +29,8 @@ */ #define PW_TYPE_INTERFACE_Node PW_TYPE_INFO_INTERFACE_BASE "Node" +#define PW_NODE_PERM_MASK PW_PERM_RWXML + #define PW_VERSION_NODE 3 struct pw_node; @@ -132,6 +134,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the node. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -146,6 +150,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions on the node. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -157,6 +163,8 @@ * \param id the parameter id to set * \param flags extra parameter flags * \param param the parameter to set + * + * This requires X and W permissions on the node. */ int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -165,6 +173,8 @@ * Send a command to the node * * \param command the command to send + * + * This requires X and W permissions on the node. */ int (*send_command) (void *object, const struct spa_command *command); };
View file
pipewire-0.3.76.tar.gz/src/pipewire/permission.h -> pipewire-0.3.77.tar.gz/src/pipewire/permission.h
Changed
@@ -29,14 +29,19 @@ #define PW_PERM_X 0100 /**< methods can be called on the object. The W flag must be * present in order to call methods that modify the object. */ #define PW_PERM_M 0010 /**< metadata can be set on object, Since 0.3.9 */ +#define PW_PERM_L 0020 /**< a link can be made between a node that doesn't have + * permission to see the other node, Since 0.3.77 */ -#define PW_PERM_RWX (PW_PERM_R|PW_PERM_W|PW_PERM_X) +#define PW_PERM_RW (PW_PERM_R|PW_PERM_W) +#define PW_PERM_RWX (PW_PERM_RW|PW_PERM_X) #define PW_PERM_RWXM (PW_PERM_RWX|PW_PERM_M) +#define PW_PERM_RWXML (PW_PERM_RWXM|PW_PERM_L) #define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R) #define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W) #define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X) #define PW_PERM_IS_M(p) (((p)&PW_PERM_M) == PW_PERM_M) +#define PW_PERM_IS_L(p) (((p)&PW_PERM_L) == PW_PERM_L) #define PW_PERM_ALL PW_PERM_RWXM #define PW_PERM_INVALID (uint32_t)(0xffffffff) @@ -48,12 +53,13 @@ #define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) }) -#define PW_PERMISSION_FORMAT "%c%c%c%c" +#define PW_PERMISSION_FORMAT "%c%c%c%c%c" #define PW_PERMISSION_ARGS(permission) \ (permission) & PW_PERM_R ? 'r' : '-', \ (permission) & PW_PERM_W ? 'w' : '-', \ (permission) & PW_PERM_X ? 'x' : '-', \ - (permission) & PW_PERM_M ? 'm' : '-' + (permission) & PW_PERM_M ? 'm' : '-', \ + (permission) & PW_PERM_L ? 'l' : '-' /** * \}
View file
pipewire-0.3.76.tar.gz/src/pipewire/port.h -> pipewire-0.3.77.tar.gz/src/pipewire/port.h
Changed
@@ -29,6 +29,8 @@ #define PW_TYPE_INTERFACE_Port PW_TYPE_INFO_INTERFACE_BASE "Port" +#define PW_PORT_PERM_MASK PW_PERM_R|PW_PERM_X|PW_PERM_M + #define PW_VERSION_PORT 3 struct pw_port; @@ -115,6 +117,8 @@ * * \param ids an array of param ids * \param n_ids the number of ids in \a ids + * + * This requires X permissions on the port. */ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids); @@ -129,6 +133,8 @@ * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL + * + * This requires X permissions on the port. */ int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num,
View file
pipewire-0.3.76.tar.gz/src/pipewire/private.h -> pipewire-0.3.77.tar.gz/src/pipewire/private.h
Changed
@@ -288,6 +288,7 @@ const char *type; /**< type of interface */ uint32_t version; /**< version of interface */ + uint32_t permission_mask; /**< possible permissions */ pw_global_bind_func_t func; /**< bind function */ void *object; /**< object associated with the interface */
View file
pipewire-0.3.76.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.77.tar.gz/src/tools/pw-dump.c
Changed
@@ -1427,6 +1427,7 @@ { "w", PW_PERM_W }, { "x", PW_PERM_X }, { "m", PW_PERM_M }, + { "l", PW_PERM_L }, { NULL, }, };
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.