Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 58
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Mon Sep 15 15:03:26 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.4.8 + +------------------------------------------------------------------- Thu Aug 7 08:53:42 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.4.7
View file
pipewire-aptx.spec
Changed
@@ -8,7 +8,7 @@ %define minimum_version 1.4.0 Name: pipewire-aptx -Version: 1.4.7 +Version: 1.4.8 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
_service
Changed
@@ -2,6 +2,6 @@ <service name="download_url"> <param name="host">gitlab.freedesktop.org</param> <param name="protocol">https</param> - <param name="path">/pipewire/pipewire/-/archive/1.4.7/pipewire-1.4.7.tar.bz2</param> + <param name="path">/pipewire/pipewire/-/archive/1.4.8/pipewire-1.4.8.tar.bz2</param> </service> </services> \ No newline at end of file
View file
_service:download_url:pipewire-1.4.7.tar.bz2/NEWS -> _service:download_url:pipewire-1.4.8.tar.bz2/NEWS
Changed
@@ -1,3 +1,50 @@ +# PipeWire 1.4.8 (2025-09-11) + +This is a bugfix release that is API and ABI compatible with +previous 1.x releases. + +## Highlights + - Low latency for Firewire devices using the ALSA drivers. + - Fix potential wrong pointers in memory mappings. + - Improve compatibility with Apple Home Pod Minis. + - JACK now implements the rename_callback. + - Various improvements and bug fixes. + + +## PipeWire + - Make sure we can only queue buffers that were previously dequeued, + to avoid some API misuse. + - Fix potential wrong pointers in memory mappings. (#4884) + - Improve the node unprepare function. (#4840) + +## Modules + - Add fp_sap25 encryption to the ROAP module for compatibility with + Apple Home Pod Minis. + - Write a correct ALAC end tag in RAOP. (#4853) + - Avoid VBAN problems with too long session names. + - Fix a potential crash in the link-factory. (#4691) + +## SPA + - Show correct values in the ALSA api.alsa.period-num property. + - Add better support for Razer BlackShark v3. + - Use only 3 periods in ALSA when in Pro-Audio mode. This gives + better latency on some drivers. Also set the period count before + the period size for improved compatibility. (#4785) + - Force IRQ mode for firewire devices in pro-audio mode even if + there are multiple capture and playback devices. + - Add a new flag in the sync_timeline metadata to track if a + release_point will be signaled or not. (#4885) + +## JACK + - Support the rename_callback. (#4761) + +## Tools + - Fix the -C option in pw-dump. + - Log more info from sndfile when opening a file failed. + + +Older versions: + # PipeWire 1.4.7 (2025-07-23) This is a bugfix release that is API and ABI compatible with @@ -29,7 +76,6 @@ ## GStreamer - Add some format validations. - # PipeWire 1.4.6 (2025-06-27) This is a bugfix release that is API and ABI compatible with @@ -61,9 +107,6 @@ ## GStreamer - Fix a refcount issue in the device provider. - -Older versions: - # PipeWire 1.4.5 (2025-06-04) This is a quick bugfix release that is API and ABI compatible with
View file
_service:download_url:pipewire-1.4.7.tar.bz2/meson.build -> _service:download_url:pipewire-1.4.8.tar.bz2/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '1.4.7', + version : '1.4.8', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3',
View file
_service:download_url:pipewire-1.4.7.tar.bz2/pipewire-jack/src/pipewire-jack.c -> _service:download_url:pipewire-1.4.8.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
@@ -102,6 +102,7 @@ #define NOTIFY_TYPE_SHUTDOWN ((7<<4)|NOTIFY_ACTIVE_FLAG) #define NOTIFY_TYPE_LATENCY ((8<<4)|NOTIFY_ACTIVE_FLAG) #define NOTIFY_TYPE_TOTAL_LATENCY ((9<<4)|NOTIFY_ACTIVE_FLAG) +#define NOTIFY_TYPE_PORT_RENAME ((10<<4)|NOTIFY_ACTIVE_FLAG) int type; struct object *object; int arg1; @@ -171,6 +172,7 @@ } port_link; struct { unsigned long flags; + char old_nameREAL_JACK_PORT_NAME_SIZE+1; char nameREAL_JACK_PORT_NAME_SIZE+1; char alias1REAL_JACK_PORT_NAME_SIZE+1; char alias2REAL_JACK_PORT_NAME_SIZE+1; @@ -1083,6 +1085,16 @@ notify->arg1, c->portregistration_arg); break; + case NOTIFY_TYPE_PORT_RENAME: + if (o->registered != notify->arg1) + break; + pw_log_debug("%p: port rename %u %s->%s", c, o->serial, + o->port.old_name, o->port.name); + do_callback(c, rename_callback, c->active, + o->serial, + o->port.old_name, o->port.name, + c->rename_arg); + break; case NOTIFY_TYPE_CONNECT: if (o->registered == notify->arg1) break; @@ -1183,6 +1195,9 @@ emit = c->portregistration_callback != NULL && o != NULL; o->visible = arg1; break; + case NOTIFY_TYPE_PORT_RENAME: + emit = c->rename_callback != NULL && o != NULL; + break; case NOTIFY_TYPE_CONNECT: emit = c->connect_callback != NULL && o != NULL; break; @@ -3674,6 +3689,67 @@ .info = node_info, }; +#define FILTER_NAME " ().:*$" +#define FILTER_PORT " ().*$" + +static void filter_name(char *str, const char *filter, char filter_char) +{ + char *p; + for (p = str; *p; p++) { + if (strchr(filter, *p) != NULL) + *p = filter_char; + } +} + +static int update_port_name(struct object *o, const char *name) +{ + struct object *ot = o->port.node, *op; + struct client *c = o->client; + char tmpREAL_JACK_PORT_NAME_SIZE+1; + char port_nameREAL_JACK_PORT_NAME_SIZE+1; + + if (o->port.is_monitor && !c->merge_monitor) + snprintf(tmp, sizeof(tmp), "%.*s%s:%s", + (int)(JACK_CLIENT_NAME_SIZE-(sizeof(MONITOR_EXT)-1)), + ot->node.name, MONITOR_EXT, name); + else + snprintf(tmp, sizeof(tmp), "%s:%s", ot->node.name, name); + + if (c->filter_name) + filter_name(tmp, FILTER_PORT, c->filter_char); + + op = find_port_by_name(c, tmp); + if (op != NULL && op != o) + snprintf(port_name, sizeof(port_name), "%.*s-%u", + (int)(sizeof(tmp)-11), tmp, o->serial); + else + snprintf(port_name, sizeof(port_name), "%s", tmp); + + if (spa_streq(port_name, o->port.name)) + return 0; + + strcpy(o->port.old_name, o->port.name); + strcpy(o->port.name, port_name); + return 1; +} + +static void port_info(void *data, const struct pw_port_info *info) +{ + struct object *o = data; + struct client *c = o->client; + + if (info->change_mask & PW_PORT_CHANGE_MASK_PROPS) { + const char *str = spa_dict_lookup(info->props, PW_KEY_PORT_NAME); + if (str != NULL) { + if (update_port_name(o, str) > 0) { + pw_log_info("%p: port rename %u %s->%s", c, o->serial, + o->port.old_name, o->port.name); + queue_notify(c, NOTIFY_TYPE_PORT_RENAME, o, 1, NULL); + } + } + } +} + static void port_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) @@ -3696,27 +3772,16 @@ static const struct pw_port_events port_events = { PW_VERSION_PORT_EVENTS, + .info = port_info, .param = port_param, }; -#define FILTER_NAME " ().:*$" -#define FILTER_PORT " ().*$" - -static void filter_name(char *str, const char *filter, char filter_char) -{ - char *p; - for (p = str; *p; p++) { - if (strchr(filter, *p) != NULL) - *p = filter_char; - } -} - static void registry_event_global(void *data, uint32_t id, uint32_t permissions, const char *type, uint32_t version, const struct spa_dict *props) { struct client *c = (struct client *) data; - struct object *o, *ot, *op; + struct object *o, *ot; const char *str; bool do_emit = true, do_sync = false; uint32_t serial; @@ -3837,6 +3902,7 @@ uint32_t node_id; bool is_monitor = false; char tmpREAL_JACK_PORT_NAME_SIZE+1; + const char *name; if ((str = spa_dict_lookup(props, PW_KEY_FORMAT_DSP)) == NULL) str = "other"; @@ -3852,7 +3918,7 @@ spa_strstartswith(str, "jack:flags:")) flags = atoi(str+11); - if ((str = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL) + if ((name = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL) goto exit; if (type_id == TYPE_ID_UMP && c->flag_midi2) @@ -3888,7 +3954,7 @@ o = NULL; if (node_id == c->node_id) { - snprintf(tmp, sizeof(tmp), "%s:%s", c->name, str); + snprintf(tmp, sizeof(tmp), "%s:%s", c->name, name); o = find_port_by_name(c, tmp); if (o != NULL) pw_log_info("%p: %s found our port %p", c, tmp, o); @@ -3906,6 +3972,7 @@ o->port.node = ot; o->port.latencySPA_DIRECTION_INPUT = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); o->port.latencySPA_DIRECTION_OUTPUT = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT); + o->port.type_id = type_id; do_emit = node_is_active(c, ot); @@ -3927,27 +3994,12 @@ pthread_mutex_lock(&c->context.lock); spa_list_append(&c->context.objects, &o->link); pthread_mutex_unlock(&c->context.lock); - - if (is_monitor && !c->merge_monitor) - snprintf(tmp, sizeof(tmp), "%.*s%s:%s", - (int)(JACK_CLIENT_NAME_SIZE-(sizeof(MONITOR_EXT)-1)), - ot->node.name, MONITOR_EXT, str); - else - snprintf(tmp, sizeof(tmp), "%s:%s", ot->node.name, str); - - if (c->filter_name) - filter_name(tmp, FILTER_PORT, c->filter_char); - - op = find_port_by_name(c, tmp); - if (op != NULL) - snprintf(o->port.name, sizeof(o->port.name), "%.*s-%u", - (int)(sizeof(tmp)-11), tmp, serial); - else - snprintf(o->port.name, sizeof(o->port.name), "%s", tmp); - - o->port.type_id = type_id; }
View file
_service:download_url:pipewire-1.4.7.tar.bz2/pipewire-v4l2/src/pipewire-v4l2.c -> _service:download_url:pipewire-1.4.8.tar.bz2/pipewire-v4l2/src/pipewire-v4l2.c
Changed
@@ -772,6 +772,19 @@ return do_dup(oldfd, FD_MAP_DUP); } +/* Deferred PipeWire init (called on first device access) */ +static void pipewire_init_func(void) +{ + pw_init(NULL, NULL); + PW_LOG_TOPIC_INIT(v4l2_log_topic); +} + +static void ensure_pipewire_init(void) +{ + static pthread_once_t pipewire_once = PTHREAD_ONCE_INIT; + pthread_once(&pipewire_once, pipewire_init_func); +} + static int v4l2_openat(int dirfd, const char *path, int oflag, mode_t mode) { int res, flags; @@ -795,6 +808,8 @@ if (passthrough) return globals.old_fops.openat(dirfd, path, oflag, mode); + ensure_pipewire_init(); + pw_log_info("path:%s oflag:%d mode:%d", path, oflag, mode); if ((file = find_file_by_dev(dev_id)) != NULL) { @@ -1385,7 +1400,6 @@ spa_list_for_each(p, &g->param_list, link) { const struct format_info *fi; uint32_t media_type, media_subtype, format; - struct spa_rectangle size; if (p->id != SPA_PARAM_EnumFormat || p->param == NULL) continue; @@ -1409,22 +1423,96 @@ if (fi->fourcc != arg->pixel_format) continue; - if (spa_pod_parse_object(p->param, - SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&size)) < 0) + + const struct spa_pod_prop *size_prop = spa_pod_find_prop(p->param, NULL, SPA_FORMAT_VIDEO_size); + if (!size_prop) continue; - arg->type = V4L2_FRMSIZE_TYPE_DISCRETE; - arg->discrete.width = size.width; - arg->discrete.height = size.height; + uint32_t n_sizes, choice; + const struct spa_pod *size_pods = spa_pod_get_values(&size_prop->value, &n_sizes, &choice); + if (!size_pods || n_sizes <= 0) + continue; + + const struct spa_rectangle *sizes = SPA_POD_BODY_CONST(size_pods); + if (size_pods->type != SPA_TYPE_Rectangle || size_pods->size != sizeof(*sizes)) + continue; + + switch (choice) { + case SPA_CHOICE_Enum: + n_sizes -= 1; + sizes += 1; + SPA_FALLTHROUGH; + case SPA_CHOICE_None: + arg->type = V4L2_FRMSIZE_TYPE_DISCRETE; + + for (size_t i = 0; i < n_sizes; i++, count++) { + arg->discrete.width = sizesi.width; + arg->discrete.height = sizesi.height; + + pw_log_debug("count:%u %.4s %ux%u", count, (char*)&fi->fourcc, + arg->discrete.width, arg->discrete.height); + + if (count == arg->index) { + found = true; + break; + } + } - pw_log_debug("count:%d %.4s %dx%d", count, (char*)&fi->fourcc, - size.width, size.height); - if (count == arg->index) { - found = true; break; + case SPA_CHOICE_Range: + if (n_sizes < 3) + continue; + + arg->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + arg->stepwise.min_width = sizes1.width; + arg->stepwise.min_height = sizes1.height; + arg->stepwise.max_width = sizes2.width; + arg->stepwise.max_height = sizes2.height; + arg->stepwise.step_width = arg->stepwise.step_height = 1; + + pw_log_debug("count:%u %.4s (%ux%u)-(%ux%u)", count, (char*)&fi->fourcc, + arg->stepwise.min_width, arg->stepwise.min_height, + arg->stepwise.max_width, arg->stepwise.max_height); + + if (count == arg->index) { + found = true; + break; + } + + count++; + + break; + case SPA_CHOICE_Step: + if (n_sizes < 4) + continue; + + arg->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + arg->stepwise.min_width = sizes1.width; + arg->stepwise.min_height = sizes1.height; + arg->stepwise.max_width = sizes2.width; + arg->stepwise.max_height = sizes2.height; + arg->stepwise.step_width = sizes3.width; + arg->stepwise.step_height = sizes3.height; + + pw_log_debug("count:%u %.4s (%ux%u)-(%ux%u)/(+%u,%u)", count, (char*)&fi->fourcc, + arg->stepwise.min_width, arg->stepwise.min_height, + arg->stepwise.min_width, arg->stepwise.min_height, + arg->stepwise.step_width, arg->stepwise.step_height); + + if (count == arg->index) { + found = true; + break; + } + + count++; + + break; + default: + continue; } - count++; + + if (found) + break; } pw_thread_loop_unlock(file->loop); @@ -2100,7 +2188,7 @@ { 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_EXPOSURE_ABSOLUTE, SPA_PROP_exposure }, { V4L2_CID_GAIN, SPA_PROP_gain }, { V4L2_CID_SHARPNESS, SPA_PROP_sharpness }, }; @@ -2563,10 +2651,14 @@ globals.old_fops.ioctl = dlsym(RTLD_NEXT, "ioctl"); globals.old_fops.mmap = dlsym(RTLD_NEXT, "mmap64"); globals.old_fops.munmap = dlsym(RTLD_NEXT, "munmap"); - - pw_init(NULL, NULL); - PW_LOG_TOPIC_INIT(v4l2_log_topic); - + /* NOTE: + * We avoid calling pw_init() here (constructor/early init path) because + * that can deadlock in certain host processes (e.g. Zoom >= 5.0) when + * the preload causes PipeWire initialisation to run too early. + * + * PipeWire initialisation (pw_init + PW_LOG_TOPIC_INIT) is deferred + * to ensure it runs on-demand in the first actual V4L2 open call. + */ pthread_mutex_init(&globals.lock, NULL); pw_array_init(&globals.file_maps, 1024); pw_array_init(&globals.fd_maps, 256);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/include/spa/buffer/meta.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/include/spa/buffer/meta.h
Changed
@@ -184,6 +184,9 @@ * layout with 2 extra fds. */ struct spa_meta_sync_timeline { +#define SPA_META_SYNC_TIMELINE_UNSCHEDULED_RELEASE (1<<0) /**< this flag is set by the producer and cleared + * by the consumer when it promises to signal + * the release point */ uint32_t flags; uint32_t padding; uint64_t acquire_point; /**< the timeline acquire point, this is when the data
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/include/spa/control/ump-utils.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/include/spa/control/ump-utils.h
Changed
@@ -197,15 +197,15 @@ break; case 0xf2: to_consume = 3; - prefix = 0x10000000; + prefix |= 0x10000000; break; case 0xf1: case 0xf3: to_consume = 2; - prefix = 0x10000000; + prefix |= 0x10000000; break; case 0xf4 ... 0xff: to_consume = 1; - prefix = 0x10000000; + prefix |= 0x10000000; break; default: return -EIO;
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/include/spa/param/audio/raw-types.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/include/spa/param/audio/raw-types.h
Changed
@@ -192,7 +192,7 @@ { SPA_AUDIO_CHANNEL_TFRC, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "TFRC", NULL }, { SPA_AUDIO_CHANNEL_TSL, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "TSL", NULL }, { SPA_AUDIO_CHANNEL_TSR, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "TSR", NULL }, - { SPA_AUDIO_CHANNEL_LLFE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "LLFR", NULL }, + { SPA_AUDIO_CHANNEL_LLFE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "LLFE", NULL }, { SPA_AUDIO_CHANNEL_RLFE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "RLFE", NULL }, { SPA_AUDIO_CHANNEL_BC, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "BC", NULL }, { SPA_AUDIO_CHANNEL_BLC, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_CHANNEL_BASE "BLC", NULL },
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/alsa/90-pipewire-alsa.rules -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/alsa/90-pipewire-alsa.rules
Changed
@@ -137,8 +137,13 @@ ATTRS{idVendor}=="9886", ATTRS{idProduct}=="0038", ENV{ACP_PROFILE_SET}="usb-gaming-headset.conf" # ID 9886:0045 is for the Astro A20 Gen2 ATTRS{idVendor}=="9886", ATTRS{idProduct}=="0045", ENV{ACP_PROFILE_SET}="usb-gaming-headset.conf" + # ID 1532:0520 is for the Razer Kraken Tournament Edition ATTRS{idVendor}=="1532", ATTRS{idProduct}=="0520", ENV{ACP_PROFILE_SET}="usb-gaming-headset.conf" +# ID 1532:0579 is Razer BlackShark v3 (usb direct to headset) +ATTRS{idVendor}=="1532", ATTRS{idProduct}=="0579", ENV{ACP_PROFILE_SET}="usb-gaming-headset.conf" +# ID 1532:057a is Razer BlackShark v3 (2.4GHz dongle) +ATTRS{idVendor}=="1532", ATTRS{idProduct}=="057a", ENV{ACP_PROFILE_SET}="usb-gaming-headset.conf" # ID 1038:1250 is for the Arctis 5
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/alsa/acp/acp.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/alsa/acp/acp.c
Changed
@@ -453,7 +453,14 @@ } snd_ctl_close(ctl_hndl); - if (n_capture == 1 && n_playback == 1) { + /* FireWire ALSA driver latency is determined by the buffer size and not the + * period. Timer-based scheduling is then not really useful on these devices as + * the latency is fixed. Enable IRQ scheduling unconditionally for these devices, + * so that controlling the latency works properly. + */ + bool is_firewire = spa_streq(pa_proplist_gets(impl->proplist, "device.bus"), "firewire"); + + if ((n_capture == 1 && n_playback == 1) || is_firewire) { PA_IDXSET_FOREACH(m, ap->output_mappings, idx) { pa_proplist_setf(m->output_proplist, "node.group", "pro-audio-%u", index); pa_proplist_setf(m->output_proplist, "node.link-group", "pro-audio-%u", index);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/alsa/alsa-acp-device.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/alsa/alsa-acp-device.c
Changed
@@ -160,7 +160,7 @@ char codecs512; struct spa_device_object_info info; struct acp_card *card = this->card; - const char *stream, *card_id; + const char *stream, *card_id, *bus; info = SPA_DEVICE_OBJECT_INFO_INIT(); info.type = SPA_TYPE_INTERFACE_Node; @@ -175,7 +175,7 @@ info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS; - items = alloca((dev->props.n_items + 11) * sizeof(*items)); + items = alloca((dev->props.n_items + 12) * sizeof(*items)); n_items = 0; snprintf(card_index, sizeof(card_index), "%d", card->index); @@ -193,6 +193,8 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PCM_STREAM, stream); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, stream); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ICON_NAME, "audio-card-analog"); + bus = acp_dict_lookup(&card->props, SPA_KEY_DEVICE_BUS); + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS, bus); snprintf(channels, sizeof(channels), "%d", dev->format.channels); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_CHANNELS, channels);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -1005,6 +1005,8 @@ state->num_bind_ctls = i; /* We'll do the actual binding after checking the card exists */ + } else if (spa_streq(k, SPA_KEY_DEVICE_BUS)) { + state->is_firewire = spa_streq(s, "firewire"); } else { alsa_set_param(state, k, s); } @@ -2052,6 +2054,13 @@ if (rate != 0 && state->rate != 0) latency = SPA_SCALE32_UP(latency, rate, state->rate); + if (state->is_firewire) { + /* XXX: For ALSA FireWire drivers, unlike for other ALSA drivers, buffer size + * XXX: contributes extra latency (as of kernel 6.16). + */ + latency += state->buffer_frames; + } + state->latencystate->port_direction.min_rate = state->latencystate->port_direction.max_rate = latency; } @@ -2326,6 +2335,35 @@ } } + if (state->default_period_num != 0) { + /* period number given use that */ + periods = state->default_period_num; + } else if (state->disable_tsched) { + /* IRQ mode, use 3 periods. This is a bit of a workaround + * for Firewire devices, which seem to only work with 3 periods. + * For PipeWire it does not actually matter how many periods + * are used, we will always keep 1 filled, so we can work fine + * with anything from 2 periods to MAX. */ + periods = 3; + } else { + periods = UINT_MAX; + } + + if (state->default_period_size == 0) { + /* Some devices (FireWire) don't produce audio if period number is too + * small, so force a minimum. This will restrict possible period sizes if + * the device has small buffer (like FireWire), so force it only if + * period size was not set manually. + */ + snd_pcm_uframes_t period_size_max; + unsigned int periods_min = (periods == UINT_MAX) ? 3 : periods; + + CHECK(snd_pcm_hw_params_set_periods_min(hndl, params, &periods_min, &dir), "set_periods_min"); + CHECK(snd_pcm_hw_params_get_period_size_max(params, &period_size_max, &dir), "get_period_size_max"); + if (period_size > period_size_max) + period_size = SPA_MIN(period_size, flp2(period_size_max)); + } + CHECK(snd_pcm_hw_params_set_period_size_near(hndl, params, &period_size, &dir), "set_period_size_near"); if (period_size == 0) { @@ -2335,8 +2373,7 @@ state->period_frames = period_size; - if (state->default_period_num != 0) { - periods = state->default_period_num; + if (periods != UINT_MAX) { CHECK(snd_pcm_hw_params_set_periods_near(hndl, params, &periods, &dir), "set_periods"); state->buffer_frames = period_size * periods; } else { @@ -3866,7 +3903,7 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, state->props.media_class); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, "true"); - if (state->have_format) + if (state->have_format && !state->disable_tsched) snprintf(latency, sizeof(latency), "%lu/%d", state->buffer_frames / (2 * state->frame_scale), state->rate); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_MAX_LATENCY, latency0 ? latency : NULL); @@ -3881,7 +3918,7 @@ snprintf(nperiods, sizeof(nperiods), "%lu", state->period_frames != 0 ? state->buffer_frames / state->period_frames : 0); else if (state->default_period_num) - snprintf(nperiods, sizeof(nperiods), "%u", state->default_period_size); + snprintf(nperiods, sizeof(nperiods), "%u", state->default_period_num); itemsn_items++ = SPA_DICT_ITEM_INIT("api.alsa.period-num", nperiods0 ? nperiods : NULL); if (state->have_format)
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/alsa/alsa-pcm.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -155,6 +155,7 @@ unsigned int disable_batch:1; unsigned int disable_tsched:1; unsigned int is_split_parent:1; + unsigned int is_firewire:1; char clock_name64; uint32_t quantum_limit;
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/audioconvert/peaks-ops.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/audioconvert/peaks-ops.h
Changed
@@ -6,6 +6,11 @@ #include <stdio.h> #include <spa/utils/defs.h> +#include <spa/support/log.h> + +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &resample_log_topic +extern struct spa_log_topic resample_log_topic; struct peaks { uint32_t cpu_flags;
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/audioconvert/resample-native-impl.h -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/audioconvert/resample-native-impl.h
Changed
@@ -5,9 +5,14 @@ #include <math.h> #include <spa/utils/defs.h> +#include <spa/support/log.h> #include "resample.h" +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &resample_log_topic +extern struct spa_log_topic resample_log_topic; + typedef void (*resample_func_t)(struct resample *r, const void * SPA_RESTRICT src, uint32_t ioffs, uint32_t *in_len, void * SPA_RESTRICT dst, uint32_t ooffs, uint32_t *out_len);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/audioconvert/resample-native.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/audioconvert/resample-native.c
Changed
@@ -11,6 +11,8 @@ #include "resample-native-precomp.h" #endif +SPA_LOG_TOPIC_DEFINE(resample_log_topic, "spa.resample"); + struct quality { uint32_t n_taps; double cutoff;
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/audiomixer/audiomixer.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/audiomixer/audiomixer.c
Changed
@@ -343,7 +343,7 @@ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Int(12, + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(12, SPA_AUDIO_FORMAT_S8, SPA_AUDIO_FORMAT_U8, SPA_AUDIO_FORMAT_S16, @@ -921,7 +921,8 @@ for (i = 0; i < MAX_PORTS; i++) free(this->in_portsi); - mix_ops_free(&this->ops); + if (this->ops.free) + mix_ops_free(&this->ops); return 0; } @@ -984,6 +985,7 @@ this->info.max_output_ports = 1; this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS; this->info.flags = SPA_NODE_FLAG_RT | SPA_NODE_FLAG_IN_DYNAMIC_PORTS; + this->info_all = this->info.change_mask; port = GET_OUT_PORT(this, 0); port->valid = true; @@ -993,6 +995,7 @@ port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS; port->info.flags = SPA_PORT_FLAG_DYNAMIC_DATA; port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; + port->info_all = port->info.change_mask; port->params0 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); port->params1 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params2 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/audiomixer/mixer-dsp.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/audiomixer/mixer-dsp.c
Changed
@@ -921,6 +921,7 @@ this->info.max_output_ports = 1; this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS; this->info.flags = SPA_NODE_FLAG_RT | SPA_NODE_FLAG_IN_DYNAMIC_PORTS; + this->info_all = this->info.change_mask; port = GET_OUT_PORT(this, 0); port->valid = true; @@ -930,6 +931,7 @@ port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS; port->info.flags = SPA_PORT_FLAG_DYNAMIC_DATA; port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; + port->info_all = port->info.change_mask; port->params0 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); port->params1 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); port->params2 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/spa/plugins/v4l2/v4l2-utils.c -> _service:download_url:pipewire-1.4.8.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
@@ -1132,7 +1132,7 @@ { 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_EXPOSURE_ABSOLUTE, SPA_PROP_exposure }, { V4L2_CID_GAIN, SPA_PROP_gain }, { V4L2_CID_SHARPNESS, SPA_PROP_sharpness }, };
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/daemon/systemd/user/pipewire.service.in -> _service:download_url:pipewire-1.4.8.tar.bz2/src/daemon/systemd/user/pipewire.service.in
Changed
@@ -22,7 +22,7 @@ NoNewPrivileges=yes RestrictNamespaces=yes SystemCallArchitectures=native -SystemCallFilter=@system-service +SystemCallFilter=@system-service mincore Type=simple ExecStart=@PW_BINARY@ Restart=on-failure
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/modules/module-link-factory.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/modules/module-link-factory.c
Changed
@@ -193,8 +193,7 @@ static void global_destroy(void *data) { struct link_data *ld = data; - struct factory_data *d = ld->data; - pw_work_queue_cancel(d->work, ld, SPA_ID_INVALID); + spa_hook_remove(&ld->global_listener); ld->global = NULL; } @@ -213,6 +212,7 @@ spa_hook_remove(&ld->global_listener); if (ld->resource) spa_hook_remove(&ld->resource_listener); + pw_work_queue_cancel(ld->data->work, ld, SPA_ID_INVALID); } static void link_initialized(void *data)
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/modules/module-raop-discover.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/modules/module-raop-discover.c
Changed
@@ -71,7 +71,7 @@ * #raop.domain = "" * #raop.device = "" * #raop.transport = "udp" | "tcp" - * #raop.encryption.type = "RSA" | "auth_setup" | "none" + * #raop.encryption.type = "none" | "RSA" | "auth_setup" | "fp_sap25" * #raop.audio.codec = "PCM" | "ALAC" | "AAC" | "AAC-ELD" * #audio.channels = 2 * #audio.format = "S16" | "S24" | "S32" @@ -244,10 +244,12 @@ * 3 = FairPlay, * 4 = MFiSAP (/auth-setup), * 5 = FairPlay SAPv2.5 */ - if (str_in_list(value, ",", "1")) - value = "RSA"; + if (str_in_list(value, ",", "5")) + value = "fp_sap25"; else if (str_in_list(value, ",", "4")) value = "auth_setup"; + else if (str_in_list(value, ",", "1")) + value = "RSA"; else value = "none"; pw_properties_set(props, "raop.encryption.type", value);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/modules/module-raop-sink.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/modules/module-raop-sink.c
Changed
@@ -197,6 +197,7 @@ CRYPTO_NONE, CRYPTO_RSA, CRYPTO_AUTH_SETUP, + CRYPTO_FP_SAP25, }; enum { CODEC_PCM, @@ -442,6 +443,7 @@ bit_writer(&bp, &bpos, *(d + 2), 8); d += 4; } + bit_writer(&bp, &bpos, 7, 3); /* end tag */ return bp - b + 1; } @@ -892,9 +894,9 @@ interval.tv_nsec = 0; // feedback timer is only needed for auth_setup encryption - if (impl->encryption == CRYPTO_AUTH_SETUP && !impl->feedback_timer) { - - impl->feedback_timer = pw_loop_add_timer(impl->loop, rtsp_do_post_feedback, impl); + if (impl->encryption == CRYPTO_FP_SAP25) { + if (!impl->feedback_timer) + impl->feedback_timer = pw_loop_add_timer(impl->loop, rtsp_do_post_feedback, impl); pw_loop_update_timer(impl->loop, impl->feedback_timer, &timeout, &interval, false); } @@ -910,7 +912,6 @@ rtp_stream_set_first(impl->stream); impl->sync = 0; - impl->sync_period = impl->rate / (impl->mtu / impl->stride); impl->recording = true; rtsp_send_volume(impl); @@ -1239,6 +1240,7 @@ switch (impl->encryption) { case CRYPTO_NONE: + case CRYPTO_FP_SAP25: sdp = spa_aprintf("v=0\r\n" "o=iTunes %s 0 IN IP%d %s\r\n" "s=iTunes\r\n" @@ -1252,6 +1254,7 @@ if (!sdp) return -errno; break; + case CRYPTO_AUTH_SETUP: sdp = spa_aprintf("v=0\r\n" "o=iTunes %s 0 IN IP%d %s\r\n" @@ -1877,6 +1880,8 @@ impl->encryption = CRYPTO_RSA; else if (spa_streq(str, "auth_setup")) impl->encryption = CRYPTO_AUTH_SETUP; + else if (spa_streq(str, "fp_sap25")) + impl->encryption = CRYPTO_FP_SAP25; else { pw_log_error( "can't handle encryption type %s", str); res = -EINVAL; @@ -1911,8 +1916,6 @@ impl->rate = RAOP_RATE; impl->latency = msec_to_samples(impl, RAOP_LATENCY_MS); impl->stride = RAOP_STRIDE; - impl->mtu = impl->stride * impl->psamples; - impl->sync_period = impl->rate / impl->psamples; if ((str = pw_properties_get(props, "raop.latency.ms")) == NULL) str = SPA_STRINGIFY(DEFAULT_LATENCY_MS); @@ -1938,10 +1941,8 @@ pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL) pw_properties_set(props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); - if (pw_properties_get(props, PW_KEY_MEDIA_FORMAT) == NULL) - pw_properties_setf(props, PW_KEY_MEDIA_FORMAT, "%d", SPA_AUDIO_FORMAT_S16_LE); if (pw_properties_get(props, "net.mtu") == NULL) - pw_properties_setf(props, "net.mtu", "%d", impl->mtu); + pw_properties_set(props, "net.mtu", "1448"); if (pw_properties_get(props, "rtp.sender-ts-offset") == NULL) pw_properties_setf(props, "rtp.sender-ts-offset", "%d", 0); if (pw_properties_get(props, "sess.ts-direct") == NULL) @@ -1977,6 +1978,8 @@ copy_props(impl, props, "sess.ts-refclk"); copy_props(impl, props, "sess.ts-direct"); + impl->mtu = pw_properties_get_uint32(impl->props, "net.mtu", 1448); + impl->sync_period = impl->rate / (impl->mtu / impl->stride); impl->core = pw_context_get_object(impl->context, PW_TYPE_INTERFACE_Core); if (impl->core == NULL) { str = pw_properties_get(props, PW_KEY_REMOTE_NAME);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/modules/module-vban/stream.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/modules/module-vban/stream.c
Changed
@@ -298,7 +298,7 @@ impl->header.format_bit = impl->format_info->format_bit; if ((str = pw_properties_get(props, "sess.name")) == NULL) str = "Stream1"; - strcpy(impl->header.stream_name, str); + snprintf(impl->header.stream_name, sizeof(impl->header.stream_name), "%s", str); break; case SPA_MEDIA_SUBTYPE_control: impl->stream_info = impl->info; @@ -319,7 +319,7 @@ impl->header.format_bit = impl->format_info->format_bit; if ((str = pw_properties_get(props, "sess.name")) == NULL) str = "Midi1"; - strcpy(impl->header.stream_name, str); + snprintf(impl->header.stream_name, sizeof(impl->header.stream_name), "%s", str); break; default: spa_assert_not_reached();
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/pipewire/filter.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/pipewire/filter.c
Changed
@@ -36,7 +36,7 @@ struct pw_buffer this; uint32_t id; #define BUFFER_FLAG_MAPPED (1 << 0) -#define BUFFER_FLAG_QUEUED (1 << 1) +#define BUFFER_FLAG_DEQUEUED (1 << 1) #define BUFFER_FLAG_ADDED (1 << 2) uint32_t flags; }; @@ -356,11 +356,9 @@ { uint32_t index; - if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED)) + if (buffer->id >= port->n_buffers) return -EINVAL; - SPA_FLAG_SET(buffer->flags, BUFFER_FLAG_QUEUED); - spa_ringbuffer_get_write_index(&queue->ring, &index); queue->idsindex & MASK_BUFFERS = buffer->id; spa_ringbuffer_write_update(&queue->ring, index + 1); @@ -382,7 +380,6 @@ spa_ringbuffer_read_update(&queue->ring, index + 1); buffer = &port->buffersid; - SPA_FLAG_CLEAR(buffer->flags, BUFFER_FLAG_QUEUED); return buffer; } @@ -941,6 +938,7 @@ pw_log_debug("%p: got buffer id:%d datas:%d mapped size %d", filter, i, buffersi->n_datas, size); } + port->n_buffers = n_buffers; for (i = 0; i < n_buffers; i++) { struct buffer *b = &port->buffersi; @@ -953,11 +951,9 @@ } SPA_FLAG_SET(b->flags, BUFFER_FLAG_ADDED); + pw_filter_emit_add_buffer(filter, port->user_data, &b->this); } - - port->n_buffers = n_buffers; - return 0; } @@ -970,9 +966,7 @@ return -EINVAL; pw_log_trace("%p: recycle buffer %d", impl, buffer_id); - if (buffer_id < port->n_buffers) - push_queue(port, &port->queued, &port->buffersbuffer_id); - + push_queue(port, &port->queued, &port->buffersbuffer_id); return 0; } @@ -2013,6 +2007,7 @@ return NULL; } pw_log_trace_fp("%p: dequeue buffer %d", p->filter, b->id); + SPA_FLAG_SET(b->flags, BUFFER_FLAG_DEQUEUED); return &b->this; } @@ -2022,6 +2017,13 @@ { struct port *p = SPA_CONTAINER_OF(port_data, struct port, user_data); struct buffer *b = SPA_CONTAINER_OF(buffer, struct buffer, this); + + if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_DEQUEUED)) { + pw_log_warn("%p: tried to queue cleared buffer %d", p->filter, b->id); + return -EINVAL; + } + SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_DEQUEUED); + pw_log_trace_fp("%p: queue buffer %d", p->filter, b->id); return push_queue(p, &p->queued, b); }
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/pipewire/impl-node.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/pipewire/impl-node.c
Changed
@@ -219,17 +219,21 @@ { struct pw_impl_node *this = user_data; struct pw_node_target *t; - int old_state; + int old_state, new_state; uint64_t trigger = 0; pw_log_trace("%p: unprepare %d remote:%d exported:%d", this, this->rt.prepared, this->remote, this->exported); - /* We mark ourself as finished now, this will avoid going further into the process loop - * in case our fd was ready (removing ourselfs from the loop should avoid that as well). - * If we were supposed to be scheduled make sure we continue the graph for the peers we - * were supposed to trigger */ - old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, PW_NODE_ACTIVATION_INACTIVE); + /* The remote client will INACTIVE itself and remove itself from the loop to avoid + * being scheduled. + * The server will mark remote nodes as FINISHED. This will make sure the node will not + * trigger the peers anymore when it will stop because we do that on the server side + * because the client might simply be dead and not able to resume anything. + */ + new_state = this->remote ? PW_NODE_ACTIVATION_FINISHED : PW_NODE_ACTIVATION_INACTIVE; + + old_state = SPA_ATOMIC_XCHG(this->rt.target.activation->status, new_state); if (PW_NODE_ACTIVATION_PENDING_TRIGGER(old_state)) trigger = get_time_ns(this->rt.target.system);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/pipewire/mem.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/pipewire/mem.c
Changed
@@ -167,7 +167,7 @@ impl->pagesize = sysconf(_SC_PAGESIZE); - pw_log_debug("%p: new", this); + pw_log_debug("%p: new pagesize:%" PRIu32 "", this, impl->pagesize); spa_hook_list_init(&impl->listener_list); pw_map_init(&impl->map, 64, 64); @@ -393,7 +393,6 @@ struct mempool *p = SPA_CONTAINER_OF(block->pool, struct mempool, this); struct mapping *m; struct memmap *mm; - struct pw_map_range range; struct stat sb; if (b->this.fd == -1) { @@ -418,13 +417,15 @@ return NULL; } - pw_map_range_init(&range, offset, size, p->pagesize); - m = memblock_find_mapping(b, flags, offset, size); - if (m == NULL) + if (m == NULL) { + struct pw_map_range range; + pw_map_range_init(&range, offset, size, p->pagesize); + m = memblock_map(b, flags, range.offset, range.size); - if (m == NULL) - return NULL; + if (m == NULL) + return NULL; + } mm = calloc(1, sizeof(struct memmap)); if (mm == NULL) { @@ -439,7 +440,7 @@ mm->this.flags = flags; mm->this.offset = offset; mm->this.size = size; - mm->this.ptr = SPA_PTROFF(m->ptr, range.start, void); + mm->this.ptr = SPA_PTROFF(m->ptr, offset - m->offset, void); pw_log_debug("%p: map:%p block:%p fd:%d flags:%08x ptr:%p (%u %u) mapping:%p ref:%d", p, &mm->this, b, b->this.fd, b->this.flags, mm->this.ptr, offset, size, m, m->ref);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/pipewire/mem.h -> _service:download_url:pipewire-1.4.8.tar.bz2/src/pipewire/mem.h
Changed
@@ -7,6 +7,8 @@ #include <pipewire/properties.h> +struct spa_hook; + #ifdef __cplusplus extern "C" { #endif
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/pipewire/stream.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/pipewire/stream.c
Changed
@@ -38,7 +38,7 @@ struct pw_buffer this; uint32_t id; #define BUFFER_FLAG_MAPPED (1 << 0) -#define BUFFER_FLAG_QUEUED (1 << 1) +#define BUFFER_FLAG_DEQUEUED (1 << 1) #define BUFFER_FLAG_ADDED (1 << 2) uint32_t flags; struct spa_meta_busy *busy; @@ -340,11 +340,9 @@ { uint32_t index; - if (SPA_FLAG_IS_SET(buffer->flags, BUFFER_FLAG_QUEUED) || - buffer->id >= stream->n_buffers) + if (buffer->id >= stream->n_buffers) return -EINVAL; - SPA_FLAG_SET(buffer->flags, BUFFER_FLAG_QUEUED); queue->incount += buffer->this.size; spa_ringbuffer_get_write_index(&queue->ring, &index); @@ -375,7 +373,6 @@ buffer = &stream->buffersid; queue->outcount += buffer->this.size; - SPA_FLAG_CLEAR(buffer->flags, BUFFER_FLAG_QUEUED); return buffer; } @@ -1020,8 +1017,7 @@ { struct stream *d = object; pw_log_trace("%p: recycle buffer %d", d, buffer_id); - if (buffer_id < d->n_buffers) - queue_push(d, &d->queued, &d->buffersbuffer_id); + queue_push(d, &d->queued, &d->buffersbuffer_id); return 0; } @@ -2478,6 +2474,9 @@ return NULL; } } + + SPA_FLAG_SET(b->flags, BUFFER_FLAG_DEQUEUED); + return &b->this; } @@ -2488,6 +2487,13 @@ struct buffer *b = SPA_CONTAINER_OF(buffer, struct buffer, this); int res; + if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_DEQUEUED)) { + pw_log_warn("%p: tried to queue cleared buffer %d", stream, b->id); + return -EINVAL; + } + + SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_DEQUEUED); + if (b->busy) SPA_ATOMIC_DEC(b->busy->count); @@ -2517,7 +2523,6 @@ index -= 1; queue->idsindex & MASK_BUFFERS = buffer->id; queue->outcount -= buffer->this.size; - SPA_FLAG_SET(buffer->flags, BUFFER_FLAG_QUEUED); spa_ringbuffer_read_update(&queue->ring, index); return ret;
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/tools/midifile.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/tools/midifile.c
Changed
@@ -58,6 +58,17 @@ return (in0 << 24) | (in1 << 16) | (in2 << 8) | in3; } +static inline int mf_seek(struct midi_file *mf, long offs) +{ + int res; + if (mf->pos == offs) + return 0; + if ((res = fseek(mf->file, offs, SEEK_SET)) != 0) + return -errno; + mf->pos = offs; + return 0; +} + static inline int mf_read(struct midi_file *mf, void *data, size_t size) { if (fread(data, size, 1, mf->file) != 1) @@ -178,10 +189,8 @@ tr->id = i; if (i + 1 < mf->info.ntracks && - fseek(mf->file, tr->start + tr->size, SEEK_SET) != 0) { - res = -errno; + (res = mf_seek(mf, tr->start + tr->size)) < 0) goto exit_close; - } } mf->mode = 1; *info = mf->info; @@ -218,7 +227,7 @@ struct midi_track *tr = &mf->tracks0; int res; - fseek(mf->file, 0, SEEK_SET); + mf_seek(mf, 0); mf->length = 6; CHECK_RES(write_n(mf->file, "MThd", 4)); @@ -351,7 +360,6 @@ uint32_t size; uint8_t status, meta; int res, running; - long offs; event->data = NULL; @@ -360,11 +368,8 @@ tr = &mf->tracksevent->track; - offs = tr->pos; - if (offs != mf->pos) { - if (fseek(mf->file, offs, SEEK_SET) != 0) - return -errno; - } + if ((res = mf_seek(mf, tr->pos)) < 0) + return res; mf_read(mf, &status, 1);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/tools/pw-cat.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/tools/pw-cat.c
Changed
@@ -1485,6 +1485,11 @@ if (!data->file) { fprintf(stderr, "sndfile: failed to open audio file \"%s\": %s\n", data->filename, sf_strerror(NULL)); + if (data->verbose) { + char loginfo4096; + if (sf_command(NULL, SFC_GET_LOG_INFO, &loginfo, sizeof(loginfo)) > 0) + fprintf(stderr, "%s\n", loginfo); + } return -EIO; }
View file
_service:download_url:pipewire-1.4.7.tar.bz2/src/tools/pw-dump.c -> _service:download_url:pipewire-1.4.8.tar.bz2/src/tools/pw-dump.c
Changed
@@ -1541,7 +1541,7 @@ colors = true; setlinebuf(data.out); - while ((c = getopt_long(argc, argv, "hVr:mNC", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVr:mNC::", long_options, NULL)) != -1) { switch (c) { case 'h' : show_help(&data, argv0, false);
View file
_service:download_url:pipewire-1.4.7.tar.bz2/test/meson.build -> _service:download_url:pipewire-1.4.8.tar.bz2/test/meson.build
Changed
@@ -53,6 +53,7 @@ 'test-properties.c', 'test-array.c', 'test-map.c', + 'test-mempool.c', 'test-utils.c', include_directories: pwtest_inc, dependencies: spa_dep ,
View file
_service:download_url:pipewire-1.4.8.tar.bz2/test/test-mempool.c
Added
@@ -0,0 +1,49 @@ +/* PipeWire */ +/* SPDX-FileCopyrightText: Copyright © 2025 PipeWire authors */ +/* SPDX-License-Identifier: MIT */ + +#include <unistd.h> + +#include <pipewire/mem.h> +#include <spa/buffer/buffer.h> + +#include "pwtest.h" + +PWTEST(mempool_issue4884) +{ + /* + * See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4884. This + * test checks if the offset is correctly applied when a mapping is reused. + */ + + long page_size = sysconf(_SC_PAGESIZE); + pwtest_errno_ok(page_size); + pwtest_int_ge(page_size, 8); + + struct pw_mempool *p = pw_mempool_new(NULL); + pwtest_ptr_notnull(p); + + struct pw_memblock *b = pw_mempool_alloc(p, PW_MEMBLOCK_FLAG_READWRITE, SPA_DATA_MemFd, 2 * page_size); + pwtest_ptr_notnull(b); + + struct pw_memmap *m1 = pw_mempool_map_id(p, b->id, PW_MEMMAP_FLAG_READWRITE, page_size / 2, page_size, NULL); + pwtest_ptr_notnull(m1); + pwtest_ptr_eq(m1->block, b); + + struct pw_memmap *m2 = pw_mempool_map_id(p, b->id, PW_MEMMAP_FLAG_READWRITE, 3 * page_size / 2, page_size / 2, NULL); + pwtest_ptr_notnull(m2); + pwtest_ptr_eq(m2->block, b); + + pwtest_int_eq(SPA_PTRDIFF(m2->ptr, m1->ptr), page_size); + + pw_mempool_destroy(p); + + return PWTEST_PASS; +} + +PWTEST_SUITE(pw_mempool) +{ + pwtest_add(mempool_issue4884, PWTEST_NOARG); + + return PWTEST_PASS; +}
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
.