Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 21
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Mon Jan 16 08:13:26 UTC 2023 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.64 + +------------------------------------------------------------------- Tue Dec 20 18:46:39 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.63
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.63 +Version: 0.3.64 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.63.tar.gz/NEWS -> pipewire-0.3.64.tar.gz/NEWS
Changed
@@ -1,3 +1,93 @@ +# PipeWire 0.3.64 (2023-01-12) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - Clear old buffer memory on ports to fix some SIGBUS errors. + - It is now possible to assign custom port names to the ports from an + adapter. This feature is helpful to those who use a multichannel + interface with long-term connections. This way they can label each + port with its designation, such as an instrument name or anything else + to be displayed in a patchbay or DAW. + - Fix some issues with node suspend and quantum and rate calculations. + - Fix some regressions in pulse-tunnel and RTP-source adaptive resampling + that could cause synchronization problems. + - UCM devices now also have a Pro Audio profile. + - NODE_TARGET (with the object.id) is now deprecated, use TARGET_OBJECT + (with the object.serial, which is not reused and can avoid races). + + +## PipeWire + - Clear all peer input port buffers when suspending. This fixes some + SIGBUS errors when some plugins were using old memory. (#2914) + - Fix a case where nodes that were not supposed to be suspended, were + kept suspended on a rate change. (#2929) + - Fix an error in the quantum and rate calculations that could cause + nodes to run with wrong quantum and rates when multiple rates were + allowed. (#2925) + +## Tools + - pw-dump will now sort dictionaries to make it easier to compare + different outputs. + - Improve output of pw-reserve. + - pw-loopback uses TARGET_OBJECT so you will need to use the serial + id (or better the name) as the target instead of the object id. + +## modules + - The filter-chain modules has seen some cleanups, refactoring and + optimizations in the various DSP functions. + - The ROC module now supports setting a custom samplerate. + - ROC 0.2.X is now required. + - The pulse tunnel and RTP source were not updating the rate field + correctly which could cause synchronization problems. (#2891) + - The filter-chain now supports an arbitrary number of control + properties. (#2933) + - It is now possible to assign custom port names to the ports from an + adapter with the PW_KEY_NODE_CHANNELNAMES. + - Support was added for capture and playback props in echo-cancel. + (#2939) + +## SPA + - The ACP code now has an option to set the probe samplerate. (#1599) + - UCM devices now also have a Pro Audio profile. + - Filtering of Step ranges is now implemented. + +## Pulse-Server + - The channel-map is now set correctly on the echo-cancel module. + - source_master and sink_master are now correctly handled in module + echo-cancel. + - Fix a regression in DRAIN where resuming after a DRAIN would fail. + This caused problems for espeak. (#2928) + - TARGET_OBJECT is now used to make it possible to use the indexes + as a target. + - ladspa-source and remap-source can now also link to monitors. + +## ALSA + - The ALSA plugin now handles the target.object correctly when set to + -1. (#2893) + +## V4L2 + - The v4l2 replacement library now also follows symlinks. + - Support for getting and setting controls was added. + - Support for G_PARM was added. + - The environment variable PIPEWIRE_V4L2_TARGET can be used to force + an application onto a specific camera. + +## Bluetooth + - Fix compilation without ldac_abr. + - Fix a missing brace in CIND reply. This could cause some devices to + fail. + - Fix configuration of the initial latency. + +## GStreamer + - The device provider now supports setting an fd so that it can connect + to PipeWire sessions from the portal. + - DMABuf support was re-enabled in gstpipewiresrc. + + +Older versions: + # PipeWire 0.3.63 (2022-12-15) This is a quick bugfix release that is API and ABI compatible with previous @@ -39,9 +129,6 @@ only for loading modules. This removes the dependency on pactl. - Improve debug of messages. - -Older versions: - # PipeWire 0.3.62 (2022-12-09) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.63.tar.gz/README.md -> pipewire-0.3.64.tar.gz/README.md
Changed
@@ -55,7 +55,8 @@ samplerate. This function will attempt to change the graph samplerate to `denom` and use the specified `num` as the buffer size. -* `PIPEWIRE_NODE=<id>` to request a link to the specified node +* `PIPEWIRE_NODE=<id>` to request a link to the specified node. The + id can be a node.name or object.serial of the target node. ### Using tools @@ -209,3 +210,9 @@ We adhere to the Contributor Covenant for our code of conduct(CODE_OF_CONDUCT.md). Donate using Liberapay(https://liberapay.com/PipeWire/donate). + +## Getting help + +You can ask for help on the IRC channel (see above). You can also ask +questions by raising(https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/new) +a gitlab issue.
View file
pipewire-0.3.63.tar.gz/doc/pipewire-daemon.dox -> pipewire-0.3.64.tar.gz/doc/pipewire-daemon.dox
Changed
@@ -133,15 +133,14 @@ # Logging The `PIPEWIRE_DEBUG` environment variable can be used to enable -more debugging. This variable supports one of two formats: +more debugging. This variable supports the following format: -- `PIPEWIRE_DEBUG=<level>` where `<level>` is either a numerical log level or its - respective key, see below. -- `PIPEWIRE_DEBUG=<glob1>:<level1>,<glob2>:<level2>,...` where the globs are +- `PIPEWIRE_DEBUG=<level>,<glob1>:<level1>,<glob2>:<level2>,...` where the globs are shell globs to match on log topics and the levels are the respective log level to set for that topic. Globs are applied in order and a matching - glob overrides an earlier glob for that category. For example, - `PIPEWIRE_DEBUG=*:E,mod.*:D,mod.foo:X` enables global error messages, + glob overrides an earlier glob for that category. A level without a glob + prefix will set the global log level and is a more preformant version of + `*:<level>`. For example, `PIPEWIRE_DEBUG=E,mod.*:D,mod.foo:X` enables global error messages, debugging on all modules but no messages on the foo module. - `<level>` specifies the log level:
View file
pipewire-0.3.63.tar.gz/meson.build -> pipewire-0.3.64.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.63', + version : '0.3.64', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3',
View file
pipewire-0.3.63.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> pipewire-0.3.64.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
@@ -1083,6 +1083,7 @@ struct global *g = data; spa_list_remove(&g->link); g->proxy = NULL; + pw_properties_free(g->props); } static const struct pw_proxy_events proxy_events = {
View file
pipewire-0.3.63.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.64.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -579,9 +579,9 @@ pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%lu/%u", pw->min_avail, io->rate); if (pw_properties_get(props, PW_KEY_NODE_RATE) == NULL) pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", io->rate); - if (pw->target != NULL && - pw_properties_get(props, PW_KEY_NODE_TARGET) == NULL) - pw_properties_setf(props, PW_KEY_NODE_TARGET, "%s", pw->target); + if (pw->target != NULL && !spa_streq(pw->target, "-1") && + pw_properties_get(props, PW_KEY_TARGET_OBJECT) == NULL) + pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%s", pw->target); if (pw_properties_get(props, PW_KEY_MEDIA_TYPE) == NULL) pw_properties_set(props, PW_KEY_MEDIA_TYPE, "Audio");
View file
pipewire-0.3.63.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.64.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -2219,7 +2219,7 @@ if (n_buffers > MAX_BUFFERS) { pw_log_error("%p: too many buffers %u > %u", c, n_buffers, MAX_BUFFERS); - return -EINVAL; + return -ENOSPC; } if (p->object->port.type_id == TYPE_ID_VIDEO && direction == SPA_DIRECTION_INPUT) { @@ -5591,16 +5591,13 @@ struct object *o; struct pw_array tmp; const char *str; - uint32_t i, count, id; + uint32_t i, count; int r; regex_t port_regex, type_regex; spa_return_val_if_fail(c != NULL, NULL); - if ((str = getenv("PIPEWIRE_NODE")) != NULL) - id = pw_properties_parse_int(str); - else - id = SPA_ID_INVALID; + str = getenv("PIPEWIRE_NODE"); if (port_name_pattern && port_name_pattern0) { if ((r = regcomp(&port_regex, port_name_pattern, REG_EXTENDED | REG_NOSUB)) != 0) { @@ -5615,7 +5612,7 @@ } } - pw_log_debug("%p: ports id:%d name:\"%s\" type:\"%s\" flags:%08lx", c, id, + pw_log_debug("%p: ports target:%s name:\"%s\" type:\"%s\" flags:%08lx", c, str, port_name_pattern, type_name_pattern, flags); pthread_mutex_lock(&c->context.lock); @@ -5631,8 +5628,11 @@ continue; if (!SPA_FLAG_IS_SET(o->port.flags, flags)) continue; - if (id != SPA_ID_INVALID && o->port.node_id != id) - continue; + if (str != NULL && o->port.node != NULL) { + if (!spa_strstartswith(o->port.name, str) && + o->port.node->serial != atoll(str)) + continue; + } if (port_name_pattern && port_name_pattern0) { bool match;
View file
pipewire-0.3.63.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.64.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c
Changed
@@ -28,6 +28,7 @@ #include <fcntl.h> #include <dlfcn.h> #include <stdarg.h> +#include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> @@ -671,7 +672,7 @@ const struct global_info *info = NULL; struct pw_proxy *proxy; const char *str; - uint32_t serial = SPA_ID_INVALID, dev; + uint32_t serial = SPA_ID_INVALID, dev, req_serial; if (spa_streq(type, PW_TYPE_INTERFACE_Node)) { @@ -691,6 +692,11 @@ !spa_atou32(str, &serial, 10)) return; + if ((str = getenv("PIPEWIRE_V4L2_TARGET")) != NULL + && spa_atou32(str, &req_serial, 10) + && req_serial != serial) + return; + dev = find_dev_for_serial(serial); if (dev != SPA_ID_INVALID && dev != file->dev_id) return; @@ -792,11 +798,20 @@ struct file *file; bool passthrough = true; uint32_t dev_id = SPA_ID_INVALID; + char *real_path; + + real_path = realpath(path, NULL); + if (!real_path) + real_path = (char *)path; - if (spa_strstartswith(path, "/dev/video")) { - if (spa_atou32(path+10, &dev_id, 10) && dev_id < MAX_DEV) + if (spa_strstartswith(real_path, "/dev/video")) { + if (spa_atou32(real_path+10, &dev_id, 10) && dev_id < MAX_DEV) passthrough = false; } + + if (real_path && real_path != path) + free(real_path); + if (passthrough) return globals.old_fops.openat(dirfd, path, oflag, mode); @@ -887,7 +902,9 @@ pw_log_info("path:%s oflag:%d mode:%d -> %d (%s)", path, oflag, mode, -1, spa_strerror(res)); + errno = -res; + return -1; } @@ -1733,6 +1750,76 @@ return res; } +static int vidioc_g_parm(struct file *file, struct v4l2_streamparm *arg) +{ + if (arg->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + struct param *p; + + pw_thread_loop_lock(file->loop); + bool found = false; + struct spa_video_info info; + int num = 0, denom = 0; + + spa_list_for_each(p, &file->node->param_list, link) { + if (p->id != SPA_PARAM_EnumFormat || p->param == NULL) + continue; + + if (param_to_info(p->param, &info) < 0) + continue; + + switch (info.media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + num = info.info.raw.framerate.num; + denom = info.info.raw.framerate.denom; + break; + case SPA_MEDIA_SUBTYPE_mjpg: + num = info.info.mjpg.framerate.num; + denom = info.info.mjpg.framerate.denom; + break; + case SPA_MEDIA_SUBTYPE_h264: + num = info.info.h264.framerate.num; + denom = info.info.h264.framerate.denom; + break; + } + + if (num == 0 || denom == 0) + continue; + + found = true; + break; + } + + if (!found) { + pw_thread_loop_unlock(file->loop); + return -EINVAL; + } + + pw_thread_loop_unlock(file->loop); + + spa_zero(*arg); + arg->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + arg->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + arg->parm.capture.capturemode = 0; + arg->parm.capture.extendedmode = 0; + arg->parm.capture.readbuffers = 0; + arg->parm.capture.timeperframe.numerator = denom; + arg->parm.capture.timeperframe.denominator = num; + + pw_log_info("VIDIOC_G_PARM frametime: %d/%d", num, denom); + + return 0; +} + +// TODO: implement setting parameters +static int vidioc_s_parm(struct file *file, struct v4l2_streamparm *arg) +{ + pw_log_warn("VIDIOC_S_PARM is unimplemented, returning current value"); + vidioc_g_parm(file, arg); + return 0; +} + static int vidioc_enuminput(struct file *file, struct v4l2_input *arg) { uint32_t index = arg->index; @@ -2014,6 +2101,261 @@ return res; } +// Copied from spa/plugins/v4l2/v4l2-utils.c +// TODO: unify with source +static struct { + uint32_t v4l2_id; + uint32_t spa_id; +} control_map = { + { V4L2_CID_BRIGHTNESS, SPA_PROP_brightness }, + { V4L2_CID_CONTRAST, SPA_PROP_contrast }, + { V4L2_CID_SATURATION, SPA_PROP_saturation }, + { V4L2_CID_HUE, SPA_PROP_hue }, + { V4L2_CID_GAMMA, SPA_PROP_gamma }, + { V4L2_CID_EXPOSURE, SPA_PROP_exposure }, + { V4L2_CID_GAIN, SPA_PROP_gain }, + { V4L2_CID_SHARPNESS, SPA_PROP_sharpness }, +}; + +static uint32_t prop_id_to_control(uint32_t prop_id) +{ + SPA_FOR_EACH_ELEMENT_VAR(control_map, c) { + if (c->spa_id == prop_id) + return c->v4l2_id; + } + if (prop_id >= SPA_PROP_START_CUSTOM) + return prop_id - SPA_PROP_START_CUSTOM; + return SPA_ID_INVALID; +} + +static int vidioc_queryctrl(struct file *file, struct v4l2_queryctrl *arg) +{ + struct param *p; + bool found = false, next = false; + + memset(arg->reserved, 0, sizeof(arg->reserved)); + + // TODO: V4L2_CTRL_FLAG_NEXT_COMPOUND + if (arg->id & V4L2_CTRL_FLAG_NEXT_CTRL) { + pw_log_debug("VIDIOC_QUERYCTRL: 0x%08" PRIx32 " | V4L2_CTRL_FLAG_NEXT_CTRL", arg->id); + arg->id = arg->id & ~V4L2_CTRL_FLAG_NEXT_CTRL & ~V4L2_CTRL_FLAG_NEXT_COMPOUND; + next = true; + } + pw_log_debug("VIDIOC_QUERYCTRL: 0x%08" PRIx32, arg->id); + + + if (file->node == NULL) + return -EIO; + + pw_thread_loop_lock(file->loop); + + // FIXME: place found item into a variable. Will fix unordered ctrls + spa_list_for_each(p, &file->node->param_list, link) { + uint32_t prop_id, ctrl_id, n_vals, choice = SPA_ID_INVALID; + const char *prop_description; + const struct spa_pod *type, *pod; + + if (p->id != SPA_PARAM_PropInfo || p->param == NULL) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_id, SPA_POD_Id(&prop_id), + SPA_PROP_INFO_description, SPA_POD_String(&prop_description)) < 0) + continue; + + if ((ctrl_id = prop_id_to_control(prop_id)) == SPA_ID_INVALID) + continue; + + if ((next && ctrl_id > arg->id) || (!next && ctrl_id == arg->id)) { + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_type, SPA_POD_PodChoice(&type)) < 0) + continue; + + // TODO: support setting controls + arg->flags = V4L2_CTRL_FLAG_READ_ONLY; + spa_scnprintf((char*)arg->name, sizeof(arg->name), "%s", prop_description); + + // check type and populate range + pod = spa_pod_get_values(type, &n_vals, &choice); + if (spa_pod_is_int(pod)) { + if (n_vals < 4) + break; + arg->type = V4L2_CTRL_TYPE_INTEGER; + int *v = SPA_POD_BODY(pod); + arg->default_value = v0; + arg->minimum = v1; + arg->maximum = v2; + arg->step = v3; + } + else if (spa_pod_is_bool(pod) && n_vals > 0) { + arg->type = V4L2_CTRL_TYPE_BOOLEAN; + arg->default_value = SPA_POD_VALUE(struct spa_pod_bool, pod); + arg->minimum = 0; + arg->maximum = 1; + arg->step = 1; + } + else { + break; + } + + arg->id = ctrl_id; + found = true; + pw_log_debug("ctrl 0x%08" PRIx32 " ok", arg->id); + break; + } + } + + pw_thread_loop_unlock(file->loop); + + if (!found) { + pw_log_info("not found ctrl 0x%08" PRIx32, arg->id); + return -EINVAL; + } + + return 0; +} + +static int vidioc_g_ctrl(struct file *file, struct v4l2_control *arg) +{ + struct param *p; + bool found = false; + + pw_log_debug("VIDIOC_G_CTRL: 0x%08" PRIx32, arg->id); + + if (file->node == NULL) + return -EIO; + + pw_thread_loop_lock(file->loop); + + spa_list_for_each(p, &file->node->param_list, link) { + uint32_t prop_id, ctrl_id, n_vals, choice = SPA_ID_INVALID; + const char *prop_description; + const struct spa_pod *type, *pod; + + if (p->id != SPA_PARAM_PropInfo || p->param == NULL) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_id, SPA_POD_Id(&prop_id), + SPA_PROP_INFO_description, SPA_POD_String(&prop_description)) < 0) + continue; + + if ((ctrl_id = prop_id_to_control(prop_id)) == SPA_ID_INVALID) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_type, SPA_POD_PodChoice(&type)) < 0) + continue; + + if (ctrl_id == arg->id) { + // TODO: support getting true ctrl values instead of defaults + pod = spa_pod_get_values(type, &n_vals, &choice); + if (spa_pod_is_int(pod)) { + if (n_vals < 4) + break; + int *v = SPA_POD_BODY(pod); + arg->value = v0; + } + else if (spa_pod_is_bool(pod) && n_vals > 0) { + arg->value = SPA_POD_VALUE(struct spa_pod_bool, pod); + } + else { + break; + } + + found = true; + pw_log_debug("ctrl 0x%08" PRIx32 " ok", arg->id); + break; + } + } + + pw_thread_loop_unlock(file->loop); + + if (!found) { + pw_log_info("not found ctrl 0x%08" PRIx32, arg->id); + return -EINVAL; + } + + return 0; +} + +static int vidioc_s_ctrl(struct file *file, struct v4l2_control *arg) +{ + struct param *p; + bool found = false; + + pw_log_info("VIDIOC_S_CTRL: 0x%08" PRIx32 " 0x%08" PRIx32, arg->id, arg->value); + + if (file->node == NULL) + return -EIO; + + pw_thread_loop_lock(file->loop); + + spa_list_for_each(p, &file->node->param_list, link) { + uint32_t prop_id, ctrl_id, n_vals, choice = SPA_ID_INVALID; + const char *prop_description; + const struct spa_pod *type, *pod; + + if (p->id != SPA_PARAM_PropInfo || p->param == NULL) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_id, SPA_POD_Id(&prop_id), + SPA_PROP_INFO_description, SPA_POD_String(&prop_description)) < 0) + continue; + + if ((ctrl_id = prop_id_to_control(prop_id)) == SPA_ID_INVALID) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_PropInfo, NULL, + SPA_PROP_INFO_type, SPA_POD_PodChoice(&type)) < 0) + continue; + + if (ctrl_id == arg->id) { + char buf1024; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf)); + struct spa_pod_frame f1; + struct spa_pod *param; + pod = spa_pod_get_values(type, &n_vals, &choice); + + spa_pod_builder_push_object(&b, &f0, + SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); + + if (spa_pod_is_int(pod)) { + spa_pod_builder_add(&b, prop_id, SPA_POD_Int(arg->value), 0); + } else if (spa_pod_is_bool(pod)) { + spa_pod_builder_add(&b, prop_id, SPA_POD_Bool(arg->value), 0); + } else { + // TODO: float and other formats + pw_log_info("unknown type"); + break; + } + + param = spa_pod_builder_pop(&b, &f0); + pw_node_set_param(file->node->proxy, SPA_PARAM_Props, 0, param); + + found = true; + pw_log_info("ctrl 0x%08" PRIx32 " set ok", arg->id); + break; + } + } + + pw_thread_loop_unlock(file->loop); + + if (!found) { + pw_log_info("not found ctrl 0x%08" PRIx32, arg->id); + return -EINVAL; + } + + return 0; +} + static int v4l2_ioctl(int fd, unsigned long int request, void *arg) { int res; @@ -2054,6 +2396,12 @@ case VIDIOC_TRY_FMT: res = vidioc_try_fmt(file, (struct v4l2_format *)arg); break; + case VIDIOC_G_PARM: + res = vidioc_g_parm(file, (struct v4l2_streamparm *)arg); + break; + case VIDIOC_S_PARM: + res = vidioc_s_parm(file, (struct v4l2_streamparm *)arg); + break; case VIDIOC_ENUMINPUT: res = vidioc_enuminput(file, (struct v4l2_input *)arg); break; @@ -2087,6 +2435,16 @@ case VIDIOC_STREAMOFF: res = vidioc_streamoff(file, (int *)arg); break; + // TODO: VIDIOC_QUERY_EXT_CTRL + case VIDIOC_QUERYCTRL: + res = vidioc_queryctrl(file, (struct v4l2_queryctrl *)arg); + break; + case VIDIOC_G_CTRL: + res = vidioc_g_ctrl(file, (struct v4l2_control *)arg); + break; + case VIDIOC_S_CTRL: + res = vidioc_s_ctrl(file, (struct v4l2_control *)arg); + break; default: res = -ENOTTY; break;
View file
pipewire-0.3.63.tar.gz/spa/include/spa/pod/filter.h -> pipewire-0.3.64.tar.gz/spa/include/spa/pod/filter.h
Changed
@@ -123,6 +123,27 @@ return 1; } +static inline int spa_pod_filter_is_step_of(uint32_t type, const void *r1, + const void *r2, uint32_t size) +{ + switch (type) { + case SPA_TYPE_Int: + return *(int32_t *) r1 % *(int32_t *) r2 == 0; + case SPA_TYPE_Long: + return *(int64_t *) r1 % *(int64_t *) r2 == 0; + case SPA_TYPE_Rectangle: + { + const struct spa_rectangle *rec1 = (struct spa_rectangle *) r1, + *rec2 = (struct spa_rectangle *) r2; + + return (rec1->width % rec2->width == 0 && + rec1->height % rec2->height == 0); + } + default: + return -ENOTSUP; + } + return 0; +} static inline int spa_pod_filter_prop(struct spa_pod_builder *b, @@ -209,7 +230,26 @@ if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Step) || (p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Step)) { - return -ENOTSUP; + int n_copied = 0; + for (j = 0, a1 = alt1, a2 = alt2; j < nalt1; j++, a1 = SPA_PTROFF(a1,size,void)) { + int res; + if (spa_pod_compare_value(type, a1, a2, size) < 0) + continue; + if (spa_pod_compare_value(type, a1, SPA_PTROFF(a2,size,void), size) > 0) + continue; + + res = spa_pod_filter_is_step_of(type, a1, SPA_PTROFF(a2,size*2,void), size); + if (res == 0) + continue; + if (res == -ENOTSUP) + return -EINVAL; + + spa_pod_builder_raw(b, a1, size); + n_copied++; + } + if (n_copied == 0) + return -EINVAL; + nc->body.type = SPA_CHOICE_Enum; } if ((p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_None) || @@ -263,10 +303,29 @@ if (p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Flags) return -ENOTSUP; - if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_None) - return -ENOTSUP; - if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Enum) - return -ENOTSUP; + if ((p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_None) || + (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Enum)) { + int n_copied = 0; + for (j = 0, a1 = alt1, a2 = alt2; j < nalt2; j++, a2 = SPA_PTROFF(a1,size,void)) { + int res; + if (spa_pod_compare_value(type, a2, a1, size) < 0) + continue; + if (spa_pod_compare_value(type, a2, SPA_PTROFF(a1,size,void), size) > 0) + continue; + + res = spa_pod_filter_is_step_of(type, a2, SPA_PTROFF(a1,size*2,void), size); + if (res == 0) + continue; + if (res == -ENOTSUP) + return -EINVAL; + + spa_pod_builder_raw(b, a2, size); + n_copied++; + } + if (n_copied == 0) + return -EINVAL; + nc->body.type = SPA_CHOICE_Enum; + } if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Flags) return -ENOTSUP;
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
@@ -314,7 +314,7 @@ snd_pcm_uframes_t try_period_size, try_buffer_size; ss.format = PA_SAMPLE_S32LE; - ss.rate = DEFAULT_RATE; + ss.rate = impl->rate; ss.channels = 64; ap = pa_xnew0(pa_alsa_profile, 1); @@ -322,6 +322,7 @@ ap->profile.name = ap->name = pa_xstrdup("pro-audio"); ap->profile.description = ap->description = pa_xstrdup(_("Pro Audio")); ap->profile.available = ACP_AVAILABLE_YES; + ap->profile.flags = ACP_PROFILE_PRO; ap->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); ap->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); pa_hashmap_put(ps->profiles, ap->name, ap); @@ -448,8 +449,7 @@ ap->profile.flags = ACP_PROFILE_OFF; pa_hashmap_put(impl->profiles, ap->name, ap); - if (!impl->use_ucm) - add_pro_profile(impl, impl->card.index); + add_pro_profile(impl, impl->card.index); PA_HASHMAP_FOREACH(ap, impl->profile_set->profiles, state) { pa_alsa_mapping *m; @@ -469,10 +469,12 @@ pa_dynarray_append(&impl->out.devices, dev); } if (impl->use_ucm) { - pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, - true, impl->ports, ap, NULL); - pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context, - true, impl, dev->pcm_handle, impl->profile_set->ignore_dB); + if (m->ucm_context.ucm_devices) { + pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, + true, impl->ports, ap, NULL); + pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context, + true, impl, dev->pcm_handle, impl->profile_set->ignore_dB); + } } else pa_alsa_path_set_add_ports(m->output_path_set, ap, impl->ports, @@ -491,10 +493,12 @@ } if (impl->use_ucm) { - pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, - false, impl->ports, ap, NULL); - pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context, - false, impl, dev->pcm_handle, impl->profile_set->ignore_dB); + if (m->ucm_context.ucm_devices) { + pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, + false, impl->ports, ap, NULL); + pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context, + false, impl, dev->pcm_handle, impl->profile_set->ignore_dB); + } } else pa_alsa_path_set_add_ports(m->input_path_set, ap, impl->ports, dev->ports, NULL); @@ -1443,7 +1447,7 @@ } /* if UCM is available for this card then update the verb */ - if (impl->use_ucm) { + if (impl->use_ucm && !(np->profile.flags & ACP_PROFILE_PRO)) { if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl, np->profile.flags & ACP_PROFILE_OFF ? NULL : np->profile.name, op ? op->profile.name : NULL)) < 0) { @@ -1453,20 +1457,26 @@ if (np->output_mappings) { PA_IDXSET_FOREACH(am, np->output_mappings, idx) { - if (impl->use_ucm) + if (impl->use_ucm) { /* Update ports priorities */ - pa_alsa_ucm_add_ports_combination(am->output.ports, &am->ucm_context, - true, impl->ports, np, NULL); + if (am->ucm_context.ucm_devices) { + pa_alsa_ucm_add_ports_combination(am->output.ports, &am->ucm_context, + true, impl->ports, np, NULL); + } + } device_enable(impl, am, &am->output); } } if (np->input_mappings) { PA_IDXSET_FOREACH(am, np->input_mappings, idx) { - if (impl->use_ucm) + if (impl->use_ucm) { /* Update ports priorities */ - pa_alsa_ucm_add_ports_combination(am->input.ports, &am->ucm_context, - false, impl->ports, np, NULL); + if (am->ucm_context.ucm_devices) { + pa_alsa_ucm_add_ports_combination(am->input.ports, &am->ucm_context, + false, impl->ports, np, NULL); + } + } device_enable(impl, am, &am->input); } } @@ -1553,6 +1563,7 @@ impl->auto_profile = true; impl->auto_port = true; impl->ignore_dB = false; + impl->rate = DEFAULT_RATE; if (props) { if ((s = acp_dict_lookup(props, "api.alsa.use-ucm")) != NULL) @@ -1569,10 +1580,12 @@ impl->auto_profile = spa_atob(s); if ((s = acp_dict_lookup(props, "api.acp.auto-port")) != NULL) impl->auto_port = spa_atob(s); + if ((s = acp_dict_lookup(props, "api.acp.probe-rate")) != NULL) + impl->rate = atoi(s); } impl->ucm.default_sample_spec.format = PA_SAMPLE_S16NE; - impl->ucm.default_sample_spec.rate = DEFAULT_RATE; + impl->ucm.default_sample_spec.rate = impl->rate; impl->ucm.default_sample_spec.channels = 2; pa_channel_map_init_extend(&impl->ucm.default_channel_map, impl->ucm.default_sample_spec.channels, PA_CHANNEL_MAP_ALSA);
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/acp/acp.h -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/acp/acp.h
Changed
@@ -237,6 +237,7 @@ #define ACP_PROFILE_ACTIVE (1<<0) #define ACP_PROFILE_OFF (1<<1) /* the Off profile */ #define ACP_PROFILE_SAVE (1<<2) /* if the profile needs saving */ +#define ACP_PROFILE_PRO (1<<3) /* the Pro profile */ uint32_t flags; const char *name;
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/acp/card.h -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/acp/card.h
Changed
@@ -47,6 +47,7 @@ bool auto_profile; bool auto_port; bool ignore_dB; + uint32_t rate; pa_alsa_ucm_config ucm; pa_alsa_profile_set *profile_set;
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
@@ -731,6 +731,7 @@ { struct state *this = object; uint32_t i; + int res; spa_return_val_if_fail(this != NULL, -EINVAL); @@ -738,14 +739,15 @@ spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers); - if (!this->have_format) - return -EIO; - - if (n_buffers == 0) { + if (this->n_buffers > 0) { spa_alsa_pause(this); - clear_buffers(this); - return 0; + if ((res = clear_buffers(this)) < 0) + return res; } + if (n_buffers > 0 && !this->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; for (i = 0; i < n_buffers; i++) { struct buffer *b = &this->buffersi;
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
@@ -673,9 +673,6 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - if (!this->have_format) - return -EIO; - spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers); if (this->n_buffers > 0) { @@ -683,6 +680,11 @@ if ((res = clear_buffers(this)) < 0) return res; } + if (n_buffers > 0 && !this->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &this->buffersi; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c -> pipewire-0.3.64.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c
Changed
@@ -748,11 +748,13 @@ spa_log_debug(this->log, "%p: port %d.%d buffers:%d format:%d", this, direction, port_id, n_buffers, port->have_format); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.64.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -2049,13 +2049,16 @@ port = GET_PORT(this, direction, port_id); - spa_return_val_if_fail(port->have_format, -EIO); - spa_log_debug(this->log, "%p: use buffers %d on port %d:%d", this, n_buffers, direction, port_id); clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + maxsize = this->quantum_limit * sizeof(float); for (i = 0; i < n_buffers; i++) {
View file
pipewire-0.3.63.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.64.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
@@ -520,7 +520,7 @@ if (ic >= dst_chan || jc >= src_chan) continue; - if (i == 0) + if (ic == 0) idx2 += snprintf(str2 + idx2, sizeof(str2) - idx2, "%-4.4s ", src_mask == ~0LU ? "MONO" : spa_debug_type_find_short_name(spa_type_audio_channel, j + 3)); @@ -533,9 +533,9 @@ else idx += snprintf(str + idx, sizeof(str) - idx, "%1.3f ", matrixij); } - if (dst_mask != 0 && src_mask != 0 && sum > 0.0f) { - if (i == 0) - spa_log_info(mix->log, " %s", str2); + if (idx2 > 0) + spa_log_info(mix->log, " %s", str2); + if (idx > 0) { spa_log_info(mix->log, "%-4.4s %s %f", dst_mask == ~0LU ? "MONO" : spa_debug_type_find_short_name(spa_type_audio_channel, i + 3),
View file
pipewire-0.3.63.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.64.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
@@ -649,10 +649,13 @@ port = GET_PORT(this, direction, port_id); - spa_return_val_if_fail(port->have_format, -EIO); - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.64.tar.gz/spa/plugins/audiomixer/mixer-dsp.c
Changed
@@ -586,10 +586,13 @@ port = GET_PORT(this, direction, port_id); - spa_return_val_if_fail(port->have_format, -EIO); - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c -> pipewire-0.3.64.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
@@ -829,11 +829,13 @@ port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/avb/avb-pcm-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/avb/avb-pcm-sink.c
Changed
@@ -629,14 +629,14 @@ spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers); - if (!port->have_format) - return -EIO; - - if (n_buffers == 0) { + if (port->n_buffers > 0) { spa_avb_pause(this); clear_buffers(this, port); - return 0; } + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi;
View file
pipewire-0.3.63.tar.gz/spa/plugins/avb/avb-pcm-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/avb/avb-pcm-source.c
Changed
@@ -629,14 +629,14 @@ spa_log_debug(this->log, "%p: use %d buffers", this, n_buffers); - if (!port->have_format) - return -EIO; - - if (n_buffers == 0) { + if (port->n_buffers > 0) { spa_avb_pause(this); clear_buffers(this, port); - return 0; } + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi;
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c
Changed
@@ -243,7 +243,7 @@ #else struct impl *this = data; int res; - if (this->eqmid == LDACBT_EQMID_BITRATE_330000 || !this->enable_abr) + if (this->eqmid == LDACBT_EQMID_MQ || !this->enable_abr) return this->eqmid; res = ldacBT_alter_eqmid_priority(this->ldac, LDACBT_EQMID_INC_CONNECTION); return res;
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
@@ -74,7 +74,7 @@ HFP_AG_INITIAL_CODEC_SETUP_WAIT }; -#define CIND_INDICATORS "(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2)),(\"signal\",(0-5)),(\"roam\",(0-1)),\"battchg\",(0-5))" +#define CIND_INDICATORS "(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2)),(\"signal\",(0-5)),(\"roam\",(0-1)),(\"battchg\",(0-5))" enum { CIND_SERVICE = 1, CIND_CALL,
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/media-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/media-sink.c
Changed
@@ -1453,11 +1453,13 @@ spa_log_debug(this->log, "use buffers %d", n_buffers); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi; @@ -1754,7 +1756,6 @@ port->latency = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); port->latency.min_quantum = 1.0f; port->latency.max_quantum = 1.0f; - set_latency(this, false); spa_list_init(&port->ready); @@ -1800,6 +1801,8 @@ reset_props(this, &this->props); + set_latency(this, false); + spa_bt_transport_add_listener(this->transport, &this->transport_listener, &transport_events, this);
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/media-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/media-source.c
Changed
@@ -1202,11 +1202,13 @@ spa_log_debug(this->log, "use buffers %d", n_buffers); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
@@ -1186,11 +1186,13 @@ spa_log_debug(this->log, "use buffers %d", n_buffers); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi;
View file
pipewire-0.3.63.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
@@ -1155,11 +1155,13 @@ spa_log_debug(this->log, "use buffers %d", n_buffers); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/control/mixer.c -> pipewire-0.3.64.tar.gz/spa/plugins/control/mixer.c
Changed
@@ -506,10 +506,13 @@ spa_log_debug(this->log, NAME " %p: use buffers %d on port %d:%d", this, n_buffers, direction, port_id); - spa_return_val_if_fail(port->have_format, -EIO); - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/jack/jack-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/jack/jack-sink.c
Changed
@@ -693,11 +693,13 @@ port = GET_PORT(this, direction, port_id); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b;
View file
pipewire-0.3.63.tar.gz/spa/plugins/jack/jack-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/jack/jack-source.c
Changed
@@ -693,11 +693,13 @@ port = GET_PORT(this, direction, port_id); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b;
View file
pipewire-0.3.63.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.64.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -774,14 +774,15 @@ port = GET_PORT(impl, direction, port_id); - if (!port->current_format) - return -EIO; - if (port->n_buffers) { spa_libcamera_stream_off(impl); if ((res = spa_libcamera_clear_buffers(impl, port)) < 0) return res; } + if (n_buffers > 0 && !port->current_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; if (buffers == NULL) return 0;
View file
pipewire-0.3.63.tar.gz/spa/plugins/support/null-audio-sink.c -> pipewire-0.3.64.tar.gz/spa/plugins/support/null-audio-sink.c
Changed
@@ -685,11 +685,13 @@ port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/test/fakesink.c -> pipewire-0.3.64.tar.gz/spa/plugins/test/fakesink.c
Changed
@@ -585,11 +585,13 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/test/fakesrc.c -> pipewire-0.3.64.tar.gz/spa/plugins/test/fakesrc.c
Changed
@@ -597,11 +597,13 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/v4l2/v4l2-source.c
Changed
@@ -756,14 +756,15 @@ port = GET_PORT(this, direction, port_id); - if (!port->have_format) - return -EIO; - if (port->n_buffers) { spa_v4l2_stream_off(this); if ((res = spa_v4l2_clear_buffers(this)) < 0) return res; } + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; if (buffers == NULL) return 0;
View file
pipewire-0.3.63.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.64.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
@@ -712,11 +712,13 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/volume/volume.c -> pipewire-0.3.64.tar.gz/spa/plugins/volume/volume.c
Changed
@@ -528,11 +528,13 @@ port = GET_PORT(this, direction, port_id); - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b; struct spa_data *d = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c -> pipewire-0.3.64.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c
Changed
@@ -505,11 +505,13 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = &this->portdirection; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b;
View file
pipewire-0.3.63.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c -> pipewire-0.3.64.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c
Changed
@@ -740,11 +740,13 @@ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = &this->port; - if (!port->have_format) - return -EIO; - clear_buffers(this, port); + if (n_buffers > 0 && !port->have_format) + return -EIO; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b;
View file
pipewire-0.3.63.tar.gz/src/examples/export-source.c -> pipewire-0.3.64.tar.gz/src/examples/export-source.c
Changed
@@ -46,6 +46,7 @@ #define M_PI_M2 ( M_PI + M_PI ) #define BUFFER_SAMPLES 128 +#define MAX_BUFFERS 32 struct buffer { uint32_t id; @@ -79,7 +80,7 @@ struct spa_audio_info_raw format; - struct buffer buffers32; + struct buffer buffersMAX_BUFFERS; uint32_t n_buffers; struct spa_list empty; @@ -325,6 +326,9 @@ struct data *d = object; uint32_t i; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { struct buffer *b = &d->buffersi; struct spa_data *datas = buffersi->datas;
View file
pipewire-0.3.63.tar.gz/src/examples/local-v4l2.c -> pipewire-0.3.64.tar.gz/src/examples/local-v4l2.c
Changed
@@ -34,6 +34,7 @@ #define WIDTH 640 #define HEIGHT 480 #define BPP 3 +#define MAX_BUFFERS 32 #include "sdl.h" @@ -68,7 +69,7 @@ struct spa_video_info_raw format; int32_t stride; - struct spa_buffer *buffers32; + struct spa_buffer *buffersMAX_BUFFERS; int n_buffers; struct pw_proxy *out, *in, *link; @@ -264,6 +265,9 @@ struct data *d = object; uint32_t i; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) d->buffersi = buffersi; d->n_buffers = n_buffers;
View file
pipewire-0.3.63.tar.gz/src/examples/video-src-fixate.c -> pipewire-0.3.64.tar.gz/src/examples/video-src-fixate.c
Changed
@@ -28,6 +28,8 @@ title */ +#include "config.h" + #include <stdio.h> #include <errno.h> #include <signal.h>
View file
pipewire-0.3.63.tar.gz/src/gst/gstpipewiredeviceprovider.c -> pipewire-0.3.64.tar.gz/src/gst/gstpipewiredeviceprovider.c
Changed
@@ -45,6 +45,7 @@ { PROP_ID = 1, PROP_SERIAL, + PROP_FD_DEVICE, }; static GstElement * @@ -52,15 +53,13 @@ { GstPipeWireDevice *pipewire_dev = GST_PIPEWIRE_DEVICE (device); GstElement *elem; - gchar *id_str, *serial_str; + gchar *serial_str; elem = gst_element_factory_make (pipewire_dev->element, name); - /* XXX: eventually only add target-object here */ - id_str = g_strdup_printf ("%u", pipewire_dev->id); serial_str = g_strdup_printf ("%"PRIu64, pipewire_dev->serial); - g_object_set (elem, "path", id_str, "target-object", serial_str, NULL); - g_free (id_str); + g_object_set (elem, "target-object", serial_str, + "fd", pipewire_dev->fd, NULL); g_free (serial_str); return elem; @@ -70,7 +69,7 @@ gst_pipewire_device_reconfigure_element (GstDevice * device, GstElement * element) { GstPipeWireDevice *pipewire_dev = GST_PIPEWIRE_DEVICE (device); - gchar *id_str, *serial_str; + gchar *serial_str; if (spa_streq(pipewire_dev->element, "pipewiresrc")) { if (!GST_IS_PIPEWIRE_SRC (element)) @@ -82,11 +81,9 @@ g_assert_not_reached (); } - /* XXX: eventually only add target-object here */ - id_str = g_strdup_printf ("%u", pipewire_dev->id); serial_str = g_strdup_printf ("%"PRIu64, pipewire_dev->serial); - g_object_set (element, "path", id_str, "target-object", serial_str, NULL); - g_free (id_str); + g_object_set (element, "target-object", serial_str, + "fd", pipewire_dev->fd, NULL); g_free (serial_str); return TRUE; @@ -108,6 +105,9 @@ case PROP_SERIAL: g_value_set_uint64 (value, device->serial); break; + case PROP_FD_DEVICE: + g_value_set_int (value, device->fd); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -129,6 +129,9 @@ case PROP_SERIAL: device->serial = g_value_get_uint64 (value); break; + case PROP_FD_DEVICE: + device->fd = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -163,6 +166,11 @@ g_param_spec_uint64 ("serial", "Serial", "The internal serial of the PipeWire device", 0, G_MAXUINT64, SPA_ID_INVALID, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_FD_DEVICE, + g_param_spec_int ("fd", "Fd", "The fd to connect with", -1, G_MAXINT, -1, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void @@ -177,18 +185,10 @@ { PROP_0, PROP_CLIENT_NAME, + PROP_FD, PROP_LAST }; -struct core_data { - int seq; - GstPipeWireDeviceProvider *self; - struct spa_hook core_listener; - struct pw_registry *registry; - struct spa_hook registry_listener; - struct spa_list nodes; -}; - struct node_data { struct spa_list link; GstPipeWireDeviceProvider *self; @@ -211,10 +211,10 @@ struct spa_hook port_listener; }; -static struct node_data *find_node_data(struct core_data *rd, uint32_t id) +static struct node_data *find_node_data(struct spa_list *nodes, uint32_t id) { struct node_data *n; - spa_list_for_each(n, &rd->nodes, link) { + spa_list_for_each(n, nodes, link) { if (n->id == id) return n; } @@ -257,7 +257,8 @@ gstdev = g_object_new (GST_TYPE_PIPEWIRE_DEVICE, "display-name", name, "caps", data->caps, "device-class", klass, - "id", data->id, "serial", data->serial, "properties", props, NULL); + "id", data->id, "serial", data->serial, "fd", self->fd, + "properties", props, NULL); gstdev->id = data->id; gstdev->serial = data->serial; @@ -269,12 +270,11 @@ return GST_DEVICE (gstdev); } -static void do_add_nodes(struct core_data *rd) +static void do_add_nodes(GstPipeWireDeviceProvider *self) { - GstPipeWireDeviceProvider *self = rd->self; struct node_data *nd; - spa_list_for_each(nd, &rd->nodes, link) { + spa_list_for_each(nd, &self->nodes, link) { if (nd->dev != NULL) continue; pw_log_info("add node %d", nd->id); @@ -290,22 +290,21 @@ static void resync(GstPipeWireDeviceProvider *self) { - self->seq = pw_core_sync(self->core, PW_ID_CORE, self->seq); + self->seq = pw_core_sync(self->core->core, PW_ID_CORE, self->seq); pw_log_debug("resync %d", self->seq); } static void on_core_done (void *data, uint32_t id, int seq) { - struct core_data *rd = data; - GstPipeWireDeviceProvider *self = rd->self; + GstPipeWireDeviceProvider *self = data; pw_log_debug("check %d %d", seq, self->seq); if (id == PW_ID_CORE && seq == self->seq) { - do_add_nodes(rd); + do_add_nodes(self); self->end = true; - if (self->loop) - pw_thread_loop_signal (self->loop, FALSE); + if (self->core) + pw_thread_loop_signal (self->core->loop, FALSE); } } @@ -313,8 +312,7 @@ static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct core_data *rd = data; - GstPipeWireDeviceProvider *self = rd->self; + GstPipeWireDeviceProvider *self = data; pw_log_warn("error id:%u seq:%d res:%d (%s): %s", id, seq, res, spa_strerror(res), message); @@ -322,7 +320,7 @@ if (id == PW_ID_CORE) { self->error = res; } - pw_thread_loop_signal(self->loop, FALSE); + pw_thread_loop_signal(self->core->loop, FALSE); } static const struct pw_core_events core_events = { @@ -470,8 +468,7 @@ const char *type, uint32_t version, const struct spa_dict *props) { - struct core_data *rd = data; - GstPipeWireDeviceProvider *self = rd->self; + GstPipeWireDeviceProvider *self = data; GstDeviceProvider *provider = (GstDeviceProvider*)self; struct node_data *nd; const char *str; @@ -479,7 +476,7 @@ if (spa_streq(type, PW_TYPE_INTERFACE_Node)) { struct pw_node *node; - node = pw_registry_bind(rd->registry, + node = pw_registry_bind(self->registry, id, type, PW_VERSION_NODE, sizeof(*nd)); if (node == NULL) goto no_mem; @@ -502,7 +499,7 @@ nd->id = id; if (!props || !spa_atou64(spa_dict_lookup(props, PW_KEY_OBJECT_SERIAL), &nd->serial, 0)) nd->serial = SPA_ID_INVALID; - spa_list_append(&rd->nodes, &nd->link); + spa_list_append(&self->nodes, &nd->link); pw_node_add_listener(node, &nd->node_listener, &node_events, nd); pw_proxy_add_listener((struct pw_proxy*)node, &nd->proxy_listener, &proxy_node_events, nd); resync(self); @@ -514,10 +511,10 @@ if ((str = spa_dict_lookup(props, PW_KEY_NODE_ID)) == NULL) return; - if ((nd = find_node_data(rd, atoi(str))) == NULL) + if ((nd = find_node_data(&self->nodes, atoi(str))) == NULL) return; - port = pw_registry_bind(rd->registry, + port = pw_registry_bind(self->registry, id, type, PW_VERSION_PORT, sizeof(*pd)); if (port == NULL) goto no_mem; @@ -554,36 +551,29 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) { GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); - struct pw_loop *l = NULL; - struct pw_context *c = NULL; - struct core_data *data; GST_DEBUG_OBJECT (self, "starting probe"); - if (!(l = pw_loop_new (NULL))) - return NULL; - - if (!(c = pw_context_new (l, NULL, sizeof(*data)))) - return NULL; - - data = pw_context_get_user_data(c); - data->self = self; - spa_list_init(&data->nodes); - - spa_list_init(&self->pending); - self->core = pw_context_connect (c, NULL, 0); - if (self->core == NULL) + self->core = gst_pipewire_core_get(self->fd); + if (self->core == NULL) { + GST_ERROR_OBJECT (self, "Failed to connect"); goto failed; + } GST_DEBUG_OBJECT (self, "connected"); - pw_core_add_listener(self->core, &data->core_listener, &core_events, data); + pw_thread_loop_lock (self->core->loop); + + spa_list_init(&self->nodes); + spa_list_init(&self->pending); self->end = FALSE; + self->error = 0; self->list_only = TRUE; self->devices = NULL; + self->registry = pw_core_get_registry(self->core->core, PW_VERSION_REGISTRY, 0); - data->registry = pw_core_get_registry(self->core, PW_VERSION_REGISTRY, 0); - pw_registry_add_listener(data->registry, &data->registry_listener, ®istry_events, data); + pw_core_add_listener(self->core->core, &self->core_listener, &core_events, self); + pw_registry_add_listener(self->registry, &self->registry_listener, ®istry_events, self); resync(self); @@ -592,20 +582,18 @@ break; if (self->end) break; - pw_loop_iterate (l, -1); + pw_thread_loop_wait (self->core->loop); } GST_DEBUG_OBJECT (self, "disconnect"); - pw_proxy_destroy ((struct pw_proxy*)data->registry); - pw_core_disconnect (self->core); - self->core = NULL; - pw_context_destroy (c); - pw_loop_destroy (l); + + g_clear_pointer ((struct pw_proxy**)&self->registry, pw_proxy_destroy); + pw_thread_loop_unlock (self->core->loop); + g_clear_pointer (&self->core, gst_pipewire_core_release); return self->devices; failed: - pw_loop_destroy (l); return NULL; } @@ -613,46 +601,28 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) { GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); - struct core_data *data; GST_DEBUG_OBJECT (self, "starting provider"); - self->list_only = FALSE; - spa_list_init(&self->pending); - - if (!(self->loop = pw_thread_loop_new ("pipewire-device-monitor", NULL))) { - GST_ERROR_OBJECT (self, "Could not create PipeWire mainloop"); - goto failed_loop; - } - - if (!(self->context = pw_context_new (pw_thread_loop_get_loop(self->loop), NULL, sizeof(*data)))) { - GST_ERROR_OBJECT (self, "Could not create PipeWire context"); - goto failed_context; - } - - if (pw_thread_loop_start (self->loop) < 0) { - GST_ERROR_OBJECT (self, "Could not start PipeWire mainloop"); - goto failed_start; - } - - pw_thread_loop_lock (self->loop); - - if ((self->core = pw_context_connect (self->context, NULL, 0)) == NULL) { + self->core = gst_pipewire_core_get(self->fd); + if (self->core == NULL) { GST_ERROR_OBJECT (self, "Failed to connect"); - goto failed_connect; + goto failed; } GST_DEBUG_OBJECT (self, "connected"); - data = pw_context_get_user_data(self->context); - data->self = self; - spa_list_init(&data->nodes); + pw_thread_loop_lock (self->core->loop); - pw_core_add_listener(self->core, &data->core_listener, &core_events, data); + spa_list_init(&self->nodes); + spa_list_init(&self->pending); + self->end = FALSE; + self->error = 0; + self->list_only = FALSE; + self->registry = pw_core_get_registry(self->core->core, PW_VERSION_REGISTRY, 0); - self->registry = pw_core_get_registry(self->core, PW_VERSION_REGISTRY, 0); - data->registry = self->registry; - pw_registry_add_listener(self->registry, &data->registry_listener, ®istry_events, data); + pw_core_add_listener(self->core->core, &self->core_listener, &core_events, self); + pw_registry_add_listener(self->registry, &self->registry_listener, ®istry_events, self); resync(self); @@ -661,24 +631,16 @@ break; if (self->end) break; - pw_thread_loop_wait (self->loop); + pw_thread_loop_wait (self->core->loop); } GST_DEBUG_OBJECT (self, "started"); - pw_thread_loop_unlock (self->loop); + pw_thread_loop_unlock (self->core->loop); return TRUE; -failed_connect: - pw_thread_loop_unlock (self->loop); -failed_start: - pw_context_destroy (self->context); - self->context = NULL; -failed_context: - pw_thread_loop_destroy (self->loop); - self->loop = NULL; -failed_loop: +failed: return TRUE; } @@ -688,25 +650,9 @@ GstPipeWireDeviceProvider *self = GST_PIPEWIRE_DEVICE_PROVIDER (provider); GST_DEBUG_OBJECT (self, "stopping provider"); - if (self->loop) - pw_thread_loop_stop (self->loop); - if (self->registry) { - pw_proxy_destroy ((struct pw_proxy*)self->registry); - self->registry = NULL; - } - if (self->core) { - pw_core_disconnect (self->core); - self->core = NULL; - } - if (self->context) { - pw_context_destroy (self->context); - self->context = NULL; - } - if (self->loop) { - pw_thread_loop_destroy (self->loop); - self->loop = NULL; - } + g_clear_pointer ((struct pw_proxy**)&self->registry, pw_proxy_destroy); + g_clear_pointer (&self->core, gst_pipewire_core_release); } static void @@ -726,6 +672,11 @@ } else self->client_name = g_value_dup_string (value); break; + + case PROP_FD: + self->fd = g_value_get_int (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -742,6 +693,11 @@ case PROP_CLIENT_NAME: g_value_set_string (value, self->client_name); break; + + case PROP_FD: + g_value_set_int (value, self->fd); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -779,6 +735,11 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); + g_object_class_install_property (gobject_class, + PROP_FD, + g_param_spec_int ("fd", "Fd", "The fd to connect with", -1, G_MAXINT, -1, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE)); + gst_device_provider_class_set_static_metadata (dm_class, "PipeWire Device Provider", "Sink/Source/Audio/Video", "List and provide PipeWire source and sink devices", @@ -789,4 +750,5 @@ gst_pipewire_device_provider_init (GstPipeWireDeviceProvider * self) { self->client_name = g_strdup(pw_get_client_name ()); + self->fd = -1; }
View file
pipewire-0.3.63.tar.gz/src/gst/gstpipewiredeviceprovider.h -> pipewire-0.3.64.tar.gz/src/gst/gstpipewiredeviceprovider.h
Changed
@@ -28,10 +28,11 @@ #include "config.h" -#include <pipewire/pipewire.h> - #include <gst/gst.h> +#include <pipewire/pipewire.h> +#include <gst/gstpipewirecore.h> + G_BEGIN_DECLS typedef struct _GstPipeWireDevice GstPipeWireDevice; @@ -57,6 +58,7 @@ GstPipeWireDeviceType type; uint32_t id; uint64_t serial; + int fd; const gchar *element; }; @@ -81,17 +83,16 @@ GstDeviceProvider parent; gchar *client_name; + int fd; - struct pw_thread_loop *loop; - - struct pw_context *context; - - struct pw_core *core; + GstPipeWireCore *core; + struct spa_hook core_listener; + struct pw_registry *registry; + struct spa_hook registry_listener; + struct spa_list nodes; struct spa_list pending; int seq; - struct pw_registry *registry; - int error; gboolean end; gboolean list_only;
View file
pipewire-0.3.63.tar.gz/src/gst/gstpipewireformat.c -> pipewire-0.3.64.tar.gz/src/gst/gstpipewireformat.c
Changed
@@ -25,6 +25,7 @@ #include <stdio.h> #include <gst/gst.h> +#include <gst/allocators/gstdmabuf.h> #include <gst/video/video.h> #include <gst/audio/audio.h> @@ -36,6 +37,14 @@ #include "gstpipewireformat.h" +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif + +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR 0 +#endif + struct media_type { const char *name; uint32_t media_type; @@ -302,6 +311,13 @@ r->width = gst_value_get_int_range_max (width); r->height = gst_value_get_int_range_max (height); return true; + } else if (idx == 3) { + r->width = gst_value_get_int_range_step (width); + r->height = gst_value_get_int_range_step (height); + if (r->width > 1 || r->height > 1) + return true; + else + return false; } } else if (wt == GST_TYPE_LIST && ht == GST_TYPE_LIST) { GArray *wa = g_value_peek_pointer (width); @@ -619,6 +635,18 @@ spa_pod_builder_prop (&d->b, SPA_FORMAT_mediaSubtype, 0); spa_pod_builder_id(&d->b, d->type->media_subtype); + if (d->cf && gst_caps_features_contains (d->cf, GST_CAPS_FEATURE_MEMORY_DMABUF)) { + struct spa_pod_frame f2; + + spa_pod_builder_prop (&d->b, SPA_FORMAT_VIDEO_modifier, + (SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE)); + spa_pod_builder_push_choice (&d->b, &f2, SPA_CHOICE_Enum, 0); + spa_pod_builder_long (&d->b, DRM_FORMAT_MOD_INVALID); + spa_pod_builder_long (&d->b, DRM_FORMAT_MOD_INVALID); + spa_pod_builder_long (&d->b, DRM_FORMAT_MOD_LINEAR); + spa_pod_builder_pop (&d->b, &f2); + } + if (d->type->media_type == SPA_MEDIA_TYPE_video) handle_video_fields (d); else if (d->type->media_type == SPA_MEDIA_TYPE_audio) @@ -654,13 +682,19 @@ ConvertData *d) { struct spa_pod *fmt; + int idx; spa_zero(d->b); d->cf = features; d->cs = structure; + if (d->cf && gst_caps_features_contains (d->cf, GST_CAPS_FEATURE_MEMORY_DMABUF)) + idx = 0; + else + idx = -1; + if ((fmt = convert_1 (d))) - g_ptr_array_insert (d->array, -1, fmt); + g_ptr_array_insert (d->array, idx, fmt); return TRUE; }
View file
pipewire-0.3.63.tar.gz/src/gst/gstpipewiresink.c -> pipewire-0.3.64.tar.gz/src/gst/gstpipewiresink.c
Changed
@@ -33,6 +33,8 @@ * </refsect2> */ +#define PW_ENABLE_DEPRECATED + #include "config.h" #include "gstpipewiresink.h" @@ -582,6 +584,8 @@ if (pwsink->target_object) { struct spa_dict_item items2 = { SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, pwsink->target_object), + /* XXX deprecated but the portal and some example apps only + * provide the object id */ SPA_DICT_ITEM_INIT(PW_KEY_NODE_TARGET, NULL), }; struct spa_dict dict = SPA_DICT_INIT_ARRAY(items);
View file
pipewire-0.3.63.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.64.tar.gz/src/gst/gstpipewiresrc.c
Changed
@@ -33,6 +33,8 @@ * </refsect2> */ +#define PW_ENABLE_DEPRECATED + #include "config.h" #include "gstpipewiresrc.h" #include "gstpipewireformat.h" @@ -43,6 +45,7 @@ #include <sys/socket.h> #include <unistd.h> +#include <spa/param/video/format.h> #include <spa/pod/builder.h> #include <spa/utils/result.h> @@ -841,6 +844,8 @@ if (pwsrc->target_object) { struct spa_dict_item items2 = { SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, pwsrc->target_object), + /* XXX deprecated but the portal and some example apps only + * provide the object id */ SPA_DICT_ITEM_INIT(PW_KEY_NODE_TARGET, NULL), }; struct spa_dict dict = SPA_DICT_INIT_ARRAY(items); @@ -949,7 +954,6 @@ if (pwsrc->caps) gst_caps_unref(pwsrc->caps); pwsrc->caps = gst_caps_from_format (param); - GST_DEBUG_OBJECT (pwsrc, "we got format %" GST_PTR_FORMAT, pwsrc->caps); pwsrc->negotiated = pwsrc->caps != NULL; @@ -958,6 +962,19 @@ struct spa_pod_builder b = { NULL }; uint8_t buffer512; uint32_t buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers); + int buffertypes; + + if (spa_pod_find_prop (param, NULL, SPA_FORMAT_VIDEO_modifier)) { + buffertypes = (1<<SPA_DATA_DmaBuf); + gst_caps_features_remove (gst_caps_get_features (pwsrc->caps, 0), + GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); + gst_caps_features_add (gst_caps_get_features (pwsrc->caps, 0), + GST_CAPS_FEATURE_MEMORY_DMABUF); + } else { + buffertypes = ((1<<SPA_DATA_MemFd) | (1<<SPA_DATA_MemPtr)); + } + + GST_DEBUG_OBJECT (pwsrc, "we got format %" GST_PTR_FORMAT, pwsrc->caps); spa_pod_builder_init (&b, buffer, sizeof (buffer)); params0 = spa_pod_builder_add_object (&b, @@ -968,9 +985,7 @@ SPA_PARAM_BUFFERS_blocks, SPA_POD_CHOICE_RANGE_Int(0, 1, INT32_MAX), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), SPA_PARAM_BUFFERS_stride, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), - SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int( - (1<<SPA_DATA_MemFd) | - (1<<SPA_DATA_MemPtr))); + SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int(buffertypes)); params1 = spa_pod_builder_add_object (&b, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
View file
pipewire-0.3.63.tar.gz/src/modules/meson.build -> pipewire-0.3.64.tar.gz/src/modules/meson.build
Changed
@@ -71,6 +71,16 @@ simd_cargs += '-DHAVE_SSE' simd_dependencies += filter_chain_sse endif +if have_avx + filter_chain_avx = static_library('filter_chain_avx', + 'module-filter-chain/dsp-ops-avx.c' , + c_args : avx_args, fma_args,'-O3', '-DHAVE_AVX', + dependencies : spa_dep , + install : false + ) + simd_cargs += '-DHAVE_AVX' + simd_dependencies += filter_chain_avx +endif if have_neon filter_chain_neon = static_library('filter_chain_neon', 'module-filter-chain/pffft.c' , @@ -495,8 +505,8 @@ endif summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules') -roc_lib = cc.find_library('roc', has_headers: 'roc/config.h' , required: get_option('roc')) -summary({'ROC': roc_lib.found()}, bool_yn: true, section: 'Streaming between daemons') +roc_dep = dependency('roc', required: get_option('roc')) +summary({'ROC': roc_dep.found()}, bool_yn: true, section: 'Streaming between daemons') pipewire_module_rtp_source = shared_library('pipewire-module-rtp-source', 'module-rtp-source.c' , @@ -516,7 +526,7 @@ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, ) -build_module_roc = roc_lib.found() +build_module_roc = roc_dep.found() if build_module_roc pipewire_module_roc_sink = shared_library('pipewire-module-roc-sink', 'module-roc-sink.c' , @@ -524,7 +534,7 @@ install : true, install_dir : modules_install_dir, install_rpath: modules_install_dir, - dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_lib, + dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_dep, ) pipewire_module_roc_source = shared_library('pipewire-module-roc-source', @@ -533,7 +543,7 @@ install : true, install_dir : modules_install_dir, install_rpath: modules_install_dir, - dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_lib, + dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, roc_dep, ) endif summary({'roc-sink': build_module_roc}, bool_yn: true, section: 'Optional Modules')
View file
pipewire-0.3.63.tar.gz/src/modules/module-adapter/adapter.c -> pipewire-0.3.64.tar.gz/src/modules/module-adapter/adapter.c
Changed
@@ -93,7 +93,7 @@ const struct pw_properties *old; enum pw_direction direction; struct pw_properties *new; - const char *str, *path, *desc, *nick, *name, *node_name, *media_class; + const char *str, *path, *desc, *nick, *name, *node_name, *media_class, *prop_port_names; char position8, *prefix; bool is_monitor, is_device, is_duplex, is_virtual, is_control = false; @@ -178,6 +178,24 @@ pw_properties_setf(new, PW_KEY_PORT_ALIAS, "%s:%s_%s", node_name, prefix, str); + prop_port_names = pw_properties_get(n->props, PW_KEY_NODE_CHANNELNAMES); + if (prop_port_names) { + struct spa_json it2; + char v256; + + spa_json_init(&it0, prop_port_names, strlen(prop_port_names)); + if (spa_json_enter_array(&it0, &it1) <= 0) + spa_json_init(&it1, prop_port_names, strlen(prop_port_names)); + + uint32_t i; + for (i = 0; i < pw_impl_port_get_id(port) + 1; i++) + if (spa_json_get_string(&it1, v, sizeof(v)) <= 0) + break; + + if (i == pw_impl_port_get_id(port) + 1) + pw_properties_setf(new, PW_KEY_PORT_NAME, "%s_%s", prefix, v); + } + pw_impl_port_update_properties(port, &new->dict); pw_properties_free(new); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-client-node/client-node.c -> pipewire-0.3.64.tar.gz/src/modules/module-client-node/client-node.c
Changed
@@ -754,7 +754,6 @@ if (n_buffers > MAX_BUFFERS) return -ENOSPC; - spa_log_debug(this->log, "%p: %s port %d.%d use buffers %p %u flags:%08x", this, direction == SPA_DIRECTION_INPUT ? "input" : "output", port_id, mix_id, buffers, n_buffers, flags);
View file
pipewire-0.3.63.tar.gz/src/modules/module-client-node/v0/client-node.c -> pipewire-0.3.64.tar.gz/src/modules/module-client-node/v0/client-node.c
Changed
@@ -38,6 +38,8 @@ #include <spa/pod/filter.h> #include <spa/utils/keys.h> +#define PW_ENABLE_DEPRECATED + #include "pipewire/pipewire.h" #include "pipewire/private.h" @@ -1330,6 +1332,7 @@ const char *from, *to; } props = { { "pipewire.autoconnect", PW_KEY_NODE_AUTOCONNECT, }, + /* XXX deprecated */ { "pipewire.target.node", PW_KEY_NODE_TARGET, } };
View file
pipewire-0.3.63.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.64.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -69,8 +69,10 @@ * * Options specific to the behavior of this module * + * - `capture.props = {}`: properties to be passed to the capture stream * - `source.props = {}`: properties to be passed to the source stream * - `sink.props = {}`: properties to be passed to the sink stream + * - `playback.props = {}`: properties to be passed to the playback stream * - `library.name = <str>`: the echo cancellation library Currently supported: * `aec/libspa-aec-webrtc`. Leave unset to use the default method (`aec/libspa-aec-webrtc`). * - `aec.args = <str>`: arguments to pass to the echo cancellation method @@ -99,12 +101,18 @@ * args = { * # library.name = aec/libspa-aec-webrtc * # node.latency = 1024/48000 + * capture.props = { + * node.name = "Echo Cancellation Capture" + * } * source.props = { * node.name = "Echo Cancellation Source" * } * sink.props = { * node.name = "Echo Cancellation Sink" * } + * playback.props = { + * node.name = "Echo Cancellation Playback" + * } * } * } * @@ -147,8 +155,10 @@ " buffer.play_delay=<delay as fraction> " " library.name =<library name> " " aec.args=<aec arguments> " + " capture.props=<properties> " " source.props=<properties> " - " sink.props=<properties> " }, + " sink.props=<properties> " + " playback.props=<properties> " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; @@ -164,17 +174,22 @@ struct spa_audio_info_raw info; + struct pw_properties *capture_props; struct pw_stream *capture; struct spa_hook capture_listener; + struct pw_properties *source_props; struct pw_stream *source; struct spa_hook source_listener; + void *rec_bufferSPA_AUDIO_MAX_CHANNELS; uint32_t rec_ringsize; struct spa_ringbuffer rec_ring; + struct pw_properties *playback_props; struct pw_stream *playback; struct spa_hook playback_listener; + struct pw_properties *sink_props; struct pw_stream *sink; struct spa_hook sink_listener; @@ -761,32 +776,11 @@ uint32_t offsets512; const struct spa_pod *params512; struct spa_pod_dynamic_builder b; - struct pw_properties *props; - const char *str; uint32_t index; - props = pw_properties_new( - PW_KEY_NODE_NAME, "echo-cancel-capture", - PW_KEY_NODE_VIRTUAL, "true", - PW_KEY_NODE_PASSIVE, "true", - NULL); - if ((str = pw_properties_get(impl->source_props, PW_KEY_NODE_GROUP)) != NULL) - pw_properties_set(props, PW_KEY_NODE_GROUP, str); - if ((str = pw_properties_get(impl->source_props, PW_KEY_NODE_LINK_GROUP)) != NULL) - pw_properties_set(props, PW_KEY_NODE_LINK_GROUP, str); - if ((str = pw_properties_get(impl->source_props, PW_KEY_NODE_LATENCY)) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - else if (impl->aec->latency) - pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec->latency); - if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_CHANNELS)) != NULL) - pw_properties_set(props, SPA_KEY_AUDIO_CHANNELS, str); - if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_POSITION)) != NULL) - pw_properties_set(props, SPA_KEY_AUDIO_POSITION, str); - if ((str = pw_properties_get(impl->source_props, "resample.prefill")) != NULL) - pw_properties_set(props, "resample.prefill", str); - impl->capture = pw_stream_new(impl->core, - "Echo-Cancel Capture", props); + "Echo-Cancel Capture", impl->capture_props); + impl->capture_props = NULL; if (impl->capture == NULL) return -errno; @@ -807,28 +801,9 @@ if (impl->monitor_mode) { impl->playback = NULL; } else { - props = pw_properties_new( - PW_KEY_NODE_NAME, "echo-cancel-playback", - PW_KEY_NODE_VIRTUAL, "true", - PW_KEY_NODE_PASSIVE, "true", - NULL); - if ((str = pw_properties_get(impl->sink_props, PW_KEY_NODE_GROUP)) != NULL) - pw_properties_set(props, PW_KEY_NODE_GROUP, str); - if ((str = pw_properties_get(impl->sink_props, PW_KEY_NODE_LINK_GROUP)) != NULL) - pw_properties_set(props, PW_KEY_NODE_LINK_GROUP, str); - if ((str = pw_properties_get(impl->sink_props, PW_KEY_NODE_LATENCY)) != NULL) - pw_properties_set(props, PW_KEY_NODE_LATENCY, str); - else if (impl->aec->latency) - pw_properties_set(props, PW_KEY_NODE_LATENCY, impl->aec->latency); - if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_CHANNELS)) != NULL) - pw_properties_set(props, SPA_KEY_AUDIO_CHANNELS, str); - if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_POSITION)) != NULL) - pw_properties_set(props, SPA_KEY_AUDIO_POSITION, str); - if ((str = pw_properties_get(impl->sink_props, "resample.prefill")) != NULL) - pw_properties_set(props, "resample.prefill", str); - impl->playback = pw_stream_new(impl->core, - "Echo-Cancel Playback", props); + "Echo-Cancel Playback", impl->playback_props); + impl->playback_props = NULL; if (impl->playback == NULL) return -errno; @@ -980,7 +955,9 @@ pw_core_disconnect(impl->core); if (impl->spa_handle) spa_plugin_loader_unload(impl->loader, impl->spa_handle); + pw_properties_free(impl->capture_props); pw_properties_free(impl->source_props); + pw_properties_free(impl->playback_props); pw_properties_free(impl->sink_props); for (i = 0; i < impl->info.channels; i++) { @@ -1055,8 +1032,12 @@ { const char *str; if ((str = pw_properties_get(props, key)) != NULL) { + if (pw_properties_get(impl->capture_props, key) == NULL) + pw_properties_set(impl->capture_props, key, str); if (pw_properties_get(impl->source_props, key) == NULL) pw_properties_set(impl->source_props, key, str); + if (pw_properties_get(impl->playback_props, key) == NULL) + pw_properties_set(impl->playback_props, key, str); if (pw_properties_get(impl->sink_props, key) == NULL) pw_properties_set(impl->sink_props, key, str); } @@ -1094,9 +1075,12 @@ goto error; } + impl->capture_props = pw_properties_new(NULL, NULL); impl->source_props = pw_properties_new(NULL, NULL); + impl->playback_props = pw_properties_new(NULL, NULL); impl->sink_props = pw_properties_new(NULL, NULL); - if (impl->source_props == NULL || impl->sink_props == NULL) { + if (impl->source_props == NULL || impl->sink_props == NULL || + impl->capture_props == NULL || impl->playback_props == NULL) { res = -errno; pw_log_error( "can't create properties: %m"); goto error; @@ -1115,13 +1099,26 @@ pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "echo-cancel-%u-%u", pid, id); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); + if (pw_properties_get(props, "resample.prefill") == NULL) + pw_properties_set(props, "resample.prefill", "true"); parse_audio_info(props, &impl->info); + if ((str = pw_properties_get(props, "capture.props")) != NULL) + pw_properties_update_string(impl->capture_props, str, strlen(str)); if ((str = pw_properties_get(props, "source.props")) != NULL) pw_properties_update_string(impl->source_props, str, strlen(str)); if ((str = pw_properties_get(props, "sink.props")) != NULL) pw_properties_update_string(impl->sink_props, str, strlen(str)); + if ((str = pw_properties_get(props, "playback.props")) != NULL) + pw_properties_update_string(impl->playback_props, str, strlen(str)); + + if (pw_properties_get(impl->capture_props, PW_KEY_NODE_NAME) == NULL) + pw_properties_set(impl->capture_props, PW_KEY_NODE_NAME, "echo-cancel-capture"); + if (pw_properties_get(impl->capture_props, PW_KEY_NODE_DESCRIPTION) == NULL) + pw_properties_set(impl->capture_props, PW_KEY_NODE_DESCRIPTION, "Echo-Cancel Capture"); + if (pw_properties_get(impl->capture_props, PW_KEY_NODE_PASSIVE) == NULL) + pw_properties_set(impl->capture_props, PW_KEY_NODE_PASSIVE, "true"); if (pw_properties_get(impl->source_props, PW_KEY_NODE_NAME) == NULL) pw_properties_set(impl->source_props, PW_KEY_NODE_NAME, "echo-cancel-source"); @@ -1129,8 +1126,13 @@ pw_properties_set(impl->source_props, PW_KEY_NODE_DESCRIPTION, "Echo-Cancel Source"); if (pw_properties_get(impl->source_props, PW_KEY_MEDIA_CLASS) == NULL) pw_properties_set(impl->source_props, PW_KEY_MEDIA_CLASS, "Audio/Source"); - if (pw_properties_get(impl->source_props, "resample.prefill") == NULL) - pw_properties_set(impl->source_props, "resample.prefill", "true"); + + if (pw_properties_get(impl->playback_props, PW_KEY_NODE_NAME) == NULL) + pw_properties_set(impl->playback_props, PW_KEY_NODE_NAME, "echo-cancel-playback"); + if (pw_properties_get(impl->playback_props, PW_KEY_NODE_DESCRIPTION) == NULL) + pw_properties_set(impl->playback_props, PW_KEY_NODE_DESCRIPTION, "Echo-Cancel Playback"); + if (pw_properties_get(impl->playback_props, PW_KEY_NODE_PASSIVE) == NULL) + pw_properties_set(impl->playback_props, PW_KEY_NODE_PASSIVE, "true"); if (pw_properties_get(impl->sink_props, PW_KEY_NODE_NAME) == NULL) pw_properties_set(impl->sink_props, PW_KEY_NODE_NAME, "echo-cancel-sink"); @@ -1139,12 +1141,13 @@ if (pw_properties_get(impl->sink_props, PW_KEY_MEDIA_CLASS) == NULL) pw_properties_set(impl->sink_props, PW_KEY_MEDIA_CLASS, impl->monitor_mode ? "Stream/Input/Audio" : "Audio/Sink"); - if (pw_properties_get(impl->sink_props, "resample.prefill") == NULL) - pw_properties_set(impl->sink_props, "resample.prefill", "true"); if (impl->monitor_mode) { - pw_properties_set(impl->sink_props, PW_KEY_NODE_PASSIVE, "true"); - pw_properties_set(impl->sink_props, PW_KEY_STREAM_MONITOR, "true"); - pw_properties_set(impl->sink_props, PW_KEY_STREAM_CAPTURE_SINK, "true"); + if (pw_properties_get(impl->sink_props, PW_KEY_NODE_PASSIVE) == NULL) + pw_properties_set(impl->sink_props, PW_KEY_NODE_PASSIVE, "true"); + if (pw_properties_get(impl->sink_props, PW_KEY_STREAM_MONITOR) == NULL) + pw_properties_set(impl->sink_props, PW_KEY_STREAM_MONITOR, "true"); + if (pw_properties_get(impl->sink_props, PW_KEY_STREAM_CAPTURE_SINK) == NULL) + pw_properties_set(impl->sink_props, PW_KEY_STREAM_CAPTURE_SINK, "true"); } if ((str = pw_properties_get(props, "aec.method")) != NULL) @@ -1252,6 +1255,7 @@ copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, SPA_KEY_AUDIO_CHANNELS); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); + copy_props(impl, props, "resample.prefill"); impl->max_buffer_size = pw_properties_get_uint32(props,"buffer.max_size", MAX_BUFSIZE_MS);
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -38,6 +38,7 @@ #include <spa/utils/result.h> #include <spa/utils/string.h> #include <spa/utils/json.h> +#include <spa/support/cpu.h> #include <spa/param/profiler.h> #include <spa/pod/dynamic.h> #include <spa/debug/pod.h> @@ -560,6 +561,8 @@ struct spa_hook core_proxy_listener; struct spa_hook core_listener; + struct dsp_ops dsp; + struct spa_list plugin_list; struct pw_properties *capture_props; @@ -1068,9 +1071,9 @@ static int setup_streams(struct impl *impl) { int res; - uint32_t i, n_params; - uint32_t offsets512; - const struct spa_pod *params512; + uint32_t i, n_params, *offs; + struct pw_array offsets; + const struct spa_pod **params = NULL; struct spa_pod_dynamic_builder b; struct graph *graph = &impl->graph; @@ -1094,23 +1097,40 @@ &impl->playback_listener, &out_stream_events, impl); - n_params = 0; spa_pod_dynamic_builder_init(&b, NULL, 0, 4096); + pw_array_init(&offsets, 512); - offsetsn_params++ = b.b.state.offset; + if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) == NULL) { + res = -errno; + goto done; + } + *offs = b.b.state.offset; spa_format_audio_raw_build(&b.b, SPA_PARAM_EnumFormat, &impl->capture_info); for (i = 0; i < graph->n_control; i++) { - offsetsn_params++ = b.b.state.offset; + if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) != NULL) + *offs = b.b.state.offset; get_prop_info(graph, &b.b, i); } - offsetsn_params++ = b.b.state.offset; + if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) != NULL) + *offs = b.b.state.offset; get_props_param(graph, &b.b); + n_params = pw_array_get_len(&offsets, uint32_t); + if (n_params == 0) { + res = -ENOMEM; + goto done; + } + if ((params = calloc(n_params, sizeof(struct spa_pod*))) == NULL) { + res = -errno; + goto done; + } + + offs = offsets.data; for (i = 0; i < n_params; i++) - paramsi = spa_pod_builder_deref(&b.b, offsetsi); + paramsi = spa_pod_builder_deref(&b.b, offsi); res = pw_stream_connect(impl->capture, PW_DIRECTION_INPUT, @@ -1122,7 +1142,7 @@ spa_pod_dynamic_builder_clean(&b); if (res < 0) - return res; + goto done; n_params = 0; spa_pod_dynamic_builder_init(&b, NULL, 0, 4096); @@ -1139,11 +1159,11 @@ params, n_params); spa_pod_dynamic_builder_clean(&b); - if (res < 0) - return res; - +done: + free(params); + pw_array_clear(&offsets); - return 0; + return res < 0 ? res : 0; } static uint32_t count_array(struct spa_json *json) @@ -1184,14 +1204,14 @@ support = pw_context_get_support(impl->context, &n_support); if (spa_streq(type, "builtin")) { - pl = load_builtin_plugin(support, n_support, path, NULL); + pl = load_builtin_plugin(support, n_support, &impl->dsp, path, NULL); } else if (spa_streq(type, "ladspa")) { - pl = load_ladspa_plugin(support, n_support, path, NULL); + pl = load_ladspa_plugin(support, n_support, &impl->dsp, path, NULL); } else if (spa_streq(type, "lv2")) { #ifdef HAVE_LILV - pl = load_lv2_plugin(support, n_support, path, NULL); + pl = load_lv2_plugin(support, n_support, &impl->dsp, path, NULL); #else pw_log_error("filter-chain is compiled without lv2 support"); pl = NULL; @@ -2244,6 +2264,9 @@ uint32_t pid = getpid(); const char *str; int res; + const struct spa_support *support; + uint32_t n_support; + struct spa_cpu *cpu_iface; PW_LOG_TOPIC_INIT(mod_topic); @@ -2274,10 +2297,16 @@ impl->module = module; impl->context = context; - impl->graph.impl = impl; + spa_list_init(&impl->plugin_list); + support = pw_context_get_support(impl->context, &n_support); + + cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); + impl->dsp.cpu_flags = cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0; + dsp_ops_init(&impl->dsp); + if (pw_properties_get(props, PW_KEY_NODE_GROUP) == NULL) pw_properties_setf(props, PW_KEY_NODE_GROUP, "filter-chain-%u-%u", pid, id); if (pw_properties_get(props, PW_KEY_NODE_LINK_GROUP) == NULL)
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -44,7 +44,7 @@ #include "convolver.h" #include "dsp-ops.h" -static struct dsp_ops dsp_ops; +static struct dsp_ops *dsp_ops; struct builtin { unsigned long rate; @@ -87,7 +87,7 @@ { struct builtin *impl = Instance; float *in = impl->port1, *out = impl->port0; - dsp_ops_copy(&dsp_ops, out, in, SampleCount); + dsp_ops_copy(dsp_ops, out, in, SampleCount); } static struct fc_port copy_ports = { @@ -136,7 +136,7 @@ srcn_src = in; gainsn_src++ = gain; } - dsp_ops_mix_gain(&dsp_ops, out, src, gains, n_src, SampleCount); + dsp_ops_mix_gain(dsp_ops, out, src, gains, n_src, SampleCount); } static struct fc_port mixer_ports = { @@ -275,7 +275,7 @@ impl->gain = gain; biquad_set(bq, type, freq * 2 / impl->rate, Q, gain); } - dsp_ops_biquad_run(&dsp_ops, bq, out, in, samples); + dsp_ops_biquad_run(dsp_ops, bq, out, in, samples); } /** bq_lowpass */ @@ -554,7 +554,7 @@ r.channels = 1; r.i_rate = in_rate; r.o_rate = out_rate; - r.cpu_flags = dsp_ops.cpu_flags; + r.cpu_flags = dsp_ops->cpu_flags; r.quality = quality; if ((res = resample_native_init(&r)) < 0) { pw_log_error("resampling failed: %s", spa_strerror(res)); @@ -731,7 +731,7 @@ impl->rate = SampleRate; - impl->conv = convolver_new(blocksize, tailsize, samples, n_samples); + impl->conv = convolver_new(dsp_ops, blocksize, tailsize, samples, n_samples); if (impl->conv == NULL) goto error; @@ -975,14 +975,9 @@ }; struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support, - const char *plugin, const char *config) + struct dsp_ops *dsp, const char *plugin, const char *config) { - struct spa_cpu *cpu_iface; - uint32_t cpu_flags; - cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); - cpu_flags = cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0; - dsp_ops.cpu_flags = cpu_flags; - dsp_ops_init(&dsp_ops); - pffft_select_cpu(cpu_flags); + dsp_ops = dsp; + pffft_select_cpu(dsp->cpu_flags); return &builtin_plugin; }
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
@@ -30,11 +30,7 @@ #include <math.h> -#include "pffft.h" - -struct fft_cpx { - float *v; -}; +static struct dsp_ops *dsp; struct convolver1 { int blockSize; @@ -42,16 +38,16 @@ int segCount; int fftComplexSize; - struct fft_cpx *segments; - struct fft_cpx *segmentsIr; + float **segments; + float **segmentsIr; float *fft_buffer; void *fft; void *ifft; - struct fft_cpx pre_mult; - struct fft_cpx conv; + float *pre_mult; + float *conv; float *overlap; float *inputBuffer; @@ -61,37 +57,35 @@ float scale; }; -static inline void fft_copy(void *dst, const void *src, int size) -{ - memcpy(dst, src, size * sizeof(float)); -} - -static void fft_clear(void *data, int size) -{ - memset(data, 0, size * sizeof(float)); -} - static void *fft_alloc(int size) { - return pffft_aligned_malloc(size * sizeof(float)); + size_t nb_bytes = size * sizeof(float); +#define ALIGNMENT 64 + void *p, *p0 = malloc(nb_bytes + ALIGNMENT); + if (!p0) + return (void *)0; + p = (void *)(((size_t)p0 + ALIGNMENT) & (~((size_t)(ALIGNMENT - 1)))); + *((void **)p - 1) = p0; + return p; } -static void fft_free(void *data) +static void fft_free(void *p) { - pffft_aligned_free(data); + if (p) + free(*((void **)p - 1)); } -static void fft_cpx_clear(struct fft_cpx *cpx, int size) +static inline void fft_cpx_clear(float *v, int size) { - fft_clear(cpx->v, size * 2); + dsp_ops_clear(dsp, v, size * 2); } -static void fft_cpx_init(struct fft_cpx *cpx, int size) +static float *fft_cpx_alloc(int size) { - cpx->v = fft_alloc(size * 2); + return fft_alloc(size * 2); } -static void fft_cpx_free(struct fft_cpx *cpx) +static void fft_cpx_free(float *cpx) { - fft_free(cpx->v); + fft_free(cpx); } static int next_power_of_two(int val) @@ -102,56 +96,15 @@ return r; } -static inline void *fft_new(int size) -{ - return pffft_new_setup(size, PFFFT_REAL); -} - -static inline void *ifft_new(int size) -{ - return pffft_new_setup(size, PFFFT_REAL); -} - -static inline void fft_destroy(void *fft) -{ - pffft_destroy_setup(fft); -} - -static inline void fft_run(void *fft, float *in, struct fft_cpx *out) -{ - pffft_transform(fft, in, out->v, NULL, PFFFT_FORWARD); -} - -static inline void ifft_run(void *ifft, struct fft_cpx *in, float *out) -{ - pffft_transform(ifft, in->v, out, NULL, PFFFT_BACKWARD); -} - -static inline void fft_convolve(void *fft, struct fft_cpx *r, - const struct fft_cpx *a, const struct fft_cpx *b, int len, float scale) -{ - pffft_zconvolve(fft, a->v, b->v, r->v, scale); -} -static inline void fft_convolve_accum(void *fft, struct fft_cpx *r, - const struct fft_cpx *c, const struct fft_cpx *a, const struct fft_cpx *b, int len, float scale) -{ - pffft_zconvolve_accumulate(fft, a->v, b->v, c->v, r->v, scale); -} - -static inline void fft_sum(float *r, const float *a, const float *b,int len) -{ - pffft_sum(a, b, r, len); -} - static void convolver1_reset(struct convolver1 *conv) { int i; for (i = 0; i < conv->segCount; i++) - fft_cpx_clear(&conv->segmentsi, conv->fftComplexSize); - fft_clear(conv->overlap, conv->blockSize); - fft_clear(conv->inputBuffer, conv->segSize); - fft_cpx_clear(&conv->pre_mult, conv->fftComplexSize); - fft_cpx_clear(&conv->conv, conv->fftComplexSize); + fft_cpx_clear(conv->segmentsi, conv->fftComplexSize); + dsp_ops_clear(dsp, conv->overlap, conv->blockSize); + dsp_ops_clear(dsp, conv->inputBuffer, conv->segSize); + fft_cpx_clear(conv->pre_mult, conv->fftComplexSize); + fft_cpx_clear(conv->conv, conv->fftComplexSize); conv->inputBufferFill = 0; conv->current = 0; } @@ -179,10 +132,10 @@ conv->segCount = (irlen + conv->blockSize-1) / conv->blockSize; conv->fftComplexSize = (conv->segSize / 2) + 1; - conv->fft = fft_new(conv->segSize); + conv->fft = dsp_ops_fft_new(dsp, conv->segSize, true); if (conv->fft == NULL) goto error; - conv->ifft = ifft_new(conv->segSize); + conv->ifft = dsp_ops_fft_new(dsp, conv->segSize, true); if (conv->ifft == NULL) goto error; @@ -190,24 +143,24 @@ if (conv->fft_buffer == NULL) goto error; - conv->segments = calloc(sizeof(struct fft_cpx), conv->segCount); - conv->segmentsIr = calloc(sizeof(struct fft_cpx), conv->segCount); + conv->segments = calloc(sizeof(float*), conv->segCount); + conv->segmentsIr = calloc(sizeof(float*), conv->segCount); for (i = 0; i < conv->segCount; i++) { int left = irlen - (i * conv->blockSize); int copy = SPA_MIN(conv->blockSize, left); - fft_cpx_init(&conv->segmentsi, conv->fftComplexSize); - fft_cpx_init(&conv->segmentsIri, conv->fftComplexSize); + conv->segmentsi = fft_cpx_alloc(conv->fftComplexSize); + conv->segmentsIri = fft_cpx_alloc(conv->fftComplexSize); - fft_copy(conv->fft_buffer, &iri * conv->blockSize, copy); + dsp_ops_copy(dsp, conv->fft_buffer, &iri * conv->blockSize, copy); if (copy < conv->segSize) - fft_clear(conv->fft_buffer + copy, conv->segSize - copy); + dsp_ops_clear(dsp, conv->fft_buffer + copy, conv->segSize - copy); - fft_run(conv->fft, conv->fft_buffer, &conv->segmentsIri); + dsp_ops_fft_run(dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIri); } - fft_cpx_init(&conv->pre_mult, conv->fftComplexSize); - fft_cpx_init(&conv->conv, conv->fftComplexSize); + conv->pre_mult = fft_cpx_alloc(conv->fftComplexSize); + conv->conv = fft_cpx_alloc(conv->fftComplexSize); conv->overlap = fft_alloc(conv->blockSize); conv->inputBuffer = fft_alloc(conv->segSize); conv->scale = 1.0f / conv->segSize; @@ -216,9 +169,9 @@ return conv; error: if (conv->fft) - fft_destroy(conv->fft); + dsp_ops_fft_free(dsp, conv->fft); if (conv->ifft) - fft_destroy(conv->ifft); + dsp_ops_fft_free(dsp, conv->ifft); if (conv->fft_buffer) fft_free(conv->fft_buffer); free(conv); @@ -229,19 +182,19 @@ { int i; for (i = 0; i < conv->segCount; i++) { - fft_cpx_free(&conv->segmentsi); - fft_cpx_free(&conv->segmentsIri); + fft_cpx_free(conv->segmentsi); + fft_cpx_free(conv->segmentsIri); } if (conv->fft) - fft_destroy(conv->fft); + dsp_ops_fft_free(dsp, conv->fft); if (conv->ifft) - fft_destroy(conv->ifft); + dsp_ops_fft_free(dsp, conv->ifft); if (conv->fft_buffer) fft_free(conv->fft_buffer); free(conv->segments); free(conv->segmentsIr); - fft_cpx_free(&conv->pre_mult); - fft_cpx_free(&conv->conv); + fft_cpx_free(conv->pre_mult); + fft_cpx_free(conv->conv); fft_free(conv->overlap); fft_free(conv->inputBuffer); free(conv); @@ -252,7 +205,7 @@ int i, processed = 0; if (conv == NULL || conv->segCount == 0) { - fft_clear(output, len); + dsp_ops_clear(dsp, output, len); return len; } @@ -260,55 +213,56 @@ const int processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill); const int inputBufferPos = conv->inputBufferFill; - fft_copy(conv->inputBuffer + inputBufferPos, input + processed, processing); + dsp_ops_copy(dsp, conv->inputBuffer + inputBufferPos, input + processed, processing); if (inputBufferPos == 0 && processing < conv->blockSize) - fft_clear(conv->inputBuffer + processing, conv->blockSize - processing); + dsp_ops_clear(dsp, conv->inputBuffer + processing, conv->blockSize - processing); - fft_run(conv->fft, conv->inputBuffer, &conv->segmentsconv->current); + dsp_ops_fft_run(dsp, conv->fft, 1, conv->inputBuffer, conv->segmentsconv->current); if (conv->segCount > 1) { if (conv->inputBufferFill == 0) { int indexAudio = (conv->current + 1) % conv->segCount; - fft_convolve(conv->fft, &conv->pre_mult, - &conv->segmentsIr1, - &conv->segmentsindexAudio, + dsp_ops_fft_cmul(dsp, conv->fft, conv->pre_mult, + conv->segmentsIr1, + conv->segmentsindexAudio, conv->fftComplexSize, conv->scale); for (i = 2; i < conv->segCount; i++) { indexAudio = (conv->current + i) % conv->segCount; - fft_convolve_accum(conv->fft, - &conv->pre_mult, - &conv->pre_mult, - &conv->segmentsIri, - &conv->segmentsindexAudio, + dsp_ops_fft_cmuladd(dsp, conv->fft, + conv->pre_mult, + conv->pre_mult, + conv->segmentsIri, + conv->segmentsindexAudio, conv->fftComplexSize, conv->scale); } } - fft_convolve_accum(conv->fft, - &conv->conv, - &conv->pre_mult, - &conv->segmentsconv->current, - &conv->segmentsIr0, + dsp_ops_fft_cmuladd(dsp, conv->fft, + conv->conv, + conv->pre_mult, + conv->segmentsconv->current, + conv->segmentsIr0, conv->fftComplexSize, conv->scale); } else { - fft_convolve(conv->fft, &conv->conv, - &conv->segmentsconv->current, - &conv->segmentsIr0, + dsp_ops_fft_cmul(dsp, conv->fft, + conv->conv, + conv->segmentsconv->current, + conv->segmentsIr0, conv->fftComplexSize, conv->scale); } - ifft_run(conv->ifft, &conv->conv, conv->fft_buffer); + dsp_ops_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer); - fft_sum(output + processed, conv->fft_buffer + inputBufferPos, + dsp_ops_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos, conv->overlap + inputBufferPos, processing); conv->inputBufferFill += processing; if (conv->inputBufferFill == conv->blockSize) { conv->inputBufferFill = 0; - fft_copy(conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize); + dsp_ops_copy(dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize); conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1); } @@ -340,23 +294,25 @@ convolver1_reset(conv->headConvolver); if (conv->tailConvolver0) { convolver1_reset(conv->tailConvolver0); - fft_clear(conv->tailOutput0, conv->tailBlockSize); - fft_clear(conv->tailPrecalculated0, conv->tailBlockSize); + dsp_ops_clear(dsp, conv->tailOutput0, conv->tailBlockSize); + dsp_ops_clear(dsp, conv->tailPrecalculated0, conv->tailBlockSize); } if (conv->tailConvolver) { convolver1_reset(conv->tailConvolver); - fft_clear(conv->tailOutput, conv->tailBlockSize); - fft_clear(conv->tailPrecalculated, conv->tailBlockSize); + dsp_ops_clear(dsp, conv->tailOutput, conv->tailBlockSize); + dsp_ops_clear(dsp, conv->tailPrecalculated, conv->tailBlockSize); } conv->tailInputFill = 0; conv->precalculatedPos = 0; } -struct convolver *convolver_new(int head_block, int tail_block, const float *ir, int irlen) +struct convolver *convolver_new(struct dsp_ops *dsp_ops, int head_block, int tail_block, const float *ir, int irlen) { struct convolver *conv; int head_ir_len; + dsp = dsp_ops; + if (head_block == 0 || tail_block == 0) return NULL; @@ -430,16 +386,16 @@ int processing = SPA_MIN(remaining, conv->headBlockSize - (conv->tailInputFill % conv->headBlockSize)); if (conv->tailPrecalculated0) - fft_sum(&outputprocessed, &outputprocessed, + dsp_ops_sum(dsp, &outputprocessed, &outputprocessed, &conv->tailPrecalculated0conv->precalculatedPos, processing); if (conv->tailPrecalculated) - fft_sum(&outputprocessed, &outputprocessed, + dsp_ops_sum(dsp, &outputprocessed, &outputprocessed, &conv->tailPrecalculatedconv->precalculatedPos, processing); conv->precalculatedPos += processing; - fft_copy(conv->tailInput + conv->tailInputFill, input + processed, processing); + dsp_ops_copy(dsp, conv->tailInput + conv->tailInputFill, input + processed, processing); conv->tailInputFill += processing; if (conv->tailPrecalculated0 && (conv->tailInputFill % conv->headBlockSize == 0)) {
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/convolver.h -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/convolver.h
Changed
@@ -25,7 +25,9 @@ #include <stdint.h> #include <stddef.h> -struct convolver *convolver_new(int block, int tail, const float *ir, int irlen); +#include "dsp-ops.h" + +struct convolver *convolver_new(struct dsp_ops *dsp, int block, int tail, const float *ir, int irlen); void convolver_free(struct convolver *conv); void convolver_reset(struct convolver *conv);
View file
pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/dsp-ops-avx.c
Added
@@ -0,0 +1,85 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include <spa/utils/defs.h> + +#include "dsp-ops.h" + +#include <immintrin.h> + +void dsp_sum_avx(struct dsp_ops *ops, float *r, const float *a, const float *b, uint32_t n_samples) +{ + uint32_t n, unrolled; + __m256 in4; + + unrolled = n_samples & ~31; + + if (SPA_LIKELY(SPA_IS_ALIGNED(r, 32)) && + SPA_LIKELY(SPA_IS_ALIGNED(a, 32)) && + SPA_LIKELY(SPA_IS_ALIGNED(b, 32))) { + for (n = 0; n < unrolled; n += 32) { + in0 = _mm256_load_ps(&an+ 0); + in1 = _mm256_load_ps(&an+ 8); + in2 = _mm256_load_ps(&an+16); + in3 = _mm256_load_ps(&an+24); + + in0 = _mm256_add_ps(in0, _mm256_load_ps(&bn+ 0)); + in1 = _mm256_add_ps(in1, _mm256_load_ps(&bn+ 8)); + in2 = _mm256_add_ps(in2, _mm256_load_ps(&bn+16)); + in3 = _mm256_add_ps(in3, _mm256_load_ps(&bn+24)); + + _mm256_store_ps(&rn+ 0, in0); + _mm256_store_ps(&rn+ 8, in1); + _mm256_store_ps(&rn+16, in2); + _mm256_store_ps(&rn+24, in3); + } + } else { + for (n = 0; n < unrolled; n += 16) { + in0 = _mm256_loadu_ps(&an+ 0); + in1 = _mm256_loadu_ps(&an+ 8); + in2 = _mm256_loadu_ps(&an+16); + in3 = _mm256_loadu_ps(&an+24); + + in0 = _mm256_add_ps(in0, _mm256_loadu_ps(&bn+ 0)); + in1 = _mm256_add_ps(in1, _mm256_loadu_ps(&bn+ 8)); + in2 = _mm256_add_ps(in2, _mm256_loadu_ps(&bn+16)); + in3 = _mm256_add_ps(in3, _mm256_loadu_ps(&bn+24)); + + _mm256_storeu_ps(&rn+ 0, in0); + _mm256_storeu_ps(&rn+ 8, in1); + _mm256_storeu_ps(&rn+16, in2); + _mm256_storeu_ps(&rn+24, in3); + } + } + for (; n < n_samples; n++) { + __m128 in1; + in0 = _mm_load_ss(&an); + in0 = _mm_add_ss(in0, _mm_load_ss(&bn)); + _mm_store_ss(&rn, in0); + } +}
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/dsp-ops-c.c
Changed
@@ -29,9 +29,10 @@ #include <spa/utils/defs.h> +#include "pffft.h" #include "dsp-ops.h" -static inline void dsp_clear_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) +void dsp_clear_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) { memset(dst, 0, sizeof(float) * n_samples); } @@ -133,3 +134,41 @@ #undef F } +void dsp_sum_c(struct dsp_ops *ops, float * dst, + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) +{ + uint32_t i; + for (i = 0; i < n_samples; i++) + dsti = ai + bi; +} + +void *dsp_fft_new_c(struct dsp_ops *ops, int32_t size, bool real) +{ + return pffft_new_setup(size, real ? PFFFT_REAL : PFFFT_COMPLEX); +} + +void dsp_fft_free_c(struct dsp_ops *ops, void *fft) +{ + pffft_destroy_setup(fft); +} +void dsp_fft_run_c(struct dsp_ops *ops, void *fft, int direction, + const float * SPA_RESTRICT src, float * SPA_RESTRICT dst) +{ + pffft_transform(fft, src, dst, NULL, direction < 0 ? PFFFT_BACKWARD : PFFFT_FORWARD); +} + +void dsp_fft_cmul_c(struct dsp_ops *ops, void *fft, + float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, + const float * SPA_RESTRICT b, uint32_t len, const float scale) +{ + pffft_zconvolve(fft, a, b, dst, scale); +} + +void dsp_fft_cmuladd_c(struct dsp_ops *ops, void *fft, + float * SPA_RESTRICT dst, const float * SPA_RESTRICT src, + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, + uint32_t len, const float scale) +{ + pffft_zconvolve_accumulate(fft, a, b, src, dst, scale); +} +
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/dsp-ops-sse.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/dsp-ops-sse.c
Changed
@@ -89,3 +89,54 @@ } } } + +void dsp_sum_sse(struct dsp_ops *ops, float *r, const float *a, const float *b, uint32_t n_samples) +{ + uint32_t n, unrolled; + __m128 in4; + + unrolled = n_samples & ~15; + + if (SPA_LIKELY(SPA_IS_ALIGNED(r, 16)) && + SPA_LIKELY(SPA_IS_ALIGNED(a, 16)) && + SPA_LIKELY(SPA_IS_ALIGNED(b, 16))) { + for (n = 0; n < unrolled; n += 16) { + in0 = _mm_load_ps(&an+ 0); + in1 = _mm_load_ps(&an+ 4); + in2 = _mm_load_ps(&an+ 8); + in3 = _mm_load_ps(&an+12); + + in0 = _mm_add_ps(in0, _mm_load_ps(&bn+ 0)); + in1 = _mm_add_ps(in1, _mm_load_ps(&bn+ 4)); + in2 = _mm_add_ps(in2, _mm_load_ps(&bn+ 8)); + in3 = _mm_add_ps(in3, _mm_load_ps(&bn+12)); + + _mm_store_ps(&rn+ 0, in0); + _mm_store_ps(&rn+ 4, in1); + _mm_store_ps(&rn+ 8, in2); + _mm_store_ps(&rn+12, in3); + } + } else { + for (n = 0; n < unrolled; n += 16) { + in0 = _mm_loadu_ps(&an+ 0); + in1 = _mm_loadu_ps(&an+ 4); + in2 = _mm_loadu_ps(&an+ 8); + in3 = _mm_loadu_ps(&an+12); + + in0 = _mm_add_ps(in0, _mm_loadu_ps(&bn+ 0)); + in1 = _mm_add_ps(in1, _mm_loadu_ps(&bn+ 4)); + in2 = _mm_add_ps(in2, _mm_loadu_ps(&bn+ 8)); + in3 = _mm_add_ps(in3, _mm_loadu_ps(&bn+12)); + + _mm_storeu_ps(&rn+ 0, in0); + _mm_storeu_ps(&rn+ 4, in1); + _mm_storeu_ps(&rn+ 8, in2); + _mm_storeu_ps(&rn+12, in3); + } + } + for (; n < n_samples; n++) { + in0 = _mm_load_ss(&an); + in0 = _mm_add_ss(in0, _mm_load_ss(&bn)); + _mm_store_ss(&rn, in0); + } +}
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/dsp-ops.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/dsp-ops.c
Changed
@@ -35,30 +35,50 @@ struct dsp_info { uint32_t cpu_flags; - void (*copy) (struct dsp_ops *ops, - void * SPA_RESTRICT dst, - const void * SPA_RESTRICT src, uint32_t n_samples); - void (*mix_gain) (struct dsp_ops *ops, - void * SPA_RESTRICT dst, - const void * SPA_RESTRICT src, - float gain, uint32_t n_src, uint32_t n_samples); - void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, - float *out, const float *in, uint32_t n_samples); + struct dsp_ops_funcs funcs; }; static struct dsp_info dsp_table = { +#if defined (HAVE_AVX) + { SPA_CPU_FLAG_AVX, + .funcs.clear = dsp_clear_c, + .funcs.copy = dsp_copy_c, + .funcs.mix_gain = dsp_mix_gain_sse, + .funcs.biquad_run = dsp_biquad_run_c, + .funcs.sum = dsp_sum_avx, + .funcs.fft_new = dsp_fft_new_c, + .funcs.fft_free = dsp_fft_free_c, + .funcs.fft_run = dsp_fft_run_c, + .funcs.fft_cmul = dsp_fft_cmul_c, + .funcs.fft_cmuladd = dsp_fft_cmuladd_c, + }, +#endif #if defined (HAVE_SSE) { SPA_CPU_FLAG_SSE, - .copy = dsp_copy_c, - .mix_gain = dsp_mix_gain_sse, - .biquad_run = dsp_biquad_run_c, + .funcs.clear = dsp_clear_c, + .funcs.copy = dsp_copy_c, + .funcs.mix_gain = dsp_mix_gain_sse, + .funcs.biquad_run = dsp_biquad_run_c, + .funcs.sum = dsp_sum_sse, + .funcs.fft_new = dsp_fft_new_c, + .funcs.fft_free = dsp_fft_free_c, + .funcs.fft_run = dsp_fft_run_c, + .funcs.fft_cmul = dsp_fft_cmul_c, + .funcs.fft_cmuladd = dsp_fft_cmuladd_c, }, #endif { 0, - .copy = dsp_copy_c, - .mix_gain = dsp_mix_gain_c, - .biquad_run = dsp_biquad_run_c, + .funcs.clear = dsp_clear_c, + .funcs.copy = dsp_copy_c, + .funcs.mix_gain = dsp_mix_gain_c, + .funcs.biquad_run = dsp_biquad_run_c, + .funcs.sum = dsp_sum_c, + .funcs.fft_new = dsp_fft_new_c, + .funcs.fft_free = dsp_fft_free_c, + .funcs.fft_run = dsp_fft_run_c, + .funcs.fft_cmul = dsp_fft_cmul_c, + .funcs.fft_cmuladd = dsp_fft_cmuladd_c, }, }; @@ -87,11 +107,8 @@ return -ENOTSUP; ops->priv = info; - ops->cpu_flags = info->cpu_flags; - ops->copy = info->copy; - ops->mix_gain = info->mix_gain; - ops->biquad_run = info->biquad_run; ops->free = impl_dsp_ops_free; + ops->funcs = info->funcs; return 0; }
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/dsp-ops.h -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/dsp-ops.h
Changed
@@ -22,13 +22,16 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef DSP_OPS_H +#define DSP_OPS_H + #include <spa/utils/defs.h> #include "biquad.h" -struct dsp_ops { - uint32_t cpu_flags; +struct dsp_ops; +struct dsp_ops_funcs { void (*clear) (struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples); void (*copy) (struct dsp_ops *ops, void * SPA_RESTRICT dst, @@ -39,19 +42,51 @@ float gain, uint32_t n_src, uint32_t n_samples); void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, float *out, const float *in, uint32_t n_samples); + void (*sum) (struct dsp_ops *ops, + float * dst, const float * SPA_RESTRICT a, + const float * SPA_RESTRICT b, uint32_t n_samples); + + void *(*fft_new) (struct dsp_ops *ops, int32_t size, bool real); + void (*fft_free) (struct dsp_ops *ops, void *fft); + void (*fft_run) (struct dsp_ops *ops, void *fft, int direction, + const float * SPA_RESTRICT src, float * SPA_RESTRICT dst); + void (*fft_cmul) (struct dsp_ops *ops, void *fft, + float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, + const float * SPA_RESTRICT b, uint32_t len, const float scale); + void (*fft_cmuladd) (struct dsp_ops *ops, void *fft, + float * dst, const float * src, + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, + uint32_t len, const float scale); +}; + +struct dsp_ops { + uint32_t cpu_flags; + void (*free) (struct dsp_ops *ops); + struct dsp_ops_funcs funcs; + const void *priv; }; int dsp_ops_init(struct dsp_ops *ops); -#define dsp_ops_copy(ops,...) (ops)->copy(ops, __VA_ARGS__) -#define dsp_ops_mix_gain(ops,...) (ops)->mix_gain(ops, __VA_ARGS__) -#define dsp_ops_biquad_run(ops,...) (ops)->biquad_run(ops, __VA_ARGS__) #define dsp_ops_free(ops) (ops)->free(ops) +#define dsp_ops_clear(ops,...) (ops)->funcs.clear(ops, __VA_ARGS__) +#define dsp_ops_copy(ops,...) (ops)->funcs.copy(ops, __VA_ARGS__) +#define dsp_ops_mix_gain(ops,...) (ops)->funcs.mix_gain(ops, __VA_ARGS__) +#define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(ops, __VA_ARGS__) +#define dsp_ops_sum(ops,...) (ops)->funcs.sum(ops, __VA_ARGS__) +#define dsp_ops_fft_new(ops,...) (ops)->funcs.fft_new(ops, __VA_ARGS__) +#define dsp_ops_fft_free(ops,...) (ops)->funcs.fft_free(ops, __VA_ARGS__) +#define dsp_ops_fft_run(ops,...) (ops)->funcs.fft_run(ops, __VA_ARGS__) +#define dsp_ops_fft_cmul(ops,...) (ops)->funcs.fft_cmul(ops, __VA_ARGS__) +#define dsp_ops_fft_cmuladd(ops,...) (ops)->funcs.fft_cmuladd(ops, __VA_ARGS__) + +#define MAKE_CLEAR_FUNC(arch) \ +void dsp_clear_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t n_samples) #define MAKE_COPY_FUNC(arch) \ void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src, uint32_t n_samples) @@ -61,11 +96,45 @@ #define MAKE_BIQUAD_RUN_FUNC(arch) \ void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \ float *out, const float *in, uint32_t n_samples) +#define MAKE_SUM_FUNC(arch) \ +void dsp_sum_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) +#define MAKE_FFT_NEW_FUNC(arch) \ +void *dsp_fft_new_##arch(struct dsp_ops *ops, int32_t size, bool real) +#define MAKE_FFT_FREE_FUNC(arch) \ +void dsp_fft_free_##arch(struct dsp_ops *ops, void *fft) +#define MAKE_FFT_RUN_FUNC(arch) \ +void dsp_fft_run_##arch(struct dsp_ops *ops, void *fft, int direction, \ + const float * SPA_RESTRICT src, float * SPA_RESTRICT dst) +#define MAKE_FFT_CMUL_FUNC(arch) \ +void dsp_fft_cmul_##arch(struct dsp_ops *ops, void *fft, \ + float * SPA_RESTRICT dst, const float * SPA_RESTRICT a, \ + const float * SPA_RESTRICT b, uint32_t len, const float scale) +#define MAKE_FFT_CMULADD_FUNC(arch) \ +void dsp_fft_cmuladd_##arch(struct dsp_ops *ops, void *fft, \ + float * dst, const float * src, \ + const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, \ + uint32_t len, const float scale) +MAKE_CLEAR_FUNC(c); MAKE_COPY_FUNC(c); MAKE_MIX_GAIN_FUNC(c); MAKE_BIQUAD_RUN_FUNC(c); +MAKE_SUM_FUNC(c); + +MAKE_FFT_NEW_FUNC(c); +MAKE_FFT_FREE_FUNC(c); +MAKE_FFT_RUN_FUNC(c); +MAKE_FFT_CMUL_FUNC(c); +MAKE_FFT_CMULADD_FUNC(c); + #if defined (HAVE_SSE) MAKE_MIX_GAIN_FUNC(sse); +MAKE_SUM_FUNC(sse); +#endif +#if defined (HAVE_AVX) +MAKE_SUM_FUNC(avx); #endif + +#endif /* DSP_OPS_H */
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c
Changed
@@ -229,7 +229,7 @@ } struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support, - const char *plugin, const char *config) + struct dsp_ops *dsp, const char *plugin, const char *config) { struct fc_plugin *pl = NULL;
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/lv2_plugin.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/lv2_plugin.c
Changed
@@ -472,7 +472,7 @@ } struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support, - const char *plugin_uri, const char *config) + struct dsp_ops *ops, const char *plugin_uri, const char *config) { struct context *c; const LilvPlugins *plugins;
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/pffft.c -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/pffft.c
Changed
@@ -135,7 +135,6 @@ #define zconvolve_accumulate_simd zconvolve_accumulate_altivec #define zconvolve_simd zconvolve_altivec #define transform_simd transform_altivec -#define sum_simd sum_altivec /* SSE1 support macros @@ -162,7 +161,6 @@ #define zconvolve_accumulate_simd zconvolve_accumulate_sse #define zconvolve_simd zconvolve_sse #define transform_simd transform_sse -#define sum_simd sum_sse /* ARM NEON support macros @@ -196,7 +194,6 @@ #define zconvolve_accumulate_simd zconvolve_accumulate_neon #define zconvolve_simd zconvolve_neon #define transform_simd transform_neon -#define sum_simd sum_neon #else #if !defined(PFFFT_SIMD_DISABLE) #warning "building with simd disabled !\n"; @@ -221,7 +218,6 @@ #define zconvolve_accumulate_simd zconvolve_accumulate_c #define zconvolve_simd zconvolve_c #define transform_simd transform_c -#define sum_simd sum_c #endif // shortcuts for complex multiplcations @@ -1412,7 +1408,6 @@ void (*zreorder)(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction); void (*zconvolve_accumulate)(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, const float *dft_c, float *dft_ab, float scaling); void (*zconvolve)(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling); - void (*sum)(const float *a, const float *b, float *ab, int len); int (*simd_size)(void); void (*validate)(void); }; @@ -2125,25 +2120,6 @@ } } - -static void sum_simd(const float *a, const float *b, float *ab, int len) -{ - int i = 0; - - if (VALIGNED(a) && VALIGNED(b) && VALIGNED(ab)) { - const v4sf *RESTRICT va = (const v4sf *)a; - const v4sf *RESTRICT vb = (const v4sf *)b; - v4sf *RESTRICT vab = (v4sf *) ab; - const int end4 = len / SIMD_SZ; - - for (; i < end4; i += 1) - vabi = VADD(vai,vbi); - i *= 4; - } - for (; i < len; ++i) - abi = ai + bi; -} - #else // defined(PFFFT_SIMD_DISABLE) // standard routine using scalar floats, without SIMD stuff. @@ -2293,13 +2269,6 @@ abi + 1 = ai * scaling; } } -static void sum_simd(const float *a, const float *b, float *ab, int len) -{ - int i; - for (i = 0; i < len; ++i) - abi = VADD(ai, bi); -} - #endif // defined(PFFFT_SIMD_DISABLE) static int simd_size_simd(void) @@ -2313,7 +2282,6 @@ .zreorder = zreorder_simd, .zconvolve_accumulate = zconvolve_accumulate_simd, .zconvolve = zconvolve_simd, - .sum = sum_simd, .simd_size = simd_size_simd, .validate = validate_pffft_simd, }; @@ -2393,11 +2361,6 @@ return funcs->zconvolve(setup, dft_a, dft_b, dft_ab, scaling); } -void pffft_sum(const float *a, const float *b, float *ab, int len) -{ - return funcs->sum(a, b, ab, len); -} - void pffft_select_cpu(int flags) { funcs = &pffft_funcs_c;
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/pffft.h -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/pffft.h
Changed
@@ -161,7 +161,6 @@ void pffft_zconvolve(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling); - void pffft_sum(const float *a, const float *b, float *ab, int len); /* the float buffers must have the correct alignment (16-byte boundary on intel and powerpc). This function may be used to obtain such
View file
pipewire-0.3.63.tar.gz/src/modules/module-filter-chain/plugin.h -> pipewire-0.3.64.tar.gz/src/modules/module-filter-chain/plugin.h
Changed
@@ -22,6 +22,9 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef PLUGIN_H +#define PLUGIN_H + #include <stdint.h> #include <stddef.h> #include <errno.h> @@ -33,6 +36,8 @@ #include <spa/utils/list.h> #include <spa/utils/string.h> +#include "dsp-ops.h" + struct fc_plugin { const struct fc_descriptor *(*make_desc)(struct fc_plugin *plugin, const char *name); void (*unload) (struct fc_plugin *plugin); @@ -98,8 +103,10 @@ } struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support, - const char *path, const char *config); + struct dsp_ops *dsp, const char *path, const char *config); struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support, - const char *path, const char *config); + struct dsp_ops *dsp, const char *path, const char *config); struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support, - const char *path, const char *config); + struct dsp_ops *dsp, const char *path, const char *config); + +#endif /* PLUGIN_H */
View file
pipewire-0.3.63.tar.gz/src/modules/module-pipe-tunnel.c -> pipewire-0.3.64.tar.gz/src/modules/module-pipe-tunnel.c
Changed
@@ -139,7 +139,7 @@ " node.latency=<latency as fraction> " \ " node.name=<name of the nodes> " \ " node.description=<description of the nodes> " \ - " target.object=<remote node target name> " \ + " target.object=<remote node target name or serial> "\ " audio.format=<sample format> " \ " audio.rate=<sample rate> " \ " audio.channels=<number of channels> " \
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/collect.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/collect.c
Changed
@@ -82,16 +82,6 @@ return SPA_ID_INVALID; } -uint32_t index_to_id(struct pw_manager *m, uint32_t index) -{ - struct pw_manager_object *o; - spa_list_for_each(o, &m->object_list, link) { - if (o->index == index) - return o->id; - } - return SPA_ID_INVALID; -} - bool collect_is_linked(struct pw_manager *m, uint32_t id, enum pw_direction direction) { struct pw_manager_object *o;
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/collect.h -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/collect.h
Changed
@@ -54,7 +54,6 @@ 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); -uint32_t index_to_id(struct pw_manager *m, uint32_t index); void select_best(struct selector *s, struct pw_manager_object *o); /* ========================================================================== */
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-combine-sink.c
Changed
@@ -312,7 +312,7 @@ pw_properties_setf(props, PW_KEY_NODE_NAME, "combine_output.sink-%u.%s", data->module->index, sink_name); pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, data->sink_name); - pw_properties_set(props, PW_KEY_NODE_TARGET, sink_name); + pw_properties_set(props, PW_KEY_TARGET_OBJECT, sink_name); pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->index); pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->index); pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true");
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-echo-cancel.c
Changed
@@ -44,8 +44,10 @@ struct spa_hook mod_listener; struct pw_properties *props; + struct pw_properties *capture_props; struct pw_properties *source_props; struct pw_properties *sink_props; + struct pw_properties *playback_props; struct spa_audio_info_raw info; }; @@ -70,6 +72,7 @@ const char *str; char *args; size_t size; + uint32_t i; if ((f = open_memstream(&args, &size)) == NULL) return -errno; @@ -85,12 +88,22 @@ fprintf(f, " audio.rate = %u", data->info.rate); if (data->info.channels != 0) { fprintf(f, " audio.channels = %u", data->info.channels); - /* TODO: convert channel positions to string */ + if (!(data->info.flags & SPA_AUDIO_FLAG_UNPOSITIONED)) { + fprintf(f, " audio.position = "); + for (i = 0; i < data->info.channels; i++) + fprintf(f, "%s%s", i == 0 ? "" : ",", + channel_id2name(data->info.positioni)); + fprintf(f, " "); + } } - fprintf(f, " source.props = {"); + fprintf(f, " capture.props = {"); + pw_properties_serialize_dict(f, &data->capture_props->dict, 0); + fprintf(f, " } source.props = {"); pw_properties_serialize_dict(f, &data->source_props->dict, 0); fprintf(f, " } sink.props = {"); pw_properties_serialize_dict(f, &data->sink_props->dict, 0); + fprintf(f, " } playback.props = {"); + pw_properties_serialize_dict(f, &data->playback_props->dict, 0); fprintf(f, " } }"); fclose(f); @@ -120,8 +133,10 @@ } pw_properties_free(d->props); + pw_properties_free(d->capture_props); pw_properties_free(d->source_props); pw_properties_free(d->sink_props); + pw_properties_free(d->playback_props); return 0; } @@ -160,6 +175,7 @@ struct module_echo_cancel_data * const d = module->user_data; struct pw_properties * const props = module->props; struct pw_properties *aec_props = NULL, *sink_props = NULL, *source_props = NULL; + struct pw_properties *playback_props = NULL, *capture_props = NULL; const char *str; struct spa_audio_info_raw info = { 0 }; int res; @@ -167,9 +183,11 @@ PW_LOG_TOPIC_INIT(mod_topic); aec_props = pw_properties_new(NULL, NULL); + capture_props = pw_properties_new(NULL, NULL); source_props = pw_properties_new(NULL, NULL); sink_props = pw_properties_new(NULL, NULL); - if (!aec_props || !source_props || !sink_props) { + playback_props = pw_properties_new(NULL, NULL); + if (!aec_props || !source_props || !sink_props || !capture_props || !playback_props) { res = -EINVAL; goto out; } @@ -190,18 +208,18 @@ if ((str = pw_properties_get(props, "source_master")) != NULL) { if (spa_strendswith(str, ".monitor")) { - pw_properties_setf(source_props, PW_KEY_NODE_TARGET, + pw_properties_setf(capture_props, PW_KEY_TARGET_OBJECT, "%.*s", (int)strlen(str)-8, str); - pw_properties_set(source_props, PW_KEY_STREAM_CAPTURE_SINK, + pw_properties_set(capture_props, PW_KEY_STREAM_CAPTURE_SINK, "true"); } else { - pw_properties_set(source_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(capture_props, PW_KEY_TARGET_OBJECT, str); } pw_properties_set(props, "source_master", NULL); } if ((str = pw_properties_get(props, "sink_master")) != NULL) { - pw_properties_set(sink_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(playback_props, PW_KEY_TARGET_OBJECT, str); pw_properties_set(props, "sink_master", NULL); } @@ -232,15 +250,19 @@ d->module = module; d->props = aec_props; + d->capture_props = capture_props; d->source_props = source_props; d->sink_props = sink_props; + d->playback_props = playback_props; d->info = info; return 0; out: pw_properties_free(aec_props); + pw_properties_free(playback_props); pw_properties_free(sink_props); pw_properties_free(source_props); + pw_properties_free(capture_props); return res; }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c
Changed
@@ -219,7 +219,7 @@ if ((str = pw_properties_get(props, "master")) != NULL || (str = pw_properties_get(props, "sink_master")) != NULL) { - pw_properties_set(playback_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(playback_props, PW_KEY_TARGET_OBJECT, str); pw_properties_set(props, "master", NULL); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-ladspa-source.c
Changed
@@ -219,7 +219,15 @@ if ((str = pw_properties_get(props, "master")) != NULL || (str = pw_properties_get(props, "source_master")) != NULL) { - pw_properties_set(capture_props, PW_KEY_NODE_TARGET, str); + if (spa_strendswith(str, ".monitor")) { + pw_properties_setf(capture_props, PW_KEY_TARGET_OBJECT, + "%.*s", (int)strlen(str)-8, str); + pw_properties_set(capture_props, PW_KEY_STREAM_CAPTURE_SINK, + "true"); + } else { + pw_properties_set(capture_props, PW_KEY_TARGET_OBJECT, str); + } + pw_properties_set(props, "source_master", NULL); pw_properties_set(props, "master", NULL); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
@@ -173,18 +173,18 @@ if ((str = pw_properties_get(props, "source")) != NULL) { if (spa_strendswith(str, ".monitor")) { - pw_properties_setf(capture_props, PW_KEY_NODE_TARGET, + pw_properties_setf(capture_props, PW_KEY_TARGET_OBJECT, "%.*s", (int)strlen(str)-8, str); pw_properties_set(capture_props, PW_KEY_STREAM_CAPTURE_SINK, "true"); } else { - pw_properties_set(capture_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(capture_props, PW_KEY_TARGET_OBJECT, str); } pw_properties_set(props, "source", NULL); } if ((str = pw_properties_get(props, "sink")) != NULL) { - pw_properties_set(playback_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(playback_props, PW_KEY_TARGET_OBJECT, str); pw_properties_set(props, "sink", NULL); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-sink.c
Changed
@@ -197,7 +197,7 @@ } } if ((str = pw_properties_get(props, "master")) != NULL) { - pw_properties_set(playback_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(playback_props, PW_KEY_TARGET_OBJECT, str); pw_properties_set(props, "master", NULL); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-remap-source.c
Changed
@@ -197,7 +197,14 @@ } } if ((str = pw_properties_get(props, "master")) != NULL) { - pw_properties_set(capture_props, PW_KEY_NODE_TARGET, str); + if (spa_strendswith(str, ".monitor")) { + pw_properties_setf(capture_props, PW_KEY_TARGET_OBJECT, + "%.*s", (int)strlen(str)-8, str); + pw_properties_set(capture_props, PW_KEY_STREAM_CAPTURE_SINK, + "true"); + } else { + pw_properties_set(capture_props, PW_KEY_TARGET_OBJECT, str); + } pw_properties_set(props, "master", NULL); }
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-roc-sink.c
Changed
@@ -116,7 +116,6 @@ { PW_KEY_MODULE_USAGE, "sink_name=<name for the sink> " "sink_properties=<properties for the sink> " "fec_code=<empty>|disable|rs8m|ldpc " - "local_ip=<local sender ip> " "remote_ip=<remote receiver ip> " "remote_source_port=<remote receiver port for source packets> " "remote_repair_port=<remote receiver port for repair packets> " }, @@ -163,11 +162,6 @@ goto out; } - if ((str = pw_properties_get(props, "local_ip")) != NULL) { - pw_properties_set(roc_props, "local.ip", str); - pw_properties_set(props, "local_ip", NULL); - } - if ((str = pw_properties_get(props, "remote_source_port")) != NULL) { pw_properties_set(roc_props, "remote.source.port", str); pw_properties_set(props, "remote_source_port", NULL);
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c
Changed
@@ -135,7 +135,7 @@ goto out; } if ((str = pw_properties_get(props, "sink")) != NULL) - pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(stream_props, PW_KEY_TARGET_OBJECT, str); if ((str = pw_properties_get(props, "sap_address")) != NULL) pw_properties_set(global_props, "sap.ip", str);
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c
Changed
@@ -163,14 +163,13 @@ } if ((str = pw_properties_get(props, "source")) != NULL) { - pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); if (spa_strendswith(str, ".monitor")) { - pw_properties_setf(stream_props, PW_KEY_NODE_TARGET, + pw_properties_setf(stream_props, PW_KEY_TARGET_OBJECT, "%.*s", (int)strlen(str)-8, str); pw_properties_set(stream_props, PW_KEY_STREAM_CAPTURE_SINK, "true"); } else { - pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); + pw_properties_set(stream_props, PW_KEY_TARGET_OBJECT, str); } } if (module_args_to_audioinfo(module->impl, props, &info) < 0) {
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-sink.c
Changed
@@ -168,7 +168,7 @@ remote_sink_name = pw_properties_get(props, "sink"); if (remote_sink_name) - pw_properties_set(props, PW_KEY_NODE_TARGET, remote_sink_name); + pw_properties_set(props, PW_KEY_TARGET_OBJECT, remote_sink_name); if ((server = pw_properties_get(props, "server")) == NULL) { pw_log_error("no server given");
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/modules/module-tunnel-source.c
Changed
@@ -168,7 +168,7 @@ remote_source_name = pw_properties_get(props, "source"); if (remote_source_name) - pw_properties_set(props, PW_KEY_NODE_TARGET, remote_source_name); + pw_properties_set(props, PW_KEY_TARGET_OBJECT, remote_source_name); if ((server = pw_properties_get(props, "server")) == NULL) { pw_log_error("no server given");
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1541,7 +1541,7 @@ reply_simple_ack(stream->client, stream->drain_tag); stream->drain_tag = 0; - stream_set_paused(stream, false, "complete drain"); + pw_stream_set_active(stream->stream, !stream->is_paused); } } @@ -1569,7 +1569,6 @@ static int do_create_playback_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m) { struct impl *impl = client->impl; - struct pw_manager *manager = client->manager; const char *name = NULL; int res; struct sample_spec ss; @@ -1781,14 +1780,9 @@ if (sink_name != NULL) { pw_properties_set(props, - PW_KEY_NODE_TARGET, sink_name); - pw_properties_set(props, PW_KEY_TARGET_OBJECT, sink_name); } else if (sink_index != SPA_ID_INVALID && sink_index != 0) { pw_properties_setf(props, - PW_KEY_NODE_TARGET, "%u", - index_to_id(manager, sink_index)); - pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%u", sink_index); } @@ -1837,7 +1831,6 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m) { struct impl *impl = client->impl; - struct pw_manager *manager = client->manager; const char *name = NULL; int res; struct sample_spec ss; @@ -2052,24 +2045,16 @@ } if (source_index != SPA_ID_INVALID && source_index != 0) { pw_properties_setf(props, - PW_KEY_NODE_TARGET, "%u", - index_to_id(manager, source_index)); - pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%u", source_index); } else if (source_name != NULL) { if (spa_strendswith(source_name, ".monitor")) { pw_properties_setf(props, - PW_KEY_NODE_TARGET, - "%.*s", (int)strlen(source_name)-8, source_name); - pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%.*s", (int)strlen(source_name)-8, source_name); pw_properties_set(props, PW_KEY_STREAM_CAPTURE_SINK, "true"); } else { pw_properties_set(props, - PW_KEY_NODE_TARGET, source_name); - pw_properties_set(props, PW_KEY_TARGET_OBJECT, source_name); } } @@ -2628,7 +2613,6 @@ if (sample == NULL) goto error_noent; - pw_properties_setf(props, PW_KEY_NODE_TARGET, "%u", o->id); pw_properties_setf(props, PW_KEY_TARGET_OBJECT, "%"PRIu64, o->serial); play = sample_play_new(client->core, sample, props, sizeof(struct pending_sample));
View file
pipewire-0.3.63.tar.gz/src/modules/module-protocol-simple.c -> pipewire-0.3.64.tar.gz/src/modules/module-protocol-simple.c
Changed
@@ -66,8 +66,8 @@ * for each connected client. * - `playback`: boolean if playback is enabled. This will create a playback * stream for each connected client. - * - `capture.node`: an optional node id or name to use for capture. - * - `playback.node`: an optional node id or name to use for playback. + * - `capture.node`: an optional node serial or name to use for capture. + * - `playback.node`: an optional node serial or name to use for playback. * - `server.address = `: an array of server addresses to listen on as * tcp:<ip>:<port>. * @@ -449,7 +449,7 @@ props = pw_properties_new( PW_KEY_NODE_LATENCY, latency, PW_KEY_NODE_RATE, pw_properties_get(impl->props, PW_KEY_NODE_RATE), - PW_KEY_NODE_TARGET, pw_properties_get(impl->props, "capture.node"), + PW_KEY_TARGET_OBJECT, pw_properties_get(impl->props, "capture.node"), PW_KEY_STREAM_CAPTURE_SINK, pw_properties_get(impl->props, PW_KEY_STREAM_CAPTURE_SINK), PW_KEY_NODE_NETWORK, "true", @@ -472,7 +472,7 @@ props = pw_properties_new( PW_KEY_NODE_LATENCY, latency, PW_KEY_NODE_RATE, pw_properties_get(impl->props, PW_KEY_NODE_RATE), - PW_KEY_NODE_TARGET, pw_properties_get(impl->props, "playback.node"), + PW_KEY_TARGET_OBJECT, pw_properties_get(impl->props, "playback.node"), PW_KEY_NODE_NETWORK, "true", NULL); if (props == NULL)
View file
pipewire-0.3.63.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.64.tar.gz/src/modules/module-pulse-tunnel.c
Changed
@@ -129,7 +129,7 @@ " node.latency=<latency as fraction> " \ " node.name=<name of the nodes> " \ " node.description=<description of the nodes> " \ - " node.target=<remote node target name> " \ + " node.target=<remote node target name or serial> " \ " audio.format=<sample format> " \ " audio.rate=<sample rate> " \ " audio.channels=<number of channels> " \ @@ -270,7 +270,7 @@ impl->current_latency, impl->target_latency); SPA_FLAG_SET(impl->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE); - impl->rate_match->rate = corr; + impl->rate_match->rate = 1.0f / corr; } static void playback_stream_process(void *d) @@ -708,8 +708,6 @@ pa_stream_set_latency_update_callback(impl->pa_stream, stream_latency_update_cb, impl); remote_node_target = pw_properties_get(impl->props, PW_KEY_TARGET_OBJECT); - if (remote_node_target == NULL) - remote_node_target = pw_properties_get(impl->props, PW_KEY_NODE_TARGET); bufferattr.fragsize = (uint32_t) -1; bufferattr.minreq = (uint32_t) -1;
View file
pipewire-0.3.64.tar.gz/src/modules/module-roc
Added
+(directory)
View file
pipewire-0.3.63.tar.gz/src/modules/module-roc-sink.c -> pipewire-0.3.64.tar.gz/src/modules/module-roc-sink.c
Changed
@@ -40,6 +40,8 @@ #include <roc/log.h> #include <roc/sender.h> +#include "module-roc/common.h" + /** \page page_module_roc_sink PipeWire Module: ROC sink * * The `roc-sink` module creates a PipeWire sink that sends samples to @@ -52,7 +54,6 @@ * * - `sink.props = {}`: properties to be passed to the sink stream * - `sink.name = <str>`: node.name of the sink - * - `local.ip = <str>`: local sender ip * - `remote.ip = <str>`: remote receiver ip * - `remote.source.port = <str>`: remote receiver TCP/UDP port for source packets * - `remote.repair.port = <str>`: remote receiver TCP/UDP port for receiver packets @@ -92,10 +93,6 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define ROC_DEFAULT_IP "0.0.0.0" -#define ROC_DEFAULT_SOURCE_PORT 10001 -#define ROC_DEFAULT_REPAIR_PORT 10002 - struct module_roc_sink_data { struct pw_impl_module *module; struct spa_hook module_listener; @@ -112,34 +109,18 @@ unsigned int do_disconnect:1; - roc_address local_addr; - roc_address remote_source_addr; - roc_address remote_repair_addr; + roc_endpoint *remote_source_addr; + roc_endpoint *remote_repair_addr; roc_context *context; roc_sender *sender; - roc_fec_code fec_code; - char *local_ip; + roc_fec_encoding fec_code; + uint32_t rate; char *remote_ip; int remote_source_port; int remote_repair_port; }; -static int roc_parse_fec_code(roc_fec_code *out, const char *str) -{ - if (!str || !*str) - *out = ROC_FEC_DEFAULT; - else if (spa_streq(str, "disable")) - *out = ROC_FEC_DISABLE; - else if (spa_streq(str, "rs8m")) - *out = ROC_FEC_RS8M; - else if (spa_streq(str, "ldpc")) - *out = ROC_FEC_LDPC_STAIRCASE; - else - return -EINVAL; - return 0; -} - static void stream_destroy(void *d) { struct module_roc_sink_data *data = d; @@ -252,7 +233,11 @@ if (data->context) roc_context_close(data->context); - free(data->local_ip); + if (data->remote_source_addr) + (void) roc_endpoint_deallocate(data->remote_source_addr); + if (data->remote_repair_addr) + (void) roc_endpoint_deallocate(data->remote_repair_addr); + free(data->remote_ip); free(data); } @@ -281,40 +266,24 @@ int res; roc_protocol audio_proto, repair_proto; - if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { - pw_log_error("Invalid local IP address"); - return -EINVAL; - } - - if (roc_address_init(&data->remote_source_addr, ROC_AF_AUTO, data->remote_ip, - data->remote_source_port)) { - pw_log_error("Invalid remote source address"); - return -EINVAL; - } - - if (roc_address_init(&data->remote_repair_addr, ROC_AF_AUTO, data->remote_ip, - data->remote_repair_port)) { - pw_log_error("Invalid remote repair address"); - return -EINVAL; - } - memset(&context_config, 0, sizeof(context_config)); - data->context = roc_context_open(&context_config); - if (!data->context) { - pw_log_error("Failed to create roc context"); + res = roc_context_open(&context_config, &data->context); + if (res) { + pw_log_error("failed to create roc context: %d", res); return -EINVAL; } memset(&sender_config, 0, sizeof(sender_config)); - sender_config.frame_sample_rate = 44100; + sender_config.frame_sample_rate = data->rate; sender_config.frame_channels = ROC_CHANNEL_SET_STEREO; sender_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; - sender_config.fec_code = data->fec_code; + sender_config.fec_encoding = data->fec_code; + + info.rate = data->rate; /* Fixed to be the same as ROC sender config above */ - info.rate = 44100; info.channels = 2; info.format = SPA_AUDIO_FORMAT_F32; info.position0 = SPA_AUDIO_CHANNEL_FL; @@ -322,24 +291,19 @@ pw_properties_setf(data->capture_props, PW_KEY_NODE_RATE, "1/%d", info.rate); - data->sender = roc_sender_open(data->context, &sender_config); - if (!data->sender) { - pw_log_error("Failed to create roc sender"); - return -EINVAL; - } - - if (roc_sender_bind(data->sender, &data->local_addr) != 0) { - pw_log_error("Failed to bind sender to local address"); + res = roc_sender_open(data->context, &sender_config, &data->sender); + if (res) { + pw_log_error("failed to create roc sender: %d", res); return -EINVAL; } switch (data->fec_code) { - case ROC_FEC_DEFAULT: - case ROC_FEC_RS8M: + case ROC_FEC_ENCODING_DEFAULT: + case ROC_FEC_ENCODING_RS8M: audio_proto = ROC_PROTO_RTP_RS8M_SOURCE; repair_proto = ROC_PROTO_RS8M_REPAIR; break; - case ROC_FEC_LDPC_STAIRCASE: + case ROC_FEC_ENCODING_LDPC_STAIRCASE: audio_proto = ROC_PROTO_RTP_LDPC_SOURCE; repair_proto = ROC_PROTO_LDPC_REPAIR; break; @@ -349,15 +313,27 @@ break; } - if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_SOURCE, audio_proto, - &data->remote_source_addr) != 0) { + res = pw_roc_create_endpoint(&data->remote_source_addr, audio_proto, data->remote_ip, data->remote_source_port); + if (res < 0) { + pw_log_warn("failed to create source endpoint: %s", spa_strerror(res)); + return res; + } + + if (roc_sender_connect(data->sender, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_SOURCE, + data->remote_source_addr) != 0) { pw_log_error("can't connect roc sender to remote source address"); return -EINVAL; } if (repair_proto != 0) { - if (roc_sender_connect(data->sender, ROC_PORT_AUDIO_REPAIR, repair_proto, - &data->remote_repair_addr) != 0) { + res = pw_roc_create_endpoint(&data->remote_repair_addr, repair_proto, data->remote_ip, data->remote_repair_port); + if (res < 0) { + pw_log_error("failed to create repair endpoint: %s", spa_strerror(res)); + return res; + } + + if (roc_sender_connect(data->sender, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_REPAIR, + data->remote_repair_addr) != 0) { pw_log_error("can't connect roc sender to remote repair address"); return -EINVAL; } @@ -458,6 +434,10 @@ if ((str = pw_properties_get(capture_props, PW_KEY_MEDIA_CLASS)) == NULL) pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); + data->rate = pw_properties_get_uint32(capture_props, PW_KEY_AUDIO_RATE, data->rate); + if (data->rate == 0) + data->rate = PW_ROC_DEFAULT_RATE; + if ((str = pw_properties_get(props, "remote.ip")) != NULL) { data->remote_ip = strdup(str); pw_properties_set(props, "remote.ip", NULL); @@ -467,37 +447,31 @@ goto out; } - if ((str = pw_properties_get(props, "local.ip")) != NULL) { - data->local_ip = strdup(str); - pw_properties_set(props, "local.ip", NULL); - } else { - data->local_ip = strdup(ROC_DEFAULT_IP); - } - if ((str = pw_properties_get(props, "remote.source.port")) != NULL) { data->remote_source_port = pw_properties_parse_int(str); pw_properties_set(props, "remote.source.port", NULL); } else { - data->remote_source_port = ROC_DEFAULT_SOURCE_PORT; + data->remote_source_port = PW_ROC_DEFAULT_SOURCE_PORT; } if ((str = pw_properties_get(props, "remote.repair.port")) != NULL) { data->remote_repair_port = pw_properties_parse_int(str); pw_properties_set(props, "remote.repair.port", NULL); } else { - data->remote_repair_port = ROC_DEFAULT_REPAIR_PORT; + data->remote_repair_port = PW_ROC_DEFAULT_REPAIR_PORT; } if ((str = pw_properties_get(props, "fec.code")) != NULL) { - if (roc_parse_fec_code(&data->fec_code, str)) { + if (pw_roc_parse_fec_encoding(&data->fec_code, str)) { pw_log_error("Invalid fec code %s, using default", str); - data->fec_code = ROC_FEC_DEFAULT; + data->fec_code = ROC_FEC_ENCODING_DEFAULT; } pw_log_info("using fec.code %s %d", str, data->fec_code); pw_properties_set(props, "fec.code", NULL); } else { - data->fec_code = ROC_FEC_DEFAULT; + data->fec_code = ROC_FEC_ENCODING_DEFAULT; } + data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core); if (data->core == NULL) { str = pw_properties_get(props, PW_KEY_REMOTE_NAME);
View file
pipewire-0.3.63.tar.gz/src/modules/module-roc-source.c -> pipewire-0.3.64.tar.gz/src/modules/module-roc-source.c
Changed
@@ -40,6 +40,8 @@ #include <roc/log.h> #include <roc/receiver.h> +#include "module-roc/common.h" + /** \page page_module_roc_source PipeWire Module: ROC source * * The `roc-source` module creates a PipeWire source that receives samples @@ -95,11 +97,6 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define ROC_DEFAULT_IP "0.0.0.0" -#define ROC_DEFAULT_SOURCE_PORT 10001 -#define ROC_DEFAULT_REPAIR_PORT 10002 -#define ROC_DEFAULT_SESS_LATENCY 200 - struct module_roc_source_data { struct pw_impl_module *module; struct spa_hook module_listener; @@ -117,14 +114,14 @@ unsigned int do_disconnect:1; uint32_t stride; - roc_address local_addr; - roc_address local_source_addr; - roc_address local_repair_addr; + roc_endpoint *local_source_addr; + roc_endpoint *local_repair_addr; roc_context *context; roc_receiver *receiver; roc_resampler_profile resampler_profile; - roc_fec_code fec_code; + roc_fec_encoding fec_code; + uint32_t rate; char *local_ip; int local_source_port; int local_repair_port; @@ -138,38 +135,6 @@ data->playback = NULL; } -static int roc_parse_resampler_profile(roc_resampler_profile *out, const char *str) -{ - if (!str || !*str) - *out = ROC_RESAMPLER_DEFAULT; - else if (spa_streq(str, "disable")) - *out = ROC_RESAMPLER_DISABLE; - else if (spa_streq(str, "high")) - *out = ROC_RESAMPLER_HIGH; - else if (spa_streq(str, "medium")) - *out = ROC_RESAMPLER_MEDIUM; - else if (spa_streq(str, "low")) - *out = ROC_RESAMPLER_LOW; - else - return -EINVAL; - return 0; -} - -static int roc_parse_fec_code(roc_fec_code *out, const char *str) -{ - if (!str || !*str) - *out = ROC_FEC_DEFAULT; - else if (spa_streq(str, "disable")) - *out = ROC_FEC_DISABLE; - else if (spa_streq(str, "rs8m")) - *out = ROC_FEC_RS8M; - else if (spa_streq(str, "ldpc")) - *out = ROC_FEC_LDPC_STAIRCASE; - else - return -EINVAL; - return 0; -} - static void playback_process(void *data) { struct module_roc_source_data *impl = data; @@ -276,6 +241,11 @@ if (data->context) roc_context_close(data->context); + if (data->local_source_addr) + (void) roc_endpoint_deallocate(data->local_source_addr); + if (data->local_repair_addr) + (void) roc_endpoint_deallocate(data->local_repair_addr); + free(data->local_ip); free(data); } @@ -304,38 +274,22 @@ int res; roc_protocol audio_proto, repair_proto; - if (roc_address_init(&data->local_addr, ROC_AF_AUTO, data->local_ip, 0)) { - pw_log_error("Invalid local IP address"); - return -EINVAL; - } - - if (roc_address_init(&data->local_source_addr, ROC_AF_AUTO, data->local_ip, - data->local_source_port)) { - pw_log_error("Invalid local source address"); - return -EINVAL; - } - - if (roc_address_init(&data->local_repair_addr, ROC_AF_AUTO, data->local_ip, - data->local_repair_port)) { - pw_log_error("Invalid local repair address"); - return -EINVAL; - } - spa_zero(context_config); - data->context = roc_context_open(&context_config); - if (!data->context) { - pw_log_error("Failed to create roc context"); + res = roc_context_open(&context_config, &data->context); + if (res) { + pw_log_error("failed to create roc context: %d", res); return -EINVAL; } spa_zero(receiver_config); - receiver_config.frame_sample_rate = 44100; + receiver_config.frame_sample_rate = data->rate; receiver_config.frame_channels = ROC_CHANNEL_SET_STEREO; receiver_config.frame_encoding = ROC_FRAME_ENCODING_PCM_FLOAT; receiver_config.resampler_profile = data->resampler_profile; + info.rate = data->rate; + /* Fixed to be the same as ROC receiver config above */ - info.rate = 44100; info.channels = 2; info.format = SPA_AUDIO_FORMAT_F32; info.position0 = SPA_AUDIO_CHANNEL_FL; @@ -357,19 +311,19 @@ */ receiver_config.target_latency = data->sess_latency_msec * 1000000; - data->receiver = roc_receiver_open(data->context, &receiver_config); - if (!data->receiver) { - pw_log_error("Failed to create roc receiver"); + res = roc_receiver_open(data->context, &receiver_config, &data->receiver); + if (res) { + pw_log_error("failed to create roc receiver: %d", res); return -EINVAL; } switch (data->fec_code) { - case ROC_FEC_DEFAULT: - case ROC_FEC_RS8M: + case ROC_FEC_ENCODING_DEFAULT: + case ROC_FEC_ENCODING_RS8M: audio_proto = ROC_PROTO_RTP_RS8M_SOURCE; repair_proto = ROC_PROTO_RS8M_REPAIR; break; - case ROC_FEC_LDPC_STAIRCASE: + case ROC_FEC_ENCODING_LDPC_STAIRCASE: audio_proto = ROC_PROTO_RTP_LDPC_SOURCE; repair_proto = ROC_PROTO_LDPC_REPAIR; break; @@ -379,14 +333,27 @@ break; } - if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_SOURCE, audio_proto, - &data->local_source_addr) != 0) { + res = pw_roc_create_endpoint(&data->local_source_addr, audio_proto, data->local_ip, data->local_source_port); + if (res < 0) { + pw_log_error("failed to create source endpoint: %s", spa_strerror(res)); + return res; + } + + if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_SOURCE, + data->local_source_addr) != 0) { pw_log_error("can't connect roc receiver to local source address"); return -EINVAL; } + if (repair_proto != 0) { - if (roc_receiver_bind(data->receiver, ROC_PORT_AUDIO_REPAIR, repair_proto, - &data->local_repair_addr) != 0) { + res = pw_roc_create_endpoint(&data->local_repair_addr, repair_proto, data->local_ip, data->local_repair_port); + if (res < 0) { + pw_log_error("failed to create repair endpoint: %s", spa_strerror(res)); + return res; + } + + if (roc_receiver_bind(data->receiver, ROC_SLOT_DEFAULT, ROC_INTERFACE_AUDIO_REPAIR, + data->local_repair_addr) != 0) { pw_log_error("can't connect roc receiver to local repair address"); return -EINVAL; } @@ -487,51 +454,55 @@ if (pw_properties_get(playback_props, PW_KEY_NODE_NETWORK) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_NETWORK, "true"); + data->rate = pw_properties_get_uint32(playback_props, PW_KEY_AUDIO_RATE, data->rate); + if (data->rate == 0) + data->rate = PW_ROC_DEFAULT_RATE; + if ((str = pw_properties_get(props, "local.ip")) != NULL) { data->local_ip = strdup(str); pw_properties_set(props, "local.ip", NULL); } else { - data->local_ip = strdup(ROC_DEFAULT_IP); + data->local_ip = strdup(PW_ROC_DEFAULT_IP); } if ((str = pw_properties_get(props, "local.source.port")) != NULL) { data->local_source_port = pw_properties_parse_int(str); pw_properties_set(props, "local.source.port", NULL); } else { - data->local_source_port = ROC_DEFAULT_SOURCE_PORT; + data->local_source_port = PW_ROC_DEFAULT_SOURCE_PORT; } if ((str = pw_properties_get(props, "local.repair.port")) != NULL) { data->local_repair_port = pw_properties_parse_int(str); pw_properties_set(props, "local.repair.port", NULL); } else { - data->local_repair_port = ROC_DEFAULT_REPAIR_PORT; + data->local_repair_port = PW_ROC_DEFAULT_REPAIR_PORT; } if ((str = pw_properties_get(props, "sess.latency.msec")) != NULL) { data->sess_latency_msec = pw_properties_parse_int(str); pw_properties_set(props, "sess.latency.msec", NULL); } else { - data->sess_latency_msec = ROC_DEFAULT_SESS_LATENCY; + data->sess_latency_msec = PW_ROC_DEFAULT_SESS_LATENCY; } if ((str = pw_properties_get(props, "resampler.profile")) != NULL) { - if (roc_parse_resampler_profile(&data->resampler_profile, str)) { + if (pw_roc_parse_resampler_profile(&data->resampler_profile, str)) { pw_log_warn("Invalid resampler profile %s, using default", str); - data->resampler_profile = ROC_RESAMPLER_DEFAULT; + data->resampler_profile = ROC_RESAMPLER_PROFILE_DEFAULT; } pw_properties_set(props, "resampler.profile", NULL); } else { - data->resampler_profile = ROC_RESAMPLER_DEFAULT; + data->resampler_profile = ROC_RESAMPLER_PROFILE_DEFAULT; } if ((str = pw_properties_get(props, "fec.code")) != NULL) { - if (roc_parse_fec_code(&data->fec_code, str)) { + if (pw_roc_parse_fec_encoding(&data->fec_code, str)) { pw_log_error("Invalid fec code %s, using default", str); - data->fec_code = ROC_FEC_DEFAULT; + data->fec_code = ROC_FEC_ENCODING_DEFAULT; } pw_properties_set(props, "fec.code", NULL); } else { - data->fec_code = ROC_FEC_DEFAULT; + data->fec_code = ROC_FEC_ENCODING_DEFAULT; } data->core = pw_context_get_object(data->module_context, PW_TYPE_INTERFACE_Core);
View file
pipewire-0.3.64.tar.gz/src/modules/module-roc/common.h
Added
@@ -0,0 +1,71 @@ +#ifndef MODULE_ROC_COMMON_H +#define MODULE_ROC_COMMON_H + +#include <roc/config.h> +#include <roc/endpoint.h> + +#include <spa/utils/string.h> + +#define PW_ROC_DEFAULT_IP "0.0.0.0" +#define PW_ROC_DEFAULT_SOURCE_PORT 10001 +#define PW_ROC_DEFAULT_REPAIR_PORT 10002 +#define PW_ROC_DEFAULT_SESS_LATENCY 200 +#define PW_ROC_DEFAULT_RATE 44100 + +static inline int pw_roc_parse_fec_encoding(roc_fec_encoding *out, const char *str) +{ + if (!str || !*str) + *out = ROC_FEC_ENCODING_DEFAULT; + else if (spa_streq(str, "disable")) + *out = ROC_FEC_ENCODING_DISABLE; + else if (spa_streq(str, "rs8m")) + *out = ROC_FEC_ENCODING_RS8M; + else if (spa_streq(str, "ldpc")) + *out = ROC_FEC_ENCODING_LDPC_STAIRCASE; + else + return -EINVAL; + return 0; +} + +static inline int pw_roc_parse_resampler_profile(roc_resampler_profile *out, const char *str) +{ + if (!str || !*str) + *out = ROC_RESAMPLER_PROFILE_DEFAULT; + else if (spa_streq(str, "disable")) + *out = ROC_RESAMPLER_PROFILE_DISABLE; + else if (spa_streq(str, "high")) + *out = ROC_RESAMPLER_PROFILE_HIGH; + else if (spa_streq(str, "medium")) + *out = ROC_RESAMPLER_PROFILE_MEDIUM; + else if (spa_streq(str, "low")) + *out = ROC_RESAMPLER_PROFILE_LOW; + else + return -EINVAL; + return 0; +} + +static inline int pw_roc_create_endpoint(roc_endpoint **result, roc_protocol protocol, const char *ip, int port) +{ + roc_endpoint *endpoint; + + if (roc_endpoint_allocate(&endpoint)) + return -ENOMEM; + + if (roc_endpoint_set_protocol(endpoint, protocol)) + goto out_error_free_ep; + + if (roc_endpoint_set_host(endpoint, ip)) + goto out_error_free_ep; + + if (roc_endpoint_set_port(endpoint, port)) + goto out_error_free_ep; + + *result = endpoint; + return 0; + +out_error_free_ep: + (void) roc_endpoint_deallocate(endpoint); + return -EINVAL; +} + +#endif /* MODULE_ROC_COMMON_H */
View file
pipewire-0.3.63.tar.gz/src/modules/module-rt.c -> pipewire-0.3.64.tar.gz/src/modules/module-rt.c
Changed
@@ -269,20 +269,12 @@ bool pw_rtkit_check_xdg_portal(struct pw_rtkit_bus *system_bus) { - DBusError error; - bool ret = true; - - dbus_error_init(&error); - - if (!dbus_bus_name_has_owner(system_bus->bus, XDG_PORTAL_SERVICE_NAME, &error)) { - pw_log_warn("Can't find xdg-portal: %s", error.name); - ret = false; - goto finish; + if (!dbus_bus_name_has_owner(system_bus->bus, XDG_PORTAL_SERVICE_NAME, NULL)) { + pw_log_warn("Can't find %s. Is xdg-desktop-portal running?", XDG_PORTAL_SERVICE_NAME); + return false; } -finish: - dbus_error_free(&error); - return ret; + return true; } void pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus)
View file
pipewire-0.3.63.tar.gz/src/modules/module-rtp-source.c -> pipewire-0.3.64.tar.gz/src/modules/module-rtp-source.c
Changed
@@ -272,7 +272,7 @@ if (sess->rate_match) { SPA_FLAG_SET(sess->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE); - sess->rate_match->rate = corr; + sess->rate_match->rate = 1.0f / corr; } } spa_ringbuffer_read_data(&sess->ring,
View file
pipewire-0.3.63.tar.gz/src/modules/module-zeroconf-discover.c -> pipewire-0.3.64.tar.gz/src/modules/module-zeroconf-discover.c
Changed
@@ -195,7 +195,7 @@ struct pw_properties *props) { if (spa_streq(key, "device")) { - pw_properties_set(props, PW_KEY_NODE_TARGET, value); + pw_properties_set(props, PW_KEY_TARGET_OBJECT, value); } else if (spa_streq(key, "rate")) { pw_properties_set(props, PW_KEY_AUDIO_RATE, value); @@ -307,7 +307,7 @@ avahi_free(value); } - if ((device = pw_properties_get(props, PW_KEY_NODE_TARGET)) != NULL) + if ((device = pw_properties_get(props, PW_KEY_TARGET_OBJECT)) != NULL) pw_properties_setf(props, PW_KEY_NODE_NAME, "tunnel.%s.%s", host_name, device); else @@ -330,7 +330,7 @@ if (desc == NULL) desc = pw_properties_get(props, PW_KEY_DEVICE_PRODUCT_NAME); if (desc == NULL) - desc = pw_properties_get(props, PW_KEY_NODE_TARGET); + desc = pw_properties_get(props, PW_KEY_TARGET_OBJECT); if (desc == NULL) desc = _("Unknown device");
View file
pipewire-0.3.63.tar.gz/src/pipewire/context.c -> pipewire-0.3.64.tar.gz/src/pipewire/context.c
Changed
@@ -917,7 +917,7 @@ *limit = s->clock_quantum_limit; } -static inline uint32_t *get_rates(struct pw_context *context, uint32_t *def, uint32_t *n_rates, +static inline const uint32_t *get_rates(struct pw_context *context, uint32_t *def, uint32_t *n_rates, bool *force) { struct settings *s = &context->settings; @@ -933,7 +933,7 @@ return s->clock_rates; } } -static void suspend_driver(struct pw_context *context, struct pw_impl_node *n) +static void reconfigure_driver(struct pw_context *context, struct pw_impl_node *n) { struct pw_impl_node *s; @@ -946,6 +946,9 @@ } pw_log_debug("%p: driver %p: '%s' suspend", context, n, n->name); + + if (n->info.state >= PW_NODE_STATE_IDLE) + n->reconfigure = true; pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED); } @@ -968,7 +971,7 @@ return fa < fb ? -1 : (fa > fb ? 1 : 0); } -static uint32_t find_best_rate(uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best) +static uint32_t find_best_rate(const uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best) { uint32_t i; for (i = 0; i < n_rates; i++) { @@ -1002,9 +1005,10 @@ struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this); struct settings *settings = &context->settings; struct pw_impl_node *n, *s, *target, *fallback; + const uint32_t *rates; uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum; - uint32_t *rates, n_rates, def_rate; - bool freewheel = false, global_force_rate, force_rate, force_quantum, global_force_quantum; + uint32_t n_rates, def_rate; + bool freewheel = false, global_force_rate, global_force_quantum; struct spa_list collect; pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason); @@ -1020,8 +1024,7 @@ get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum); rates = get_rates(context, &def_rate, &n_rates, &global_force_rate); - force_quantum = global_force_quantum = rate_quantum == 0; - force_rate = global_force_rate; + global_force_quantum = rate_quantum == 0; /* start from all drivers and group all nodes that are linked * to it. Some nodes are not (yet) linked to anything and they @@ -1118,10 +1121,25 @@ struct spa_fraction rate = SPA_FRACTION(0, 0); uint32_t quantum, target_rate, current_rate; uint64_t quantum_stamp = 0, rate_stamp = 0; + bool force_rate, force_quantum; + const uint32_t *node_rates; + uint32_t node_n_rates, node_def_rate; + uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum; if (!n->driving || n->exported) continue; + node_def_quantum = def_quantum; + node_min_quantum = min_quantum; + node_max_quantum = max_quantum; + node_rate_quantum = rate_quantum; + force_quantum = global_force_quantum; + + node_def_rate = def_rate; + node_n_rates = n_rates; + node_rates = rates; + force_rate = global_force_rate; + /* collect quantum and rate */ spa_list_for_each(s, &n->follower_list, follower_link) { @@ -1135,17 +1153,17 @@ } if (!global_force_quantum && s->force_quantum > 0 && s->stamp > quantum_stamp) { - def_quantum = min_quantum = max_quantum = s->force_quantum; - rate_quantum = 0; + node_def_quantum = node_min_quantum = node_max_quantum = s->force_quantum; + node_rate_quantum = 0; quantum_stamp = s->stamp; force_quantum = true; } if (!global_force_rate && s->force_rate > 0 && s->stamp > rate_stamp) { - def_rate = s->force_rate; + node_def_rate = s->force_rate; + node_n_rates = 1; + node_rates = &s->force_rate; force_rate = true; - n_rates = 1; - rates = &s->force_rate; rate_stamp = s->stamp; } @@ -1180,8 +1198,11 @@ if (force_rate) lock_rate = false; + if (n->reconfigure) + running = true; + current_rate = n->current_rate.denom; - if (lock_rate || + if (lock_rate || n->reconfigure || (!force_rate && (n->info.state > PW_NODE_STATE_IDLE))) /* when someone wants us to lock the rate of this driver or @@ -1192,14 +1213,14 @@ /* Here we are allowed to change the rate of the driver. * Start with the default rate. If the desired rate is * allowed, switch to it */ - target_rate = def_rate; + target_rate = node_def_rate; if (rate.denom != 0 && rate.num == 1) - target_rate = find_best_rate(rates, n_rates, + target_rate = find_best_rate(node_rates, node_n_rates, rate.denom, target_rate); } if (target_rate != current_rate) { - bool do_suspend = false; + bool do_reconfigure = false; /* we doing a rate switch */ pw_log_info("(%s-%u) state:%s new rate:%u->%u", n->name, n->info.id, @@ -1209,41 +1230,42 @@ if (force_rate) { if (settings->clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD) - do_suspend = true; + do_reconfigure = true; } else { if (n->info.state >= PW_NODE_STATE_SUSPENDED) - do_suspend = true; + do_reconfigure = true; } - if (do_suspend) - suspend_driver(context, n); + if (do_reconfigure) + reconfigure_driver(context, n); + /* we're setting the pending rate. This will become the new * current rate in the next iteration of the graph. */ n->current_rate = SPA_FRACTION(1, target_rate); n->current_pending = true; current_rate = target_rate; /* we might be suspended now and the links need to be prepared again */ - if (do_suspend) + if (do_reconfigure) goto again; } - if (rate_quantum != 0 && current_rate != rate_quantum) { + if (node_rate_quantum != 0 && current_rate != node_rate_quantum) { /* the quantum values are scaled with the current rate */ - def_quantum = def_quantum * current_rate / rate_quantum; - min_quantum = min_quantum * current_rate / rate_quantum; - max_quantum = max_quantum * current_rate / rate_quantum; + node_def_quantum = node_def_quantum * current_rate / node_rate_quantum; + node_min_quantum = node_min_quantum * current_rate / node_rate_quantum; + node_max_quantum = node_max_quantum * current_rate / node_rate_quantum; } /* calculate desired quantum */ if (max_latency.denom != 0) { uint32_t tmp = (max_latency.num * current_rate / max_latency.denom); - if (tmp < max_quantum) - max_quantum = tmp; + if (tmp < node_max_quantum) + node_max_quantum = tmp; } - quantum = def_quantum; + quantum = node_def_quantum; if (latency.denom != 0) quantum = (latency.num * current_rate / latency.denom); - quantum = SPA_CLAMP(quantum, min_quantum, max_quantum); + quantum = SPA_CLAMP(quantum, node_min_quantum, node_max_quantum); quantum = SPA_MIN(quantum, lim_quantum); if (settings->clock_power_of_two_quantum) @@ -1261,7 +1283,7 @@ if (n->info.state < PW_NODE_STATE_RUNNING && n->current_pending) { /* the driver node is not actually running and we have a - * panding change. Apply the change to the position now so + * pending change. Apply the change to the position now so * that we have the right values when we change the node * states of the driver and followers to RUNNING below */ pw_log_debug("%p: apply duration:%"PRIu64" rate:%u/%u", context,
View file
pipewire-0.3.63.tar.gz/src/pipewire/filter.c -> pipewire-0.3.64.tar.gz/src/pipewire/filter.c
Changed
@@ -885,16 +885,19 @@ pw_log_debug("%p: port:%d.%d buffers:%u disconnecting:%d", impl, direction, port_id, n_buffers, impl->disconnecting); + if ((port = get_port(impl, direction, port_id)) == NULL) + return -EINVAL; + if (impl->disconnecting && n_buffers > 0) return -EIO; - if ((port = get_port(impl, direction, port_id)) == NULL) - return -EINVAL; + clear_buffers(port); impl_flags = port->flags; prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0); - clear_buffers(port); + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; for (i = 0; i < n_buffers; i++) { int buf_size = 0;
View file
pipewire-0.3.63.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.64.tar.gz/src/pipewire/impl-node.c
Changed
@@ -59,8 +59,6 @@ struct spa_list param_list; struct spa_list pending_list; - unsigned int pause_on_idle:1; - unsigned int suspend_on_idle:1; unsigned int cache_params:1; unsigned int pending_play:1; }; @@ -221,12 +219,12 @@ pw_log_debug("%p: idle node state:%s pending:%s pause-on-idle:%d", this, pw_node_state_as_string(this->info.state), pw_node_state_as_string(impl->pending_state), - impl->pause_on_idle); + this->pause_on_idle); if (impl->pending_state <= PW_NODE_STATE_IDLE) return 0; - if (!impl->pause_on_idle) + if (!this->pause_on_idle) return 0; node_deactivate(this); @@ -385,7 +383,7 @@ case PW_NODE_STATE_IDLE: case PW_NODE_STATE_SUSPENDED: case PW_NODE_STATE_ERROR: - if (state != PW_NODE_STATE_IDLE || impl->pause_on_idle) + if (state != PW_NODE_STATE_IDLE || node->pause_on_idle) pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node); break; default: @@ -420,10 +418,19 @@ spa_list_for_each(resource, &node->global->resource_list, link) pw_resource_error(resource, res, error); } + if (node->reconfigure) { + if (state == PW_NODE_STATE_SUSPENDED && + node->pause_on_idle) { + node->reconfigure = false; + } + if (state == PW_NODE_STATE_RUNNING) + node->reconfigure = false; + } if (old == PW_NODE_STATE_RUNNING && state == PW_NODE_STATE_IDLE && - impl->suspend_on_idle) - pw_impl_node_set_state(node, PW_NODE_STATE_SUSPENDED); + node->suspend_on_idle) { + pw_impl_node_set_state(node, PW_NODE_STATE_SUSPENDED); + } } static int suspend_node(struct pw_impl_node *this) @@ -917,10 +924,10 @@ pw_log_debug("%p: name '%s'", node, node->name); } - impl->pause_on_idle = pw_properties_get_bool(node->properties, PW_KEY_NODE_PAUSE_ON_IDLE, true); - impl->suspend_on_idle = pw_properties_get_bool(node->properties, PW_KEY_NODE_SUSPEND_ON_IDLE, false); - impl->cache_params = pw_properties_get_bool(node->properties, PW_KEY_NODE_CACHE_PARAMS, true); + node->pause_on_idle = pw_properties_get_bool(node->properties, PW_KEY_NODE_PAUSE_ON_IDLE, true); + node->suspend_on_idle = pw_properties_get_bool(node->properties, PW_KEY_NODE_SUSPEND_ON_IDLE, false); node->transport_sync = pw_properties_get_bool(node->properties, PW_KEY_NODE_TRANSPORT_SYNC, false); + impl->cache_params = pw_properties_get_bool(node->properties, PW_KEY_NODE_CACHE_PARAMS, true); driver = pw_properties_get_bool(node->properties, PW_KEY_NODE_DRIVER, false); if (node->driver != driver) { @@ -2215,7 +2222,7 @@ pw_node_state_as_string(old), pw_node_state_as_string(state), node->active, - impl->pause_on_idle); + node->pause_on_idle); if (old != state) pw_impl_node_emit_state_request(node, state);
View file
pipewire-0.3.63.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.64.tar.gz/src/pipewire/impl-port.c
Changed
@@ -1473,6 +1473,12 @@ port->added = false; } /* setting the format always destroys the negotiated buffers */ + if (port->direction == PW_DIRECTION_OUTPUT) { + struct pw_impl_link *l; + /* remove all buffers shared with an output port peer */ + spa_list_for_each(l, &port->links, output_link) + pw_impl_port_use_buffers(l->input, &l->rt.in_mix, 0, NULL, 0); + } pw_buffers_clear(&port->buffers); pw_buffers_clear(&port->mix_buffers); @@ -1567,6 +1573,7 @@ return -EIO; if (n_buffers == 0) { + mix->have_buffers = false; if (port->n_mix == 1) pw_impl_port_update_state(port, PW_IMPL_PORT_STATE_READY, 0, NULL); }
View file
pipewire-0.3.63.tar.gz/src/pipewire/keys.h -> pipewire-0.3.64.tar.gz/src/pipewire/keys.h
Changed
@@ -155,8 +155,6 @@ #define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ #define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected * to a compatible node */ -#define PW_KEY_NODE_TARGET "node.target" /**< node wants to be connected to the target - * node/session */ #define PW_KEY_NODE_LATENCY "node.latency" /**< the requested latency of the node as * a fraction. Ex: 128/48000 */ #define PW_KEY_NODE_MAX_LATENCY "node.max-latency" /**< the maximum supported latency of the @@ -173,9 +171,9 @@ * active */ #define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node. The node is - * initially linked to node.target or - * target.object or the default node. If the - * targets is removed, the node is destroyed */ + * initially linked to target.object or the + * default node. If the target is removed, + * the node is destroyed */ #define PW_KEY_NODE_ALWAYS_PROCESS "node.always-process" /**< process even when unlinked */ #define PW_KEY_NODE_WANT_DRIVER "node.want-driver" /**< the node wants to be grouped with a driver * node in order to schedule the graph. */ @@ -197,6 +195,8 @@ #define PW_KEY_NODE_TRIGGER "node.trigger" /**< the node is not scheduled automatically * based on the dependencies in the graph * but it will be triggered explicitly. */ +#define PW_KEY_NODE_CHANNELNAMES "node.channel-names" /**< names of node's + * channels (unrelated to positions) */ /** Port keys */ #define PW_KEY_PORT_ID "port.id" /**< port id */ @@ -336,9 +336,11 @@ #ifdef PW_ENABLE_DEPRECATED #define PW_KEY_PRIORITY_MASTER "priority.master" /**< deprecated */ +#define PW_KEY_NODE_TARGET "node.target" /**< deprecated since 0.3.64, use target.object. */ #endif /* PW_ENABLE_DEPRECATED */ -#define PW_KEY_TARGET_OBJECT "target.object" /**< a target object to link to */ +#define PW_KEY_TARGET_OBJECT "target.object" /**< a target object to link to. This can be + * and object name or object.serial */ /** \} */
View file
pipewire-0.3.63.tar.gz/src/pipewire/pipewire.c -> pipewire-0.3.64.tar.gz/src/pipewire/pipewire.c
Changed
@@ -530,7 +530,7 @@ if (!str || (slen = strlen(str)) == 0) return NULL; - /* String format is PIPEWIRE_DEBUG=<glob>:<level>,<glob>:<level>,..., + /* String format is PIPEWIRE_DEBUG=<glob>:<level>,..., * converted into { conn.* = 0}, {glob = level}, {glob = level}, .... , * with the connection namespace disabled by default. */
View file
pipewire-0.3.63.tar.gz/src/pipewire/private.h -> pipewire-0.3.64.tar.gz/src/pipewire/private.h
Changed
@@ -719,6 +719,9 @@ unsigned int current_pending:1; /**< a quantum/rate update is pending */ unsigned int moved:1; /**< the node was moved drivers */ unsigned int added:1; /**< the node was add to graph */ + unsigned int pause_on_idle:1; /**< Pause processing when IDLE */ + unsigned int suspend_on_idle:1; + unsigned int reconfigure:1; uint32_t port_user_data_size; /**< extra size for port user data */
View file
pipewire-0.3.63.tar.gz/src/pipewire/stream.c -> pipewire-0.3.64.tar.gz/src/pipewire/stream.c
Changed
@@ -39,6 +39,8 @@ #include <spa/debug/types.h> #include <spa/debug/pod.h> +#define PW_ENABLE_DEPRECATED + #include "pipewire/pipewire.h" #include "pipewire/stream.h" #include "pipewire/private.h" @@ -922,13 +924,13 @@ if (impl->disconnecting && n_buffers > 0) return -EIO; - if (n_buffers > MAX_BUFFERS) - return -EINVAL; - prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0); clear_buffers(stream); + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + for (i = 0; i < n_buffers; i++) { int buf_size = 0; struct buffer *b = &impl->buffersi; @@ -1890,9 +1892,10 @@ stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL); if (target_id != PW_ID_ANY) + /* XXX this is deprecated but still used by the portal and its apps */ pw_properties_setf(stream->properties, PW_KEY_NODE_TARGET, "%d", target_id); else if ((str = getenv("PIPEWIRE_NODE")) != NULL) - pw_properties_set(stream->properties, PW_KEY_NODE_TARGET, str); + pw_properties_set(stream->properties, PW_KEY_TARGET_OBJECT, str); if ((flags & PW_STREAM_FLAG_AUTOCONNECT) && pw_properties_get(stream->properties, PW_KEY_NODE_AUTOCONNECT) == NULL) { str = getenv("PIPEWIRE_AUTOCONNECT");
View file
pipewire-0.3.63.tar.gz/src/pipewire/stream.h -> pipewire-0.3.64.tar.gz/src/pipewire/stream.h
Changed
@@ -85,8 +85,9 @@ * \subsection ssec_stream_target Stream target * * To make the newly connected stream automatically connect to an existing - * PipeWire node, use the \ref PW_STREAM_FLAG_AUTOCONNECT and the port_path - * argument while connecting. + * PipeWire node, use the \ref PW_STREAM_FLAG_AUTOCONNECT and set the + * PW_KEY_OBJECT_SERIAL or the PW_KEY_NODE_NAME value of the target node + * in the PW_KEY_TARGET_OBJECT property before connecting. * * \subsection ssec_stream_formats Stream formats *
View file
pipewire-0.3.63.tar.gz/src/tools/midifile.c -> pipewire-0.3.64.tar.gz/src/tools/midifile.c
Changed
@@ -118,6 +118,9 @@ track->size = parse_be32(mf->p + 4); mf->p = track->data + track->size; + if (mf->p > mf->data + mf->size) + return -EINVAL; + return 0; }
View file
pipewire-0.3.63.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.64.tar.gz/src/tools/pw-cat.c
Changed
@@ -790,7 +790,7 @@ " --media-type Set media type (default %s)\n" " --media-category Set media category (default %s)\n" " --media-role Set media role (default %s)\n" - " --target Set node target (default %s)\n" + " --target Set node target serial or name (default %s)\n" " 0 means don't link\n" " --latency Set node latency (default %s)\n" " Xunit (unit = s, ms, us, ns)\n"
View file
pipewire-0.3.63.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.64.tar.gz/src/tools/pw-dump.c
Changed
@@ -322,6 +322,7 @@ static void put_dict(struct data *d, const char *key, struct spa_dict *dict) { const struct spa_dict_item *it; + spa_dict_qsort(dict); put_begin(d, key, "{", 0); spa_dict_for_each(it, dict) put_value(d, it->key, it->value);
View file
pipewire-0.3.63.tar.gz/src/tools/pw-loopback.c -> pipewire-0.3.64.tar.gz/src/tools/pw-loopback.c
Changed
@@ -95,9 +95,9 @@ " -m, --channel-map Channel map (default '%s')\n" " -l, --latency Desired latency in ms\n" " -d, --delay Desired delay in float s\n" - " -C --capture Capture source to connect to\n" + " -C --capture Capture source to connect to (name or serial)\n" " --capture-props Capture stream properties\n" - " -P --playback Playback sink to connect to\n" + " -P --playback Playback sink to connect to (name or serial)\n" " --playback-props Playback stream properties\n", name, data->opt_node_name, @@ -184,10 +184,10 @@ data.delay = atof(optarg); break; case 'C': - pw_properties_set(data.capture_props, PW_KEY_NODE_TARGET, optarg); + pw_properties_set(data.capture_props, PW_KEY_TARGET_OBJECT, optarg); break; case 'P': - pw_properties_set(data.playback_props, PW_KEY_NODE_TARGET, optarg); + pw_properties_set(data.playback_props, PW_KEY_TARGET_OBJECT, optarg); break; case 'i': pw_properties_update_string(data.capture_props, optarg, strlen(optarg));
View file
pipewire-0.3.63.tar.gz/src/tools/pw-reserve.c -> pipewire-0.3.64.tar.gz/src/tools/pw-reserve.c
Changed
@@ -214,21 +214,28 @@ if (!opt_monitor) { res = rd_device_acquire(impl.device); if (res == -EBUSY) { - printf("device %s is busy, use -r to attempt to release\n", opt_name); + printf("device %s is busy\n", opt_name); if (opt_release) { printf("doing RequestRelease on %s\n", opt_name); res = rd_device_request_release(impl.device); + } else { + printf("use -r to attempt to release\n"); } - } else { + } else if (res < 0) { printf("Device %s can not be acquired: %s\n", opt_name, spa_strerror(res)); } } - pw_main_loop_run(impl.mainloop); + if (res >= 0) + pw_main_loop_run(impl.mainloop); - if (!opt_monitor) - rd_device_release(impl.device); + if (!opt_monitor) { + if (opt_release) { + printf("doing Release on %s\n", opt_name); + rd_device_release(impl.device); + } + } exit: if (impl.conn)
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
.