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 56
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Tue Jul 1 16:46:10 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.4.6 + +------------------------------------------------------------------- Sat Jun 14 11:49:24 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.4.5
View file
pipewire-aptx.spec
Changed
@@ -8,7 +8,7 @@ %define minimum_version 1.4.0 Name: pipewire-aptx -Version: 1.4.5 +Version: 1.4.6 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.5/pipewire-1.4.5.tar.bz2</param> + <param name="path">/pipewire/pipewire/-/archive/1.4.6/pipewire-1.4.6.tar.bz2</param> </service> </services> \ No newline at end of file
View file
_service:download_url:pipewire-1.4.5.tar.bz2/NEWS -> _service:download_url:pipewire-1.4.6.tar.bz2/NEWS
Changed
@@ -1,3 +1,37 @@ +# PipeWire 1.4.6 (2025-06-27) + +This is a bugfix release that is API and ABI compatible with +previous 1.x releases. + +## Highlights + - Fix a crasher bug in filter-chain and one in the ALSA plugin. + - Improve latency reporting in module-combine-stream. + - Some smaller fixes and cleanups. + + +## modules + - Improve latency handling in module-combine-stream. (#4731) + - Improve save activation/deactivation of the filter-graph in + module-filter-chain to avoid crashes. (#4700, #4750) + - Add an option to disable RAOP with a context.property. + +## SPA + - Handle NULL io in alsa wakeup code. This can happen when there + is negotiation happening. (#4734) + - Enable interrupts after an ALSA error to keep the dataflow + going. + - Reset some stats better after an ALSA error. + - Support the alsa.use-ucm property for the ALSA udev plugin. + +# pulse-server + - Mark empty buffers. This improves some code paths in the mixer. + +## 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 @@ -22,9 +56,6 @@ - Fix a potential deadlock when calling _drop and _drain at the same time. (#4728) - -Older versions: - # PipeWire 1.4.4 (2025-05-29) This is a quick bugfix release that is API and ABI compatible with
View file
_service:download_url:pipewire-1.4.5.tar.bz2/doc/DoxygenLayout.xml -> _service:download_url:pipewire-1.4.6.tar.bz2/doc/DoxygenLayout.xml
Changed
@@ -41,6 +41,11 @@ <tab type="globals" visible="no" title="" intro=""/> </tab> <tab type="examples" visible="yes" title="" intro=""/> + <tab type="usergroup" title="PipeWire Versions"> + <tab type="user" url="https://docs.pipewire.org/1.2/" title="1.2.x"/> + <tab type="user" url="https://docs.pipewire.org/1.4/" title="1.4.x"/> + <tab type="user" url="https://docs.pipewire.org/devel/" title="Development"/> + </tab> </navindex> <!-- Layout definition for a class page -->
View file
_service:download_url:pipewire-1.4.5.tar.bz2/meson.build -> _service:download_url:pipewire-1.4.6.tar.bz2/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '1.4.5', + version : '1.4.6', 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.5.tar.bz2/spa/include/spa/param/audio/raw-types.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/param/audio/raw-types.h
Changed
@@ -274,6 +274,15 @@ return spa_type_to_short_name(type, spa_type_audio_channel, "UNK"); } +#define SPA_TYPE_INFO_AudioVolumeRampScale SPA_TYPE_INFO_ENUM_BASE "AudioVolumeRampScale" +#define SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE SPA_TYPE_INFO_AudioVolumeRampScale ":" + +static const struct spa_type_info spa_type_audio_volume_ramp_scale = { + { SPA_AUDIO_VOLUME_RAMP_INVALID, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "INVALID", NULL }, + { SPA_AUDIO_VOLUME_RAMP_LINEAR, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "LINEAR", NULL }, + { SPA_AUDIO_VOLUME_RAMP_CUBIC, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE "CUBIC", NULL }, + { 0, 0, NULL, NULL }, +}; /** * \}
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/include/spa/param/props-types.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/param/props-types.h
Changed
@@ -41,12 +41,12 @@ { SPA_PROP_bluetoothAudioCodec, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "bluetoothAudioCodec", spa_type_bluetooth_audio_codec }, { SPA_PROP_bluetoothOffloadActive, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "bluetoothOffloadActive", NULL }, - { SPA_PROP_waveType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL }, + { SPA_PROP_waveType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL }, { SPA_PROP_frequency, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "frequency", NULL }, { SPA_PROP_volume, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "volume", NULL }, { SPA_PROP_mute, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "mute", NULL }, - { SPA_PROP_patternType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "patternType", NULL }, - { SPA_PROP_ditherType, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "ditherType", NULL }, + { SPA_PROP_patternType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "patternType", NULL }, + { SPA_PROP_ditherType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "ditherType", NULL }, { SPA_PROP_truncate, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "truncate", NULL }, { SPA_PROP_channelVolumes, SPA_TYPE_Array, SPA_TYPE_INFO_PROPS_BASE "channelVolumes", spa_type_prop_float_array }, { SPA_PROP_volumeBase, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "volumeBase", NULL }, @@ -62,7 +62,7 @@ { SPA_PROP_volumeRampStepSamples, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampStepSamples", NULL }, { SPA_PROP_volumeRampTime, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampTime", NULL }, { SPA_PROP_volumeRampStepTime, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "volumeRampStepTime", NULL }, - { SPA_PROP_volumeRampScale, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "volumeRampScale", NULL }, + { SPA_PROP_volumeRampScale, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "volumeRampScale", spa_type_audio_volume_ramp_scale }, { SPA_PROP_brightness, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "brightness", NULL }, { SPA_PROP_contrast, SPA_TYPE_Float, SPA_TYPE_INFO_PROPS_BASE "contrast", NULL },
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/include/spa/support/loop.h -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/include/spa/support/loop.h
Changed
@@ -121,6 +121,9 @@ * \param block If \true, do not return until func has been called. Otherwise, * returns immediately. Passing \true does not risk a deadlock because * the data thread is never allowed to wait on any other thread. + * It the loop requires some locking, it must be acquired before + * calling this function because a blocking invoke will release + * the lock while blocking. * \param user_data An opaque pointer passed to func. * \return `-EPIPE` if the internal ring buffer filled up, * if block is \false, 0 if seq was SPA_ID_INVALID or
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -2574,6 +2574,7 @@ state->alsa_sync = true; state->alsa_sync_warning = false; state->alsa_started = false; + spa_dll_init(&state->dll); return 0; } @@ -2606,6 +2607,7 @@ } static inline int check_position_config(struct state *state, bool starting); +static void update_sources(struct state *state, bool active); static int alsa_recover(struct state *state) { @@ -2685,6 +2687,8 @@ if (follower != driver && follower->linked) do_start(follower); } + + update_sources(state, true); return 0; } @@ -2797,6 +2801,12 @@ double err, corr, avg; int32_t diff; + if (SPA_UNLIKELY(state->dll.bw == 0.0)) { + spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate); + state->next_time = current_time; + state->base_time = current_time; + } + if (state->disable_tsched && !follower) { err = (int64_t)(current_time - state->next_time); err = err / 1e9 * state->rate; @@ -2807,11 +2817,6 @@ err = target - delay; } - if (SPA_UNLIKELY(state->dll.bw == 0.0)) { - spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate); - state->next_time = current_time; - state->base_time = current_time; - } diff = (int32_t) (state->last_threshold - state->threshold); if (SPA_UNLIKELY(diff != 0)) { @@ -2888,9 +2893,9 @@ state->clock->next_nsec = state->next_time; } - spa_log_trace_fp(state->log, "%p: follower:%d %"PRIu64" %f %ld %ld %f %f %u", - state, follower, current_time, corr, delay, target, err, state->threshold * corr, - state->threshold); + spa_log_trace_fp(state->log, "%p: follower:%d %"PRIu64" %"PRIu64" %f %ld %ld %f %f %u", + state, follower, current_time, state->next_time, corr, delay, target, + err, state->threshold * corr, state->threshold); return 0; } @@ -3000,28 +3005,30 @@ if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, following)) < 0)) return res; - if (following && state->alsa_started && !state->linked) { + if (following && state->alsa_started) { if (SPA_UNLIKELY(state->alsa_sync)) { enum spa_log_level lev; - if (SPA_UNLIKELY(state->alsa_sync_warning)) - lev = SPA_LOG_LEVEL_WARN; - else - lev = SPA_LOG_LEVEL_INFO; - - if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) - lev = SPA_LOG_LEVEL_DEBUG; - - spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld " - "target:%ld thr:%u, resync (%d suppressed)", - state->name, avail, delay, - target, state->threshold, suppressed); - - if (avail > target) - snd_pcm_rewind(state->hndl, avail - target); - else if (avail < target) - spa_alsa_silence(state, target - avail); - avail = target; + if (!state->linked) { + if (SPA_UNLIKELY(state->alsa_sync_warning)) + lev = SPA_LOG_LEVEL_WARN; + else + lev = SPA_LOG_LEVEL_INFO; + + if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) + lev = SPA_LOG_LEVEL_DEBUG; + + spa_log_lev(state->log, lev, "%s: follower avail:%lu delay:%ld " + "target:%ld thr:%u, resync (%d suppressed)", + state->name, avail, delay, + target, state->threshold, suppressed); + + if (avail > target) + snd_pcm_rewind(state->hndl, avail - target); + else if (avail < target) + spa_alsa_silence(state, target - avail); + avail = target; + } spa_dll_init(&state->dll); state->alsa_sync = false; } else @@ -3266,27 +3273,28 @@ return res; max_read = state->buffer_frames; - if (following && !state->linked) { + if (following) { if (state->alsa_sync) { - enum spa_log_level lev; - - if (SPA_UNLIKELY(state->alsa_sync_warning)) - lev = SPA_LOG_LEVEL_WARN; - else - lev = SPA_LOG_LEVEL_INFO; - - if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) - lev = SPA_LOG_LEVEL_DEBUG; - - spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u " - "resample:%d, resync (%d suppressed)", state->name, delay, - target, state->threshold, state->resample, suppressed); - - if (avail < target) - max_read = target - avail; - else if (avail > target) { - snd_pcm_forward(state->hndl, avail - target); - avail = target; + if (!state->linked) { + enum spa_log_level lev; + if (SPA_UNLIKELY(state->alsa_sync_warning)) + lev = SPA_LOG_LEVEL_WARN; + else + lev = SPA_LOG_LEVEL_INFO; + + if ((suppressed = spa_ratelimit_test(&state->rate_limit, current_time)) < 0) + lev = SPA_LOG_LEVEL_DEBUG; + + spa_log_lev(state->log, lev, "%s: follower delay:%ld target:%ld thr:%u " + "resample:%d, resync (%d suppressed)", state->name, delay, + target, state->threshold, state->resample, suppressed); + + if (avail < target) + max_read = target - avail; + else if (avail > target) { + snd_pcm_forward(state->hndl, avail - target); + avail = target; + } } state->alsa_sync = false; spa_dll_init(&state->dll); @@ -3409,11 +3417,13 @@ { struct spa_io_buffers *io = state->io; - spa_log_trace_fp(state->log, "%p: %d", state, io->status); + spa_log_trace_fp(state->log, "%p: %d", state, io ? io->status : 0); update_sources(state, false); - io->status = SPA_STATUS_NEED_DATA; + if (io != NULL) + io->status = SPA_STATUS_NEED_DATA; + return spa_node_call_ready(&state->callbacks, SPA_STATUS_NEED_DATA); }
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-seq.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-seq.c
Changed
@@ -330,7 +330,7 @@ state->port_info(state->port_info_data, addr, NULL); break; default: - spa_log_info(state->log, "unhandled event %d: %d:%d", + spa_log_debug(state->log, "unhandled event %d: %d:%d", type, addr->client, addr->port); break;
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/alsa/alsa-udev.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/alsa/alsa-udev.c
Changed
@@ -94,6 +94,7 @@ struct spa_source notify; unsigned int use_acp:1; unsigned int expose_busy:1; + int use_ucm; }; static int impl_udev_open(struct impl *this) @@ -500,7 +501,7 @@ if (num_pcm_devices > 0) { struct spa_device_object_info info; char *cn = NULL, *cln = NULL; - struct spa_dict_item items25; + struct spa_dict_item items26; unsigned int n_items = 0; card->pcm_device_id = calc_pcm_device_id(card); @@ -521,6 +522,9 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_ENUM_API, "udev"); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_API, "alsa"); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Device"); + if (this->use_ucm != -1) + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_USE_UCM, + this->use_ucm ? "true" : "false"); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PATH, path); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_CARD, path+3); if (snd_card_get_name(card->card_nr, &cn) >= 0) @@ -1105,6 +1109,7 @@ alsa_log_topic_init(this->log); this->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop); this->main_system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System); + this->use_ucm = -1; if (this->main_loop == NULL) { spa_log_error(this->log, "a main-loop is needed"); @@ -1131,6 +1136,8 @@ this->use_acp = spa_atob(str); else if ((str = spa_dict_lookup(info, "alsa.udev.expose-busy")) != NULL) this->expose_busy = spa_atob(str); + else if ((str = spa_dict_lookup(info, "alsa.use-ucm")) != NULL) + this->use_ucm = spa_atob(str) ? 1 : 0; } return 0;
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -291,7 +291,6 @@ unsigned int started:1; unsigned int setup:1; unsigned int resample_peaks:1; - unsigned int is_passthrough:1; unsigned int ramp_volume:1; unsigned int drained:1; unsigned int rate_adjust:1; @@ -3014,9 +3013,6 @@ spa_log_warn(this->log, "%p: memory %d on buffer %d not aligned", this, j, i); } - if (direction == SPA_DIRECTION_OUTPUT && - !SPA_FLAG_IS_SET(dj.flags, SPA_DATA_FLAG_DYNAMIC)) - this->is_passthrough = false; b->datasj = dj.data; @@ -3597,6 +3593,7 @@ if (io->status & SPA_STATUS_DRAINED) { spa_log_debug(this->log, "%p: port %d drained", this, port->id); in_avail = flush_in = draining = true; + in_empty = false; } else { spa_log_trace_fp(this->log, "%p: empty input port %d %p %d %d %d", this, port->id, io, io->status, io->buffer_id,
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c
Changed
@@ -598,7 +598,7 @@ for (j = 0; j < in_data->planes; j++, k++) { b->datasj.type = SPA_DATA_MemPtr; - b->datasj.flags = 0; + b->datasj.flags = SPA_DATA_FLAG_READABLE; b->datasj.fd = -1; b->datasj.mapoffset = 0; b->datasj.maxsize = in_data->size; @@ -629,7 +629,7 @@ for (j = 0; j < out_data->planes; j++) { b->datasj.type = SPA_DATA_MemPtr; - b->datasj.flags = 0; + b->datasj.flags = SPA_DATA_FLAG_READWRITE; b->datasj.fd = -1; b->datasj.mapoffset = 0; b->datasj.maxsize = out_data->size;
View file
_service:download_url:pipewire-1.4.5.tar.bz2/spa/plugins/test/fakesrc.c -> _service:download_url:pipewire-1.4.6.tar.bz2/spa/plugins/test/fakesrc.c
Changed
@@ -130,7 +130,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, SPA_PROP_live, SPA_POD_Bool(p->live), - SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Id(2, p->pattern, p->pattern)); + SPA_PROP_patternType, SPA_POD_CHOICE_ENUM_Int(2, p->pattern, p->pattern)); break; } default: @@ -173,7 +173,7 @@ spa_pod_parse_object(param, SPA_TYPE_OBJECT_Props, NULL, SPA_PROP_live, SPA_POD_OPT_Bool(&p->live), - SPA_PROP_patternType, SPA_POD_OPT_Id(&p->pattern)); + SPA_PROP_patternType, SPA_POD_OPT_Int(&p->pattern)); if (p->live) port->info.flags |= SPA_PORT_FLAG_LIVE;
View file
_service:download_url:pipewire-1.4.5.tar.bz2/src/daemon/pipewire.conf.avail/50-raop.conf.in -> _service:download_url:pipewire-1.4.6.tar.bz2/src/daemon/pipewire.conf.avail/50-raop.conf.in
Changed
@@ -1,4 +1,6 @@ context.modules = # Use mDNS to detect and load module-raop-sink - { name = libpipewire-module-raop-discover } + { name = libpipewire-module-raop-discover + condition = { module.raop = !false } + }
View file
_service:download_url:pipewire-1.4.5.tar.bz2/src/gst/gstpipewiredeviceprovider.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/gst/gstpipewiredeviceprovider.c
Changed
@@ -324,7 +324,7 @@ if(self->list_only) { self->devices = g_list_insert_sorted (self->devices, - gst_object_ref_sink (device), + gst_object_ref (device), compare_device_session_priority); } else { gst_object_ref (device);
View file
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-combine-stream.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-combine-stream.c
Changed
@@ -319,6 +319,7 @@ int64_t delay_samples; /* for main loop */ int64_t data_delay_samples; /* for data loop */ + int64_t compensate_samples; /* for main loop */ unsigned int ready:1; unsigned int added:1; @@ -574,6 +575,7 @@ max_delay = SPA_MAX(max_delay, delay); s->delay_samples = delay; + s->compensate_samples = 0; } spa_list_for_each(s, &impl->streams, link) { @@ -581,9 +583,9 @@ if (s->delay_samples != INT64_MIN) { int64_t delay = max_delay - s->delay_samples; + s->compensate_samples = delay; size = delay * sizeof(float); } - resize_delay(s, size); } @@ -653,6 +655,40 @@ } } +static void param_latency_changed(struct impl *impl, const struct spa_pod *param) +{ + if (param == NULL) + return; + + pw_log_debug("latency update"); + struct stream *s; + struct spa_latency_info info; + const struct spa_pod *params1; + + if (spa_latency_parse(param, &info) < 0) + return; + + spa_list_for_each(s, &impl->streams, link) { + uint8_t buffer1024; + struct spa_pod_builder b; + + if (s->stream == NULL) + continue; + + pw_log_debug("updating stream %d", s->id); + if (impl->latency_compensate) { + struct spa_latency_info other = info; + other.min_rate += s->compensate_samples; + other.max_rate += s->compensate_samples; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + params0 = spa_latency_build(&b, SPA_PARAM_Latency, &other); + } else { + params0 = param; + } + pw_stream_update_params(s->stream, params, 1); + } +} + static int do_remove_stream(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) { @@ -730,6 +766,9 @@ case PW_STREAM_STATE_UNCONNECTED: stream_destroy(s); break; + case PW_STREAM_STATE_STREAMING: + update_latency(s->impl); + break; default: break; } @@ -1070,6 +1109,7 @@ enum pw_stream_state state, const char *error) { struct impl *impl = d; + struct stream *s; switch (state) { case PW_STREAM_STATE_ERROR: case PW_STREAM_STATE_UNCONNECTED: @@ -1077,6 +1117,10 @@ break; case PW_STREAM_STATE_PAUSED: clear_delaybuf(impl); + spa_list_for_each(s, &impl->streams, link) { + pw_stream_flush(s->stream, false); + } + pw_stream_flush(impl->combine, false); impl->combine_id = pw_stream_get_node_id(impl->combine); pw_log_info("got combine id %d", impl->combine_id); break; @@ -1291,10 +1335,12 @@ update_latency(impl); break; } - case SPA_PARAM_Tag: { + case SPA_PARAM_Tag: param_tag_changed(impl, param); break; - } + case SPA_PARAM_Latency: + param_latency_changed(impl, param); + break; default: break; } @@ -1489,7 +1535,7 @@ spa_list_init(&impl->streams); if (args == NULL) - args = ""; + args = "{}"; props = pw_properties_new_string_checked(args, strlen(args), &loc); if (props == NULL) {
View file
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-filter-chain.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-filter-chain.c
Changed
@@ -844,6 +844,7 @@ struct spa_hook graph_listener; uint32_t n_inputs; uint32_t n_outputs; + bool graph_active; }; static void capture_destroy(void *d) @@ -863,6 +864,8 @@ struct pw_buffer *t; if ((t = pw_stream_dequeue_buffer(impl->capture)) == NULL) break; + /* playback part is not ready, consume, discard and recycle + * the capture buffers */ pw_stream_queue_buffer(impl->capture, t); } } @@ -929,7 +932,8 @@ pw_log_trace_fp("%p: stride:%d size:%d requested:%"PRIu64" (%"PRIu64")", impl, stride, data_size, out->requested, out->requested * stride); - spa_filter_graph_process(impl->graph, cin, cout, data_size / sizeof(float)); + if (impl->graph_active) + spa_filter_graph_process(impl->graph, cin, cout, data_size / sizeof(float)); done: if (in != NULL) @@ -938,6 +942,61 @@ pw_stream_queue_buffer(impl->playback, out); } +static int do_deactivate(struct spa_loop *loop, bool async, uint32_t seq, + const void *data, size_t size, void *user_data) +{ + struct impl *impl = user_data; + impl->graph_active = false; + return 0; +} + +static int activate_graph(struct impl *impl) +{ + char rate64; + int res; + + if (impl->graph_active) + return 0; + + snprintf(rate, sizeof(rate), "%lu", impl->rate); + res = spa_filter_graph_activate(impl->graph, &SPA_DICT_ITEMS( + SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, rate))); + + if (res >= 0) + impl->graph_active = true; + + return res; +} + +static int deactivate_graph(struct impl *impl) +{ + struct pw_loop *data_loop; + + if (!impl->graph_active) + return 0; + + data_loop = pw_stream_get_data_loop(impl->playback); + pw_loop_invoke(data_loop, do_deactivate, 0, NULL, 0, true, impl); + + return spa_filter_graph_deactivate(impl->graph); +} + +static int reset_graph(struct impl *impl) +{ + struct pw_loop *data_loop; + int res; + bool old_active = impl->graph_active; + + data_loop = pw_stream_get_data_loop(impl->playback); + pw_loop_invoke(data_loop, do_deactivate, 0, NULL, 0, true, impl); + + res = spa_filter_graph_reset(impl->graph); + + impl->graph_active = old_active; + + return res; +} + static void param_latency_changed(struct impl *impl, const struct spa_pod *param) { struct spa_latency_info latency; @@ -976,14 +1035,10 @@ enum pw_stream_state state, const char *error) { struct impl *impl = data; - struct spa_filter_graph *graph = impl->graph; - int res; switch (state) { case PW_STREAM_STATE_PAUSED: - pw_stream_flush(impl->playback, false); pw_stream_flush(impl->capture, false); - spa_filter_graph_reset(graph); break; case PW_STREAM_STATE_UNCONNECTED: pw_log_info("module %p: unconnected", impl); @@ -993,34 +1048,10 @@ pw_log_info("module %p: error: %s", impl, error); break; case PW_STREAM_STATE_STREAMING: - { - uint32_t target = impl->info.rate; - if (target == 0) - target = impl->position ? - impl->position->clock.target_rate.denom : DEFAULT_RATE; - if (target == 0) { - res = -EINVAL; - goto error; - } - if (impl->rate != target) { - char rate64; - impl->rate = target; - snprintf(rate, sizeof(rate), "%lu", impl->rate); - spa_filter_graph_deactivate(graph); - if ((res = spa_filter_graph_activate(graph, - &SPA_DICT_ITEMS( - SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, rate)))) < 0) - goto error; - } - break; - } default: break; } return; -error: - pw_stream_set_error(impl->capture, res, "can't start graph: %s", - spa_strerror(res)); } static void io_changed(void *data, uint32_t id, void *area, uint32_t size) @@ -1039,7 +1070,6 @@ bool capture) { struct impl *impl = data; - struct spa_filter_graph *graph = impl->graph; int res; switch (id) { @@ -1049,8 +1079,8 @@ spa_zero(info); if (param == NULL) { pw_log_info("module %p: filter deactivate", impl); - if (capture) - spa_filter_graph_deactivate(graph); + if (!capture) + deactivate_graph(impl); impl->rate = 0; } else { if ((res = spa_format_audio_raw_parse(param, &info)) < 0) @@ -1093,6 +1123,51 @@ .param_changed = capture_param_changed }; +static void playback_state_changed(void *data, enum pw_stream_state old, + enum pw_stream_state state, const char *error) +{ + struct impl *impl = data; + int res; + + switch (state) { + case PW_STREAM_STATE_PAUSED: + pw_stream_flush(impl->playback, false); + reset_graph(impl); + break; + case PW_STREAM_STATE_UNCONNECTED: + pw_log_info("module %p: unconnected", impl); + pw_impl_module_schedule_destroy(impl->module); + break; + case PW_STREAM_STATE_ERROR: + pw_log_info("module %p: error: %s", impl, error); + break; + case PW_STREAM_STATE_STREAMING: + { + uint32_t target = impl->info.rate; + if (target == 0) + target = impl->position ? + impl->position->clock.target_rate.denom : DEFAULT_RATE; + if (target == 0) { + res = -EINVAL; + goto error; + } + if (impl->rate != target) { + impl->rate = target; + deactivate_graph(impl); + } + if ((res = activate_graph(impl)) < 0) + goto error; + break; + } + default: + break;
View file
_service:download_url:pipewire-1.4.5.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c -> _service:download_url:pipewire-1.4.6.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1379,6 +1379,7 @@ if (stream->direction == PW_DIRECTION_OUTPUT) { int32_t avail = spa_ringbuffer_get_read_index(&stream->ring, &index); + bool empty = false; minreq = buffer->requested * stream->frame_size; if (minreq == 0) @@ -1391,6 +1392,7 @@ /* underrun, produce a silence buffer */ size = SPA_MIN(d->maxsize, minreq); sample_spec_silence(&stream->ss, p, size); + empty = true; if (stream->draining && !stream->corked) { stream->draining = false; @@ -1406,6 +1408,7 @@ stream->buffer, MAXLENGTH, index % MAXLENGTH, p, avail); + empty = false; } index += size; pd.read_inc = size; @@ -1446,6 +1449,7 @@ d->chunk->offset = 0; d->chunk->stride = stream->frame_size; d->chunk->size = size; + SPA_FLAG_UPDATE(d->chunk->flags, SPA_CHUNK_FLAG_EMPTY, empty); buffer->size = size / stream->frame_size; } else { int32_t filled = spa_ringbuffer_get_write_index(&stream->ring, &index);
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
.