Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
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; + } + return; +error: + pw_stream_set_error(impl->capture, res, "can't start graph: %s", + spa_strerror(res)); +} + static void playback_param_changed(void *data, uint32_t id, const struct spa_pod *param) { param_changed(data, id, param, false); @@ -1110,6 +1185,7 @@ .destroy = playback_destroy, .process = playback_process, .io_changed = io_changed, + .state_changed = playback_state_changed, .param_changed = playback_param_changed, };
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
.