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 17
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Mon Nov 21 11:36:55 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.60 + +------------------------------------------------------------------- Sat Oct 15 16:39:17 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.59
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.59 +Version: 0.3.60 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
pipewire-0.3.59.tar.gz/.gitlab-ci.yml -> pipewire-0.3.60.tar.gz/.gitlab-ci.yml
Changed
@@ -25,7 +25,7 @@ .fedora: variables: # Update this tag when you want to trigger a rebuild - FDO_DISTRIBUTION_TAG: '2022-03-05.0' + FDO_DISTRIBUTION_TAG: '2022-11-07.0' FDO_DISTRIBUTION_VERSION: '35' FDO_DISTRIBUTION_PACKAGES: >- alsa-lib-devel @@ -52,6 +52,7 @@ libv4l-devel libva-devel libX11-devel + ModemManager-devel openssl-devel pulseaudio-libs-devel python3-docutils @@ -68,6 +69,7 @@ python3-pip pulseaudio-utils openal-soft + readline-devel FDO_DISTRIBUTION_EXEC: >- pip3 install meson @@ -105,7 +107,7 @@ .alpine: variables: # Update this tag when you want to trigger a rebuild - FDO_DISTRIBUTION_TAG: '2022-01-28.2' + FDO_DISTRIBUTION_TAG: '2022-09-07.0' FDO_DISTRIBUTION_VERSION: '3.15' FDO_DISTRIBUTION_PACKAGES: >- alsa-lib-dev @@ -128,6 +130,7 @@ libusb-dev libx11-dev meson + modemmanager-dev ncurses-dev pulseaudio-dev readline-dev @@ -176,7 +179,6 @@ - ninja $NINJA_ARGS -C "$BUILD_DIR" - ninja $NINJA_ARGS -C "$BUILD_DIR" test - ninja $NINJA_ARGS -C "$BUILD_DIR" install - - ./check_missing_headers.sh artifacts: name: pipewire-$CI_COMMIT_SHA when: always @@ -223,6 +225,8 @@ - .fdo.distribution-image@ubuntu - .build stage: build + variables: + MESON_OPTIONS: "-Dsession-managers=" .build_on_fedora: extends: @@ -248,6 +252,7 @@ -Dvulkan=enabled -Dsdl2=enabled -Dsndfile=enabled + -Dsession-managers= artifacts: name: pipewire-$CI_COMMIT_SHA when: always @@ -262,6 +267,8 @@ - .fdo.distribution-image@alpine - .build stage: build + variables: + MESON_OPTIONS: "-Dsession-managers=" # build with all auto() options enabled build_all: @@ -270,7 +277,14 @@ variables: # Fedora doesn't have libfreeaptx, lc3plus, lc3, or roc # libcamera has no stable API, so let's not chase that target - MESON_OPTIONS: "-Dauto_features=enabled -Dbluez5-codec-aptx=disabled -Dbluez5-codec-lc3plus=disabled -Dbluez5-codec-lc3=disabled -Droc=disabled -Dlibcamera=disabled" + MESON_OPTIONS: >- + -Dauto_features=enabled + -Dbluez5-codec-aptx=disabled + -Dbluez5-codec-lc3plus=disabled + -Dbluez5-codec-lc3=disabled + -Droc=disabled + -Dlibcamera=disabled + -Dsession-managers= parallel: matrix: - CC: gcc, clang @@ -280,7 +294,7 @@ extends: - .build_on_fedora variables: - MESON_OPTIONS: "" + MESON_OPTIONS: "-Dsession-managers=" parallel: matrix: - CC: gcc, clang @@ -296,7 +310,7 @@ MESON_OPTION_VALUE: enabled, disabled script: - echo "Building with -D$MESON_OPTION=$MESON_OPTION_VALUE" - - meson "$BUILD_DIR" . --prefix="$PREFIX" "-D$MESON_OPTION=$MESON_OPTION_VALUE" + - meson "$BUILD_DIR" . --prefix="$PREFIX" "-D$MESON_OPTION=$MESON_OPTION_VALUE" -Dsession-managers= - ninja $NINJA_ARGS -C "$BUILD_DIR" - ninja $NINJA_ARGS -C "$BUILD_DIR" test @@ -307,7 +321,7 @@ extends: - .build_on_fedora variables: - MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true" + MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true -Dsession-managers=" parallel: matrix: - CC: gcc, clang @@ -363,6 +377,8 @@ - echo "Building with meson options $MESON_OPTIONS" - meson "$BUILD_DIR" . --prefix="$PREFIX" $MESON_OPTIONS - meson test -C "$BUILD_DIR" --setup=valgrind + variables: + MESON_OPTIONS: "-Dsession-managers=" build_with_coverity: extends: @@ -383,6 +399,7 @@ -Dvulkan=enabled -Dsdl2=enabled -Dsndfile=enabled + -Dsession-managers= - cov-configure --config coverity_conf.xml --comptype gcc --compiler cc --template --xml-option=append_arg@C:--ppp_translator @@ -432,6 +449,18 @@ git grep -q -e "\\\subpage $page" || (echo "\\page $page is missing \\subpage entry in doc/pipewire-modules.dox" && false) done +check_missing_headers: + extends: + - .fedora + - .not_coverity + - .fdo.distribution-image@fedora + stage: analysis + dependencies: + - build_on_fedora + script: + - export PREFIX=`find -name prefix-*` + - ./.gitlab/ci/check_missing_headers.sh + pages: extends: - .not_coverity
View file
pipewire-0.3.60.tar.gz/.gitlab/ci
Added
+(directory)
View file
pipewire-0.3.60.tar.gz/.gitlab/ci/check_missing_headers.sh
Changed
(renamed from check_missing_headers.sh)
View file
pipewire-0.3.59.tar.gz/NEWS -> pipewire-0.3.60.tar.gz/NEWS
Changed
@@ -1,3 +1,151 @@ +# PipeWire 0.3.60 (2022-11-10) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + - The filter-chain now handles errors better and has fixes for many + crasher bugs. + - A new RTP module was added with a sender and receiver. It uses SAP + to announce and consume RTP streams and is compatible with the + PulseAudio RTP modules. + - Many small bluetooth improvements and fixes. + - The alsa plugin will now only start playback when there is data. This + results in better sync and lower latency between capture and playback. + - The v4l2 and libcamera plugins have seen a lot of improvements. They + support control properties now. Also pw-v4l2 has seen many improvements + and mostly passes the v4l2-compliance test now. + - Many more bugfixes and improvements. + + +## PipeWire + - Code cleanups, compiler warning fixes. + - Add some extra checks to avoid scheduling an inactive node. + - Rework the sequence of events to start and stop nodes. + - Improve param enumeration. + - An option was added to give priority to the Buffer params of the + consumer. This makes it possible to use the default values of the + consumer (instead of the producer) when capturing from a source. + - The graph rate selection was improved to pick a rate closest to the + requested one (instead of picking the default). + +## Modules + - Fix some crashes in filter-chain. (#2737) + - X11 Bell module will now be loaded by default when available. + - A new RTP module was added with a sender and receiver. It uses SAP + to announce and consume RTP streams and is compatible with the + PulseAudio RTP modules. + - Improve RAOP compatibility. + - The echo-cancel module now uses the resampler prefill option to align + input and output samples without buffering. Better latency control + when starting and stopping has been implemented. + - The pulse tunnel will now write aligned samples to pulseaudio even + when the ringbuffer wraps around. This fixes playback issues with + multichannel sinks. + - Add a delay option to module-loopback using a ringbuffer. + - Implement echo-cancel params. + - The filter-chain module has better error reporting. + - The LADSPA search path was extended with some more common paths. + - The echo-canceler input can now also be a monitor of a sink. This + improves compatibility with some proton games that expect a real + sink instead of a virtual one. + +## Tools + - Better error reporting in pw-link. + - pw-top now also shows IEC958 passthrough formats and JPEG/H264 video + formats. + - pw-top refreshes the screen faster. + - pw-top now prints the state of the node and shows less info for + inactive nodes. + - pw-dump now uses the new seq field in the spa_param_info to discard + old param updates and avoid duplicate params in the output. + +## Bluetooth + - Add ModemManager support in the native backend. + - Clean up GetManagedObjects handling. + - Handle QoS from the endpoints in the codec. + - Increase the socket buffer to have more control over the rate and QoS. + - Simplify the packet flushing code. + - Stop processing nodes before destroying them. + - Fix timers when a source switches drivers. + - Codecs can now share endpoints. This reduces the amount of endpoints and + avoids problems with devices that can't handle a large amount of + codec endpoints. + - Report batery status to UPower for HFP AG. + - Fix bitpool increase. + +## SPA + - The audioresampler now avoids clicks and pops between activating and + deactivating the adaptive resampler when used by the stream API. + - Use default locale to parse float parameters. + - The upmix functions now have SSE optimizations. + - Avoid recalculating the complete channelmix setup when only the + volume changes. + - The alsa plugin will now only start playback when there is data. This + results in better sync and lower latency between capture and playback. + - The ALSA MIDI sequencer will now pull data from the graph even when it + did not output anything. Fixes some graph stalls with the sequencer in + some cases. (#2775) + - v4l2 and libcamera sources now recycle buffers when nothing is consuming + them. This avoids stalling the graph. + - libcamera now suggests a more appropriate frame size than the smallest + poster frame. + - Improve state changes in audioconvert. (#2764) + - A new seq field was added to spa_param_info to keep track of pending + param updates. + - Support speaker output only on RealTek ALC4080. (#2744) + - The v4l2 source now supports setting controls. + - The libcamera plugin now supports enumerating and setting controls. + - A new unit test for 6.1 channel mapping was added. (#2809) More debug + info was added to audioconvert for the channel matrix. + - Audioconvert will now also upmix a rear-center channel when needed. + +## pulse-server + - Add support for the RTP send and recv modules with the new native + RTP module. + - Add option to set latency for pulse-tunnel streams and + module-zeroconf-discover. + - The socket will now be given the same permissions as what pulseaudio + did (0777). + - Implement module-loopback latency_msec correctly with the new delay + parameter. + - sysfs.path is now filled with the same data as pulseaudio. + - The manager now uses the new seq field in the spa_param_info. + - Fix a bug where in some cases the read pointer would get out of sync + and cause too large requests. (#2799) + +## ALSA + - The alsa plugin now reuses the stream in prepare which results in + better performance. + - Some deadlocks have been fixed in the ALSA plugin. + - The ALSA plugin reports more accurate timing information in some cases. + +## V4l2 + - The v4l2 compatibility layer has received a lot of updates. + - Improved node names and format enumeration. + - Support for multiple /dev/videoX devices, each mapped to a unique + PipeWire node. + - Passes the v4l2-compliance test now with both the v4l2 and libcamera + backend in PipeWire. + - Improved mmap support for inline buffer memory. This makes it possible to + consume PipeWire streams. + - Negotiation works more reliably now. + +## JACK + - Implement jack_acquire_real_time_scheduling() and + jack_drop_real_time_scheduling() by keeping the thread utils in a global + state. + - Fix jack_client_thread_id() to return NULL when the client is not active, + just like jack1 and jack2. + - An option was added to let the jack_set_buffer_size() function update the + global metadata. A quirk was added so that jack_bufsize uses this new feature + to make the buffer size settings persistent and global, just like jack. + - jack_port_register() and jack_port_unregister() can be called on an + active client so make this thread safe. (#2652) + + +Older versions: + # PipeWire 0.3.59 (2022-09-30) This is a bugfix release that is API and ABI compatible with previous @@ -72,9 +220,6 @@ - PIPEWIRE_ALSA can now be used as an environment variable to restrict the plugin formats and buffer size. -Older versions: - - # PipeWire 0.3.58 (2022-09-15) This is a bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.59.tar.gz/doc/pipewire-modules.dox -> pipewire-0.3.60.tar.gz/doc/pipewire-modules.dox
Changed
@@ -73,6 +73,8 @@ - \subpage page_module_raop_discover - \subpage page_module_roc_sink - \subpage page_module_roc_source +- \subpage page_module_rtp_sink +- \subpage page_module_rtp_source - \subpage page_module_rt - \subpage page_module_session_manager - \subpage page_module_x11_bell
View file
pipewire-0.3.59.tar.gz/man/pw-top.1.rst.in -> pipewire-0.3.60.tar.gz/man/pw-top.1.rst.in
Changed
@@ -27,13 +27,15 @@ The columns presented are as follows: S - Measurement status. - ! representing inactive - no connections - - Blank representing active + Node status. + E = ERROR + C = CREATING + S = SUSPENDED + I = IDLE + R = RUNNING ID - The ID of the pipewire node/device, as found in *pw-dump* + The ID of the pipewire node/device, as found in *pw-dump* and *pw-cli* QUANT The current quantum (for drivers) and the suggested quantum for follower @@ -135,6 +137,8 @@ For raw audio formats, the layout is <sampleformat> <channels> <samplerate>. + For IEC958 passthrough audio formats, the layout is IEC958 <codec> <samplerate>. + For DSD formats, the layout is <dsd-rate> <channels>. For Video formats, the layout is <pixelformat> <width>x<height>.
View file
pipewire-0.3.59.tar.gz/meson.build -> pipewire-0.3.60.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.59', + version : '0.3.60', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3', @@ -67,6 +67,7 @@ common_flags = '-fvisibility=hidden', + '-fno-strict-aliasing', '-Werror=suggest-attribute=format', '-Wsign-compare', '-Wpointer-arith', @@ -97,7 +98,7 @@ if have_cpp cxx = meson.get_compiler('cpp') - cxx_flags = common_flags + cxx_flags = common_flags + '-Wno-c99-designator' add_project_arguments(cxx.get_supported_arguments(cxx_flags), language: 'cpp') endif @@ -259,10 +260,10 @@ sdl_dep = dependency('sdl2', required : get_option('sdl2')) summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies') drm_dep = dependency('libdrm', required : false) -readline_dep = dependency('readline', required : false) +readline_dep = dependency('readline', required : get_option('readline')) if not readline_dep.found() - readline_dep = cc.find_library('readline', required: false) + readline_dep = cc.find_library('readline', required : get_option('readline')) endif summary({'readline (for pw-cli)': readline_dep.found()}, bool_yn: true, section: 'Misc dependencies')
View file
pipewire-0.3.59.tar.gz/meson_options.txt -> pipewire-0.3.60.tar.gz/meson_options.txt
Changed
@@ -92,6 +92,10 @@ description: 'Enable HFP in native backend in bluez5 spa plugin', type: 'feature', value: 'enabled') +option('bluez5-backend-native-mm', + description: 'Enable ModemManager in native backend in bluez5 spa plugin', + type: 'feature', + value: 'disabled') option('bluez5-backend-ofono', description: 'Enable oFono HFP backend in bluez5 spa plugin (no dependency on oFono)', type: 'feature', @@ -228,7 +232,7 @@ option('session-managers', description : 'Session managers to build (can be for none or an absolute path)', type : 'array', - value : 'media-session') + value : 'wireplumber') option('raop', description: 'Enable module for Remote Audio Output Protocol', type: 'feature', @@ -261,3 +265,7 @@ description: 'Enable Flatpak support', type: 'feature', value: 'enabled') +option('readline', + description: 'Enable code that depends on libreadline', + type: 'feature', + value: 'auto')
View file
pipewire-0.3.59.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> pipewire-0.3.60.tar.gz/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -123,7 +123,9 @@ struct spa_hook stream_listener; int64_t delay; - uint64_t now; + uint64_t transfered; + uint64_t buffered; + int64_t now; uintptr_t seq; struct spa_audio_info_raw format; @@ -163,21 +165,15 @@ static int update_active(snd_pcm_ioplug_t *io) { snd_pcm_pipewire_t *pw = io->private_data; - bool active; - - active = check_active(io); - - if (pw->active != active) { - uint64_t val; + pw->active = check_active(io); + uint64_t val; - pw->active = active; + if (pw->active || pw->error < 0) + spa_system_eventfd_write(pw->system, io->poll_fd, 1); + else + spa_system_eventfd_read(pw->system, io->poll_fd, &val); - if (active) - spa_system_eventfd_write(pw->system, io->poll_fd, 1); - else - spa_system_eventfd_read(pw->system, io->poll_fd, &val); - } - return active; + return pw->active; } static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw) @@ -233,8 +229,10 @@ return pw->error; *revents = pfds0.revents & ~(POLLIN | POLLOUT); - if (pfds0.revents & POLLIN && check_active(io)) + if (pfds0.revents & POLLIN && check_active(io)) { *revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN; + update_active(io); + } return 0; } @@ -266,7 +264,7 @@ do { seq1 = SEQ_READ(pw->seq); - delay = pw->delay; + delay = pw->delay + pw->transfered; now = pw->now; if (io->stream == SND_PCM_STREAM_PLAYBACK) avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr); @@ -450,9 +448,8 @@ pw_stream_get_time_n(pw->stream, &pwt, sizeof(pwt)); delay = pwt.delay; - if (pwt.rate.num != 0) { + if (pwt.rate.num != 0) delay = delay * io->rate * pwt.rate.num / pwt.rate.denom; - } before = hw_avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr); @@ -467,12 +464,20 @@ SEQ_WRITE(pw->seq); + if (pw->now != pwt.now) { + pw->transfered = pw->buffered; + pw->buffered = 0; + } + xfer = snd_pcm_pipewire_process(pw, b, &hw_avail, want); pw->delay = delay; /* the buffer is now queued in the stream and consumed */ if (io->stream == SND_PCM_STREAM_PLAYBACK) - pw->delay += xfer; + pw->transfered += xfer; + + /* more then requested data transfered, use them in next iteration */ + pw->buffered = (want == 0 || pw->transfered < want) ? 0 : (pw->transfered % want); pw->now = pwt.now; SEQ_WRITE(pw->seq); @@ -563,11 +568,6 @@ goto done; pw->hw_params_changed = false; - if (pw->stream != NULL) { - pw_stream_destroy(pw->stream); - pw->stream = NULL; - } - props = pw_properties_new(NULL, NULL); if (props == NULL) goto error; @@ -593,13 +593,20 @@ pw_properties_get(props, PW_KEY_MEDIA_ROLE) == NULL) pw_properties_setf(props, PW_KEY_MEDIA_ROLE, "%s", pw->role); + params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &pw->format); + + if (pw->stream != NULL) { + pw_stream_update_properties(pw->stream, &props->dict); + pw_stream_update_params(pw->stream, params, 1); + goto done; + } + pw->stream = pw_stream_new(pw->core, pw->node_name, props); if (pw->stream == NULL) goto error; pw_stream_add_listener(pw->stream, &pw->stream_listener, &stream_events, pw); - params0 = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &pw->format); pw->error = 0; pw_stream_connect(pw->stream, @@ -867,10 +874,9 @@ static enum snd_pcm_chmap_position channel_to_chmap(enum spa_audio_channel channel) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(chmap_info); i++) - if (chmap_infoi.channel == channel) - return chmap_infoi.pos; + SPA_FOR_EACH_ELEMENT_VAR(chmap_info, info) + if (info->channel == channel) + return info->pos; return SND_CHMAP_UNKNOWN; }
View file
pipewire-0.3.59.tar.gz/pipewire-jack/jack/uuid.h -> pipewire-0.3.60.tar.gz/pipewire-jack/jack/uuid.h
Changed
@@ -1,18 +1,18 @@ /* Copyright (C) 2013 Paul Davis - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software + along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -30,7 +30,7 @@ #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ #define JACK_UUID_EMPTY_INITIALIZER 0 -extern jack_uuid_t jack_client_uuid_generate (); +extern jack_uuid_t jack_client_uuid_generate (void); extern jack_uuid_t jack_port_uuid_generate (uint32_t port_id); extern uint32_t jack_uuid_to_index (jack_uuid_t);
View file
pipewire-0.3.59.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.60.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -98,6 +98,7 @@ pthread_mutex_t lock; struct pw_array descriptions; struct spa_list free_objects; + struct spa_thread_utils *thread_utils; }; static struct globals globals; @@ -311,6 +312,7 @@ struct spa_hook proxy_listener; struct metadata *metadata; + struct metadata *settings; uint32_t node_id; uint32_t serial; @@ -401,6 +403,7 @@ int self_connect_mode; int rt_max; unsigned int fix_midi_events:1; + unsigned int global_buffer_size:1; jack_position_t jack_position; jack_transport_state_t jack_state; @@ -610,13 +613,9 @@ { struct mix *m; - if (!p->valid) - return; - spa_list_consume(m, &p->mix, port_link) free_mix(c, m); - p->valid = false; pw_map_remove(&c->portsp->direction, p->port_id); free_object(c, p->object); pw_properties_free(p->props); @@ -1056,7 +1055,7 @@ struct buffer *b; struct spa_data *d; - if (frames == 0) + if (frames == 0 || !p->valid) return NULL; if (SPA_UNLIKELY((mix = p->global_mix) == NULL)) @@ -2576,11 +2575,18 @@ return spa_thread_utils_acquire_rt(c->context.old_thread_utils, thread, priority); } +static int impl_drop_rt(void *object, struct spa_thread *thread) +{ + struct client *c = (struct client *) object; + return spa_thread_utils_drop_rt(c->context.old_thread_utils, thread); +} + static struct spa_thread_utils_methods thread_utils_impl = { SPA_VERSION_THREAD_UTILS_METHODS, .create = impl_create, .join = impl_join, .acquire_rt = impl_acquire_rt, + .drop_rt = impl_drop_rt, }; static jack_port_type_id_t string_to_type(const char *port_type) @@ -2721,6 +2727,24 @@ .destroy = metadata_proxy_destroy, }; +static void settings_proxy_removed(void *data) +{ + struct client *c = data; + pw_proxy_destroy((struct pw_proxy*)c->settings->proxy); +} + +static void settings_proxy_destroy(void *data) +{ + struct client *c = data; + spa_hook_remove(&c->settings->proxy_listener); + c->settings = NULL; +} + +static const struct pw_proxy_events settings_proxy_events = { + PW_VERSION_PROXY_EVENTS, + .removed = settings_proxy_removed, + .destroy = settings_proxy_destroy, +}; static void proxy_removed(void *data) { struct object *o = data; @@ -3033,24 +3057,34 @@ if (c->metadata != NULL) goto exit; - if ((str = spa_dict_lookup(props, PW_KEY_METADATA_NAME)) != NULL && - !spa_streq(str, "default")) + if ((str = spa_dict_lookup(props, PW_KEY_METADATA_NAME)) == NULL) goto exit; - proxy = pw_registry_bind(c->registry, - id, type, PW_VERSION_METADATA, sizeof(struct metadata)); - - c->metadata = pw_proxy_get_user_data(proxy); - c->metadata->proxy = (struct pw_metadata*)proxy; - c->metadata->default_audio_sink0 = '\0'; - c->metadata->default_audio_source0 = '\0'; - - pw_proxy_add_listener(proxy, - &c->metadata->proxy_listener, - &metadata_proxy_events, c); - pw_metadata_add_listener(proxy, - &c->metadata->listener, - &metadata_events, c); + if (spa_streq(str, "default")) { + proxy = pw_registry_bind(c->registry, + id, type, PW_VERSION_METADATA, sizeof(struct metadata)); + + c->metadata = pw_proxy_get_user_data(proxy); + c->metadata->proxy = (struct pw_metadata*)proxy; + c->metadata->default_audio_sink0 = '\0'; + c->metadata->default_audio_source0 = '\0'; + + pw_proxy_add_listener(proxy, + &c->metadata->proxy_listener, + &metadata_proxy_events, c); + pw_metadata_add_listener(proxy, + &c->metadata->listener, + &metadata_events, c); + } else if (spa_streq(str, "settings")) { + proxy = pw_registry_bind(c->registry, + id, type, PW_VERSION_METADATA, sizeof(struct metadata)); + + c->settings = pw_proxy_get_user_data(proxy); + c->settings->proxy = (struct pw_metadata*)proxy; + pw_proxy_add_listener(proxy, + &c->settings->proxy_listener, + &settings_proxy_events, c); + } goto exit; } else { @@ -3303,6 +3337,8 @@ if (client->context.old_thread_utils == NULL) client->context.old_thread_utils = pw_thread_utils_get(); + globals.thread_utils = client->context.old_thread_utils; + client->context.thread_utils.iface = SPA_INTERFACE_INIT( SPA_TYPE_INTERFACE_ThreadUtils, SPA_VERSION_THREAD_UTILS, @@ -3411,6 +3447,7 @@ client->locked_process = pw_properties_get_bool(client->props, "jack.locked-process", true); client->default_as_system = pw_properties_get_bool(client->props, "jack.default-as-system", false); client->fix_midi_events = pw_properties_get_bool(client->props, "jack.fix-midi-events", true); + client->global_buffer_size = pw_properties_get_bool(client->props, "jack.global-buffer-size", false); client->self_connect_mode = SELF_CONNECT_ALLOW; if ((str = pw_properties_get(client->props, "jack.self-connect-mode")) != NULL) { @@ -3509,10 +3546,11 @@ pw_proxy_destroy((struct pw_proxy*)c->registry); } if (c->metadata && c->metadata->proxy) { - spa_hook_remove(&c->metadata->listener); - spa_hook_remove(&c->metadata->proxy_listener); pw_proxy_destroy((struct pw_proxy*)c->metadata->proxy); } + if (c->settings && c->settings->proxy) { + pw_proxy_destroy((struct pw_proxy*)c->settings->proxy); + } if (c->core) { spa_hook_remove(&c->core_listener); @@ -3773,14 +3811,10 @@ jack_native_thread_t jack_client_thread_id (jack_client_t *client) { struct client *c = (struct client *) client; - void *thr; spa_return_val_if_fail(c != NULL, (pthread_t){0}); - thr = pw_data_loop_get_thread(c->loop); - if (thr == NULL) - return pthread_self(); - return (pthread_t) thr; + return (jack_native_thread_t)pw_data_loop_get_thread(c->loop); } SPA_EXPORT @@ -4137,15 +4171,22 @@ pw_log_info("%p: buffer-size %u", client, nframes); pw_thread_loop_lock(c->context.loop); - pw_properties_setf(c->props, PW_KEY_NODE_FORCE_QUANTUM, "%u", nframes); + if (c->global_buffer_size && c->settings && c->settings->proxy) { + char val256; + snprintf(val, sizeof(val), "%u", nframes == 1 ? 0: nframes); + pw_metadata_set_property(c->settings->proxy, 0, + "clock.force-quantum", "", val); + } else {
View file
pipewire-0.3.59.tar.gz/pipewire-jack/src/uuid.c -> pipewire-0.3.60.tar.gz/pipewire-jack/src/uuid.c
Changed
@@ -33,7 +33,7 @@ #include <pipewire/pipewire.h> SPA_EXPORT -jack_uuid_t jack_client_uuid_generate () +jack_uuid_t jack_client_uuid_generate (void) { static uint32_t uuid_cnt = 0; jack_uuid_t uuid = 0x2; /* JackUUIDClient */;
View file
pipewire-0.3.59.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.60.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c
Changed
@@ -57,6 +57,7 @@ #define DEFAULT_CARD "PipeWire Camera" #define DEFAULT_BUS_INFO "PipeWire" +#define MAX_DEV 32 struct file_map { void *addr; struct file *file; @@ -64,6 +65,8 @@ struct fd_map { int fd; +#define FD_MAP_DUP (1<<0) + uint32_t flags; struct file *file; }; @@ -73,6 +76,7 @@ pthread_mutex_t lock; struct pw_array fd_maps; struct pw_array file_maps; + uint32_t dev_mapMAX_DEV; }; static struct globals globals; @@ -93,6 +97,9 @@ struct file { int ref; + uint32_t dev_id; + uint32_t serial; + struct pw_properties *props; struct pw_thread_loop *loop; struct pw_loop *l; @@ -114,23 +121,27 @@ struct pw_stream *stream; struct spa_hook stream_listener; + enum v4l2_priority priority; + struct v4l2_format v4l2_format; uint32_t reqbufs; + int reqbufs_fd; struct buffer buffersMAX_BUFFERS; uint32_t n_buffers; uint32_t size; + uint32_t sequence; + struct pw_array buffer_maps; uint32_t last_fourcc; unsigned int running:1; + unsigned int closed:1; int fd; }; -#define MAX_PARAMS 32 - struct global_info { const char *type; uint32_t version; @@ -156,8 +167,8 @@ int changed; void *info; + struct spa_list pending_list; struct spa_list param_list; - int param_seqMAX_PARAMS; union { struct { @@ -173,6 +184,7 @@ struct param { struct spa_list link; uint32_t id; + int32_t seq; struct spa_pod *param; }; @@ -192,7 +204,7 @@ } static struct param *add_param(struct spa_list *params, - int seq, int *param_seq, uint32_t id, const struct spa_pod *param) + int seq, uint32_t id, const struct spa_pod *param) { struct param *p; @@ -204,24 +216,12 @@ id = SPA_POD_OBJECT_ID(param); } - if (id >= MAX_PARAMS) { - pw_log_error("too big param id %d", id); - errno = EINVAL; - return NULL; - } - - if (seq != param_seqid) { - pw_log_debug("ignoring param %d, seq:%d != current_seq:%d", - id, seq, param_seqid); - errno = EBUSY; - return NULL; - } - p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0)); if (p == NULL) return NULL; p->id = id; + p->seq = seq; if (param != NULL) { p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod); memcpy(p->param, param, SPA_POD_SIZE(param)); @@ -234,6 +234,39 @@ return p; } +static void update_params(struct file *file) +{ + struct param *p, *t; + struct global *node; + struct pw_node_info *info; + uint32_t i; + + if ((node = file->node) == NULL) + return; + if ((info = node->info) == NULL) + return; + + for (i = 0; i < info->n_params; i++) { + spa_list_for_each_safe(p, t, &node->pending_list, link) { + if (p->id == info->paramsi.id && + p->seq != info->paramsi.seq && + p->param != NULL) { + spa_list_remove(&p->link); + free(p); + } + } + } + + spa_list_consume(p, &node->pending_list, link) { + spa_list_remove(&p->link); + if (p->param == NULL) { + clear_params(&node->param_list, p->id); + free(p); + } else { + spa_list_append(&node->param_list, &p->link); + } + } +} #define ATOMIC_DEC(s) __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST) #define ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST) @@ -247,6 +280,8 @@ file->ref = 1; file->fd = -1; + file->reqbufs_fd = -1; + file->priority = V4L2_PRIORITY_DEFAULT; spa_list_init(&file->globals); pw_array_init(&file->buffer_maps, sizeof(struct buffer_map) * MAX_BUFFERS); return file; @@ -254,6 +289,8 @@ static void free_file(struct file *file) { + pw_log_info("file:%d", file->fd); + if (file->loop) pw_thread_loop_stop(file->loop); @@ -282,49 +319,99 @@ static void unref_file(struct file *file) { + pw_log_debug("file:%d ref:%d", file->fd, file->ref); if (ATOMIC_DEC(file->ref) <= 0) free_file(file); } -static int add_fd_map(int fd, struct file *file) +static int add_fd_map(int fd, struct file *file, uint32_t flags) { struct fd_map *map; pthread_mutex_lock(&globals.lock); map = pw_array_add(&globals.fd_maps, sizeof(*map)); if (map != NULL) { map->fd = fd; + map->flags = flags; map->file = file; ATOMIC_INC(file->ref); + pw_log_debug("fd:%d -> file:%d ref:%d", fd, file->fd, file->ref); } pthread_mutex_unlock(&globals.lock); return 0;
View file
pipewire-0.3.59.tar.gz/pipewire-v4l2/src/pw-v4l2.in -> pipewire-0.3.60.tar.gz/pipewire-v4l2/src/pw-v4l2.in
Changed
@@ -54,10 +54,16 @@ shift $(( OPTIND - 1 )) +if "$PW_UNINSTALLED" = 1 ; then + PW_V4L2_LD_PRELOAD="$PW_BUILDDIR"'/pipewire-v4l2/src/libpw-v4l2.so' +else + PW_V4L2_LD_PRELOAD='@LIBV4L2_PATH@/libpw-v4l2.so' +fi + if "$LD_PRELOAD" = "" ; then - LD_PRELOAD='@LIBV4L2_PATH@/libpw-v4l2.so' + LD_PRELOAD="$PW_V4L2_LD_PRELOAD" else - LD_PRELOAD="$LD_PRELOAD "'@LIBV4L2_PATH@/libpw-v4l2.so' + LD_PRELOAD="$LD_PRELOAD $PW_V4L2_LD_PRELOAD" fi export LD_PRELOAD
View file
pipewire-0.3.59.tar.gz/po/cs.po -> pipewire-0.3.60.tar.gz/po/cs.po
Changed
@@ -8,10 +8,10 @@ msgid "" msgstr "" "Project-Id-Version: pipewire.master-tx\n" -"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/" -"issues/new\n" -"POT-Creation-Date: 2021-04-18 16:54+0800\n" -"PO-Revision-Date: 2021-10-12 14:18+0200\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" +"issues\n" +"POT-Creation-Date: 2022-09-15 15:26+0000\n" +"PO-Revision-Date: 2022-10-21 16:44+0200\n" "Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n" "Language-Team: čeština <gnome-cs-list@gnome.org>\n" "Language: cs\n" @@ -19,9 +19,9 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Poedit 3.0\n" +"X-Generator: Poedit 3.1.1\n" -#: src/daemon/pipewire.c:43 +#: src/daemon/pipewire.c:46 #, c-format msgid "" "%s options\n" @@ -42,36 +42,52 @@ msgid "Start the PipeWire Media System" msgstr "Spustit multimediální systém PipeWire" -#: src/examples/media-session/alsa-monitor.c:526 -#: spa/plugins/alsa/acp/compat.c:187 -msgid "Built-in Audio" -msgstr "Vnitřní zvukový systém" +#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180 +#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180 +#, c-format +msgid "Tunnel to %s/%s" +msgstr "Tunel do %s/%s" -#: src/examples/media-session/alsa-monitor.c:530 -#: spa/plugins/alsa/acp/compat.c:192 -msgid "Modem" -msgstr "Modem" +#: src/modules/module-fallback-sink.c:51 +#| msgid "Game Output" +msgid "Dummy Output" +msgstr "Předstíraný výstup" -#: src/examples/media-session/alsa-monitor.c:539 +#: src/modules/module-pulse-tunnel.c:662 +#, c-format +msgid "Tunnel for %s@%s" +msgstr "Tunel pro %s@%s" + +#: src/modules/module-zeroconf-discover.c:332 msgid "Unknown device" msgstr "Neznámé zařízení" -#: src/tools/pw-cat.c:991 +#: src/modules/module-zeroconf-discover.c:344 +#, c-format +msgid "%s on %s@%s" +msgstr "%s na %s@%s" + +#: src/modules/module-zeroconf-discover.c:348 +#, c-format +msgid "%s on %s" +msgstr "%s na %s" + +#: src/tools/pw-cat.c:784 #, c-format msgid "" -"%s options <file>\n" +"%s options <file>|-\n" " -h, --help Show this help\n" " --version Show version\n" " -v, --verbose Enable verbose operations\n" "\n" msgstr "" -"%s volby <soubor>\n" +"%s volby <soubor>|-\n" " -h, --help Zobrazit tuto nápovědu\n" " --version Zobrazit verzi\n" " -v, --verbose Povolit podrobné operace\n" "\n" -#: src/tools/pw-cat.c:998 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -85,7 +101,7 @@ " or direct samples (256)\n" " the rate is the one of the source " "file\n" -" --list-targets List available targets for --target\n" +" -P --properties Set node properties\n" "\n" msgstr "" " -R, --remote Název vzdáleného démonu\n" @@ -102,10 +118,10 @@ " nebo přímé vzorky (256)\n" " frekvence je stejná jako u " "zdrojového souboru\n" -" --list-targets Zobrazit dostupné cíle pro --target\n" +" -P --properties Nastavit vlastnosti uzlu\n" "\n" -#: src/tools/pw-cat.c:1016 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -141,19 +157,21 @@ "je %d)\n" "\n" -#: src/tools/pw-cat.c:1033 +#: src/tools/pw-cat.c:826 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" " -m, --midi Midi mode\n" +" -d, --dsd DSD mode\n" "\n" msgstr "" " -p, --playback Playback mód\n" " -r, --record Recording mód\n" " -m, --midi Midi mód\n" +" -d, --dsd DSD mód\n" "\n" -#: src/tools/pw-cli.c:2932 +#: src/tools/pw-cli.c:2255 #, c-format msgid "" "%s options command\n" @@ -171,199 +189,195 @@ " -r, --remote Název vzdáleného démonu\n" "\n" -#: spa/plugins/alsa/acp/acp.c:290 +#: spa/plugins/alsa/acp/acp.c:321 msgid "Pro Audio" msgstr "Pro Audio" -#: spa/plugins/alsa/acp/acp.c:411 spa/plugins/alsa/acp/alsa-mixer.c:4704 -#: spa/plugins/bluez5/bluez5-device.c:1000 +#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "Vypnuto" -#: spa/plugins/alsa/acp/channelmap.h:466 -msgid "(invalid)" -msgstr "(neplatné)" - -#: spa/plugins/alsa/acp/alsa-mixer.c:2709 +#: spa/plugins/alsa/acp/alsa-mixer.c:2652 msgid "Input" msgstr "Vstup" -#: spa/plugins/alsa/acp/alsa-mixer.c:2710 +#: spa/plugins/alsa/acp/alsa-mixer.c:2653 msgid "Docking Station Input" msgstr "Vstup dokovací stanice" -#: spa/plugins/alsa/acp/alsa-mixer.c:2711 +#: spa/plugins/alsa/acp/alsa-mixer.c:2654 msgid "Docking Station Microphone" msgstr "Mikrofon dokovací stanice" -#: spa/plugins/alsa/acp/alsa-mixer.c:2712 +#: spa/plugins/alsa/acp/alsa-mixer.c:2655 msgid "Docking Station Line In" msgstr "Linkový vstup dokovací stanice" -#: spa/plugins/alsa/acp/alsa-mixer.c:2713 -#: spa/plugins/alsa/acp/alsa-mixer.c:2804 +#: spa/plugins/alsa/acp/alsa-mixer.c:2656 +#: spa/plugins/alsa/acp/alsa-mixer.c:2747 msgid "Line In" msgstr "Linkový vstup" -#: spa/plugins/alsa/acp/alsa-mixer.c:2714 -#: spa/plugins/alsa/acp/alsa-mixer.c:2798 -#: spa/plugins/bluez5/bluez5-device.c:1145 +#: spa/plugins/alsa/acp/alsa-mixer.c:2657 +#: spa/plugins/alsa/acp/alsa-mixer.c:2741 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "Mikrofon" -#: spa/plugins/alsa/acp/alsa-mixer.c:2715 -#: spa/plugins/alsa/acp/alsa-mixer.c:2799 +#: spa/plugins/alsa/acp/alsa-mixer.c:2658 +#: spa/plugins/alsa/acp/alsa-mixer.c:2742 msgid "Front Microphone"
View file
pipewire-0.3.59.tar.gz/po/hr.po -> pipewire-0.3.60.tar.gz/po/hr.po
Changed
@@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-06-30 12:50+0200\n" -"PO-Revision-Date: 2022-06-30 13:14+0200\n" +"POT-Creation-Date: 2022-10-01 14:01+0200\n" +"PO-Revision-Date: 2022-10-01 14:12+0200\n" "Last-Translator: gogo <trebelnik2@gmail.com>\n" "Language-Team: Croatian <https://translate.fedoraproject.org/projects/" "pipewire/pipewire/hr/>\n" @@ -16,9 +16,9 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Poedit 2.3\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Poedit 3.0.1\n" "X-Launchpad-Export-Date: 2017-04-20 21:04+0000\n" #: src/daemon/pipewire.c:46 @@ -44,7 +44,7 @@ msgid "Dummy Output" msgstr "Lažni izlaz" -#: src/modules/module-pulse-tunnel.c:648 +#: src/modules/module-pulse-tunnel.c:662 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunel za %s@%s" @@ -164,7 +164,7 @@ " -d, --dsd DSD način\n" "\n" -#: src/tools/pw-cli.c:3165 +#: src/tools/pw-cli.c:2250 #, c-format msgid "" "%s options command\n" @@ -187,8 +187,8 @@ msgid "Pro Audio" msgstr "Pro Audio" -#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1161 +#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "Isključeno" @@ -215,7 +215,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1330 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "Mikrofon" @@ -281,7 +281,7 @@ msgstr "Bez pojačanja basa" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1335 +#: spa/plugins/bluez5/bluez5-device.c:1460 msgid "Speaker" msgstr "Zvučnik" @@ -396,7 +396,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1320 +#: spa/plugins/bluez5/bluez5-device.c:1442 msgid "Headset" msgstr "Slušalice s mikrofonom" @@ -520,7 +520,8 @@ msgid "%s Input" msgstr "%s ulaz" -#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267 +#: spa/plugins/alsa/acp/alsa-util.c:1187 +#: spa/plugins/alsa/acp/alsa-util.c:1281 #, c-format msgid "" "snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu " @@ -548,16 +549,16 @@ "Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite " "problem ALSA razvijateljima." -#: spa/plugins/alsa/acp/alsa-util.c:1239 +#: spa/plugins/alsa/acp/alsa-util.c:1253 #, c-format msgid "" -"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s" -"%lu ms).\n" +"snd_pcm_delay() returned a value that is exceptionally large: %li byte " +"(%s%lu ms).\n" "Most likely this is a bug in the ALSA driver '%s'. Please report this issue " "to the ALSA developers." msgid_plural "" -"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s" -"%lu ms).\n" +"snd_pcm_delay() returned a value that is exceptionally large: %li bytes " +"(%s%lu ms).\n" "Most likely this is a bug in the ALSA driver '%s'. Please report this issue " "to the ALSA developers." msgstr0 "" @@ -566,17 +567,17 @@ "Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite " "problem ALSA razvijateljima." msgstr1 "" -"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta (%s" -"%lu ms).\n" +"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta " +"(%s%lu ms).\n" "Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite " "problem ALSA razvijateljima." msgstr2 "" -"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta (%s" -"%lu ms).\n" +"snd_pcm_delay() je vratio vrijednost koja je iznimno velika: %li bajta " +"(%s%lu ms).\n" "Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite " "problem ALSA razvijateljima." -#: spa/plugins/alsa/acp/alsa-util.c:1286 +#: spa/plugins/alsa/acp/alsa-util.c:1300 #, c-format msgid "" "snd_pcm_avail_delay() returned strange values: delay %lu is less than avail " @@ -589,7 +590,7 @@ "Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite " "problem ALSA razvijateljima." -#: spa/plugins/alsa/acp/alsa-util.c:1329 +#: spa/plugins/alsa/acp/alsa-util.c:1343 #, c-format msgid "" "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte " @@ -629,65 +630,96 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1172 +#: spa/plugins/bluez5/bluez5-device.c:1247 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "Zvučni pristupnik (A2DP izvor i HSP/HFP AG)" -#: spa/plugins/bluez5/bluez5-device.c:1197 +#: spa/plugins/bluez5/bluez5-device.c:1272 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" msgstr "Reprodukcija visoke autentičnosti (A2DP slivnik, kôdek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1200 +#: spa/plugins/bluez5/bluez5-device.c:1275 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" msgstr "Telefonija visoke autentičnosti (A2DP slivnik, kôdek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1208 +#: spa/plugins/bluez5/bluez5-device.c:1283 msgid "High Fidelity Playback (A2DP Sink)" msgstr "Reprodukcija visoke autentičnosti (A2DP slivnik)" -#: spa/plugins/bluez5/bluez5-device.c:1210 +#: spa/plugins/bluez5/bluez5-device.c:1285 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "Telefonija visoke autentičnosti (A2DP izvor/slivnik)" -#: spa/plugins/bluez5/bluez5-device.c:1238 +#: spa/plugins/bluez5/bluez5-device.c:1322 +#, c-format +msgid "High Fidelity Playback (BAP Sink, codec %s)" +msgstr "Reprodukcija visoke autentičnosti (BAP slivnik, kôdek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1326 +#, c-format +msgid "High Fidelity Input (BAP Source, codec %s)" +msgstr "Ulaz visoke autentičnosti (BAP izvor, kôdek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1330 +#, c-format +msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)" +msgstr "Telefonija visoke autentičnosti (BAP izvor/slivnik, kôdek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1359 #, c-format msgid "Headset Head Unit (HSP/HFP, codec %s)" msgstr "Jedinica slušalice s mikrofonom (HSP/HFP, kôdek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1243 +#: spa/plugins/bluez5/bluez5-device.c:1364 msgid "Headset Head Unit (HSP/HFP)" msgstr "Jedinica slušalice s mikrofonom (HSP/HFP)"
View file
pipewire-0.3.59.tar.gz/po/pipewire.pot -> pipewire-0.3.60.tar.gz/po/pipewire.pot
Changed
@@ -37,7 +37,7 @@ msgid "Dummy Output" msgstr "" -#: src/modules/module-pulse-tunnel.c:648 +#: src/modules/module-pulse-tunnel.c:662 #, c-format msgid "Tunnel for %s@%s" msgstr "" @@ -113,7 +113,7 @@ "\n" msgstr "" -#: src/tools/pw-cli.c:3165 +#: src/tools/pw-cli.c:2250 #, c-format msgid "" "%s options command\n" @@ -128,8 +128,8 @@ msgid "Pro Audio" msgstr "" -#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1161 +#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "" @@ -156,7 +156,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1330 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "" @@ -222,7 +222,7 @@ msgstr "" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1335 +#: spa/plugins/bluez5/bluez5-device.c:1460 msgid "Speaker" msgstr "" @@ -337,7 +337,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1320 +#: spa/plugins/bluez5/bluez5-device.c:1442 msgid "Headset" msgstr "" @@ -461,8 +461,8 @@ msgid "%s Input" msgstr "" -#: spa/plugins/alsa/acp/alsa-util.c:1173 -#: spa/plugins/alsa/acp/alsa-util.c:1267 +#: spa/plugins/alsa/acp/alsa-util.c:1187 +#: spa/plugins/alsa/acp/alsa-util.c:1281 #, c-format msgid "" "snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu " @@ -477,22 +477,22 @@ msgstr0 "" msgstr1 "" -#: spa/plugins/alsa/acp/alsa-util.c:1239 +#: spa/plugins/alsa/acp/alsa-util.c:1253 #, c-format msgid "" -"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s" -"%lu ms).\n" +"snd_pcm_delay() returned a value that is exceptionally large: %li byte " +"(%s%lu ms).\n" "Most likely this is a bug in the ALSA driver '%s'. Please report this issue " "to the ALSA developers." msgid_plural "" -"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s" -"%lu ms).\n" +"snd_pcm_delay() returned a value that is exceptionally large: %li bytes " +"(%s%lu ms).\n" "Most likely this is a bug in the ALSA driver '%s'. Please report this issue " "to the ALSA developers." msgstr0 "" msgstr1 "" -#: spa/plugins/alsa/acp/alsa-util.c:1286 +#: spa/plugins/alsa/acp/alsa-util.c:1300 #, c-format msgid "" "snd_pcm_avail_delay() returned strange values: delay %lu is less than avail " @@ -501,7 +501,7 @@ "to the ALSA developers." msgstr "" -#: spa/plugins/alsa/acp/alsa-util.c:1329 +#: spa/plugins/alsa/acp/alsa-util.c:1343 #, c-format msgid "" "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte " @@ -528,61 +528,92 @@ msgid "Modem" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1172 +#: spa/plugins/bluez5/bluez5-device.c:1247 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1197 +#: spa/plugins/bluez5/bluez5-device.c:1272 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1200 +#: spa/plugins/bluez5/bluez5-device.c:1275 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1208 +#: spa/plugins/bluez5/bluez5-device.c:1283 msgid "High Fidelity Playback (A2DP Sink)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1210 +#: spa/plugins/bluez5/bluez5-device.c:1285 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1238 +#: spa/plugins/bluez5/bluez5-device.c:1322 +#, c-format +msgid "High Fidelity Playback (BAP Sink, codec %s)" +msgstr "" + +#: spa/plugins/bluez5/bluez5-device.c:1326 +#, c-format +msgid "High Fidelity Input (BAP Source, codec %s)" +msgstr "" + +#: spa/plugins/bluez5/bluez5-device.c:1330 +#, c-format +msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)" +msgstr "" + +#: spa/plugins/bluez5/bluez5-device.c:1359 #, c-format msgid "Headset Head Unit (HSP/HFP, codec %s)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1243 +#: spa/plugins/bluez5/bluez5-device.c:1364 msgid "Headset Head Unit (HSP/HFP)" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1325 +#: spa/plugins/bluez5/bluez5-device.c:1443 +#: spa/plugins/bluez5/bluez5-device.c:1448 +#: spa/plugins/bluez5/bluez5-device.c:1455 +#: spa/plugins/bluez5/bluez5-device.c:1461 +#: spa/plugins/bluez5/bluez5-device.c:1467 +#: spa/plugins/bluez5/bluez5-device.c:1473 +#: spa/plugins/bluez5/bluez5-device.c:1479 +#: spa/plugins/bluez5/bluez5-device.c:1485 +#: spa/plugins/bluez5/bluez5-device.c:1491 msgid "Handsfree" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1340 +#: spa/plugins/bluez5/bluez5-device.c:1449 +msgid "Handsfree (HFP)" +msgstr "" + +#: spa/plugins/bluez5/bluez5-device.c:1466 msgid "Headphone" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1345 +#: spa/plugins/bluez5/bluez5-device.c:1472 msgid "Portable" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1350 +#: spa/plugins/bluez5/bluez5-device.c:1478 msgid "Car" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1355 +#: spa/plugins/bluez5/bluez5-device.c:1484 msgid "HiFi" msgstr "" -#: spa/plugins/bluez5/bluez5-device.c:1360
View file
pipewire-0.3.59.tar.gz/po/pt_BR.po -> pipewire-0.3.60.tar.gz/po/pt_BR.po
Changed
@@ -1,18 +1,19 @@ # Brazilian Portuguese translation for pipewire -# Copyright (C) 2021 Rafael Fontenelle <rafaelff@gnome.org> +# Copyright (C) 2022 Rafael Fontenelle <rafaelff@gnome.org> # This file is distributed under the same license as the pipewire package. # Fabian Affolter <fab@fedoraproject.org>, 2008. # Igor Pires Soares <igor@projetofedora.org>, 2009, 2012. # Rafael Fontenelle <rafaelff@gnome.org>, 2013-2021. +# Matheus Barbosa <mdpb.matheus@gmail.com>, 2022. # msgid "" msgstr "" "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2021-08-01 15:31+0000\n" -"PO-Revision-Date: 2021-08-01 17:02-0300\n" -"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n" +"POT-Creation-Date: 2022-09-30 03:27+0000\n" +"PO-Revision-Date: 2022-01-25 19:49-0300\n" +"Last-Translator: Matheus Barbosa <mdpb.matheus@gmail.com>\n" "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" @@ -21,7 +22,7 @@ "Plural-Forms: nplurals=2; plural=(n > 1)\n" "X-Generator: Gtranslator 40.0\n" -#: src/daemon/pipewire.c:45 +#: src/daemon/pipewire.c:46 #, c-format msgid "" "%s options\n" @@ -43,58 +44,51 @@ msgid "Start the PipeWire Media System" msgstr "Inicia o Sistema de Mídia PipeWire" -#: src/examples/media-session/alsa-monitor.c:586 -#: spa/plugins/alsa/acp/compat.c:189 -msgid "Built-in Audio" -msgstr "Áudio interno" - -#: src/examples/media-session/alsa-monitor.c:590 -#: spa/plugins/alsa/acp/compat.c:194 -msgid "Modem" -msgstr "Modem" - -#: src/examples/media-session/alsa-monitor.c:599 -#: src/modules/module-zeroconf-discover.c:296 -msgid "Unknown device" -msgstr "Dispositivo desconhecido" - -#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:173 -#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:173 +#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180 +#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180 #, c-format msgid "Tunnel to %s/%s" msgstr "Túnel para %s/%s" -#: src/modules/module-pulse-tunnel.c:534 +#: src/modules/module-fallback-sink.c:51 +msgid "Dummy Output" +msgstr "Saída de falsa" + +#: src/modules/module-pulse-tunnel.c:662 #, c-format msgid "Tunnel for %s@%s" msgstr "Túnel para %s@%s" -#: src/modules/module-zeroconf-discover.c:308 +#: src/modules/module-zeroconf-discover.c:332 +msgid "Unknown device" +msgstr "Dispositivo desconhecido" + +#: src/modules/module-zeroconf-discover.c:344 #, c-format msgid "%s on %s@%s" msgstr "%s em %s@%s" -#: src/modules/module-zeroconf-discover.c:312 +#: src/modules/module-zeroconf-discover.c:348 #, c-format msgid "%s on %s" msgstr "%s em %s" -#: src/tools/pw-cat.c:1000 +#: src/tools/pw-cat.c:784 #, c-format msgid "" -"%s options <file>\n" +"%s options <file>|-\n" " -h, --help Show this help\n" " --version Show version\n" " -v, --verbose Enable verbose operations\n" "\n" msgstr "" -"%s opções <arquivo>\n" +"%s opções <arquivo>|-\n" " -h, --help Mostra esta ajuda\n" " --version Mostra a versão\n" " -v, --verbose Habilita operações verbosas\n" "\n" -#: src/tools/pw-cat.c:1007 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -108,7 +102,7 @@ " or direct samples (256)\n" " the rate is the one of the source " "file\n" -" --list-targets List available targets for --target\n" +" -P --properties Set node properties\n" "\n" msgstr "" " -R, --remote Nome do daemon remoto\n" @@ -124,11 +118,10 @@ " Xunit (unidade = s, ms, us, ns)\n" " ou amostras diretas (256)\n" " a taxa é um dos arquivos fontes\n" -" --list-targets Lista alvos disponíveis para --" -"target\n" +" --properties Define as propriedades do nó\n" "\n" -#: src/tools/pw-cat.c:1025 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -165,19 +158,21 @@ "(padrão: %d)\n" "\n" -#: src/tools/pw-cat.c:1042 +#: src/tools/pw-cat.c:826 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" " -m, --midi Midi mode\n" +" -d, --dsd DSD mode\n" "\n" msgstr "" " -p, --playback Modo de reprodução\n" " -r, --record Modo de gravação\n" -" -m, --midi Modo midi\n" +" -m, --midi Modo Midi\n" +" -d, --dsd Modo DSD\n" "\n" -#: src/tools/pw-cli.c:2954 +#: src/tools/pw-cli.c:2255 #, c-format msgid "" "%s options command\n" @@ -194,12 +189,12 @@ " -r, --remote Nome do daemon remoto\n" "\n" -#: spa/plugins/alsa/acp/acp.c:306 +#: spa/plugins/alsa/acp/acp.c:321 msgid "Pro Audio" msgstr "Pro Audio" -#: spa/plugins/alsa/acp/acp.c:429 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1043 +#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "Desligado" @@ -226,7 +221,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1198 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "Microfone" @@ -298,7 +293,7 @@ msgstr "Sem reforço de graves" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1203 +#: spa/plugins/bluez5/bluez5-device.c:1460 msgid "Speaker" msgstr "Auto-falante" @@ -414,7 +409,7 @@ # Fone de ouvido não se encaixa como tradução aqui, pois há ou pode haver microfone junto. #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1188 +#: spa/plugins/bluez5/bluez5-device.c:1442 msgid "Headset" msgstr "Headset"
View file
pipewire-0.3.59.tar.gz/po/sv.po -> pipewire-0.3.60.tar.gz/po/sv.po
Changed
@@ -19,8 +19,8 @@ "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2022-07-19 15:27+0000\n" -"PO-Revision-Date: 2022-07-10 10:22+0200\n" +"POT-Creation-Date: 2022-10-20 15:27+0000\n" +"PO-Revision-Date: 2022-09-16 12:58+0200\n" "Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -28,7 +28,7 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 3.1\n" +"X-Generator: Poedit 3.1.1\n" #: src/daemon/pipewire.c:46 #, c-format @@ -61,26 +61,26 @@ msgid "Dummy Output" msgstr "Attrapputgång" -#: src/modules/module-pulse-tunnel.c:648 +#: src/modules/module-pulse-tunnel.c:681 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunnel för %s@%s" -#: src/modules/module-zeroconf-discover.c:332 +#: src/modules/module-zeroconf-discover.c:335 msgid "Unknown device" msgstr "Okänd enhet" -#: src/modules/module-zeroconf-discover.c:344 +#: src/modules/module-zeroconf-discover.c:347 #, c-format msgid "%s on %s@%s" msgstr "%s på %s@%s" -#: src/modules/module-zeroconf-discover.c:348 +#: src/modules/module-zeroconf-discover.c:351 #, c-format msgid "%s on %s" msgstr "%s på %s" -#: src/tools/pw-cat.c:784 +#: src/tools/pw-cat.c:782 #, c-format msgid "" "%s options <file>|-\n" @@ -95,7 +95,7 @@ " -v, --verbose Aktivera utförliga operationer\n" "\n" -#: src/tools/pw-cat.c:791 +#: src/tools/pw-cat.c:789 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -125,7 +125,7 @@ " -P --properties Sätt nodegenskaper\n" "\n" -#: src/tools/pw-cat.c:809 +#: src/tools/pw-cat.c:807 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -160,7 +160,7 @@ "%d)\n" "\n" -#: src/tools/pw-cat.c:826 +#: src/tools/pw-cat.c:824 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" @@ -174,7 +174,7 @@ " -d, --dsd DSD-läge\n" "\n" -#: src/tools/pw-cli.c:3165 +#: src/tools/pw-cli.c:2250 #, c-format msgid "" "%s options command\n" @@ -195,8 +195,8 @@ msgid "Pro Audio" msgstr "Professionellt ljud" -#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1188 +#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1237 msgid "Off" msgstr "Av" @@ -223,7 +223,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1360 +#: spa/plugins/bluez5/bluez5-device.c:1455 msgid "Microphone" msgstr "Mikrofon" @@ -289,7 +289,7 @@ msgstr "Ingen basökning" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1366 +#: spa/plugins/bluez5/bluez5-device.c:1461 msgid "Speaker" msgstr "Högtalare" @@ -404,7 +404,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1348 +#: spa/plugins/bluez5/bluez5-device.c:1443 msgid "Headset" msgstr "Headset" @@ -528,7 +528,7 @@ msgid "%s Input" msgstr "%s-ingång" -#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267 +#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281 #, c-format msgid "" "snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu " @@ -551,7 +551,7 @@ "Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera " "problemet till ALSA-utvecklarna." -#: spa/plugins/alsa/acp/alsa-util.c:1239 +#: spa/plugins/alsa/acp/alsa-util.c:1253 #, c-format msgid "" "snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s" @@ -574,7 +574,7 @@ "Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera " "problemet till ALSA-utvecklarna." -#: spa/plugins/alsa/acp/alsa-util.c:1286 +#: spa/plugins/alsa/acp/alsa-util.c:1300 #, c-format msgid "" "snd_pcm_avail_delay() returned strange values: delay %lu is less than avail " @@ -587,7 +587,7 @@ "Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera " "problemet till ALSA-utvecklarna." -#: spa/plugins/alsa/acp/alsa-util.c:1329 +#: spa/plugins/alsa/acp/alsa-util.c:1343 #, c-format msgid "" "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte " @@ -622,77 +622,92 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1199 +#: spa/plugins/bluez5/bluez5-device.c:1248 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)" -#: spa/plugins/bluez5/bluez5-device.c:1224 +#: spa/plugins/bluez5/bluez5-device.c:1273 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1227 +#: spa/plugins/bluez5/bluez5-device.c:1276 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1235 +#: spa/plugins/bluez5/bluez5-device.c:1284 msgid "High Fidelity Playback (A2DP Sink)" msgstr "High fidelity-uppspelning (A2DP-utgång)" -#: spa/plugins/bluez5/bluez5-device.c:1237 +#: spa/plugins/bluez5/bluez5-device.c:1286 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "High fidelity duplex (A2DP-källa/utgång)" -#: spa/plugins/bluez5/bluez5-device.c:1265 +#: spa/plugins/bluez5/bluez5-device.c:1323 +#, c-format +msgid "High Fidelity Playback (BAP Sink, codec %s)" +msgstr "High fidelity-uppspelning (BAP-utgång, kodek %s)" + +#: spa/plugins/bluez5/bluez5-device.c:1327
View file
pipewire-0.3.59.tar.gz/po/tr.po -> pipewire-0.3.60.tar.gz/po/tr.po
Changed
@@ -11,8 +11,8 @@ "Project-Id-Version: PipeWire master\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/" "issues/new\n" -"POT-Creation-Date: 2022-04-03 12:56+0200\n" -"PO-Revision-Date: 2022-05-14 18:35+0300\n" +"POT-Creation-Date: 2022-06-30 12:50+0200\n" +"PO-Revision-Date: 2022-10-23 10:40+0300\n" "Last-Translator: Oğuz Ersen <oguz@ersen.moe>\n" "Language-Team: Turkish <tr>\n" "Language: tr\n" @@ -35,8 +35,8 @@ " --version Sürümü göster\n" " -c, --config Yapılandırmayı yükle (Öntanımlı %s)\n" -#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:190 -#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:190 +#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:180 +#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:180 #, c-format msgid "Tunnel to %s/%s" msgstr "%s/%s tüneli" @@ -45,41 +45,41 @@ msgid "Dummy Output" msgstr "Temsili Çıkış" -#: src/modules/module-pulse-tunnel.c:545 +#: src/modules/module-pulse-tunnel.c:662 #, c-format msgid "Tunnel for %s@%s" msgstr "%s@%s için tünel" -#: src/modules/module-zeroconf-discover.c:313 +#: src/modules/module-zeroconf-discover.c:332 msgid "Unknown device" msgstr "Bilinmeyen aygıt" -#: src/modules/module-zeroconf-discover.c:325 +#: src/modules/module-zeroconf-discover.c:344 #, c-format msgid "%s on %s@%s" msgstr "%s, %s@%s" -#: src/modules/module-zeroconf-discover.c:329 +#: src/modules/module-zeroconf-discover.c:348 #, c-format msgid "%s on %s" msgstr "%s, %s" -#: src/tools/pw-cat.c:1087 +#: src/tools/pw-cat.c:784 #, c-format msgid "" -"%s options <file>\n" +"%s options <file>|-\n" " -h, --help Show this help\n" " --version Show version\n" " -v, --verbose Enable verbose operations\n" "\n" msgstr "" -"%s seçenekler <dosya>\n" +"%s seçenekler <dosya>|-\n" " -h, --help Bu yardımı göster\n" " --version Sürümü göster\n" " -v, --verbose Ayrıntılı işlemleri etkinleştir\n" "\n" -#: src/tools/pw-cat.c:1094 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -93,7 +93,7 @@ " or direct samples (256)\n" " the rate is the one of the source " "file\n" -" --list-targets List available targets for --target\n" +" -P --properties Set node properties\n" "\n" msgstr "" " -R, --remote Uzak arka plan programı adı\n" @@ -109,11 +109,10 @@ " Xbirim (birim = s, ms, us, ns)\n" " veya doğrudan örneklemeler (256)\n" " oran kaynak dosyadan biridir\n" -" --list-targets --target için kullanılabilir " -"hedefleri listele\n" +" -P --properties Düğüm özelliklerini ayarla\n" "\n" -#: src/tools/pw-cat.c:1112 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -149,7 +148,7 @@ "15) (öntanımlı %d)\n" "\n" -#: src/tools/pw-cat.c:1129 +#: src/tools/pw-cat.c:826 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" @@ -163,7 +162,7 @@ " -d, --dsd DSD modu\n" "\n" -#: src/tools/pw-cli.c:3051 +#: src/tools/pw-cli.c:2250 #, c-format msgid "" "%s options command\n" @@ -186,7 +185,7 @@ msgstr "Profesyonel Ses" #: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1159 +#: spa/plugins/bluez5/bluez5-device.c:1236 msgid "Off" msgstr "Kapalı" @@ -213,7 +212,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2657 #: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:1328 +#: spa/plugins/bluez5/bluez5-device.c:1454 msgid "Microphone" msgstr "Mikrofon" @@ -279,7 +278,7 @@ msgstr "Bas Artırma Yok" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1333 +#: spa/plugins/bluez5/bluez5-device.c:1460 msgid "Speaker" msgstr "Hoparlör" @@ -394,7 +393,7 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:4484 #: spa/plugins/alsa/acp/alsa-mixer.c:4642 -#: spa/plugins/bluez5/bluez5-device.c:1318 +#: spa/plugins/bluez5/bluez5-device.c:1442 msgid "Headset" msgstr "Kulaklık" @@ -518,7 +517,7 @@ msgid "%s Input" msgstr "%s Girişi" -#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267 +#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281 #, c-format msgid "" "snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu " @@ -535,7 +534,7 @@ "Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA " "geliştiricilerine bildirin." -#: spa/plugins/alsa/acp/alsa-util.c:1239 +#: spa/plugins/alsa/acp/alsa-util.c:1253 #, c-format msgid "" "snd_pcm_delay() returned a value that is exceptionally large: %li byte " @@ -552,7 +551,7 @@ "Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA " "geliştiricilerine bildirin." -#: spa/plugins/alsa/acp/alsa-util.c:1286 +#: spa/plugins/alsa/acp/alsa-util.c:1300 #, c-format msgid "" "snd_pcm_avail_delay() returned strange values: delay %lu is less than avail " @@ -565,7 +564,7 @@ "Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA " "geliştiricilerine bildirin." -#: spa/plugins/alsa/acp/alsa-util.c:1329 +#: spa/plugins/alsa/acp/alsa-util.c:1343 #, c-format msgid "" "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte " @@ -583,7 +582,7 @@ "Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA " "geliştiricilerine bildirin." -#: spa/plugins/alsa/acp/channelmap.h:464 +#: spa/plugins/alsa/acp/channelmap.h:457 msgid "(invalid)" msgstr "(geçersiz)" @@ -595,65 +594,96 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1170 +#: spa/plugins/bluez5/bluez5-device.c:1247
View file
pipewire-0.3.59.tar.gz/pw-uninstalled.sh -> pipewire-0.3.60.tar.gz/pw-uninstalled.sh
Changed
@@ -41,7 +41,7 @@ export SPA_DATA_DIR="${SCRIPT_DIR}/spa/plugins" # the directory with pipewire modules export PIPEWIRE_MODULE_DIR="${BUILDDIR}/src/modules" -export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${PATH}" +export PATH="${BUILDDIR}/src/daemon:${BUILDDIR}/src/tools:${BUILDDIR}/src/media-session:${BUILDDIR}/src/examples:${BUILDDIR}/pipewire-v4l2/src:${PATH}" export LD_LIBRARY_PATH="${BUILDDIR}/src/pipewire/:${BUILDDIR}/pipewire-jack/src/${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}" export GST_PLUGIN_PATH="${BUILDDIR}/src/gst/${GST_PLUGIN_PATH+":${GST_PLUGIN_PATH}"}" # the directory with card profiles and paths @@ -50,6 +50,7 @@ # ALSA plugin directory export ALSA_PLUGIN_DIR="${BUILDDIR}/pipewire-alsa/alsa-plugins" +export PW_BUILDDIR=$BUILDDIR export PW_UNINSTALLED=1 export PKG_CONFIG_PATH="${BUILDDIR}/meson-uninstalled/:${PKG_CONFIG_PATH}"
View file
pipewire-0.3.59.tar.gz/spa/include/spa/interfaces/audio/aec.h -> pipewire-0.3.60.tar.gz/spa/include/spa/interfaces/audio/aec.h
Changed
@@ -23,6 +23,7 @@ */ +#include <spa/pod/builder.h> #include <spa/utils/dict.h> #include <spa/utils/hook.h> #include <spa/param/audio/raw.h> @@ -60,7 +61,7 @@ }; struct spa_audio_aec_methods { -#define SPA_VERSION_AUDIO_AEC_METHODS 1 +#define SPA_VERSION_AUDIO_AEC_METHODS 2 uint32_t version; int (*add_listener) (void *object, @@ -75,6 +76,11 @@ int (*activate) (void *object); /* since 0.3.58, version 1:1 */ int (*deactivate) (void *object); + + /* version 1:2 */ + int (*enum_props) (void* object, int index, struct spa_pod_builder* builder); + int (*get_params) (void* object, struct spa_pod_builder* builder); + int (*set_params) (void *object, const struct spa_pod *args); }; #define spa_audio_aec_method(o,method,version,...) \ @@ -93,6 +99,9 @@ #define spa_audio_aec_set_props(o,...) spa_audio_aec_method(o, set_props, 0, __VA_ARGS__) #define spa_audio_aec_activate(o) spa_audio_aec_method(o, activate, 1) #define spa_audio_aec_deactivate(o) spa_audio_aec_method(o, deactivate, 1) +#define spa_audio_aec_enum_props(o,...) spa_audio_aec_method(o, enum_props, 2, __VA_ARGS__) +#define spa_audio_aec_get_params(o,...) spa_audio_aec_method(o, get_params, 2, __VA_ARGS__) +#define spa_audio_aec_set_params(o,...) spa_audio_aec_method(o, set_params, 2, __VA_ARGS__) #ifdef __cplusplus } /* extern "C" */
View file
pipewire-0.3.59.tar.gz/spa/include/spa/param/audio/format-utils.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/audio/format-utils.h
Changed
@@ -47,9 +47,9 @@ info->flags = 0; res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info->format), - SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate), - SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels), + SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format), + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); if (position == NULL || !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS)) @@ -64,7 +64,7 @@ int res; res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info->format)); + SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format)); return res; } @@ -74,8 +74,8 @@ int res; res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_iec958Codec, SPA_POD_Id(&info->codec), - SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate)); + SPA_FORMAT_AUDIO_iec958Codec, SPA_POD_OPT_Id(&info->codec), + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate)); return res; } @@ -87,10 +87,10 @@ info->flags = 0; res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_bitorder, SPA_POD_Id(&info->bitorder), - SPA_FORMAT_AUDIO_interleave, SPA_POD_Int(&info->interleave), - SPA_FORMAT_AUDIO_rate, SPA_POD_Int(&info->rate), - SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels), + SPA_FORMAT_AUDIO_bitorder, SPA_POD_OPT_Id(&info->bitorder), + SPA_FORMAT_AUDIO_interleave, SPA_POD_OPT_Int(&info->interleave), + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); if (position == NULL || !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
View file
pipewire-0.3.59.tar.gz/spa/include/spa/param/param.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/param.h
Changed
@@ -72,7 +72,9 @@ uint32_t flags; uint32_t user; /**< private user field. You can use this to keep * state. */ - uint32_t padding5; + int32_t seq; /**< private seq field. You can use this to keep + * state of a pending update. */ + uint32_t padding4; }; #define SPA_PARAM_INFO(id,flags) ((struct spa_param_info){ (id), (flags) })
View file
pipewire-0.3.59.tar.gz/spa/include/spa/param/video/format-utils.h -> pipewire-0.3.60.tar.gz/spa/include/spa/param/video/format-utils.h
Changed
@@ -44,10 +44,10 @@ { return spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_VIDEO_format, SPA_POD_Id(&info->format), + SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format), SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier), - SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&info->size), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), + SPA_FORMAT_VIDEO_size, SPA_POD_OPT_Rectangle(&info->size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_OPT_Fraction(&info->framerate), SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_OPT_Fraction(&info->max_framerate), SPA_FORMAT_VIDEO_views, SPA_POD_OPT_Int(&info->views), SPA_FORMAT_VIDEO_interlaceMode, SPA_POD_OPT_Id(&info->interlace_mode), @@ -67,7 +67,7 @@ { return spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_VIDEO_format, SPA_POD_Id(&info->format), + SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format), SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier)); }
View file
pipewire-0.3.59.tar.gz/spa/include/spa/pod/event.h -> pipewire-0.3.60.tar.gz/spa/include/spa/pod/event.h
Changed
@@ -49,9 +49,9 @@ #define SPA_EVENT_ID(ev,type) (SPA_EVENT_TYPE(ev) == (type) ? \ (ev)->body.body.id : SPA_ID_INVALID) -#define SPA_EVENT_INIT_FULL(t,size,type,id,...) (t) \ - { { size, SPA_TYPE_OBJECT }, \ - { { type, id }, ##__VA_ARGS__ } } \ +#define SPA_EVENT_INIT_FULL(t,size,type,id,...) ((t) \ + { { (size), SPA_TYPE_OBJECT }, \ + { { (type), (id) }, ##__VA_ARGS__ } }) \ #define SPA_EVENT_INIT(type,id) \ SPA_EVENT_INIT_FULL(struct spa_event, \
View file
pipewire-0.3.59.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.60.tar.gz/spa/include/spa/utils/defs.h
Changed
@@ -82,7 +82,8 @@ #endif #define SPA_FLAG_MASK(field,mask,flag) (((field) & (mask)) == (flag)) -#define SPA_FLAG_IS_SET(field,flag) SPA_FLAG_MASK(field,flag,flag) +#define SPA_FLAG_IS_SET(field,flag) SPA_FLAG_MASK(field, flag, flag) + #define SPA_FLAG_SET(field,flag) ((field) |= (flag)) #define SPA_FLAG_CLEAR(field, flag) \ ({ \ @@ -140,21 +141,24 @@ #define SPA_FOR_EACH_ELEMENT(arr, ptr) \ for ((ptr) = arr; (void*)(ptr) < SPA_PTROFF(arr, sizeof(arr), void); (ptr)++) +#define SPA_FOR_EACH_ELEMENT_VAR(arr, var) \ + for (__typeof__((arr)0)* (var) = arr; (void*)(var) < SPA_PTROFF(arr, sizeof(arr), void); (var)++) + #define SPA_ABS(a) \ ({ \ __typeof__(a) _a = (a); \ SPA_LIKELY(_a >= 0) ? _a : -_a; \ }) -#define SPA_MIN(a,b) \ -({ \ - __typeof__(a) _min_a = (a); \ - __typeof__(b) _min_b = (b); \ +#define SPA_MIN(a,b) \ +({ \ + __typeof__(a) _min_a = (a); \ + __typeof__(b) _min_b = (b); \ SPA_LIKELY(_min_a <= _min_b) ? _min_a : _min_b; \ }) -#define SPA_MAX(a,b) \ -({ \ - __typeof__(a) _max_a = (a); \ - __typeof__(b) _max_b = (b); \ +#define SPA_MAX(a,b) \ +({ \ + __typeof__(a) _max_a = (a); \ + __typeof__(b) _max_b = (b); \ SPA_LIKELY(_max_a >= _max_b) ? _max_a : _max_b; \ }) #define SPA_CLAMP(v,low,high) \ @@ -174,7 +178,7 @@ #define SPA_SWAP(a,b) \ ({ \ __typeof__(a) _t = (a); \ - (a) = b; (b) = _t; \ + (a) = b; (b) = _t; \ }) #define SPA_TYPECHECK(type,x) \ @@ -254,21 +258,21 @@ #define SPA_RESTRICT #endif -#define SPA_ROUND_DOWN(num,value) ((num) - ((num) % (value))) -#define SPA_ROUND_UP(num,value) ((((num) + (value) - 1) / (value)) * (value)) - -#define SPA_MASK_NEGATED(num1, num2) \ -({ \ - SPA_STATIC_ASSERT(__builtin_constant_p(num2) ? \ - (__typeof__(num2))(__typeof__(num1))(__typeof__(num2))(num2) == (num2) : \ - sizeof(num1) >= sizeof(num2), \ - "truncation problem when masking " #num1 \ - " with ~" #num2); \ - ((num1) & ~(__typeof__(num1))(num2)); \ +#define SPA_ROUND_DOWN(num,value) \ +({ \ + __typeof__(num) _num = (num); \ + ((_num) - ((_num) % (value))); \ }) +#define SPA_ROUND_UP(num,value) \ +({ \ + __typeof__(value) _v = (value); \ + ((((num) + (_v) - 1) / (_v)) * (_v)); \ +}) + +#define SPA_ROUND_MASK(num,mask) ((__typeof__(num))((mask)-1)) -#define SPA_ROUND_DOWN_N(num,align) SPA_MASK_NEGATED((num), (align) - 1) -#define SPA_ROUND_UP_N(num,align) SPA_ROUND_DOWN_N((num) + ((align) - 1),align) +#define SPA_ROUND_DOWN_N(num,align) ((num) & ~SPA_ROUND_MASK(num, align)) +#define SPA_ROUND_UP_N(num,align) ((((num)-1) | SPA_ROUND_MASK(num, align))+1) #define SPA_PTR_ALIGNMENT(p,align) ((intptr_t)(p) & ((align)-1)) #define SPA_IS_ALIGNED(p,align) (SPA_PTR_ALIGNMENT(p,align) == 0)
View file
pipewire-0.3.59.tar.gz/spa/include/spa/utils/hook.h -> pipewire-0.3.60.tar.gz/spa/include/spa/utils/hook.h
Changed
@@ -166,7 +166,7 @@ * */ #define SPA_INTERFACE_INIT(_type,_version,_funcs,_data) \ - (struct spa_interface){ _type, _version, SPA_CALLBACKS_INIT(_funcs,_data), } + ((struct spa_interface){ (_type), (_version), SPA_CALLBACKS_INIT(_funcs,_data), }) /** * Invoke method named \a method in the \a callbacks.
View file
pipewire-0.3.59.tar.gz/spa/meson.build -> pipewire-0.3.60.tar.gz/spa/meson.build
Changed
@@ -66,6 +66,10 @@ summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') lc3_dep = dependency('lc3', required : get_option('bluez5-codec-lc3')) summary({'LC3': lc3_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') + if get_option('bluez5-backend-hsp-native').allowed() or get_option('bluez5-backend-hfp-native').allowed() + mm_dep = dependency('ModemManager', version : '>= 1.10.0', required : get_option('bluez5-backend-native-mm')) + summary({'ModemManager': mm_dep.found()}, bool_yn: true, section: 'Bluetooth backends') + endif endif avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg')) jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
@@ -624,7 +624,7 @@ pa_card *impl = snd_mixer_elem_get_callback_private(melem); snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem); snd_ctl_elem_value_t *elem_value; - bool plugged_in; + bool plugged_in, any_input_port_available; void *state; pa_alsa_jack *jack; struct temp_port_avail *tp, *tports; @@ -735,6 +735,31 @@ if (impl->card.active_profile_index != ACP_INVALID_INDEX) active_available = impl->card.profilesimpl->card.active_profile_index->available; + /* First round - detect, if we have any input port available. + If the hardware can report the state for all I/O jacks, only speakers + may be plugged in. */ + any_input_port_available = false; + PA_HASHMAP_FOREACH(profile, impl->profiles, state) { + pa_device_port *port; + void *state2; + + if (profile->profile.flags & ACP_PROFILE_OFF) + continue; + + PA_HASHMAP_FOREACH(port, impl->ports, state2) { + if (!pa_hashmap_get(port->profiles, profile->profile.name)) + continue; + + if (port->port.direction == ACP_DIRECTION_CAPTURE && + port->port.available != ACP_AVAILABLE_NO) { + any_input_port_available = true; + goto input_port_found; + } + } + } +input_port_found: + + /* Second round */ PA_HASHMAP_FOREACH(profile, impl->profiles, state) { pa_device_port *port; void *state2; @@ -768,7 +793,7 @@ if (has_input_port && !has_output_port && found_available_input_port) available = ACP_AVAILABLE_YES; - if (has_output_port && !has_input_port && found_available_output_port) + if (has_output_port && (!has_input_port || !any_input_port_available) && found_available_output_port) available = ACP_AVAILABLE_YES; if (has_output_port && has_input_port && found_available_output_port && found_available_input_port) available = ACP_AVAILABLE_YES;
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-acp-device.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-acp-device.c
Changed
@@ -216,7 +216,7 @@ { int err = 0; struct spa_dict_item *items; - uint32_t i, n_items; + uint32_t n_items; const struct acp_dict_item *it; struct acp_card *card = this->card; char path128; @@ -241,10 +241,10 @@ #undef ADD_ITEM if (this->info.change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) { - for (i = 0; i < SPA_N_ELEMENTS(this->params); i++) { - if (this->paramsi.user > 0) { - this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL; - this->paramsi.user = 0; + SPA_FOR_EACH_ELEMENT_VAR(this->params, p) { + if (p->user > 0) { + p->flags ^= SPA_PARAM_INFO_SERIAL; + p->user = 0; } } }
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -638,12 +638,10 @@ static snd_pcm_format_t spa_format_to_alsa(uint32_t format, bool *planar) { - size_t i; - - for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) { - *planar = format_infoi.spa_pformat == format; - if (format_infoi.spa_format == format || *planar) - return format_infoi.format; + SPA_FOR_EACH_ELEMENT_VAR(format_info, i) { + *planar = i->spa_pformat == format; + if (i->spa_format == format || *planar) + return i->format; } return SND_PCM_FORMAT_UNKNOWN; } @@ -969,7 +967,7 @@ struct spa_pod **result, struct spa_pod_builder *b) { int res, err; - size_t i, j; + size_t j; snd_pcm_t *hndl; snd_pcm_hw_params_t *params; struct spa_pod_frame f2; @@ -1020,8 +1018,10 @@ spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_None, 0); choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f1); - for (i = 1, j = 0; i < SPA_N_ELEMENTS(format_info); i++) { - const struct format_info *fi = &format_infoi; + j = 0; + SPA_FOR_EACH_ELEMENT_VAR(format_info, fi) { + if (fi->format == SND_PCM_FORMAT_UNKNOWN) + continue; if (snd_pcm_format_mask_test(fmask, fi->format)) { if ((snd_pcm_access_mask_test(amask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED) || @@ -1775,7 +1775,7 @@ state->alsa_started = false; if (state->stream == SND_PCM_STREAM_PLAYBACK) - spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom); + spa_alsa_silence(state, state->start_delay + state->threshold + state->headroom); return do_start(state); } @@ -2355,7 +2355,7 @@ { int res; - if (SPA_UNLIKELY(delay > target + state->max_error)) { + if (state->alsa_started && SPA_UNLIKELY(delay > target + state->max_error)) { spa_log_trace(state->log, "%p: early wakeup %lu %lu", state, delay, target); if (delay > target * 3) delay = target * 3; @@ -2558,10 +2558,10 @@ state->alsa_recovering = false; state->alsa_started = false; + /* start capture now, playback will start after first write */ if (state->stream == SND_PCM_STREAM_PLAYBACK) - spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom); - - if ((err = do_start(state)) < 0) + spa_alsa_silence(state, state->start_delay + state->threshold + state->headroom); + else if ((err = do_start(state)) < 0) return err; set_timers(state);
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-seq-bridge.c
Changed
@@ -566,7 +566,7 @@ if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_TYPE_OBJECT_Format, SPA_PARAM_Format, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); break;
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-seq.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-seq.c
Changed
@@ -586,11 +586,11 @@ continue; if (prepare_buffer(state, port) >= 0) { - port->buffer->buf->datas0.chunk->offset = 0; - port->buffer->buf->datas0.chunk->size = port->builder.state.offset, - spa_pod_builder_pop(&port->builder, &port->frame); + port->buffer->buf->datas0.chunk->offset = 0; + port->buffer->buf->datas0.chunk->size = port->builder.state.offset; + /* move buffer to ready queue */ spa_list_remove(&port->buffer->link); SPA_FLAG_SET(port->buffer->flags, BUFFER_FLAG_OUT); @@ -702,23 +702,28 @@ return res; } -static int update_time(struct seq_state *state, uint64_t nsec, bool follower) +static void update_position(struct seq_state *state) { - snd_seq_queue_status_t *status; - const snd_seq_real_time_t* queue_time; - uint64_t queue_real; - double err, corr; - uint64_t queue_elapsed; - if (state->position) { struct spa_io_clock *clock = &state->position->clock; state->rate = clock->rate; + if (state->rate.num == 0 || state->rate.denom == 0) + state->rate = SPA_FRACTION(1, 48000); state->duration = clock->duration; } else { state->rate = SPA_FRACTION(1, 48000); state->duration = 1024; } state->threshold = state->duration; +} + +static int update_time(struct seq_state *state, uint64_t nsec, bool follower) +{ + snd_seq_queue_status_t *status; + const snd_seq_real_time_t* queue_time; + uint64_t queue_real; + double err, corr; + uint64_t queue_elapsed; corr = 1.0 - (state->dll.z2 + state->dll.z3); @@ -776,6 +781,8 @@ { int res; + update_position(state); + res = process_recycle(state); if (state->following && state->position) { @@ -800,11 +807,13 @@ spa_log_trace(state->log, "timeout %"PRIu64, state->current_time); + update_position(state); + update_time(state, state->current_time, false); res = process_read(state); - if (res > 0) - spa_node_call_ready(&state->callbacks, res); + if (res >= 0) + spa_node_call_ready(&state->callbacks, res | SPA_STATUS_NEED_DATA); set_timeout(state, state->next_time); } @@ -878,15 +887,7 @@ while (snd_seq_drain_output(state->event.hndl) > 0) sleep(1); - if (state->position) { - struct spa_io_clock *clock = &state->position->clock; - state->rate = clock->rate; - state->duration = clock->duration; - } else { - state->rate = SPA_FRACTION(1, 48000); - state->duration = 1024; - } - state->threshold = state->duration; + update_position(state); state->started = true;
View file
pipewire-0.3.59.tar.gz/spa/plugins/alsa/alsa-udev.c -> pipewire-0.3.60.tar.gz/spa/plugins/alsa/alsa-udev.c
Changed
@@ -465,7 +465,7 @@ if (str && *str) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS_PATH, str); } - if ((str = udev_device_get_syspath(dev)) && *str) { + if ((str = udev_device_get_devpath(dev)) && *str) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SYSFS_PATH, str); } if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) { @@ -651,9 +651,9 @@ { bool deleted = false; struct impl *this = source->data; - struct { + union { struct inotify_event e; - char nameNAME_MAX+1; + char nameNAME_MAX+1+sizeof(struct inotify_event); } buf; while (true) { @@ -670,17 +670,20 @@ e = SPA_PTROFF(&buf, len, void); for (p = &buf; p < e; - p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) { + p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) { unsigned int id; struct device *device; event = (const struct inotify_event *) p; + spa_assert_se(SPA_PTRDIFF(e, p) >= (ptrdiff_t)sizeof(struct inotify_event) && + SPA_PTRDIFF(e, p) - sizeof(struct inotify_event) >= event->len && + "bad event from kernel"); /* Device becomes accessible or not busy */ if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) { bool access; if (sscanf(event->name, "controlC%u", &id) != 1 && - sscanf(event->name, "pcmC%uD", &id) != 1) + sscanf(event->name, "pcmC%uD", &id) != 1) continue; if ((device = find_device(this, id)) == NULL) continue;
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioadapter.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -556,30 +556,6 @@ return 0; } -static int format_audio_raw_parse_opt(const struct spa_pod *format, struct spa_audio_info_raw *info) -{ - struct spa_pod *position = NULL; - uint32_t media_type, media_subtype; - int res; - if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0) - return res; - if (media_type != SPA_MEDIA_TYPE_audio || - media_subtype != SPA_MEDIA_SUBTYPE_raw) - return -ENOTSUP; - - spa_zero(*info); - res = spa_pod_parse_object(format, - SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format), - SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), - SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); - if (position == NULL || - !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS)) - SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); - - return res; -} - static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { @@ -627,8 +603,18 @@ if (format) { struct spa_audio_info info; - if (format_audio_raw_parse_opt(format, &info.info.raw) >= 0) + + spa_zero(info); + if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) + return res; + if (info.media_type != SPA_MEDIA_TYPE_audio || + info.media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -ENOTSUP; + + if (spa_format_audio_raw_parse(format, &info.info.raw) >= 0) { + info.info.raw.rate = 0; this->default_format = info; + } } switch (mode) { @@ -814,21 +800,23 @@ switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Start: + spa_log_debug(this->log, "%p: starting %d", this, this->started); if (this->started) return 0; if ((res = negotiate_format(this)) < 0) return res; if ((res = negotiate_buffers(this)) < 0) return res; + this->started = true; break; case SPA_NODE_COMMAND_Suspend: - configure_format(this, 0, NULL); - SPA_FALLTHROUGH + spa_log_debug(this->log, "%p: suspending", this); + break; case SPA_NODE_COMMAND_Pause: - this->started = false; - spa_log_debug(this->log, "%p: stopped", this); + spa_log_debug(this->log, "%p: pausing", this); break; case SPA_NODE_COMMAND_Flush: + spa_log_debug(this->log, "%p: flushing", this); this->io_buffers.status = SPA_STATUS_OK; break; default: @@ -852,9 +840,18 @@ } switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Start: - this->started = true; spa_log_debug(this->log, "%p: started", this); break; + case SPA_NODE_COMMAND_Suspend: + configure_format(this, 0, NULL); + SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Pause: + this->started = false; + spa_log_debug(this->log, "%p: stopped", this); + break; + case SPA_NODE_COMMAND_Flush: + spa_log_debug(this->log, "%p: flushed", this); + break; } return res; } @@ -1155,6 +1152,11 @@ spa_log_trace_fp(this->log, "%p: ready %d", this, status); + if (!this->started) { + spa_log_warn(this->log, "%p: ready stopped node", this); + return -EIO; + } + if (this->target != this->follower) { this->driver = true;
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -220,6 +220,7 @@ unsigned int resample_peaks:1; unsigned int is_passthrough:1; unsigned int drained:1; + unsigned int rate_adjust:1; uint32_t empty_size; float *empty; @@ -241,16 +242,15 @@ static void emit_node_info(struct impl *this, bool full) { uint64_t old = full ? this->info.change_mask : 0; - uint32_t i; if (full) this->info.change_mask = this->info_all; if (this->info.change_mask) { if (this->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) { - for (i = 0; i < SPA_N_ELEMENTS(this->params); i++) { - if (this->paramsi.user > 0) { - this->paramsi.flags ^= SPA_PARAM_INFO_SERIAL; - this->paramsi.user = 0; + SPA_FOR_EACH_ELEMENT_VAR(this->params, p) { + if (p->user > 0) { + p->flags ^= SPA_PARAM_INFO_SERIAL; + p->user = 0; } } } @@ -262,7 +262,6 @@ static void emit_port_info(struct impl *this, struct port *port, bool full) { uint64_t old = full ? port->info.change_mask : 0; - uint32_t i; if (full) port->info.change_mask = port->info_all; @@ -282,10 +281,10 @@ port->info.props = &SPA_DICT_INIT(items, n_items); if (port->info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) { - for (i = 0; i < SPA_N_ELEMENTS(port->params); i++) { - if (port->paramsi.user > 0) { - port->paramsi.flags ^= SPA_PARAM_INFO_SERIAL; - port->paramsi.user = 0; + SPA_FOR_EACH_ELEMENT_VAR(port->params, p) { + if (p->user > 0) { + p->flags ^= SPA_PARAM_INFO_SERIAL; + p->user = 0; } } } @@ -432,7 +431,6 @@ { struct props *p = &this->props; struct spa_pod_frame f2; - uint32_t i; switch (result.index) { case 0: @@ -596,9 +594,9 @@ spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0); spa_pod_builder_push_struct(&b, &f1); - for (i = 0; i < SPA_N_ELEMENTS(channelmix_upmix_info); i++) { - spa_pod_builder_string(&b, channelmix_upmix_infoi.label); - spa_pod_builder_string(&b, channelmix_upmix_infoi.description); + SPA_FOR_EACH_ELEMENT_VAR(channelmix_upmix_info, i) { + spa_pod_builder_string(&b, i->label); + spa_pod_builder_string(&b, i->description); } spa_pod_builder_pop(&b, &f1); param = spa_pod_builder_pop(&b, &f0); @@ -646,9 +644,9 @@ 0); spa_pod_builder_prop(&b, SPA_PROP_INFO_labels, 0); spa_pod_builder_push_struct(&b, &f1); - for (i = 0; i < SPA_N_ELEMENTS(dither_method_info); i++) { - spa_pod_builder_string(&b, dither_method_infoi.label); - spa_pod_builder_string(&b, dither_method_infoi.description); + SPA_FOR_EACH_ELEMENT_VAR(dither_method_info, i) { + spa_pod_builder_string(&b, i->label); + spa_pod_builder_string(&b, i->description); } spa_pod_builder_pop(&b, &f1); param = spa_pod_builder_pop(&b, &f0); @@ -827,8 +825,11 @@ if (spa_pod_is_string(pod)) { spa_pod_copy_string(pod, sizeof(value), value); } else if (spa_pod_is_float(pod)) { - snprintf(value, sizeof(value), "%f", + spa_dtoa(value, sizeof(value), SPA_POD_VALUE(struct spa_pod_float, pod)); + } else if (spa_pod_is_double(pod)) { + spa_dtoa(value, sizeof(value), + SPA_POD_VALUE(struct spa_pod_double, pod)); } else if (spa_pod_is_int(pod)) { snprintf(value, sizeof(value), "%d", SPA_POD_VALUE(struct spa_pod_int, pod)); @@ -844,6 +845,9 @@ spa_log_info(this->log, "key:'%s' val:'%s'", name, value); changed += audioconvert_set_param(this, name, value); } + if (changed) { + channelmix_init(&this->mix); + } return changed; } @@ -911,6 +915,11 @@ break; case SPA_PROP_rate: spa_pod_get_double(&prop->value, &p->rate); + if (!this->rate_adjust && p->rate != 1.0) { + this->rate_adjust = true; + spa_log_info(this->log, "%p: activating adaptive resampler", + this); + } break; case SPA_PROP_params: changed += parse_prop_params(this, &prop->value); @@ -925,7 +934,6 @@ else if (have_channel_volume) p->have_soft_volume = false; - channelmix_init(&this->mix); set_volume(this); } return changed; @@ -1064,7 +1072,10 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; - if (info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + if (info.info.raw.format == 0 || + info.info.raw.rate == 0 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) return -EINVAL; infop = &info; @@ -1280,12 +1291,23 @@ this->paramsIDX_Props.user++; } +static char *format_position(char *str, size_t len, uint32_t channels, uint32_t *position) +{ + uint32_t i, idx = 0; + for (i = 0; i < channels; i++) + idx += snprintf(str + idx, len - idx, "%s%s", i == 0 ? "" : " ", + spa_debug_type_find_short_name(spa_type_audio_channel, + positioni)); + return str; +} + static int setup_channelmix(struct impl *this) { struct dir *in = &this->dirSPA_DIRECTION_INPUT; struct dir *out = &this->dirSPA_DIRECTION_OUTPUT; uint32_t i, src_chan, dst_chan, p; uint64_t src_mask, dst_mask; + char str1024; int res; src_chan = in->format.info.raw.channels; @@ -1300,6 +1322,11 @@ dst_mask |= 1ULL << (p < 64 ? p : 0); } + spa_log_info(this->log, "in %s (%016"PRIx64")", format_position(str, sizeof(str), + src_chan, in->format.info.raw.position), src_mask); + spa_log_info(this->log, "out %s (%016"PRIx64")", format_position(str, sizeof(str), + dst_chan, out->format.info.raw.position), dst_mask); + if (src_mask & 1) src_mask = default_mask(src_chan); if (dst_mask & 1) @@ -1357,6 +1384,8 @@ this->resample.quality = this->props.resample_quality; this->resample.cpu_flags = this->cpu_flags; + this->rate_adjust = this->props.rate != 1.0; + if (this->resample_peaks) res = resample_peaks_init(&this->resample); else @@ -1941,9 +1970,13 @@ spa_log_error(this->log, "can't parse format %s", spa_strerror(res)); return res; } - if (info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) { - spa_log_error(this->log, "too many channels %d > %d", - info.info.raw.channels, SPA_AUDIO_MAX_CHANNELS); + if (info.info.raw.format == 0 || + info.info.raw.rate == 0 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) { + spa_log_error(this->log, "invalid format:%d rate:%d channels:%d", + info.info.raw.format, info.info.raw.rate, + info.info.raw.channels);
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/benchmark-fmt-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/benchmark-fmt-ops.c
Changed
@@ -105,21 +105,17 @@ static void run_testc(const char *name, const char *impl, bool in_packed, bool out_packed, convert_func_t func, int channel_count) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(sample_sizes); i++) { + SPA_FOR_EACH_ELEMENT_VAR(sample_sizes, s) { run_test1(name, impl, in_packed, out_packed, func, channel_count, - (sample_sizesi + (channel_count -1)) / channel_count); + (*s + (channel_count -1)) / channel_count); } } static void run_test(const char *name, const char *impl, bool in_packed, bool out_packed, convert_func_t func) { - size_t i, j; - - for (i = 0; i < SPA_N_ELEMENTS(sample_sizes); i++) { - for (j = 0; j < SPA_N_ELEMENTS(channel_counts); j++) { - run_test1(name, impl, in_packed, out_packed, func, channel_countsj, - (sample_sizesi + (channel_countsj -1)) / channel_countsj); + SPA_FOR_EACH_ELEMENT_VAR(sample_sizes, s) { + SPA_FOR_EACH_ELEMENT_VAR(channel_counts, c) { + run_test1(name, impl, in_packed, out_packed, func, *c, (*s + (*c -1)) / *c); } } }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops-sse.c
Changed
@@ -101,6 +101,64 @@ } } +static inline void avg_sse(float *d, const float *s0, const float *s1, uint32_t n_samples) +{ + uint32_t n, unrolled; + __m128 half = _mm_set1_ps(0.5f); + + if (SPA_IS_ALIGNED(d, 16) && + SPA_IS_ALIGNED(s0, 16) && + SPA_IS_ALIGNED(s1, 16)) + unrolled = n_samples & ~7; + else + unrolled = 0; + + for (n = 0; n < unrolled; n += 8) { + _mm_store_ps(&dn + 0, + _mm_mul_ps( + _mm_add_ps( + _mm_load_ps(&s0n + 0), + _mm_load_ps(&s1n + 0)), + half)); + _mm_store_ps(&dn + 4, + _mm_mul_ps( + _mm_add_ps( + _mm_load_ps(&s0n + 4), + _mm_load_ps(&s1n + 4)), + half)); + } + + for (; n < n_samples; n++) + _mm_store_ss(&dn, + _mm_mul_ss( + _mm_add_ss( + _mm_load_ss(&s0n), + _mm_load_ss(&s1n)), + half)); +} + +static inline void sub_sse(float *d, const float *s0, const float *s1, uint32_t n_samples) +{ + uint32_t n, unrolled; + + if (SPA_IS_ALIGNED(d, 16) && + SPA_IS_ALIGNED(s0, 16) && + SPA_IS_ALIGNED(s1, 16)) + unrolled = n_samples & ~7; + else + unrolled = 0; + + for (n = 0; n < unrolled; n += 8) { + _mm_store_ps(&dn + 0, + _mm_sub_ps(_mm_load_ps(&s0n + 0), _mm_load_ps(&s1n + 0))); + _mm_store_ps(&dn + 4, + _mm_sub_ps(_mm_load_ps(&s0n + 4), _mm_load_ps(&s1n + 4))); + } + for (; n < n_samples; n++) + _mm_store_ss(&dn, + _mm_sub_ss(_mm_load_ss(&s0n), _mm_load_ss(&s1n))); +} + void channelmix_copy_sse(struct channelmix *mix, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_samples) { @@ -145,6 +203,133 @@ } } +void +channelmix_f32_2_3p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples) +{ + uint32_t i, n, unrolled, n_dst = mix->dst_chan; + float **d = (float **)dst; + const float **s = (const float **)src; + const float v0 = mix->matrix00; + const float v1 = mix->matrix11; + const float v2 = (mix->matrix20 + mix->matrix21) * 0.5f; + const float v3 = (mix->matrix30 + mix->matrix31) * 0.5f; + + if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { + for (i = 0; i < n_dst; i++) + clear_sse(di, n_samples); + } + else { + if (mix->widen == 0.0f) { + vol_sse(d0, s0, v0, n_samples); + vol_sse(d1, s1, v1, n_samples); + avg_sse(d2, s0, s1, n_samples); + } else { + const __m128 mv0 = _mm_set1_ps(mix->matrix00); + const __m128 mv1 = _mm_set1_ps(mix->matrix11); + const __m128 mw = _mm_set1_ps(mix->widen); + const __m128 mh = _mm_set1_ps(0.5f); + __m128 t01, t11, w1, c1; + + if (SPA_IS_ALIGNED(s0, 16) && + SPA_IS_ALIGNED(s1, 16) && + SPA_IS_ALIGNED(d0, 16) && + SPA_IS_ALIGNED(d1, 16) && + SPA_IS_ALIGNED(d2, 16)) + unrolled = n_samples & ~3; + else + unrolled = 0; + + for(n = 0; n < unrolled; n += 4) { + t00 = _mm_load_ps(&s0n); + t10 = _mm_load_ps(&s1n); + c0 = _mm_add_ps(t00, t10); + w0 = _mm_mul_ps(c0, mw); + _mm_store_ps(&d0n, _mm_mul_ps(_mm_sub_ps(t00, w0), mv0)); + _mm_store_ps(&d1n, _mm_mul_ps(_mm_sub_ps(t10, w0), mv1)); + _mm_store_ps(&d2n, _mm_mul_ps(c0, mh)); + } + for (; n < n_samples; n++) { + t00 = _mm_load_ss(&s0n); + t10 = _mm_load_ss(&s1n); + c0 = _mm_add_ss(t00, t10); + w0 = _mm_mul_ss(c0, mw); + _mm_store_ss(&d0n, _mm_mul_ss(_mm_sub_ss(t00, w0), mv0)); + _mm_store_ss(&d1n, _mm_mul_ss(_mm_sub_ss(t10, w0), mv1)); + _mm_store_ss(&d2n, _mm_mul_ss(c0, mh)); + } + } + lr4_process(&mix->lr43, d3, d2, v3, n_samples); + lr4_process(&mix->lr42, d2, d2, v2, n_samples); + } +} + +void +channelmix_f32_2_5p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples) +{ + uint32_t i, n_dst = mix->dst_chan; + float **d = (float **)dst; + const float **s = (const float **)src; + const float v4 = mix->matrix40; + const float v5 = mix->matrix51; + + if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { + for (i = 0; i < n_dst; i++) + clear_sse(di, n_samples); + } + else { + channelmix_f32_2_3p1_sse(mix, dst, src, n_samples); + + if (mix->upmix != CHANNELMIX_UPMIX_PSD) { + vol_sse(d4, s0, v4, n_samples); + vol_sse(d5, s1, v5, n_samples); + } else { + sub_sse(d4, s0, s1, n_samples); + + delay_convolve_run(mix->buffer1, &mix->pos1, BUFFER_SIZE, mix->delay, + mix->taps, mix->n_taps, d5, d4, -v5, n_samples); + delay_convolve_run(mix->buffer0, &mix->pos0, BUFFER_SIZE, mix->delay, + mix->taps, mix->n_taps, d4, d4, v4, n_samples); + } + } +} + +void +channelmix_f32_2_7p1_sse(struct channelmix *mix, void * SPA_RESTRICT dst, + const void * SPA_RESTRICT src, uint32_t n_samples) +{ + uint32_t i, n_dst = mix->dst_chan; + float **d = (float **)dst; + const float **s = (const float **)src; + const float v4 = mix->matrix40; + const float v5 = mix->matrix51; + const float v6 = mix->matrix60; + const float v7 = mix->matrix71; + + if (SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_ZERO)) { + for (i = 0; i < n_dst; i++) + clear_sse(di, n_samples); + } + else { + channelmix_f32_2_3p1_sse(mix, dst, src, n_samples); + + vol_sse(d4, s0, v4, n_samples); + vol_sse(d5, s1, v5, n_samples); + + if (mix->upmix != CHANNELMIX_UPMIX_PSD) { + vol_sse(d6, s0, v6, n_samples); + vol_sse(d7, s1, v7, n_samples); + } else { + sub_sse(d6, s0, s1, n_samples); + + delay_convolve_run(mix->buffer1, &mix->pos1, BUFFER_SIZE, mix->delay, + mix->taps, mix->n_taps, d7, d6, -v7, n_samples); + delay_convolve_run(mix->buffer0, &mix->pos0, BUFFER_SIZE, mix->delay, + mix->taps, mix->n_taps, d6, d6, v6, n_samples); + } + } +} /* FL+FR+FC+LFE -> FL+FR */ void channelmix_f32_3p1_2_sse(struct channelmix *mix, void * SPA_RESTRICT dst,
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
@@ -30,6 +30,7 @@ #include <spa/support/cpu.h> #include <spa/support/log.h> #include <spa/utils/defs.h> +#include <spa/debug/types.h> #include "channelmix-ops.h" #include "hilbert.h" @@ -69,8 +70,17 @@ MAKE(4, MASK_QUAD, 1, MASK_MONO, channelmix_f32_4_1_c), MAKE(4, MASK_3_1, 1, MASK_MONO, channelmix_f32_4_1_c), MAKE(2, MASK_STEREO, 4, MASK_QUAD, channelmix_f32_2_4_c), +#if defined (HAVE_SSE) + MAKE(2, MASK_STEREO, 4, MASK_3_1, channelmix_f32_2_3p1_sse, SPA_CPU_FLAG_SSE), +#endif MAKE(2, MASK_STEREO, 4, MASK_3_1, channelmix_f32_2_3p1_c), +#if defined (HAVE_SSE) + MAKE(2, MASK_STEREO, 6, MASK_5_1, channelmix_f32_2_5p1_sse, SPA_CPU_FLAG_SSE), +#endif MAKE(2, MASK_STEREO, 6, MASK_5_1, channelmix_f32_2_5p1_c), +#if defined (HAVE_SSE) + MAKE(2, MASK_STEREO, 8, MASK_7_1, channelmix_f32_2_7p1_sse, SPA_CPU_FLAG_SSE), +#endif MAKE(2, MASK_STEREO, 8, MASK_7_1, channelmix_f32_2_7p1_c), #if defined (HAVE_SSE) MAKE(4, MASK_3_1, 2, MASK_STEREO, channelmix_f32_3p1_2_sse, SPA_CPU_FLAG_SSE), @@ -95,7 +105,7 @@ MAKE(8, MASK_7_1, 4, MASK_3_1, channelmix_f32_7p1_3p1_c), #if defined (HAVE_SSE) - MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse), + MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_sse, SPA_CPU_FLAG_SSE), #endif MAKE(ANY, 0, ANY, 0, channelmix_f32_n_m_c), }; @@ -108,19 +118,18 @@ static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uint64_t src_mask, uint32_t dst_chan, uint64_t dst_mask, uint32_t cpu_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(channelmix_table); i++) { - if (!MATCH_CPU_FLAGS(channelmix_tablei.cpu_flags, cpu_flags)) + SPA_FOR_EACH_ELEMENT_VAR(channelmix_table, info) { + if (!MATCH_CPU_FLAGS(info->cpu_flags, cpu_flags)) continue; if (src_chan == dst_chan && src_mask == dst_mask) - return &channelmix_tablei; + return info; - if (MATCH_CHAN(channelmix_tablei.src_chan, src_chan) && - MATCH_CHAN(channelmix_tablei.dst_chan, dst_chan) && - MATCH_MASK(channelmix_tablei.src_mask, src_mask) && - MATCH_MASK(channelmix_tablei.dst_mask, dst_mask)) - return &channelmix_tablei; + if (MATCH_CHAN(info->src_chan, src_chan) && + MATCH_CHAN(info->dst_chan, dst_chan) && + MATCH_MASK(info->src_mask, src_mask) && + MATCH_MASK(info->dst_mask, dst_mask)) + return info; } return NULL; } @@ -302,6 +311,7 @@ _MATRIX(SL,RL) += 1.0f; _MATRIX(SR,RR) += 1.0f; } + keep &= ~SIDE; } else if (dst_mask & STEREO) { spa_log_debug(mix->log, "assign RL+RR to FL+FR (%f)", slev); if (matrix_encoding == MATRIX_DOLBY) { @@ -339,6 +349,7 @@ _MATRIX(RL,SL) += 1.0f; _MATRIX(RR,SR) += 1.0f; } + keep &= ~REAR; } else if (dst_mask & _MASK(RC)) { spa_log_debug(mix->log, "assign SL+SR to RC (%f)", SQRT1_2); _MATRIX(RC,SL)+= SQRT1_2; @@ -474,10 +485,33 @@ spa_log_debug(mix->log, "won't produce SIDE"); } } + if (unassigned & _MASK(RC)) { + if ((src_mask & REAR) == REAR) { + spa_log_debug(mix->log, "produce RC from REAR (%f)", 0.5f); + _MATRIX(RC,RL) += 0.5f; + _MATRIX(RC,RR) += 0.5f; + } else if ((src_mask & SIDE) == SIDE) { + spa_log_debug(mix->log, "produce RC from SIDE (%f)", 0.5f); + _MATRIX(RC,SL) += 0.5f; + _MATRIX(RC,SR) += 0.5f; + } else if ((src_mask & STEREO) == STEREO) { + spa_log_debug(mix->log, "produce RC from STEREO (%f)", 0.5f); + _MATRIX(RC,FL) += 0.5f; + _MATRIX(RC,FR) += 0.5f; + } else if ((src_mask & FRONT) == FRONT && + mix->upmix == CHANNELMIX_UPMIX_SIMPLE) { + spa_log_debug(mix->log, "produce RC from FC (%f)", slev); + _MATRIX(RC,FC) += slev; + } else { + spa_log_debug(mix->log, "won't produce RC"); + } + } done: for (jc = 0, ic = 0, i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { float sum = 0.0f; + char str1024, str21024; + int idx = 0, idx2 = 0; if ((dst_mask & (1UL << i)) == 0) continue; for (jc = 0, j = 0; j < SPA_AUDIO_MAX_CHANNELS; j++) { @@ -485,9 +519,27 @@ continue; if (ic >= dst_chan || jc >= src_chan) continue; + + if (i == 0) + idx2 += snprintf(str2 + idx2, sizeof(str2) - idx2, "%-4.4s ", + spa_debug_type_find_short_name(spa_type_audio_channel, j + 3)); + mix->matrix_origicjc++ = matrixij; sum += fabs(matrixij); + + if (matrixij == 0.0f) + idx += snprintf(str + idx, sizeof(str) - idx, " "); + else + idx += snprintf(str + idx, sizeof(str) - idx, "%1.3f ", matrixij); } + if (dst_mask != 0 && src_mask != 0 && sum > 0.0f) { + if (i == 0) + spa_log_info(mix->log, " %s", str2); + spa_log_info(mix->log, "%-4.4s %s %f", + spa_debug_type_find_short_name(spa_type_audio_channel, i + 3), + str, sum); + } + maxsum = SPA_MAX(maxsum, sum); if (i == _CH(LFE) && mix->lfe_cutoff > 0.0f && filter_lfe) { spa_log_info(mix->log, "channel %d is LFE cutoff:%f", ic, mix->lfe_cutoff);
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/channelmix-ops.h -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/channelmix-ops.h
Changed
@@ -109,10 +109,9 @@ static inline uint32_t channelmix_upmix_from_label(const char *label) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(channelmix_upmix_info); i++) { - if (spa_streq(channelmix_upmix_infoi.label, label)) - return channelmix_upmix_infoi.upmix; + SPA_FOR_EACH_ELEMENT_VAR(channelmix_upmix_info, i) { + if (spa_streq(i->label, label)) + return i->upmix; } return CHANNELMIX_UPMIX_NONE; } @@ -148,6 +147,9 @@ #if defined (HAVE_SSE) DEFINE_FUNCTION(copy, sse); DEFINE_FUNCTION(f32_n_m, sse); +DEFINE_FUNCTION(f32_2_3p1, sse); +DEFINE_FUNCTION(f32_2_5p1, sse); +DEFINE_FUNCTION(f32_2_7p1, sse); DEFINE_FUNCTION(f32_3p1_2, sse); DEFINE_FUNCTION(f32_5p1_2, sse); DEFINE_FUNCTION(f32_5p1_3p1, sse);
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/fmt-ops.c
Changed
@@ -359,14 +359,13 @@ static const struct conv_info *find_conv_info(uint32_t src_fmt, uint32_t dst_fmt, uint32_t n_channels, uint32_t cpu_flags, uint32_t conv_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(conv_table); i++) { - if (conv_tablei.src_fmt == src_fmt && - conv_tablei.dst_fmt == dst_fmt && - MATCH_CHAN(conv_tablei.n_channels, n_channels) && - MATCH_CPU_FLAGS(conv_tablei.cpu_flags, cpu_flags) && - MATCH_DITHER(conv_tablei.conv_flags, conv_flags)) - return &conv_tablei; + SPA_FOR_EACH_ELEMENT_VAR(conv_table, c) { + if (c->src_fmt == src_fmt && + c->dst_fmt == dst_fmt && + MATCH_CHAN(c->n_channels, n_channels) && + MATCH_CPU_FLAGS(c->cpu_flags, cpu_flags) && + MATCH_DITHER(c->conv_flags, conv_flags)) + return c; } return NULL; } @@ -403,11 +402,10 @@ static const struct noise_info *find_noise_info(uint32_t method, uint32_t cpu_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(noise_table); i++) { - if (noise_tablei.method == method && - MATCH_CPU_FLAGS(noise_tablei.cpu_flags, cpu_flags)) - return &noise_tablei; + SPA_FOR_EACH_ELEMENT_VAR(noise_table, t) { + if (t->method == method && + MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags)) + return t; } return NULL; } @@ -471,17 +469,14 @@ static const struct dither_info *find_dither_info(uint32_t method, uint32_t rate) { - size_t i; - - for (i = 0; i < SPA_N_ELEMENTS(dither_info); i++) { - const struct dither_info *di = &dither_infoi; + SPA_FOR_EACH_ELEMENT_VAR(dither_info, di) { if (di->method != method) continue; /* don't use shaped for too low rates, it moves the noise to * audible ranges */ if (di->ns != NULL && rate < di->rate * 3 / 4) return find_dither_info(DITHER_METHOD_TRIANGULAR_HF, rate); - return &dither_infoi; + return di; } return NULL; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
@@ -271,10 +271,9 @@ static inline uint32_t dither_method_from_label(const char *label) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(dither_method_info); i++) { - if (spa_streq(dither_method_infoi.label, label)) - return dither_method_infoi.method; + SPA_FOR_EACH_ELEMENT_VAR(dither_method_info, i) { + if (spa_streq(i->label, label)) + return i->method; } return DITHER_METHOD_NONE; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/peaks-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/peaks-ops.c
Changed
@@ -59,11 +59,9 @@ static const struct peaks_info *find_peaks_info(uint32_t cpu_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(peaks_table); i++) { - if (!MATCH_CPU_FLAGS(peaks_tablei.cpu_flags, cpu_flags)) - continue; - return &peaks_tablei; + SPA_FOR_EACH_ELEMENT_VAR(peaks_table, t) { + if (MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags)) + return t; } return NULL; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/resample-native.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/resample-native.c
Changed
@@ -66,6 +66,7 @@ (alpha / 2.0) * cos(2.0 * x); return r; } + static inline double window_cosh(double x, double n_taps) { double r; @@ -80,7 +81,7 @@ return r; } -#define window window_cosh +#define window (1 ? window_cosh : window_blackman) static int build_filter(float *taps, uint32_t stride, uint32_t n_taps, uint32_t n_phases, double cutoff) { @@ -125,11 +126,10 @@ #define MATCH_CPU_FLAGS(a,b) ((a) == 0 || ((a) & (b)) == a) static const struct resample_info *find_resample_info(uint32_t format, uint32_t cpu_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(resample_table); i++) { - if (resample_tablei.format == format && - MATCH_CPU_FLAGS(resample_tablei.cpu_flags, cpu_flags)) - return &resample_tablei; + SPA_FOR_EACH_ELEMENT_VAR(resample_table, t) { + if (t->format == format && + MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags)) + return t; } return NULL; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-audioconvert.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-audioconvert.c
Changed
@@ -681,9 +681,9 @@ res = memcmp(b->datasj.data, out_data->datak, out_data->size); if (res != 0) { - fprintf(stderr, "error plane %d\n", j); + fprintf(stderr, "error port %d plane %d\n", i, j); spa_debug_mem(0, b->datasj.data, out_data->size); - spa_debug_mem(0, out_data->dataj, out_data->size); + spa_debug_mem(0, out_data->datak, out_data->size); } spa_assert_se(res == 0); @@ -702,7 +702,9 @@ static const float data_f32p_3 = { 0.3f, 0.3f, 0.3f, 0.3f }; static const float data_f32p_4 = { 0.4f, 0.4f, 0.4f, 0.4f }; static const float data_f32p_5 = { 0.5f, 0.5f, 0.5f, 0.5f }; +static const float data_f32p_5_6p1 = { 0.953553438f, 0.953553438f, 0.953553438f, 0.953553438f }; static const float data_f32p_6 = { 0.6f, 0.6f, 0.6f, 0.6f }; +static const float data_f32p_6_6p1 = { 1.053553343f, 1.053553343f, 1.053553343f, 1.053553343f }; static const float data_f32p_7 = { 0.7f, 0.7f, 0.7f, 0.7f }; static const float data_f32p_8 = { 0.8f, 0.8f, 0.8f, 0.8f }; @@ -710,6 +712,14 @@ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f }; +static const float data_f32_6p1 = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f }; +static const float data_f32_6p1_from_5p1 = { 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.55f, 0.5f, 0.6f }; static const float data_f32_7p1_remapped = { 0.1f, 0.2f, 0.5f, 0.6f, 0.7f, 0.8f, 0.3f, 0.4f, 0.1f, 0.2f, 0.5f, 0.6f, 0.7f, 0.8f, 0.3f, 0.4f, @@ -740,6 +750,27 @@ .size = sizeof(float) * 4 }; +struct data dsp_5p1_from_6p1 = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 6, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR, + }), + .ports = 6, + .planes = 1, + .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5_6p1, data_f32p_6_6p1, }, + .size = sizeof(float) * 4 +}; + + struct data dsp_5p1_remapped = { .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, .info = SPA_AUDIO_INFO_RAW_INIT( @@ -760,6 +791,68 @@ .size = sizeof(float) * 4 }; +struct data dsp_5p1_remapped_from_6p1 = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 6, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + }), + .ports = 6, + .planes = 1, + .data = { data_f32p_1, data_f32p_2, data_f32p_5_6p1, data_f32p_6_6p1, data_f32p_3, data_f32p_4, }, + .size = sizeof(float) * 4 +}; + +struct data dsp_6p1 = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 7, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RC, + SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR, + }), + .ports = 7, + .planes = 1, + .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5, data_f32p_6, data_f32p_7 }, + .size = sizeof(float) * 4 +}; + +struct data dsp_6p1_side = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 7, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RC, + SPA_AUDIO_CHANNEL_SL, + SPA_AUDIO_CHANNEL_SR, + }), + .ports = 7, + .planes = 1, + .data = { data_f32p_1, data_f32p_2, data_f32p_3, data_f32p_4, data_f32p_5, data_f32p_6, data_f32p_7 }, + .size = sizeof(float) * 4 +}; + struct data dsp_7p1_remapped = { .mode = SPA_PARAM_PORT_CONFIG_MODE_dsp, .info = SPA_AUDIO_INFO_RAW_INIT( @@ -862,6 +955,90 @@ .size = sizeof(float) * 4 }; +struct data conv_f32_48000_6p1 = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_convert, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 7, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RC, + SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR, + }), + .ports = 1, + .planes = 1, + .data = { data_f32_6p1 }, + .size = sizeof(data_f32_6p1) +}; + +struct data conv_f32_48000_6p1_from_5p1 = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_convert, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 7, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RC, + SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR, + }), + .ports = 1, + .planes = 1, + .data = { data_f32_6p1_from_5p1 }, + .size = sizeof(data_f32_6p1_from_5p1) +}; + +struct data conv_f32_48000_6p1_side = { + .mode = SPA_PARAM_PORT_CONFIG_MODE_convert, + .info = SPA_AUDIO_INFO_RAW_INIT( + .format = SPA_AUDIO_FORMAT_F32, + .rate = 48000, + .channels = 7, + .position = { + SPA_AUDIO_CHANNEL_FL, + SPA_AUDIO_CHANNEL_FR, + SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, + SPA_AUDIO_CHANNEL_RC, + SPA_AUDIO_CHANNEL_SL, + SPA_AUDIO_CHANNEL_SR, + }), + .ports = 1, + .planes = 1, + .data = { data_f32_6p1 }, + .size = sizeof(data_f32_6p1) +};
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-channelmix.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-channelmix.c
Changed
@@ -220,6 +220,46 @@ 0.0, 0.0, 0.0, 0.0, 0.0, 1.0)); } +static void test_6p1_N(void) +{ + test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RC)|_M(SL)|_M(SR), 1, _M(MONO), 0, + MATRIX(0.707107, 0.707107, 1.0, 0.0, 0.5, 0.5, 0.5)); + test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC), + 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR), 0, + MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.707107, + 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.707107)); + test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC), + 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RL)|_M(RR), 0, + MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.707107, + 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.707107)); + test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RC)|_M(RL)|_M(RR), + 6, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(RL)|_M(RR), 0, + MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.707107, 1.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.707107, 0.0, 1.0)); + test_mix(7, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RC), + 8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 0, + MATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.707107, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.707107)); +} + static void test_7p1_N(void) { test_mix(8, _M(FL)|_M(FR)|_M(LFE)|_M(FC)|_M(SL)|_M(SR)|_M(RL)|_M(RR), 1, _M(MONO), 0, @@ -316,6 +356,7 @@ test_3p1_N(); test_4_N(); test_5p1_N(); + test_6p1_N(); test_7p1_N(); test_n_m_impl();
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/test-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/test-source.c
Changed
@@ -535,8 +535,12 @@ case SPA_AUDIO_FORMAT_S24: case SPA_AUDIO_FORMAT_S24_OE: return 3; - default: + case SPA_AUDIO_FORMAT_S32P: + case SPA_AUDIO_FORMAT_S32: + case SPA_AUDIO_FORMAT_S32_OE: return 4; + default: + return 0; } } @@ -571,6 +575,12 @@ return res; port->stride = calc_width(&info); + if (port->stride == 0) + return -EINVAL; + if (info.info.raw.rate == 0 || + info.info.raw.channels == 0) + return -EINVAL; + if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) { port->blocks = info.info.raw.channels; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audioconvert/volume-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audioconvert/volume-ops.c
Changed
@@ -56,11 +56,9 @@ static const struct volume_info *find_volume_info(uint32_t cpu_flags) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(volume_table); i++) { - if (!MATCH_CPU_FLAGS(volume_tablei.cpu_flags, cpu_flags)) - continue; - return &volume_tablei; + SPA_FOR_EACH_ELEMENT_VAR(volume_table, t) { + if (MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags)) + return t; } return NULL; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
@@ -566,6 +566,10 @@ if (memcmp(&info, &this->format, sizeof(struct spa_audio_info))) return -EINVAL; } else { + if (info.info.raw.format == 0 || + info.info.raw.channels == 0) + return -EINVAL; + this->ops.fmt = info.info.raw.format; this->ops.n_channels = info.info.raw.channels; this->ops.cpu_flags = this->cpu_flags;
View file
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/mix-ops-avx.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/mix-ops-avx.c
Changed
@@ -32,62 +32,6 @@ #include <immintrin.h> -static inline void mix_4(float * dst, - const float * SPA_RESTRICT src0, - const float * SPA_RESTRICT src1, - const float * SPA_RESTRICT src2, - uint32_t n_samples) -{ - uint32_t n, unrolled; - - if (SPA_IS_ALIGNED(src0, 32) && - SPA_IS_ALIGNED(src1, 32) && - SPA_IS_ALIGNED(src2, 32) && - SPA_IS_ALIGNED(dst, 32)) - unrolled = n_samples & ~15; - else - unrolled = 0; - - for (n = 0; n < unrolled; n += 16) { - __m256 in14, in24; - - in10 = _mm256_load_ps(&dstn + 0); - in20 = _mm256_load_ps(&dstn + 8); - in11 = _mm256_load_ps(&src0n + 0); - in21 = _mm256_load_ps(&src0n + 8); - in12 = _mm256_load_ps(&src1n + 0); - in22 = _mm256_load_ps(&src1n + 8); - in13 = _mm256_load_ps(&src2n + 0); - in23 = _mm256_load_ps(&src2n + 8); - - in10 = _mm256_add_ps(in10, in11); - in20 = _mm256_add_ps(in20, in21); - in12 = _mm256_add_ps(in12, in13); - in22 = _mm256_add_ps(in22, in23); - in10 = _mm256_add_ps(in10, in12); - in20 = _mm256_add_ps(in20, in22); - - _mm256_store_ps(&dstn + 0, in10); - _mm256_store_ps(&dstn + 8, in20); - } - for (; n < n_samples; n++) { - __m128 in4; - in0 = _mm_load_ss(&dstn), - in1 = _mm_load_ss(&src0n), - in2 = _mm_load_ss(&src1n), - in3 = _mm_load_ss(&src2n), - in0 = _mm_add_ss(in0, in1); - in2 = _mm_add_ss(in2, in3); - in0 = _mm_add_ss(in0, in2); - _mm_store_ss(&dstn, in0); - } -} - - -static inline void mix_2(float * dst, const float * SPA_RESTRICT src, uint32_t n_samples) -{ -} - void mix_f32_avx(struct mix_ops *ops, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src, uint32_t n_src, uint32_t n_samples)
View file
pipewire-0.3.59.tar.gz/spa/plugins/audiomixer/mix-ops.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiomixer/mix-ops.c
Changed
@@ -98,13 +98,11 @@ static const struct mix_info *find_mix_info(uint32_t fmt, uint32_t n_channels, uint32_t cpu_flags) { - size_t i; - - for (i = 0; i < SPA_N_ELEMENTS(mix_table); i++) { - if (mix_tablei.fmt == fmt && - MATCH_CHAN(mix_tablei.n_channels, n_channels) && - MATCH_CPU_FLAGS(mix_tablei.cpu_flags, cpu_flags)) - return &mix_tablei; + SPA_FOR_EACH_ELEMENT_VAR(mix_table, t) { + if (t->fmt == fmt && + MATCH_CHAN(t->n_channels, n_channels) && + MATCH_CPU_FLAGS(t->cpu_flags, cpu_flags)) + return t; } return NULL; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c -> pipewire-0.3.60.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
@@ -743,6 +743,10 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; + if (info.info.raw.rate == 0 || + info.info.raw.channels == 0) + return -EINVAL; + switch (info.info.raw.format) { case SPA_AUDIO_FORMAT_S16: idx = 0;
View file
pipewire-0.3.59.tar.gz/spa/plugins/avb/avb-pcm.c -> pipewire-0.3.60.tar.gz/spa/plugins/avb/avb-pcm.c
Changed
@@ -439,7 +439,7 @@ } } -static int frame_size(uint32_t format) +static int calc_frame_size(uint32_t format) { switch(format) { case SPA_AUDIO_FORMAT_F32_BE: @@ -647,7 +647,7 @@ SPA_AVBTP_PACKET_AAF_SET_FORMAT(pdu, spa_format_to_aaf(state->format)); SPA_AVBTP_PACKET_AAF_SET_NSR(pdu, spa_rate_to_aaf(state->rate)); SPA_AVBTP_PACKET_AAF_SET_CHAN_PER_FRAME(pdu, state->channels); - SPA_AVBTP_PACKET_AAF_SET_BIT_DEPTH(pdu, frame_size(state->format)*8); + SPA_AVBTP_PACKET_AAF_SET_BIT_DEPTH(pdu, calc_frame_size(state->format)*8); SPA_AVBTP_PACKET_AAF_SET_DATA_LEN(pdu, payload_size); SPA_AVBTP_PACKET_AAF_SET_SP(pdu, SPA_AVBTP_AAF_PCM_SP_NORMAL); } @@ -690,14 +690,22 @@ int spa_avb_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) { - int res; + int res, frame_size; struct props *p = &state->props; + frame_size = calc_frame_size(fmt->info.raw.format); + if (frame_size == 0) + return -EINVAL; + + if (fmt->info.raw.rate == 0 || + fmt->info.raw.channels == 0) + return -EINVAL; + state->format = fmt->info.raw.format; state->rate = fmt->info.raw.rate; state->channels = fmt->info.raw.channels; state->blocks = 1; - state->stride = state->channels * frame_size(state->format); + state->stride = state->channels * frame_size; if ((res = setup_socket(state)) < 0) return res;
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
@@ -206,11 +206,11 @@ spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_None, 0); choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f1); i = 0; - for (size_t j = 0; j < SPA_N_ELEMENTS(aac_frequencies); j++) { - if (AAC_GET_FREQUENCY(conf) & aac_frequenciesj.config) { + SPA_FOR_EACH_ELEMENT_VAR(aac_frequencies, f) { + if (AAC_GET_FREQUENCY(conf) & f->config) { if (i++ == 0) - spa_pod_builder_int(b, aac_frequenciesj.value); - spa_pod_builder_int(b, aac_frequenciesj.value); + spa_pod_builder_int(b, f->value); + spa_pod_builder_int(b, f->value); } } if (i == 0) @@ -272,14 +272,15 @@ if (!(conf.object_type & (AAC_OBJECT_TYPE_MPEG2_AAC_LC | AAC_OBJECT_TYPE_MPEG4_AAC_LC))) return -EINVAL; - - for (j = 0; j < SPA_N_ELEMENTS(aac_frequencies); ++j) { - if (AAC_GET_FREQUENCY(conf) & aac_frequenciesj.config) { - info->info.raw.rate = aac_frequenciesj.value; + j = 0; + SPA_FOR_EACH_ELEMENT_VAR(aac_frequencies, f) { + if (AAC_GET_FREQUENCY(conf) & f->config) { + info->info.raw.rate = f->value; + j++; break; } } - if (j == SPA_N_ELEMENTS(aac_frequencies)) + if (j == 0) return -EINVAL; if (conf.channels & AAC_CHANNELS_2) { @@ -609,7 +610,7 @@ if (res != AACENC_OK) return -EINVAL; - return 0; + return this->cur_bitrate; } static int codec_reduce_bitpool(void *data)
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
@@ -747,15 +747,17 @@ static int codec_reduce_bitpool(void *data) { struct impl *this = data; - this->e.next_bitrate = this->bitrate * 3 / 4; - return 0; + this->e.next_bitrate = SPA_CLAMP(this->bitrate * 3 / 4, + BITRATE_MIN * this->channels, BITRATE_MAX * this->channels); + return this->e.next_bitrate; } static int codec_increase_bitpool(void *data) { struct impl *this = data; - this->e.next_bitrate = this->bitrate * 5 / 4; - return 0; + this->e.next_bitrate = SPA_CLAMP(this->bitrate * 5 / 4, + BITRATE_MIN * this->channels, BITRATE_MAX * this->channels); + return this->e.next_bitrate; } const struct media_codec a2dp_codec_lc3plus_hr = {
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c
Changed
@@ -1360,7 +1360,6 @@ .codec_id = A2DP_CODEC_VENDOR, \ .vendor = { .vendor_id = OPUS_05_VENDOR_ID, \ .codec_id = OPUS_05_CODEC_ID }, \ - .fill_caps = codec_fill_caps, \ .select_config = codec_select_config, \ .enum_config = codec_enum_config, \ .validate_config = codec_validate_config, \ @@ -1385,6 +1384,7 @@ .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, .name = "opus_05", .description = "Opus", + .fill_caps = codec_fill_caps, }; const struct media_codec a2dp_codec_opus_05_51 = { @@ -1392,6 +1392,8 @@ .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, .name = "opus_05_51", .description = "Opus 5.1 Surround", + .endpoint_name = "opus_05", + .fill_caps = NULL, }; const struct media_codec a2dp_codec_opus_05_71 = { @@ -1399,6 +1401,8 @@ .id = SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, .name = "opus_05_71", .description = "Opus 7.1 Surround", + .endpoint_name = "opus_05", + .fill_caps = NULL, }; /* Bidi return channel codec: doesn't have endpoints */ @@ -1415,6 +1419,7 @@ .name = "opus_05_duplex", .description = "Opus Duplex", .duplex_codec = &a2dp_codec_opus_05_return, + .fill_caps = codec_fill_caps, }; const struct media_codec a2dp_codec_opus_05_pro = { @@ -1425,6 +1430,8 @@ .init_props = codec_init_props, .clear_props = codec_clear_props, .duplex_codec = &a2dp_codec_opus_05_return, + .endpoint_name = "opus_05_duplex", + .fill_caps = NULL, }; MEDIA_CODEC_EXPORT_DEF(
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/backend-native.c
Changed
@@ -51,6 +51,9 @@ #include <libusb.h> #endif +#include "modemmanager.h" +#include "upower.h" + static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.native"); #undef SPA_LOG_TOPIC_DEFAULT #define SPA_LOG_TOPIC_DEFAULT &log_topic @@ -60,12 +63,39 @@ #define HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC 5000 #define HFP_CODEC_SWITCH_TIMEOUT_MSEC 20000 +#define INTERNATIONAL_NUMBER 145 +#define NATIONAL_NUMBER 129 + +#define MAX_HF_INDICATORS 16 + enum { HFP_AG_INITIAL_CODEC_SETUP_NONE = 0, HFP_AG_INITIAL_CODEC_SETUP_SEND, HFP_AG_INITIAL_CODEC_SETUP_WAIT }; +#define CIND_INDICATORS "(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2)),(\"signal\",(0-5)),(\"roam\",(0-1)),\"battchg\",(0-5))" +enum { + CIND_SERVICE = 1, + CIND_CALL, + CIND_CALLSETUP, + CIND_CALLHELD, + CIND_SIGNAL, + CIND_ROAM, + CIND_BATTERY_LEVEL, + CIND_MAX +}; + +struct modem { + bool network_has_service; + unsigned int signal_strength; + bool network_is_roaming; + char *operator_name; + char *own_number; + bool active_call; + unsigned int call_setup; +}; + struct impl { struct spa_bt_backend this; @@ -87,6 +117,13 @@ struct spa_list rfcomm_list; unsigned int defer_setup_enabled:1; + + struct modem modem; + unsigned int battery_level; + + void *modemmanager; + struct spa_source *ring_timer; + void *upower; }; struct transport_data { @@ -142,9 +179,13 @@ unsigned int hfp_ag_initial_codec_setup:2; unsigned int cind_call_active:1; unsigned int cind_call_notify:1; + unsigned int extended_error_reporting:1; + unsigned int clip_notify:1; enum hfp_hf_state hf_state; enum hsp_hs_state hs_state; unsigned int codec; + uint32_t cind_enabled_indicators; + char *hf_indicatorsMAX_HF_INDICATORS; #endif }; @@ -233,6 +274,11 @@ static void rfcomm_free(struct rfcomm *rfcomm) { codec_switch_stop_timer(rfcomm); + for (int i = 0; i < MAX_HF_INDICATORS; i++) { + if (rfcomm->hf_indicatorsi) { + free(rfcomm->hf_indicatorsi); + } + } spa_list_remove(&rfcomm->link); if (rfcomm->path) free(rfcomm->path); @@ -351,6 +397,14 @@ return len; } +static void rfcomm_send_error(const struct rfcomm *rfcomm, enum cmee_error error) +{ + if (rfcomm->extended_error_reporting) + rfcomm_send_reply(rfcomm, "+CME ERROR: %d", error); + else + rfcomm_send_reply(rfcomm, "ERROR"); +} + static bool rfcomm_volume_enabled(struct rfcomm *rfcomm) { return rfcomm->device != NULL @@ -720,6 +774,7 @@ unsigned int selected_codec; unsigned int indicator; unsigned int indicator_value; + unsigned int value; int xapl_vendor; int xapl_product; int xapl_features; @@ -761,6 +816,7 @@ } /* send reply to HF with the features supported by Audio Gateway (=computer) */ + ag_features |= mm_supported_features(); ag_features |= SPA_BT_HFP_AG_FEATURE_HF_INDICATORS; rfcomm_send_reply(rfcomm, "+BRSF: %u", ag_features); rfcomm_send_reply(rfcomm, "OK"); @@ -788,10 +844,12 @@ rfcomm_send_reply(rfcomm, "OK"); } else if (spa_strstartswith(buf, "AT+CIND=?")) { - rfcomm_send_reply(rfcomm, "+CIND:(\"service\",(0-1)),(\"call\",(0-1)),(\"callsetup\",(0-3)),(\"callheld\",(0-2))"); + rfcomm_send_reply(rfcomm, "+CIND:%s", CIND_INDICATORS); rfcomm_send_reply(rfcomm, "OK"); } else if (spa_strstartswith(buf, "AT+CIND?")) { - rfcomm_send_reply(rfcomm, "+CIND: 0,%d,0,0", rfcomm->cind_call_active); + rfcomm_send_reply(rfcomm, "+CIND: %d,%d,%d,0,%d,%d,%d", backend->modem.network_has_service, + backend->modem.active_call, backend->modem.call_setup, backend->modem.signal_strength, + backend->modem.network_is_roaming, backend->battery_level); rfcomm_send_reply(rfcomm, "OK"); } else if (spa_strstartswith(buf, "AT+CMER")) { int mode, keyp, disp, ind; @@ -824,8 +882,13 @@ } } else if (!rfcomm->slc_configured) { spa_log_warn(backend->log, "RFCOMM receive command before SLC completed: %s", buf); - rfcomm_send_reply(rfcomm, "ERROR"); + rfcomm_send_error(rfcomm, CMEE_AG_FAILURE); return true; + + /* ***** + * Following commands requires a Service Level Connection + * ***** */ + } else if (sscanf(buf, "AT+BCS=%u", &selected_codec) == 1) { /* parse BCS(=Bluetooth Codec Selection) reply */ bool was_switching_codec = rfcomm->hfp_ag_switching_codec && (rfcomm->device != NULL); @@ -836,7 +899,7 @@ if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC) { spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec); - rfcomm_send_reply(rfcomm, "ERROR"); + rfcomm_send_error(rfcomm, CMEE_AG_FAILURE); if (was_switching_codec) spa_bt_device_emit_codec_switched(rfcomm->device, -EIO); return true; @@ -854,7 +917,7 @@ if (rfcomm->transport == NULL) { spa_log_warn(backend->log, "can't create transport: %m"); // TODO: We should manage the missing transport - rfcomm_send_reply(rfcomm, "ERROR"); + rfcomm_send_error(rfcomm, CMEE_AG_FAILURE); if (was_switching_codec) spa_bt_device_emit_codec_switched(rfcomm->device, -ENOMEM); return true; @@ -867,10 +930,105 @@ if (was_switching_codec) spa_bt_device_emit_codec_switched(rfcomm->device, 0); } else if (spa_strstartswith(buf, "AT+BIA=")) { - /* We only support 'call' indicator, which HFP 4.35.1 defines as - always active (assuming CMER enabled it), so we don't need to - parse anything here. */ + /* retrieve indicators activation + * form: AT+BIA=indrep1,indrep2,indrepx */ + char *str = buf + 7; + unsigned int ind = 1; + + while (*str && ind < CIND_MAX && *str != '\r' && *str != '\n') { + if (*str == ',') { + ind++; + goto next_indicator; + } + + /* Ignore updates to mandantory indicators which are always ON */ + if (ind == CIND_CALL || ind == CIND_CALLSETUP || ind == CIND_CALLHELD) + goto next_indicator; + + switch (*str) { + case '0': + rfcomm->cind_enabled_indicators &= ~(1 << ind); + break; + case '1': + rfcomm->cind_enabled_indicators |= (1 << ind); + break; + default: + spa_log_warn(backend->log, "Unsupported entry in %s: %c", buf, *str);
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-caps.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bap-codec-caps.h
Changed
@@ -110,4 +110,33 @@ uint8_t n_blks; } __attribute__ ((packed)) bap_lc3_t; +#define BT_ISO_QOS_CIG_UNSET 0xff +#define BT_ISO_QOS_CIS_UNSET 0xff + +#define BT_ISO_QOS_TARGET_LATENCY_LOW 0x01 +#define BT_ISO_QOS_TARGET_LATENCY_BALANCED 0x02 +#define BT_ISO_QOS_TARGET_LATENCY_RELIABILITY 0x03 + +struct bap_endpoint_qos { + uint8_t framing; + uint8_t phy; + uint8_t retransmission; + uint16_t latency; + uint32_t delay_min; + uint32_t delay_max; + uint32_t preferred_delay_min; + uint32_t preferred_delay_max; +}; + +struct bap_codec_qos { + uint32_t interval; + uint8_t framing; + uint8_t phy; + uint16_t sdu; + uint8_t retransmission; + uint16_t latency; + uint32_t delay; + uint8_t target_latency; +}; + #endif
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bap-codec-lc3.c
Changed
@@ -501,24 +501,31 @@ return 0; } -static void codec_get_qos(const struct media_codec *codec, - const void *config, size_t config_size, - struct codec_qos *qos) +static int codec_get_qos(const struct media_codec *codec, + const void *config, size_t config_size, + const struct bap_endpoint_qos *endpoint_qos, + struct bap_codec_qos *qos) { bap_lc3_t conf; - memset(qos, 0, sizeof(*qos)); + spa_zero(*qos); if (!parse_conf(&conf, config, config_size)) - return; + return -EINVAL; qos->framing = false; - qos->phy = "2M"; + if (endpoint_qos->phy & 0x2) + qos->phy = 0x2; + else if (endpoint_qos->phy & 0x1) + qos->phy = 0x1; + else + qos->phy = 0x2; qos->retransmission = 2; /* default */ qos->sdu = conf.framelen * conf.n_blks; qos->latency = 20; /* default */ qos->delay = 40000U; qos->interval = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 7500 : 10000); + qos->target_latency = BT_ISO_QOS_TARGET_LATENCY_BALANCED; switch (conf.rate) { case LC3_CONFIG_FREQ_8KHZ: @@ -533,6 +540,18 @@ qos->latency = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 15 : 20); break; } + + /* Clamp to ASE values */ + if (endpoint_qos->latency >= 0x0005 && endpoint_qos->latency <= 0x0FA0) + /* Values outside the range are RFU */ + qos->latency = SPA_MAX(qos->latency, endpoint_qos->latency); + + if (endpoint_qos->delay_min) + qos->delay = SPA_MAX(qos->delay, endpoint_qos->delay_min); + if (endpoint_qos->delay_max) + qos->delay = SPA_MIN(qos->delay, endpoint_qos->delay_max); + + return 0; } static void *codec_init(const struct media_codec *codec, uint32_t flags, @@ -586,7 +605,7 @@ } this->codesize = this->samples * this->channels * sizeof(int32_t); - if (flags & MEDIA_CODEC_FLAG_SINK) { + if (!(flags & MEDIA_CODEC_FLAG_SINK)) { for (ich = 0; ich < this->channels; ich++) { this->encich = lc3_setup_encoder(this->frame_dus, this->samplerate, 0, calloc(1, lc3_encoder_size(this->frame_dus, this->samplerate))); if (this->encich == NULL) {
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -113,6 +113,7 @@ unsigned int filters_added:1; unsigned int objects_listed:1; + DBusPendingCall *get_managed_objects_call; struct spa_bt_backend *backend; struct spa_bt_backend *backendsBACKEND_NUM; @@ -451,10 +452,11 @@ return 0; } -static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink) +static const struct media_codec *media_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink, const struct media_codec *preferred) { const char *ep_name; const struct media_codec * const * const media_codecs = monitor->media_codecs; + const struct media_codec *found = NULL; int i; if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) { @@ -478,10 +480,20 @@ const struct media_codec *codec = media_codecsi; const char *codec_ep_name = codec->endpoint_name ? codec->endpoint_name : codec->name; - if (spa_streq(ep_name, codec_ep_name)) - return codec; + + if (!spa_streq(ep_name, codec_ep_name)) + continue; + if ((*sink && !codec->decode) || (!*sink && !codec->encode)) + continue; + + /* Same endpoint may be shared with multiple codec objects, + * which may e.g. correspond to different encoder settings. + * Look up which one we selected. + */ + if ((preferred && codec == preferred) || found == NULL) + found = codec; } - return NULL; + return found; } static int media_endpoint_to_profile(const char *endpoint) @@ -504,6 +516,30 @@ return spa_dict_lookup(&monitor->enabled_codecs, codec->name) != NULL; } +static bool codec_has_direction(const struct media_codec *codec, enum spa_bt_media_direction direction) +{ + switch (direction) { + case SPA_BT_MEDIA_SOURCE: + return codec->encode; + case SPA_BT_MEDIA_SINK: + return codec->decode; + default: + spa_assert_not_reached(); + } +} + +static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor, + const struct media_codec *codec, + enum spa_bt_media_direction direction) +{ + /* Codecs with fill_caps == NULL share endpoint with another codec, + * and don't have their own endpoint + */ + return is_media_codec_enabled(monitor, codec) && + codec_has_direction(codec, direction) && + codec->fill_caps; +} + static DBusHandlerResult endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) { struct spa_bt_monitor *monitor = userdata; @@ -529,7 +565,14 @@ spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size); spa_log_hexdump(monitor->log, SPA_LOG_LEVEL_DEBUG, 2, cap, (size_t)size); - codec = media_endpoint_to_codec(monitor, path, &sink); + /* For codecs sharing the same endpoint, BlueZ-initiated connections + * always pick the default one. The session manager will + * switch the codec to a saved value after connection, so this generally + * does not matter. + */ + codec = media_endpoint_to_codec(monitor, path, &sink, NULL); + spa_log_debug(monitor->log, "%p: %s codec:%s", monitor, path, codec ? codec->name : "<null>"); + if (codec != NULL) /* FIXME: We can't determine which device the SelectConfiguration() * call is associated with, therefore device settings are not passed. @@ -557,7 +600,7 @@ DBUS_TYPE_BYTE, &pconf, size, DBUS_TYPE_INVALID)) return DBUS_HANDLER_RESULT_NEED_MEMORY; - exit_send: +exit_send: if (!dbus_connection_send(conn, r, NULL)) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -574,12 +617,21 @@ { struct spa_bt_monitor *monitor = userdata; const char *path; - const char *object_path; DBusMessageIter args, props, iter; DBusMessage *r = NULL; - int size, res; + int res; const struct media_codec *codec; bool sink; + const char *err_msg = "Unknown error"; + + const char *endpoint_path = NULL; + uint8_t capsA2DP_MAX_CAPS_SIZE; + uint8_t configA2DP_MAX_CAPS_SIZE; + int caps_size = 0; + DBusMessageIter dict; + struct bap_endpoint_qos endpoint_qos; + + spa_zero(endpoint_qos); if (!dbus_message_iter_init(m, &args) || !spa_streq(dbus_message_get_signature(m), "a{sv}")) { spa_log_error(monitor->log, "Invalid signature for method SelectProperties()"); @@ -592,22 +644,24 @@ path = dbus_message_get_path(m); - codec = media_endpoint_to_codec(monitor, path, &sink); + /* TODO: for codecs with shared endpoint, this currently always picks the default + * one. However, currently we don't have BAP codecs with shared endpoint, so + * this does not matter, but in case they are needed later we should pick the + * right one here. + */ + codec = media_endpoint_to_codec(monitor, path, &sink, NULL); + spa_log_debug(monitor->log, "%p: %s codec:%s", monitor, path, codec ? codec->name : "<null>"); if (!codec) { - res = -ENOTSUP; - spa_log_error(monitor->log, "Unsupported codec: %d (%s)", - res, spa_strerror(res)); - if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", - "Unsupported codec")) == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - goto exit_send; + spa_log_error(monitor->log, "Unsupported codec"); + err_msg = "Unsupported codec"; + goto error; } - /* Read transport properties */ + /* Parse transport properties */ while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) { const char *key; DBusMessageIter value, entry; - int var; + int type; dbus_message_iter_recurse(&props, &entry); dbus_message_iter_get_basic(&entry, &key); @@ -615,112 +669,156 @@ dbus_message_iter_next(&entry); dbus_message_iter_recurse(&entry, &value); - var = dbus_message_iter_get_arg_type(&value); + type = dbus_message_iter_get_arg_type(&value); if (spa_streq(key, "Capabilities")) { - DBusMessageIter array, dict; - uint8_t configA2DP_MAX_CAPS_SIZE, *cap; - uint8_t *pconf = (uint8_t *) config; - - if (r) { - spa_log_warn(monitor->log, "Multiple Capabilities entries, skipped"); - goto next_entry; - } + DBusMessageIter array; + uint8_t *buf; - if (var != DBUS_TYPE_ARRAY) { - spa_log_error(monitor->log, "Property %s of wrong type %c", key, (char)var); - if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", - "Invalid property")) == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - goto exit_send; + if (type != DBUS_TYPE_ARRAY) { + spa_log_error(monitor->log, "Property %s of wrong type %c", key, (char)type); + goto error_invalid; } dbus_message_iter_recurse(&value, &array); - var = dbus_message_iter_get_arg_type(&array); - if (var != DBUS_TYPE_BYTE) { - spa_log_error(monitor->log, "%s is an array of wrong type %c", key, (char)var); - if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", - "Invalid property")) == NULL) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - goto exit_send; - } -
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -74,6 +74,7 @@ DEVICE_PROFILE_A2DP = 2, DEVICE_PROFILE_HSP_HFP = 3, DEVICE_PROFILE_BAP = 4, + DEVICE_PROFILE_LAST = DEVICE_PROFILE_BAP, }; struct props { @@ -1092,18 +1093,18 @@ *codec = 0; *next = index + 1; - if (index <= 3) { + if (index <= DEVICE_PROFILE_LAST) { return index; } else if (index != SPA_ID_INVALID) { const struct spa_type_info *info; uint32_t profile; - *codec = index - 3; + *codec = index - DEVICE_PROFILE_LAST; *next = SPA_ID_INVALID; for (info = spa_type_bluetooth_audio_codec; info->type; ++info) if (info->type > *codec) - *next = SPA_MIN(info->type + 3, *next); + *next = SPA_MIN(info->type + DEVICE_PROFILE_LAST, *next); if (get_hfp_codec(*codec)) profile = DEVICE_PROFILE_HSP_HFP; @@ -1128,14 +1129,14 @@ if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_MEDIA_SOURCE)) return profile; - return codec + 3; + return codec + DEVICE_PROFILE_LAST; } if (profile == DEVICE_PROFILE_HSP_HFP) { if (codec == 0 || (this->bt_dev->connected_profiles & SPA_BT_PROFILE_HFP_AG)) return profile; - return codec + 3; + return codec + DEVICE_PROFILE_LAST; } return SPA_ID_INVALID;
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
@@ -126,8 +126,12 @@ for (i = 0; bluez5_codec_a2dp->codecsi; ++i) { const struct media_codec *c = bluez5_codec_a2dp->codecsi; + const char *ep = c->endpoint_name ? c->endpoint_name : c->name; size_t j; + if (!ep) + goto next_codec; + if (impl->n_codecs >= MAX_CODECS) { spa_log_error(impl->log, "too many A2DP codecs"); break; @@ -136,13 +140,16 @@ /* Don't load duplicate endpoints */ for (j = 0; j < impl->n_codecs; ++j) { const struct media_codec *c2 = impl->codecsj; - const char *ep1 = c->endpoint_name ? c->endpoint_name : c->name; const char *ep2 = c2->endpoint_name ? c2->endpoint_name : c2->name; - if (spa_streq(ep1, ep2)) + if (spa_streq(ep, ep2) && c->fill_caps && c2->fill_caps) { + spa_log_debug(impl->log, "media codec %s from %s duplicate endpoint %s", + c->name, factory_name, ep); goto next_codec; + } } - spa_log_debug(impl->log, "loaded media codec %s from %s", c->name, factory_name); + spa_log_debug(impl->log, "loaded media codec %s from %s, endpoint:%s", + c->name, factory_name, ep); if (c->set_log) c->set_log(impl->log);
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/defs.h
Changed
@@ -459,6 +459,8 @@ void (*destroy) (void *data); }; +struct media_codec; + struct spa_bt_device { struct spa_list link; struct spa_bt_monitor *monitor; @@ -507,9 +509,9 @@ const struct spa_dict *settings; DBusPendingCall *battery_pending_call; -}; -struct media_codec; + const struct media_codec *preferred_codec; +}; struct spa_bt_device *spa_bt_device_find(struct spa_bt_monitor *monitor, const char *path); struct spa_bt_device *spa_bt_device_find_by_address(struct spa_bt_monitor *monitor, const char *remote_address, const char *local_address);
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-codecs.h -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-codecs.h
Changed
@@ -36,6 +36,7 @@ #include <spa/support/log.h> #include "a2dp-codec-caps.h" +#include "bap-codec-caps.h" /* * The codec plugin SPA interface is private. The version should be incremented @@ -44,7 +45,7 @@ #define SPA_TYPE_INTERFACE_Bluez5CodecMedia SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:Media:Private" -#define SPA_VERSION_BLUEZ5_CODEC_MEDIA 5 +#define SPA_VERSION_BLUEZ5_CODEC_MEDIA 7 struct spa_bluez5_codec_a2dp { struct spa_interface iface; @@ -79,16 +80,6 @@ uint32_t channels; }; -struct codec_qos { - uint32_t interval; - bool framing; - char *phy; - uint16_t sdu; - uint8_t retransmission; - uint16_t latency; - uint32_t delay; -}; - struct media_codec { enum spa_bluetooth_audio_codec id; uint8_t codec_id; @@ -107,8 +98,10 @@ struct spa_log *log; + /** If fill_caps is NULL, no endpoint is registered (for sharing with another codec). */ int (*fill_caps) (const struct media_codec *codec, uint32_t flags, uint8_t capsA2DP_MAX_CAPS_SIZE); + int (*select_config) (const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, const struct media_codec_audio_info *info, @@ -119,9 +112,10 @@ int (*validate_config) (const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info); - void (*get_qos)(const struct media_codec *codec, + int (*get_qos)(const struct media_codec *codec, const void *config, size_t config_size, - struct codec_qos *qos); + const struct bap_endpoint_qos *endpoint_qos, + struct bap_codec_qos *qos); /** qsort comparison sorting caps in order of preference for the codec. * Used in codec switching to select best remote endpoints.
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-sink.c
Changed
@@ -62,17 +62,14 @@ #define DEFAULT_CLOCK_NAME "clock.system.monotonic" struct props { - uint32_t min_latency; - uint32_t max_latency; int64_t latency_offset; char clock_name64; }; -#define FILL_FRAMES 2 +#define FILL_FRAMES 4 +#define MIN_BUFFERS 2 #define MAX_BUFFERS 32 -#define MIN_LATENCY 128 -#define MAX_LATENCY 8192 -#define BUFFER_SIZE (MAX_LATENCY*8) +#define BUFFER_SIZE (8192*8) struct buffer { uint32_t id; @@ -121,6 +118,8 @@ struct spa_hook_list hooks; struct spa_callbacks callbacks; + uint32_t quantum_limit; + uint64_t info_all; struct spa_node_info info; #define IDX_PropInfo 0 @@ -137,6 +136,7 @@ unsigned int started:1; unsigned int following:1; unsigned int is_output:1; + unsigned int flush_pending:1; unsigned int is_duplex:1; @@ -152,6 +152,10 @@ uint64_t current_time; uint64_t next_time; uint64_t last_error; + uint64_t process_time; + + uint64_t prev_flush_time; + uint64_t next_flush_time; const struct media_codec *codec; bool codec_props_changed; @@ -161,30 +165,23 @@ int need_flush; bool fragment; - uint64_t fragment_timeout; uint32_t block_size; uint8_t bufferBUFFER_SIZE; uint32_t buffer_used; uint32_t header_size; - uint32_t frame_count; + uint32_t block_count; uint16_t seqnum; uint32_t timestamp; uint64_t sample_count; uint8_t tmp_bufferBUFFER_SIZE; uint32_t tmp_buffer_used; uint32_t fd_buffer_size; - - /* Times */ - uint64_t start_time; - uint64_t total_samples; }; -#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) static void reset_props(struct impl *this, struct props *props) { - props->min_latency = MIN_LATENCY; - props->max_latency = MAX_LATENCY; props->latency_offset = 0; strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); } @@ -214,33 +211,17 @@ switch (id) { case SPA_PARAM_PropInfo: { - struct props *p = &this->props; - switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, - SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_minLatency), - SPA_PROP_INFO_description, SPA_POD_String("The minimum latency"), - SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->min_latency, 1, INT32_MAX)); - break; - case 1: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_PropInfo, id, - SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_maxLatency), - SPA_PROP_INFO_description, SPA_POD_String("The maximum latency"), - SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX)); - break; - case 2: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_PropInfo, id, SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_latencyOffsetNsec), SPA_PROP_INFO_description, SPA_POD_String("Latency offset (ns)"), SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Long(0LL, INT64_MIN, INT64_MAX)); break; default: enum_codec = true; - index_offset = 3; + index_offset = 1; } break; } @@ -252,8 +233,6 @@ case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, - SPA_PROP_minLatency, SPA_POD_Int(p->min_latency), - SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency), SPA_PROP_latencyOffsetNsec, SPA_POD_Long(p->latency_offset)); break; default: @@ -391,8 +370,6 @@ } else { spa_pod_parse_object(param, SPA_TYPE_OBJECT_Props, NULL, - SPA_PROP_minLatency, SPA_POD_OPT_Int(&new_props.min_latency), - SPA_PROP_maxLatency, SPA_POD_OPT_Int(&new_props.max_latency), SPA_PROP_latencyOffsetNsec, SPA_POD_OPT_Long(&new_props.latency_offset)); } @@ -444,7 +421,7 @@ this->codec_props_changed = false; } this->need_flush = 0; - this->frame_count = 0; + this->block_count = 0; this->fragment = false; this->buffer_used = this->codec->start_encode(this->codec_data, this->buffer, sizeof(this->buffer), @@ -469,20 +446,32 @@ static int send_buffer(struct impl *this) { int written, unsent; + unsent = get_transport_unused_size(this); if (unsent >= 0) { unsent = this->fd_buffer_size - unsent; this->codec->abr_process(this->codec_data, unsent); } - spa_log_trace(this->log, "%p: send %d %u %u %u %u", - this, this->frame_count, this->block_size, this->seqnum, - this->timestamp, this->buffer_used); - written = send(this->flush_source.fd, this->buffer, this->buffer_used, MSG_DONTWAIT | MSG_NOSIGNAL); - spa_log_trace(this->log, "%p: send %d", this, written); + if (SPA_UNLIKELY(spa_log_level_topic_enabled(this->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_TRACE))) { + struct timespec ts; + uint64_t now; + uint64_t dt; + + spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &ts); + now = SPA_TIMESPEC_TO_NSEC(&ts); + dt = now - this->prev_flush_time; + this->prev_flush_time = now; + + spa_log_trace(this->log, + "%p: send blocks:%d block:%u seq:%u ts:%u size:%u " + "wrote:%d dt:%"PRIu64, + this, this->block_count, this->block_size, this->seqnum, + this->timestamp, this->buffer_used, written, dt); + } if (written < 0) { spa_log_debug(this->log, "%p: %m", this); @@ -502,7 +491,7 @@ spa_log_trace(this->log, "%p: encode %d used %d, %d %d %d", this, size, this->buffer_used, port->frame_size, this->block_size, - this->frame_count); + this->block_count); if (this->need_flush) return 0; @@ -530,7 +519,7 @@ return processed; this->sample_count += processed / port->frame_size; - this->frame_count += processed / this->block_size; + this->block_count += processed / this->block_size; this->buffer_used += out_encoded; spa_log_trace(this->log, "%p: processed %d %zd used %d",
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/media-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/media-source.c
Changed
@@ -276,6 +276,7 @@ struct impl *this = user_data; struct port *port = &this->port; + set_timers(this); spa_bt_decode_buffer_recover(&port->buffer); return 0; } @@ -567,13 +568,14 @@ return 0; } +static int produce_buffer(struct impl *this); + static void media_on_timeout(struct spa_source *source) { struct impl *this = source->data; struct port *port = &this->port; uint64_t exp, duration; uint32_t rate; - struct spa_io_buffers *io = port->io; uint64_t prev_time, now_time; if (this->transport == NULL) @@ -608,8 +610,11 @@ this->clock->next_nsec = this->next_time; } - spa_log_trace(this->log, "%p: %d", this, io->status); - io->status = SPA_STATUS_HAVE_DATA; + if (port->io) { + int status = produce_buffer(this); + spa_log_trace(this->log, "%p: io:%d status:%d", this, port->io->status, status); + } + spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA); set_timeout(this, this->next_time); @@ -631,10 +636,7 @@ this->transport_acquired = true; - if (this->codec->bap) - flags = 0; - else - flags = this->is_duplex ? 0 : MEDIA_CODEC_FLAG_SINK; + flags = this->is_duplex ? 0 : MEDIA_CODEC_FLAG_SINK; this->codec_data = this->codec->init(this->codec, flags, @@ -1099,6 +1101,11 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; + if (info.info.raw.rate == 0 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + return -EINVAL; + port->frame_size = info.info.raw.channels; switch (info.info.raw.format) { @@ -1342,21 +1349,15 @@ } } -static int impl_node_process(void *object) +static int produce_buffer(struct impl *this) { - struct impl *this = object; - struct port *port; - struct spa_io_buffers *io; struct buffer *buffer; + struct port *port = &this->port; + struct spa_io_buffers *io = port->io; - spa_return_val_if_fail(this != NULL, -EINVAL); - - port = &this->port; - if ((io = port->io) == NULL) + if (io == NULL) return -EIO; - spa_log_trace(this->log, "%p status:%d", this, io->status); - /* Return if we already have a buffer */ if (io->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA; @@ -1367,7 +1368,7 @@ io->buffer_id = SPA_ID_INVALID; } - /* Handle buffering delay */ + /* Handle buffering */ process_buffering(this); /* Return if there are no buffers ready to be processed */ @@ -1387,6 +1388,37 @@ return SPA_STATUS_HAVE_DATA; } +static int impl_node_process(void *object) +{ + struct impl *this = object; + struct port *port; + struct spa_io_buffers *io; + + spa_return_val_if_fail(this != NULL, -EINVAL); + + port = &this->port; + if ((io = port->io) == NULL) + return -EIO; + + spa_log_trace(this->log, "%p status:%d", this, io->status); + + /* Return if we already have a buffer */ + if (io->status == SPA_STATUS_HAVE_DATA) + return SPA_STATUS_HAVE_DATA; + + /* Recycle */ + if (io->buffer_id < port->n_buffers) { + recycle_buffer(this, port, io->buffer_id); + io->buffer_id = SPA_ID_INVALID; + } + + /* Follower produces buffers here, driver in timeout */ + if (this->following) + return produce_buffer(this); + else + return SPA_STATUS_OK; +} + static const struct spa_node_methods impl_node = { SPA_VERSION_NODE_METHODS, .add_listener = impl_node_add_listener, @@ -1452,8 +1484,8 @@ { struct impl *this = (struct impl *) handle; struct port *port = &this->port; - if (this->codec_data) - this->codec->deinit(this->codec_data); + + do_stop(this); if (this->codec_props && this->codec->clear_props) this->codec->clear_props(this->codec_props); if (this->transport)
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/meson.build
Changed
@@ -10,6 +10,7 @@ get_option('bluez5-backend-hfp-native').allowed()) cdata.set('HAVE_BLUEZ_5_BACKEND_HSP_NATIVE', get_option('bluez5-backend-hsp-native').allowed()) cdata.set('HAVE_BLUEZ_5_BACKEND_HFP_NATIVE', get_option('bluez5-backend-hfp-native').allowed()) +cdata.set('HAVE_BLUEZ_5_BACKEND_NATIVE_MM', get_option('bluez5-backend-native-mm').allowed()) cdata.set('HAVE_BLUEZ_5_BACKEND_OFONO', get_option('bluez5-backend-ofono').allowed()) cdata.set('HAVE_BLUEZ_5_BACKEND_HSPHFPD', get_option('bluez5-backend-hsphfpd').allowed()) cdata.set('HAVE_BLUEZ_5_HCI', dependency('bluez', version: '< 6', required: false).found()) @@ -38,7 +39,11 @@ if libusb_dep.found() bluez5_deps += libusb_dep endif - bluez5_sources += 'backend-native.c' + if mm_dep.found() + bluez5_deps += mm_dep + bluez5_sources += 'modemmanager.c' + endif + bluez5_sources += 'backend-native.c', 'upower.c' endif if get_option('bluez5-backend-ofono').allowed()
View file
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/modemmanager.c
Added
@@ -0,0 +1,1259 @@ +/* Spa Bluez5 ModemManager proxy + * + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <errno.h> +#include <spa/utils/string.h> + +#include <ModemManager.h> + +#include "modemmanager.h" + +#define DBUS_INTERFACE_OBJECTMANAGER "org.freedesktop.DBus.ObjectManager" + +struct modem { + char *path; + bool network_has_service; + unsigned int signal_strength; +}; + +struct impl { + struct spa_bt_monitor *monitor; + + struct spa_log *log; + DBusConnection *conn; + + char *allowed_modem_device; + bool filters_added; + DBusPendingCall *pending; + DBusPendingCall *voice_pending; + + const struct mm_ops *ops; + void *user_data; + + struct modem modem; + struct spa_list call_list; +}; + +struct dbus_cmd_data { + struct impl *this; + struct call *call; + void *user_data; +}; + +static bool mm_dbus_connection_send_with_reply(struct impl *this, DBusMessage *m, DBusPendingCall **pending_return, + DBusPendingCallNotifyFunction function, void *user_data) +{ + dbus_bool_t dbus_ret; + + spa_assert(*pending_return == NULL); + + dbus_ret = dbus_connection_send_with_reply(this->conn, m, pending_return, -1); + if (!dbus_ret || *pending_return == NULL) { + spa_log_debug(this->log, "dbus call failure"); + return false; + } + + dbus_ret = dbus_pending_call_set_notify(*pending_return, function, user_data, NULL); + if (!dbus_ret) { + spa_log_debug(this->log, "dbus set notify failure"); + dbus_pending_call_cancel(*pending_return); + dbus_pending_call_unref(*pending_return); + *pending_return = NULL; + return false; + } + + return true; +} + +static int mm_state_to_clcc(struct impl *this, MMCallState state) +{ + switch (state) { + case MM_CALL_STATE_DIALING: + return CLCC_DIALING; + case MM_CALL_STATE_RINGING_OUT: + return CLCC_ALERTING; + case MM_CALL_STATE_RINGING_IN: + return CLCC_INCOMING; + case MM_CALL_STATE_ACTIVE: + return CLCC_ACTIVE; + case MM_CALL_STATE_HELD: + return CLCC_HELD; + case MM_CALL_STATE_WAITING: + return CLCC_WAITING; + case MM_CALL_STATE_TERMINATED: + case MM_CALL_STATE_UNKNOWN: + default: + return -1; + } +} + +static void mm_call_state_changed(struct impl *this) +{ + struct call *call; + bool call_indicator = false; + enum call_setup call_setup_indicator = CIND_CALLSETUP_NONE; + + spa_list_for_each(call, &this->call_list, link) { + call_indicator |= (call->state == CLCC_ACTIVE); + + if (call->state == CLCC_INCOMING && call_setup_indicator < CIND_CALLSETUP_INCOMING) + call_setup_indicator = CIND_CALLSETUP_INCOMING; + else if (call->state == CLCC_DIALING && call_setup_indicator < CIND_CALLSETUP_DIALING) + call_setup_indicator = CIND_CALLSETUP_DIALING; + else if (call->state == CLCC_ALERTING && call_setup_indicator < CIND_CALLSETUP_ALERTING) + call_setup_indicator = CIND_CALLSETUP_ALERTING; + } + + if (this->ops->set_call_active) + this->ops->set_call_active(call_indicator, this->user_data); + + if (this->ops->set_call_setup) + this->ops->set_call_setup(call_setup_indicator, this->user_data); +} + +static void mm_get_call_properties_reply(DBusPendingCall *pending, void *user_data) +{ + struct call *call = user_data; + struct impl *this = call->this; + DBusMessage *r; + DBusMessageIter arg_i, element_i; + MMCallDirection direction; + MMCallState state; + + spa_assert(call->pending == pending); + dbus_pending_call_unref(pending); + call->pending = NULL; + + r = dbus_pending_call_steal_reply(pending); + if (r == NULL) + return; + + if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) { + spa_log_warn(this->log, "ModemManager D-Bus Call not available"); + goto finish; + } + if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { + spa_log_error(this->log, "GetAll() failed: %s", dbus_message_get_error_name(r)); + goto finish; + } + + if (!dbus_message_iter_init(r, &arg_i) || !spa_streq(dbus_message_get_signature(r), "a{sv}")) { + spa_log_error(this->log, "Invalid arguments in GetAll() reply"); + goto finish; + } + + spa_log_debug(this->log, "Call path: %s", call->path); + + dbus_message_iter_recurse(&arg_i, &element_i); + while (dbus_message_iter_get_arg_type(&element_i) != DBUS_TYPE_INVALID) { + DBusMessageIter i, value_i; + const char *key; + + dbus_message_iter_recurse(&element_i, &i); + + dbus_message_iter_get_basic(&i, &key); + dbus_message_iter_next(&i); + dbus_message_iter_recurse(&i, &value_i); + + if (spa_streq(key, MM_CALL_PROPERTY_DIRECTION)) { + dbus_message_iter_get_basic(&value_i, &direction); + spa_log_debug(this->log, "Call direction: %u", direction); + call->direction = (direction == MM_CALL_DIRECTION_INCOMING) ? CALL_INCOMING : CALL_OUTGOING; + } else if (spa_streq(key, MM_CALL_PROPERTY_NUMBER)) { + char *number; + + dbus_message_iter_get_basic(&value_i, &number); + spa_log_debug(this->log, "Call number: %s", number); + if (call->number) + free(call->number); + call->number = strdup(number); + } else if (spa_streq(key, MM_CALL_PROPERTY_STATE)) { + int clcc_state; + + dbus_message_iter_get_basic(&value_i, &state); + spa_log_debug(this->log, "Call state: %u", state); + clcc_state = mm_state_to_clcc(this, state); + if (clcc_state < 0) { + spa_log_debug(this->log, "Unsupported modem state: %s, state=%d", call->path, call->state); + } else {
View file
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/modemmanager.h
Added
@@ -0,0 +1,161 @@ +/* Spa Bluez5 ModemManager proxy + * + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPA_BLUEZ5_MODEMMANAGER_H_ +#define SPA_BLUEZ5_MODEMMANAGER_H_ + +#include <spa/utils/list.h> + +#include "defs.h" + +enum cmee_error { + CMEE_AG_FAILURE = 0, + CMEE_NO_CONNECTION_TO_PHONE = 1, + CMEE_OPERATION_NOT_ALLOWED = 3, + CMEE_OPERATION_NOT_SUPPORTED = 4, + CMEE_INVALID_CHARACTERS_TEXT_STRING = 25, + CMEE_INVALID_CHARACTERS_DIAL_STRING = 27, + CMEE_NO_NETWORK_SERVICE = 30 +}; + +enum call_setup { + CIND_CALLSETUP_NONE = 0, + CIND_CALLSETUP_INCOMING, + CIND_CALLSETUP_DIALING, + CIND_CALLSETUP_ALERTING +}; + +enum call_direction { + CALL_OUTGOING, + CALL_INCOMING +}; + +enum call_state { + CLCC_ACTIVE, + CLCC_HELD, + CLCC_DIALING, + CLCC_ALERTING, + CLCC_INCOMING, + CLCC_WAITING, + CLCC_RESPONSE_AND_HOLD +}; + +struct call { + struct spa_list link; + unsigned int index; + struct impl *this; + DBusPendingCall *pending; + + char *path; + char *number; + bool call_indicator; + enum call_direction direction; + enum call_state state; + bool multiparty; +}; + +struct mm_ops { + void (*send_cmd_result)(bool success, enum cmee_error error, void *user_data); + void (*set_modem_service)(bool available, void *user_data); + void (*set_modem_signal_strength)(unsigned int strength, void *user_data); + void (*set_modem_operator_name)(const char *name, void *user_data); + void (*set_modem_own_number)(const char *number, void *user_data); + void (*set_modem_roaming)(bool is_roaming, void *user_data); + void (*set_call_active)(bool active, void *user_data); + void (*set_call_setup)(enum call_setup value, void *user_data); +}; + +#ifdef HAVE_BLUEZ_5_BACKEND_NATIVE_MM +void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info, + const struct mm_ops *ops, void *user_data); +void mm_unregister(void *data); +bool mm_is_available(void *modemmanager); +unsigned int mm_supported_features(); +bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error); +bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error); +bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error); +bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error); +const char *mm_get_incoming_call_number(void *modemmanager); +struct spa_list *mm_get_calls(void *modemmanager); +#else +void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info, + const struct mm_ops *ops, void *user_data) +{ + return NULL; +} + +void mm_unregister(void *data) +{ +} + +bool mm_is_available(void *modemmanager) +{ + return false; +} + +unsigned int mm_supported_features(void) +{ + return 0; +} + +bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error) +{ + if (error) + *error = CMEE_OPERATION_NOT_SUPPORTED; + return false; +} + +bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error) +{ + if (error) + *error = CMEE_OPERATION_NOT_SUPPORTED; + return false; +} + +bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error) +{ + if (error) + *error = CMEE_OPERATION_NOT_SUPPORTED; + return false; +} + +bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error) +{ + if (error) + *error = CMEE_OPERATION_NOT_SUPPORTED; + return false; +} + +const char *mm_get_incoming_call_number(void *modemmanager) +{ + return NULL; +} + +struct spa_list *mm_get_calls(void *modemmanager) +{ + return NULL; +} +#endif + +#endif
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/quirks.c
Changed
@@ -88,10 +88,9 @@ { "faststream", SPA_BT_FEATURE_FASTSTREAM }, { "a2dp-duplex", SPA_BT_FEATURE_A2DP_DUPLEX }, }; - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(feature_keys); ++i) { - if (spa_streq(str, feature_keysi.key)) - return feature_keysi.value; + SPA_FOR_EACH_ELEMENT_VAR(feature_keys, f) { + if (spa_streq(str, f->key)) + return f->value; } return 0; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
@@ -60,14 +60,10 @@ #define DEFAULT_CLOCK_NAME "clock.system.monotonic" struct props { - uint32_t min_latency; - uint32_t max_latency; char clock_name64; }; #define MAX_BUFFERS 32 -#define MIN_LATENCY 512 -#define MAX_LATENCY 1024 struct buffer { uint32_t id; @@ -130,6 +126,8 @@ struct spa_param_info paramsN_NODE_PARAMS; struct props props; + uint32_t quantum_limit; + /* Transport */ struct spa_bt_transport *transport; struct spa_hook transport_listener; @@ -140,38 +138,39 @@ /* Flags */ unsigned int started:1; unsigned int following:1; + unsigned int flush_pending:1; /* Sources */ struct spa_source source; + struct spa_source flush_timer_source; /* Timer */ int timerfd; - struct timespec now; + int flush_timerfd; struct spa_io_clock *clock; struct spa_io_position *position; + uint64_t current_time; + uint64_t next_time; + uint64_t process_time; + uint64_t prev_flush_time; + uint64_t next_flush_time; + /* mSBC */ sbc_t msbc; uint8_t *buffer; uint8_t *buffer_head; uint8_t *buffer_next; int buffer_size; - - /* Times */ - uint64_t start_time; - uint64_t total_samples; + int msbc_seq; }; #define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) -static const uint32_t default_min_latency = MIN_LATENCY; -static const uint32_t default_max_latency = MAX_LATENCY; static const char sntable4 = { 0x08, 0x38, 0xC8, 0xF8 }; static void reset_props(struct props *props) { - props->min_latency = default_min_latency; - props->max_latency = default_max_latency; strncpy(props->clock_name, DEFAULT_CLOCK_NAME, sizeof(props->clock_name)); } @@ -199,23 +198,7 @@ switch (id) { case SPA_PARAM_PropInfo: { - struct props *p = &this->props; - switch (result.index) { - case 0: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_PropInfo, id, - SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_minLatency), - SPA_PROP_INFO_description, SPA_POD_String("The minimum latency"), - SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->min_latency, 1, INT32_MAX)); - break; - case 1: - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_PropInfo, id, - SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_maxLatency), - SPA_PROP_INFO_description, SPA_POD_String("The maximum latency"), - SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(p->max_latency, 1, INT32_MAX)); - break; default: return 0; } @@ -223,14 +206,10 @@ } case SPA_PARAM_Props: { - struct props *p = &this->props; - switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Props, id, - SPA_PROP_minLatency, SPA_POD_Int(p->min_latency), - SPA_PROP_maxLatency, SPA_POD_Int(p->max_latency)); + SPA_TYPE_OBJECT_Props, id); break; default: return 0; @@ -260,28 +239,17 @@ ts.it_interval.tv_sec = 0; ts.it_interval.tv_nsec = 0; return spa_system_timerfd_settime(this->data_system, - this->timerfd, 0, &ts, NULL); + this->timerfd, SPA_FD_TIMER_ABSTIME, &ts, NULL); } static int set_timers(struct impl *this) { - return set_timeout(this, this->following ? 0 : 1); -} - -static uint64_t get_next_timeout(struct impl *this, uint64_t now_time, uint64_t processed_samples) -{ - struct port *port = &this->port; - uint64_t playback_time = 0, elapsed_time = 0, next_time = 0; - - this->total_samples += processed_samples; + struct timespec now; - playback_time = (this->total_samples * SPA_NSEC_PER_SEC) / port->current_format.info.raw.rate; - if (now_time > this->start_time) - elapsed_time = now_time - this->start_time; - if (elapsed_time < playback_time) - next_time = playback_time - elapsed_time; + spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &now); + this->next_time = SPA_TIMESPEC_TO_NSEC(&now); - return next_time; + return set_timeout(this, this->following ? 0 : this->next_time); } static int do_reassign_follower(struct spa_loop *loop, @@ -344,9 +312,7 @@ reset_props(&new_props); } else { spa_pod_parse_object(param, - SPA_TYPE_OBJECT_Props, NULL, - SPA_PROP_minLatency, SPA_POD_OPT_Int(&new_props.min_latency), - SPA_PROP_maxLatency, SPA_POD_OPT_Int(&new_props.max_latency)); + SPA_TYPE_OBJECT_Props, NULL); } changed = (memcmp(&new_props, &this->props, sizeof(struct props)) != 0); @@ -378,22 +344,64 @@ return 0; } +static void enable_flush_timer(struct impl *this, bool enabled) +{ + struct itimerspec ts; + + if (!enabled) + this->next_flush_time = 0; + + ts.it_value.tv_sec = this->next_flush_time / SPA_NSEC_PER_SEC; + ts.it_value.tv_nsec = this->next_flush_time % SPA_NSEC_PER_SEC; + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + spa_system_timerfd_settime(this->data_system, + this->flush_timerfd, SPA_FD_TIMER_ABSTIME, &ts, NULL); + + this->flush_pending = enabled; +} + +static uint32_t get_queued_frames(struct impl *this) +{ + struct port *port = &this->port; + uint32_t bytes = 0; + struct buffer *b; + + spa_list_for_each(b, &port->ready, link) { + struct spa_data *d = b->buf->datas; + + bytes += d0.chunk->size; + } + + if (bytes > port->ready_offset) + bytes -= port->ready_offset; + else + bytes = 0; + + return bytes / port->frame_size; +} + static void flush_data(struct impl *this)
View file
pipewire-0.3.59.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
@@ -248,6 +248,7 @@ struct impl *this = user_data; struct port *port = &this->port; + set_timers(this); spa_bt_decode_buffer_recover(&port->buffer); return 0; } @@ -590,13 +591,14 @@ return 0; } +static int produce_buffer(struct impl *this); + static void sco_on_timeout(struct spa_source *source) { struct impl *this = source->data; struct port *port = &this->port; uint64_t exp, duration; uint32_t rate; - struct spa_io_buffers *io = port->io; uint64_t prev_time, now_time; if (this->transport == NULL) @@ -631,8 +633,11 @@ this->clock->next_nsec = this->next_time; } - spa_log_trace(this->log, "%p: %d", this, io->status); - io->status = SPA_STATUS_HAVE_DATA; + if (port->io) { + int status = produce_buffer(this); + spa_log_trace(this->log, "%p: io:%d status:%d", this, port->io->status, status); + } + spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA); set_timeout(this, this->next_time); @@ -1068,6 +1073,11 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; + if (info.info.raw.format != SPA_AUDIO_FORMAT_S16_LE || + info.info.raw.rate == 0 || + info.info.raw.channels != 1) + return -EINVAL; + port->frame_size = info.info.raw.channels * 2; port->current_format = info; port->have_format = true; @@ -1285,17 +1295,13 @@ } } -static int impl_node_process(void *object) +static int produce_buffer(struct impl *this) { - struct impl *this = object; - struct port *port; - struct spa_io_buffers *io; struct buffer *buffer; + struct port *port = &this->port; + struct spa_io_buffers *io = port->io; - spa_return_val_if_fail(this != NULL, -EINVAL); - - port = &this->port; - if ((io = port->io) == NULL) + if (io == NULL) return -EIO; /* Return if we already have a buffer */ @@ -1308,7 +1314,7 @@ io->buffer_id = SPA_ID_INVALID; } - /* Produce data */ + /* Handle buffering */ process_buffering(this); /* Return if there are no buffers ready to be processed */ @@ -1328,6 +1334,35 @@ return SPA_STATUS_HAVE_DATA; } +static int impl_node_process(void *object) +{ + struct impl *this = object; + struct port *port; + struct spa_io_buffers *io; + + spa_return_val_if_fail(this != NULL, -EINVAL); + + port = &this->port; + if ((io = port->io) == NULL) + return -EIO; + + /* Return if we already have a buffer */ + if (io->status == SPA_STATUS_HAVE_DATA) + return SPA_STATUS_HAVE_DATA; + + /* Recycle */ + if (io->buffer_id < port->n_buffers) { + recycle_buffer(this, port, io->buffer_id); + io->buffer_id = SPA_ID_INVALID; + } + + /* Follower produces buffers here, driver in timeout */ + if (this->following) + return produce_buffer(this); + else + return SPA_STATUS_OK; +} + static const struct spa_node_methods impl_node = { SPA_VERSION_NODE_METHODS, .add_listener = impl_node_add_listener, @@ -1391,6 +1426,8 @@ static int impl_clear(struct spa_handle *handle) { struct impl *this = (struct impl *) handle; + + do_stop(this); if (this->transport) spa_hook_remove(&this->transport_listener); spa_system_close(this->data_system, this->timerfd);
View file
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/upower.c
Added
@@ -0,0 +1,311 @@ +/* Spa Bluez5 UPower proxy + * + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <errno.h> +#include <spa/utils/string.h> + +#include "upower.h" + +#define UPOWER_SERVICE "org.freedesktop.UPower" +#define UPOWER_DEVICE_INTERFACE UPOWER_SERVICE ".Device" +#define UPOWER_DISPLAY_DEVICE_OBJECT "/org/freedesktop/UPower/devices/DisplayDevice" + +struct impl { + struct spa_bt_monitor *monitor; + + struct spa_log *log; + DBusConnection *conn; + + bool filters_added; + + void *user_data; + void (*set_battery_level)(unsigned int level, void *user_data); +}; + +static DBusHandlerResult upower_parse_percentage(struct impl *this, DBusMessageIter *variant_i) +{ + double percentage; + unsigned int battery_level; + + dbus_message_iter_get_basic(variant_i, &percentage); + spa_log_debug(this->log, "Battery level: %f %%", percentage); + + battery_level = (unsigned int) round(percentage / 20.0); + this->set_battery_level(battery_level, this->user_data); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void upower_get_percentage_properties_reply(DBusPendingCall *pending, void *user_data) +{ + struct impl *backend = user_data; + DBusMessage *r; + DBusMessageIter i, variant_i; + + r = dbus_pending_call_steal_reply(pending); + if (r == NULL) + return; + + if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { + spa_log_error(backend->log, "Failed to get percentage from UPower: %s", + dbus_message_get_error_name(r)); + goto finish; + } + + if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "v")) { + spa_log_error(backend->log, "Invalid arguments in Get() reply"); + goto finish; + } + + dbus_message_iter_recurse(&i, &variant_i); + upower_parse_percentage(backend, &variant_i); + +finish: + dbus_message_unref(r); +} + +static void upower_clean(struct impl *this) +{ + this->set_battery_level(0, this->user_data); +} + +static DBusHandlerResult upower_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data) +{ + struct impl *this = user_data; + DBusError err; + + dbus_error_init(&err); + + if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) { + const char *name, *old_owner, *new_owner; + + spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m)); + + if (!dbus_message_get_args(m, &err, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, + DBUS_TYPE_INVALID)) { + spa_log_error(this->log, "Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message); + goto finish; + } + + if (spa_streq(name, UPOWER_SERVICE)) { + if (old_owner && *old_owner) { + spa_log_debug(this->log, "UPower daemon disappeared (%s)", old_owner); + upower_clean(this); + } + + if (new_owner && *new_owner) { + DBusPendingCall *call; + static const char* upower_device_interface = UPOWER_DEVICE_INTERFACE; + static const char* percentage_property = "Percentage"; + + spa_log_debug(this->log, "UPower daemon appeared (%s)", new_owner); + + m = dbus_message_new_method_call(UPOWER_SERVICE, UPOWER_DISPLAY_DEVICE_OBJECT, DBUS_INTERFACE_PROPERTIES, "Get"); + if (m == NULL) + goto finish; + dbus_message_append_args(m, DBUS_TYPE_STRING, &upower_device_interface, + DBUS_TYPE_STRING, &percentage_property, DBUS_TYPE_INVALID); + dbus_connection_send_with_reply(this->conn, m, &call, -1); + dbus_pending_call_set_notify(call, upower_get_percentage_properties_reply, this, NULL); + dbus_message_unref(m); + } + } + } else if (dbus_message_is_signal(m, DBUS_INTERFACE_PROPERTIES, DBUS_SIGNAL_PROPERTIES_CHANGED)) { + const char *path; + DBusMessageIter iface_i, props_i; + const char *interface; + + if (!dbus_message_iter_init(m, &iface_i) || !spa_streq(dbus_message_get_signature(m), "sa{sv}as")) { + spa_log_error(this->log, "Invalid signature found in PropertiesChanged"); + goto finish; + } + + dbus_message_iter_get_basic(&iface_i, &interface); + dbus_message_iter_next(&iface_i); + spa_assert(dbus_message_iter_get_arg_type(&iface_i) == DBUS_TYPE_ARRAY); + + dbus_message_iter_recurse(&iface_i, &props_i); + + path = dbus_message_get_path(m); + + if (spa_streq(interface, UPOWER_DEVICE_INTERFACE)) { + spa_log_debug(this->log, "Properties changed on %s", path); + + while (dbus_message_iter_get_arg_type(&props_i) != DBUS_TYPE_INVALID) { + DBusMessageIter i, value_i; + const char *key; + + dbus_message_iter_recurse(&props_i, &i); + + dbus_message_iter_get_basic(&i, &key); + dbus_message_iter_next(&i); + dbus_message_iter_recurse(&i, &value_i); + + if(spa_streq(key, "Percentage")) + upower_parse_percentage(this, &value_i); + + dbus_message_iter_next(&props_i); + } + } + } + +finish: + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int add_filters(struct impl *this) +{ + DBusError err; + + if (this->filters_added) + return 0; + + dbus_error_init(&err); + + if (!dbus_connection_add_filter(this->conn, upower_filter_cb, this, NULL)) { + spa_log_error(this->log, "failed to add filter function"); + goto fail; + } + + dbus_bus_add_match(this->conn, + "type='signal',sender='org.freedesktop.DBus'," + "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" UPOWER_SERVICE "'", &err); + dbus_bus_add_match(this->conn, + "type='signal',sender='" UPOWER_SERVICE "'," + "interface='" DBUS_INTERFACE_PROPERTIES "',member='" DBUS_SIGNAL_PROPERTIES_CHANGED "',"
View file
pipewire-0.3.60.tar.gz/spa/plugins/bluez5/upower.h
Added
@@ -0,0 +1,36 @@ +/* Spa Bluez5 UPower proxy + * + * Copyright © 2022 Collabora + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPA_BLUEZ5_UPOWER_H_ +#define SPA_BLUEZ5_UPOWER_H_ + +#include "defs.h" + +void *upower_register(struct spa_log *log, + void *dbus_connection, + void (*set_battery_level)(unsigned int level, void *user_data), + void *user_data); +void upower_unregister(void *data); + +#endif \ No newline at end of file
View file
pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.60.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -112,7 +112,14 @@ struct spa_port_info info = SPA_PORT_INFO_INIT(); struct spa_io_buffers *io = nullptr; struct spa_io_sequence *control = nullptr; - struct spa_param_info params8; +#define PORT_PropInfo 0 +#define PORT_EnumFormat 1 +#define PORT_Meta 2 +#define PORT_IO 3 +#define PORT_Format 4 +#define PORT_Buffers 5 +#define N_PORT_PARAMS 6 + struct spa_param_info paramsN_PORT_PARAMS; uint32_t fmt_index = 0; PixelFormat enum_fmt; @@ -123,16 +130,16 @@ { spa_list_init(&queue); - params0 = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ); - params1 = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); - params2 = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); - params3 = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); - params4 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); - params5 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); + paramsPORT_PropInfo = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ); + paramsPORT_EnumFormat = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); + paramsPORT_Meta = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ); + paramsPORT_IO = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ); + paramsPORT_Format = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); + paramsPORT_Buffers = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); info.flags = SPA_PORT_FLAG_LIVE | SPA_PORT_FLAG_PHYSICAL | SPA_PORT_FLAG_TERMINAL; info.params = params; - info.n_params = 6; + info.n_params = N_PORT_PARAMS; } }; @@ -149,7 +156,12 @@ SPA_NODE_CHANGE_MASK_PROPS | SPA_NODE_CHANGE_MASK_PARAMS; struct spa_node_info info = SPA_NODE_INFO_INIT(); - struct spa_param_info params8; +#define NODE_PropInfo 0 +#define NODE_Props 1 +#define NODE_EnumFormat 2 +#define NODE_Format 3 +#define N_NODE_PARAMS 4 + struct spa_param_info paramsN_NODE_PARAMS; std::string device_id; std::string device_name; @@ -175,6 +187,7 @@ struct spa_source source = {}; + ControlList ctrls; bool active = false; bool acquired = false; @@ -191,6 +204,55 @@ #include "libcamera-utils.cpp" +static int port_get_format(struct impl *impl, struct port *port, + uint32_t index, + const struct spa_pod *filter, + struct spa_pod **param, + struct spa_pod_builder *builder) +{ + struct spa_pod_frame f; + + if (!port->current_format) + return -EIO; + if (index > 0) + return 0; + + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format->media_type), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format->media_subtype), + 0); + + switch (port->current_format->media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format->info.raw.format), + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.raw.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.raw.framerate), + 0); + break; + case SPA_MEDIA_SUBTYPE_mjpg: + case SPA_MEDIA_SUBTYPE_jpeg: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.mjpg.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.mjpg.framerate), + 0); + break; + case SPA_MEDIA_SUBTYPE_h264: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format->info.h264.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format->info.h264.framerate), + 0); + break; + default: + return -EIO; + } + + *param = (struct spa_pod*)spa_pod_builder_pop(builder, &f); + + return 1; +} + static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter) @@ -201,6 +263,7 @@ uint8_t buffer1024; struct spa_result_node_params result; uint32_t count = 0; + int res; spa_return_val_if_fail(impl != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); @@ -231,7 +294,9 @@ SPA_PROP_INFO_type, SPA_POD_String(impl->device_name.c_str())); break; default: - return 0; + return spa_libcamera_enum_controls(impl, + GET_OUT_PORT(impl, 0), + seq, result.index - 2, num, filter); } break; } @@ -249,6 +314,13 @@ } break; } + case SPA_PARAM_EnumFormat: + return spa_libcamera_enum_format(impl, GET_OUT_PORT(impl, 0), + seq, start, num, filter); + case SPA_PARAM_Format: + if ((res = port_get_format(impl, GET_OUT_PORT(impl, 0), result.index, filter, ¶m, &b)) <= 0) + return res; + break; default: return -ENOENT; } @@ -275,22 +347,28 @@ switch (id) { case SPA_PARAM_Props: { + struct spa_pod_object *obj = (struct spa_pod_object *) param; + struct spa_pod_prop *prop; + if (param == NULL) { impl->device_id.clear(); impl->device_name.clear(); return 0; } - - char device128; - int res = spa_pod_parse_object(param, - SPA_TYPE_OBJECT_Props, NULL, - SPA_PROP_device, SPA_POD_OPT_Stringn(device, sizeof(device))); - - if (res < 0) - return res; - - impl->device_id = device; - + SPA_POD_OBJECT_FOREACH(obj, prop) { + char device128; + + switch (prop->key) { + case SPA_PROP_device: + strncpy(device, (char *)SPA_POD_CONTENTS(struct spa_pod_string, &prop->value), + sizeof(device)-1); + impl->device_id = device; + break; + default: + spa_libcamera_set_control(impl, prop); + break; + } + } break; } default: @@ -356,7 +434,6 @@ { SPA_KEY_DEVICE_API, "libcamera" }, { SPA_KEY_MEDIA_CLASS, "Video/Source" }, { SPA_KEY_MEDIA_ROLE, "Camera" }, - { SPA_KEY_NODE_PAUSE_ON_IDLE, "false" }, { SPA_KEY_NODE_DRIVER, "true" }, }; @@ -444,55 +521,6 @@
View file
pipewire-0.3.59.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp -> pipewire-0.3.60.tar.gz/spa/plugins/libcamera/libcamera-utils.cpp
Changed
@@ -32,6 +32,7 @@ #include <errno.h> #include <sys/mman.h> #include <poll.h> +#include <limits.h> #include <linux/media.h> @@ -104,6 +105,8 @@ impl->pendingRequests.push_back(request); return 0; } else { + request->controls().merge(impl->ctrls); + impl->ctrls.clear(); if ((res = impl->camera->queueRequest(request)) < 0) { spa_log_warn(impl->log, "can't queue buffer %u: %s", buffer_id, spa_strerror(res)); @@ -238,6 +241,14 @@ return NULL; } +static int score_size(Size &a, Size &b) +{ + int x, y; + x = (int)a.width - (int)b.width; + y = (int)a.height - (int)b.height; + return x * x + y * y; +} + static int spa_libcamera_enum_format(struct impl *impl, struct port *port, int seq, uint32_t start, uint32_t num, const struct spa_pod *filter) @@ -249,7 +260,7 @@ struct spa_pod_frame f2; struct spa_result_node_params result; struct spa_pod *fmt; - uint32_t count = 0; + uint32_t i, count = 0, num_sizes; PixelFormat format; Size frameSize; SizeRange sizeRange = SizeRange(); @@ -284,8 +295,23 @@ goto next_fmt; } - if (port->size_index < formats.sizes(format).size()) { - frameSize = formats.sizes(format)port->size_index; + num_sizes = formats.sizes(format).size(); + if (num_sizes > 0 && port->size_index <= num_sizes) { + if (port->size_index == 0) { + Size wanted = Size(640, 480), test; + int score, best = INT_MAX; + for (i = 0; i < num_sizes; i++) { + test = formats.sizes(format)i; + score = score_size(wanted, test); + if (score < best) { + best = score; + frameSize = test; + } + } + } + else { + frameSize = formats.sizes(format)port->size_index - 1; + } } else if (port->size_index < 1) { sizeRange = formats.range(format); if (sizeRange.hStep == 0 || sizeRange.vStep == 0) { @@ -437,9 +463,158 @@ uint32_t start, uint32_t num, const struct spa_pod *filter) { + const ControlInfoMap &info = impl->camera->controls(); + uint8_t buffer1024; + struct spa_pod_builder b = { 0 }; + struct spa_pod_frame f2; + struct spa_result_node_params result; + struct spa_pod *ctrl; + uint32_t count = 0, skip; + int res; + const ControlId *ctrl_id; + ControlInfo ctrl_info; + + result.id = SPA_PARAM_PropInfo; + result.next = start; + + auto it = info.begin(); + for (skip = result.next; skip; skip--) + it++; + + if (false) { +next: + it++; + } + result.index = result.next++; + if (it == info.end()) + goto enum_end; + + ctrl_id = it->first; + ctrl_info = it->second; + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); + spa_pod_builder_add(&b, + SPA_PROP_INFO_id, SPA_POD_Id(ctrl_id->id()), + SPA_PROP_INFO_description, SPA_POD_String(ctrl_id->name().c_str()), + 0); + + switch (ctrl_id->type()) { + case ControlTypeBool: + spa_pod_builder_add(&b, + SPA_PROP_INFO_type, SPA_POD_CHOICE_Bool( + (bool)ctrl_info.def().get<bool>()), + 0); + break; + case ControlTypeFloat: + spa_pod_builder_add(&b, + SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float( + (float)ctrl_info.def().get<float>(), + (float)ctrl_info.min().get<float>(), + (float)ctrl_info.max().get<float>()), + 0); + break; + case ControlTypeInteger32: + spa_pod_builder_add(&b, + SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int( + (int32_t)ctrl_info.def().get<int32_t>(), + (int32_t)ctrl_info.min().get<int32_t>(), + (int32_t)ctrl_info.max().get<int32_t>()), + 0); + break; + default: + goto next; + } + + ctrl = (struct spa_pod*) spa_pod_builder_pop(&b, &f0); + + if (spa_pod_filter(&b, &result.param, ctrl, filter) < 0) + goto next; + + spa_node_emit_result(&impl->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); + + if (++count != num) + goto next; + +enum_end: + res = 0; + return res; +} + +struct val { + uint32_t type; + float f_val; + int32_t i_val; + bool b_val; + uint32_t id; +}; + +static int do_update_ctrls(struct spa_loop *loop, + bool async, + uint32_t seq, + const void *data, + size_t size, + void *user_data) +{ + struct impl *impl = (struct impl *)user_data; + const struct val *d = (const struct val *)data; + switch (d->type) { + case ControlTypeBool: + impl->ctrls.set(d->id, d->b_val); + break; + case ControlTypeFloat: + impl->ctrls.set(d->id, d->f_val); + break; + case ControlTypeInteger32: + //impl->ctrls.set(d->id, (int32_t)d->i_val); + break; + default: + break; + } return 0; } +static int +spa_libcamera_set_control(struct impl *impl, const struct spa_pod_prop *prop) +{ + const ControlInfoMap &info = impl->camera->controls(); + const ControlId *ctrl_id; + int res; + struct val d; + + auto v = info.idmap().find(prop->key); + if (v == info.idmap().end()) + return -ENOENT; + + ctrl_id = v->second; + + d.type = ctrl_id->type(); + d.id = ctrl_id->id(); + + switch (d.type) {
View file
pipewire-0.3.59.tar.gz/spa/plugins/support/cpu-x86.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/cpu-x86.c
Changed
@@ -56,6 +56,7 @@ } else if (family == 0x06) model += extended_model; } + (void)model; flags = 0; if (ecx & bit_SSE3)
View file
pipewire-0.3.59.tar.gz/spa/plugins/support/cpu.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/cpu.c
Changed
@@ -171,19 +171,18 @@ /* https://wiki.freebsd.org/bhyve */ { "BHYVE", SPA_CPU_VM_BHYVE }, }; - uint32_t i, j; - for (i = 0; i < SPA_N_ELEMENTS(dmi_vendors); i++) { + SPA_FOR_EACH_ELEMENT_VAR(dmi_vendors, dv) { char buffer256, *s; - if ((s = read_file(dmi_vendorsi, buffer, sizeof(buffer))) == NULL) + if ((s = read_file(*dv, buffer, sizeof(buffer))) == NULL) continue; - for (j = 0; j < SPA_N_ELEMENTS(dmi_vendor_table); j++) { - if (spa_strstartswith(s, dmi_vendor_tablej.vendor)) { + SPA_FOR_EACH_ELEMENT_VAR(dmi_vendor_table, t) { + if (spa_strstartswith(s, t->vendor)) { spa_log_debug(impl->log, "Virtualization %s found in DMI (%s)", - s, dmi_vendorsi); - impl->vm_type = dmi_vendor_tablej.id; + s, *dv); + impl->vm_type = t->id; goto done; } }
View file
pipewire-0.3.59.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/loop.c
Changed
@@ -186,8 +186,8 @@ if (block) { if ((res = spa_system_eventfd_write(impl->system, impl->ack_fd, 1)) < 0) - spa_log_warn(impl->log, "%p: failed to write event fd: %s", - impl, spa_strerror(res)); + spa_log_warn(impl->log, "%p: failed to write event fd:%d: %s", + impl, impl->ack_fd, spa_strerror(res)); } } impl->flushing = false; @@ -283,8 +283,8 @@ spa_loop_control_hook_before(&impl->hooks_list); if ((res = spa_system_eventfd_read(impl->system, impl->ack_fd, &count)) < 0) - spa_log_warn(impl->log, "%p: failed to read event fd: %s", - impl, spa_strerror(res)); + spa_log_warn(impl->log, "%p: failed to read event fd:%d: %s", + impl, impl->ack_fd, spa_strerror(res)); spa_loop_control_hook_after(&impl->hooks_list); @@ -526,12 +526,12 @@ if (enabled && !s->enabled) { if ((res = spa_system_eventfd_write(s->impl->system, source->fd, 1)) < 0) - spa_log_warn(s->impl->log, "%p: failed to write idle fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to write idle fd:%d: %s", source, source->fd, spa_strerror(res)); } else if (!enabled && s->enabled) { uint64_t count; if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0) - spa_log_warn(s->impl->log, "%p: failed to read idle fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to read idle fd:%d: %s", source, source->fd, spa_strerror(res)); } s->enabled = enabled; @@ -586,7 +586,7 @@ int res; if ((res = spa_system_eventfd_read(s->impl->system, source->fd, &count)) < 0) - spa_log_warn(s->impl->log, "%p: failed to read event fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to read event fd:%d: %s", source, source->fd, spa_strerror(res)); s->func.event(source->data, count); @@ -639,7 +639,7 @@ spa_assert(source->func == source_event_func); if (SPA_UNLIKELY((res = spa_system_eventfd_write(s->impl->system, source->fd, 1)) < 0)) - spa_log_warn(s->impl->log, "%p: failed to write event fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to write event fd:%d: %s", source, source->fd, spa_strerror(res)); return res; } @@ -652,7 +652,7 @@ if (SPA_UNLIKELY((res = spa_system_timerfd_read(s->impl->system, source->fd, &expirations)) < 0)) - spa_log_warn(s->impl->log, "%p: failed to read timer fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to read timer fd:%d: %s", source, source->fd, spa_strerror(res)); s->func.timer(source->data, expirations); @@ -732,7 +732,7 @@ int res, signal_number = 0; if ((res = spa_system_signalfd_read(s->impl->system, source->fd, &signal_number)) < 0) - spa_log_warn(s->impl->log, "%p: failed to read signal fd %d: %s", + spa_log_warn(s->impl->log, "%p: failed to read signal fd:%d: %s", source, source->fd, spa_strerror(res)); s->func.signal(source->data, signal_number); @@ -865,11 +865,9 @@ impl = (struct impl *) handle; - if (impl->enter_count != 0) - spa_log_warn(impl->log, "%p: loop is entered %d times", - impl, impl->enter_count); - - spa_assert(!impl->polling); + if (impl->enter_count != 0 || impl->polling) + spa_log_warn(impl->log, "%p: loop is entered %d times polling:%d", + impl, impl->enter_count, impl->polling); spa_list_consume(source, &impl->source_list, link) loop_destroy_source(impl, &source->source);
View file
pipewire-0.3.59.tar.gz/spa/plugins/support/null-audio-sink.c -> pipewire-0.3.60.tar.gz/spa/plugins/support/null-audio-sink.c
Changed
@@ -610,6 +610,11 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; + if (info.info.raw.rate == 0 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + return -EINVAL; + if (info.info.raw.format == SPA_AUDIO_FORMAT_F32) { port->bpf = 4 * info.info.raw.channels; port->blocks = 1;
View file
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-source.c
Changed
@@ -145,7 +145,8 @@ #define NODE_PropInfo 0 #define NODE_Props 1 #define NODE_EnumFormat 2 -#define N_NODE_PARAMS 3 +#define NODE_Format 3 +#define N_NODE_PARAMS 4 struct spa_param_info paramsN_NODE_PARAMS; struct props props; @@ -167,6 +168,56 @@ #include "v4l2-utils.c" +static int port_get_format(struct port *port, + uint32_t index, + const struct spa_pod *filter, + struct spa_pod **param, + struct spa_pod_builder *builder) +{ + struct spa_pod_frame f; + + if (!port->have_format) + return -EIO; + if (index > 0) + return 0; + + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format.media_type), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format.media_subtype), + 0); + + switch (port->current_format.media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format.info.raw.format), + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.raw.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.raw.framerate), + 0); + break; + case SPA_MEDIA_SUBTYPE_mjpg: + case SPA_MEDIA_SUBTYPE_jpeg: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.mjpg.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.mjpg.framerate), + 0); + break; + case SPA_MEDIA_SUBTYPE_h264: + spa_pod_builder_add(builder, + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.h264.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.h264.framerate), + 0); + break; + default: + return -EIO; + } + + *param = spa_pod_builder_pop(builder, &f); + + return 1; +} + + static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter) @@ -177,6 +228,7 @@ uint8_t buffer1024; struct spa_result_node_params result; uint32_t count = 0; + int res; spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); @@ -216,9 +268,9 @@ SPA_PROP_INFO_type, SPA_POD_Int(p->device_fd)); break; default: - return 0; + return spa_v4l2_enum_controls(this, seq, result.index - 3, num, filter); } - return spa_v4l2_enum_controls(this, seq, start, num, filter); + break; } case SPA_PARAM_Props: { @@ -239,6 +291,11 @@ } case SPA_PARAM_EnumFormat: return spa_v4l2_enum_format(this, seq, start, num, filter); + case SPA_PARAM_Format: + if((res = port_get_format(GET_OUT_PORT(this, 0), + result.index, filter, ¶m, &b)) <= 0) + return res; + break; default: return -ENOENT; } @@ -266,14 +323,29 @@ case SPA_PARAM_Props: { struct props *p = &this->props; + struct spa_pod_object *obj = (struct spa_pod_object *) param; + struct spa_pod_prop *prop; + int res = 0; if (param == NULL) { reset_props(p); return 0; } - spa_pod_parse_object(param, - SPA_TYPE_OBJECT_Props, NULL, - SPA_PROP_device, SPA_POD_OPT_Stringn(p->device, sizeof(p->device))); + SPA_POD_OBJECT_FOREACH(obj, prop) { + switch (prop->key) { + case SPA_PROP_device: + strncpy(p->device, + (char *)SPA_POD_CONTENTS(struct spa_pod_string, &prop->value), + sizeof(p->device)-1); + break; + default: + res = spa_v4l2_set_control(this, prop->key, prop); + break; + } + if (res < 0) + return res; + } + break; } default: @@ -440,58 +512,6 @@ return -ENOTSUP; } -static int port_get_format(void *object, - enum spa_direction direction, uint32_t port_id, - uint32_t index, - const struct spa_pod *filter, - struct spa_pod **param, - struct spa_pod_builder *builder) -{ - struct impl *this = object; - struct port *port = GET_PORT(this, direction, port_id); - struct spa_pod_frame f; - - if (!port->have_format) - return -EIO; - if (index > 0) - return 0; - - spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format); - spa_pod_builder_add(builder, - SPA_FORMAT_mediaType, SPA_POD_Id(port->current_format.media_type), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(port->current_format.media_subtype), - 0); - - switch (port->current_format.media_subtype) { - case SPA_MEDIA_SUBTYPE_raw: - spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_format, SPA_POD_Id(port->current_format.info.raw.format), - SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.raw.size), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.raw.framerate), - 0); - break; - case SPA_MEDIA_SUBTYPE_mjpg: - case SPA_MEDIA_SUBTYPE_jpeg: - spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.mjpg.size), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.mjpg.framerate), - 0); - break; - case SPA_MEDIA_SUBTYPE_h264: - spa_pod_builder_add(builder, - SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&port->current_format.info.h264.size), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&port->current_format.info.h264.framerate), - 0); - break; - default: - return -EIO; - } - - *param = spa_pod_builder_pop(builder, &f); - - return 1; -} - static int impl_node_port_enum_params(void *object, int seq, enum spa_direction direction, uint32_t port_id, @@ -529,8 +549,7 @@ return spa_v4l2_enum_format(this, seq, start, num, filter); case SPA_PARAM_Format: - if((res = port_get_format(this, direction, port_id, - result.index, filter, ¶m, &b)) <= 0) + if((res = port_get_format(port, result.index, filter, ¶m, &b)) <= 0) return res; break;
View file
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-udev.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-udev.c
Changed
@@ -266,7 +266,7 @@ if (str && *str) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_BUS_PATH, str); } - if ((str = udev_device_get_syspath(dev)) && *str) { + if ((str = udev_device_get_devpath(dev)) && *str) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_SYSFS_PATH, str); } if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) {
View file
pipewire-0.3.59.tar.gz/spa/plugins/v4l2/v4l2-utils.c -> pipewire-0.3.60.tar.gz/spa/plugins/v4l2/v4l2-utils.c
Changed
@@ -30,7 +30,7 @@ #include <sys/mman.h> #include <poll.h> -static void v4l2_on_fd_events(struct spa_source *source); +#include <spa/utils/result.h> static int xioctl(int fd, int request, void *arg) { @@ -43,7 +43,6 @@ return err; } - int spa_v4l2_open(struct spa_v4l2_device *dev, const char *path) { struct stat st; @@ -351,11 +350,9 @@ static const struct format_info *fourcc_to_format_info(uint32_t fourcc) { - size_t i; - - for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) { - if (format_infoi.fourcc == fourcc) - return &format_infoi; + SPA_FOR_EACH_ELEMENT_VAR(format_info, i) { + if (i->fourcc == fourcc) + return i; } return NULL; } @@ -363,11 +360,9 @@ #if 0 static const struct format_info *video_format_to_format_info(uint32_t format) { - int i; - - for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) { - if (format_infoi.format == format) - return &format_infoi; + SPA_FOR_EACH_ELEMENT_VAR(format_info, i) { + if (i->format == format) + return i; } return NULL; } @@ -381,10 +376,11 @@ size_t i; for (i = startidx; i < SPA_N_ELEMENTS(format_info); i++) { - if ((format_infoi.media_type == type) && - (format_infoi.media_subtype == subtype) && - (format == 0 || format_infoi.format == format)) - return &format_infoi; + const struct format_info *fi = &format_infoi; + if ((fi->media_type == type) && + (fi->media_subtype == subtype) && + (format == 0 || fi->format == format)) + return fi; } return NULL; } @@ -895,8 +891,9 @@ bool match; spa_zero(fmt); - spa_zero(streamparm); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + spa_zero(streamparm); streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; switch (format->media_subtype) { @@ -929,7 +926,6 @@ return -EINVAL; } - fmt.fmt.pix.pixelformat = info->fourcc; fmt.fmt.pix.field = V4L2_FIELD_ANY; fmt.fmt.pix.width = size->width; @@ -1046,28 +1042,38 @@ return res; } +static struct { + uint32_t v4l2_id; + uint32_t spa_id; +} control_map = { + { V4L2_CID_BRIGHTNESS, SPA_PROP_brightness }, + { V4L2_CID_CONTRAST, SPA_PROP_contrast }, + { V4L2_CID_SATURATION, SPA_PROP_saturation }, + { V4L2_CID_HUE, SPA_PROP_hue }, + { V4L2_CID_GAMMA, SPA_PROP_gamma }, + { V4L2_CID_EXPOSURE, SPA_PROP_exposure }, + { V4L2_CID_GAIN, SPA_PROP_gain }, + { V4L2_CID_SHARPNESS, SPA_PROP_sharpness }, +}; + static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id) { - switch (control_id) { - case V4L2_CID_BRIGHTNESS: - return SPA_PROP_brightness; - case V4L2_CID_CONTRAST: - return SPA_PROP_contrast; - case V4L2_CID_SATURATION: - return SPA_PROP_saturation; - case V4L2_CID_HUE: - return SPA_PROP_hue; - case V4L2_CID_GAMMA: - return SPA_PROP_gamma; - case V4L2_CID_EXPOSURE: - return SPA_PROP_exposure; - case V4L2_CID_GAIN: - return SPA_PROP_gain; - case V4L2_CID_SHARPNESS: - return SPA_PROP_sharpness; - default: - return SPA_PROP_START_CUSTOM + control_id; + SPA_FOR_EACH_ELEMENT_VAR(control_map, c) { + if (c->v4l2_id == control_id) + return c->spa_id; + } + return SPA_PROP_START_CUSTOM + control_id; +} + +static uint32_t prop_id_to_control(struct impl *impl, uint32_t prop_id) +{ + SPA_FOR_EACH_ELEMENT_VAR(control_map, c) { + if (c->spa_id == prop_id) + return c->v4l2_id; } + if (prop_id >= SPA_PROP_START_CUSTOM) + return prop_id - SPA_PROP_START_CUSTOM; + return SPA_ID_INVALID; } static int @@ -1231,6 +1237,56 @@ return res; } +static int +spa_v4l2_set_control(struct impl *this, uint32_t id, + const struct spa_pod_prop *prop) +{ + struct port *port = &this->out_ports0; + struct spa_v4l2_device *dev = &port->dev; + struct v4l2_control control; + int res; + + spa_zero(control); + control.id = prop_id_to_control(this, prop->key); + if (control.id == SPA_ID_INVALID) + return -ENOENT; + + if ((res = spa_v4l2_open(dev, this->props.device)) < 0) + return res; + + switch (SPA_POD_TYPE(&prop->value)) { + case SPA_TYPE_Bool: + { + bool val; + if ((res = spa_pod_get_bool(&prop->value, &val)) < 0) + goto done; + control.value = val; + break; + } + case SPA_TYPE_Int: + { + int32_t val; + if ((res = spa_pod_get_int(&prop->value, &val)) < 0) + goto done; + control.value = val; + break; + } + default: + res = -EINVAL; + goto done; + } + if (xioctl(dev->fd, VIDIOC_S_CTRL, &control) < 0) { + res = -errno; + goto done; + } + + res = 0; + +done: + spa_v4l2_close(dev); + return res; +} + static int mmap_read(struct impl *this) { struct port *port = &this->out_ports0; @@ -1310,7 +1366,13 @@ return;
View file
pipewire-0.3.59.tar.gz/spa/plugins/videoconvert/videoadapter.c -> pipewire-0.3.60.tar.gz/spa/plugins/videoconvert/videoadapter.c
Changed
@@ -562,24 +562,6 @@ return 0; } -static int format_video_raw_parse_opt(const struct spa_pod *format, struct spa_video_info_raw *info) -{ - uint32_t media_type, media_subtype; - int res; - if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0) - return res; - if (media_type != SPA_MEDIA_TYPE_video || - media_subtype != SPA_MEDIA_SUBTYPE_raw) - return -ENOTSUP; - - spa_zero(*info); - res = spa_pod_parse_object(format, - SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format), - SPA_FORMAT_VIDEO_size, SPA_POD_OPT_Int(&info->size)); - return res; -} - static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { @@ -599,8 +581,9 @@ if ((res = spa_format_parse(param, &info.media_type, &info.media_subtype)) < 0) return res; if (info.media_type != SPA_MEDIA_TYPE_video || - info.media_subtype != SPA_MEDIA_SUBTYPE_raw) - return -EINVAL; + info.media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -EINVAL; + if (spa_format_video_raw_parse(param, &info.info.raw) < 0) return -EINVAL; @@ -627,7 +610,15 @@ if (format) { struct spa_video_info info; - if (format_video_raw_parse_opt(format, &info.info.raw) >= 0) + + spa_zero(info); + if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) + return res; + if (info.media_type != SPA_MEDIA_TYPE_video || + info.media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -ENOTSUP; + + if (spa_format_video_raw_parse(format, &info.info.raw) >= 0) this->default_format = info; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.60.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
@@ -643,6 +643,12 @@ else return -EINVAL; + if (info.info.raw.size.width == 0 || + info.info.raw.size.height == 0 || + info.info.raw.framerate.num == 0 || + info.info.raw.framerate.denom == 0) + return -EINVAL; + port->current_format = info; port->have_format = true; }
View file
pipewire-0.3.59.tar.gz/spa/plugins/volume/volume.c -> pipewire-0.3.60.tar.gz/spa/plugins/volume/volume.c
Changed
@@ -321,10 +321,9 @@ 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_Id(3, + SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(2, SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S32), + SPA_AUDIO_FORMAT_S16), SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int( DEFAULT_RATE, 1, INT32_MAX), SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int( @@ -472,6 +471,11 @@ if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) return -EINVAL; + if (info.info.raw.format != SPA_AUDIO_FORMAT_S16 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + return -EINVAL; + this->bpf = 2 * info.info.raw.channels; this->current_format = info; port->have_format = true;
View file
pipewire-0.3.59.tar.gz/spa/tests/benchmark-dict.c -> pipewire-0.3.60.tar.gz/spa/tests/benchmark-dict.c
Changed
@@ -39,7 +39,7 @@ static struct spa_dict_item itemsMAX_ITEMS; static char valuesMAX_ITEMS32; -static void gen_values() +static void gen_values(void) { uint32_t i, j, idx; static const char chars = "abcdefghijklmnopqrstuvwxyz.:*ABCDEFGHIJKLMNOPQRSTUVWXYZ";
View file
pipewire-0.3.59.tar.gz/spa/tests/benchmark-pod.c -> pipewire-0.3.60.tar.gz/spa/tests/benchmark-pod.c
Changed
@@ -37,7 +37,7 @@ #define MAX_COUNT 10000000 -static void test_builder() +static void test_builder(void) { uint8_t buffer1024; struct spa_pod_builder b = { NULL, }; @@ -90,7 +90,7 @@ t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1)); } -static void test_builder2() +static void test_builder2(void) { uint8_t buffer1024; struct spa_pod_builder b = { NULL, }; @@ -131,7 +131,7 @@ t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1)); } -static void test_parse() +static void test_parse(void) { uint8_t buffer1024; struct spa_pod_builder b = { NULL, }; @@ -216,7 +216,7 @@ t2 - t1, count, count * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1)); } -static void test_parser() +static void test_parser(void) { uint8_t buffer1024; struct spa_pod_builder b = { NULL, };
View file
pipewire-0.3.59.tar.gz/src/daemon/jack.conf.in -> pipewire-0.3.60.tar.gz/src/daemon/jack.conf.in
Changed
@@ -83,6 +83,7 @@ #jack.locked-process = true #jack.default-as-system = false #jack.fix-midi-events = true + #jack.global-buffer-size = false } # client specific properties @@ -102,4 +103,16 @@ } } } + { + matches = + { + application.process.binary = "jack_bufsize" + } + + actions = { + update-props = { + jack.global-buffer-size = true + } + } + }
View file
pipewire-0.3.59.tar.gz/src/daemon/pipewire.conf.in -> pipewire-0.3.60.tar.gz/src/daemon/pipewire.conf.in
Changed
@@ -159,14 +159,15 @@ { name = libpipewire-module-session-manager } # Use libcanberra to play X11 Bell - #{ name = libpipewire-module-x11-bell - # args = { - # #sink.name = "@DEFAULT_SINK@" - # #sample.name = "bell-window-system" - # #x11.display = null - # #x11.xauthority = null - # } - #} + { name = libpipewire-module-x11-bell + args = { + #sink.name = "@DEFAULT_SINK@" + #sample.name = "bell-window-system" + #x11.display = null + #x11.xauthority = null + } + flags = ifexists nofail + } context.objects =
View file
pipewire-0.3.59.tar.gz/src/examples/export-sink.c -> pipewire-0.3.60.tar.gz/src/examples/export-sink.c
Changed
@@ -303,11 +303,10 @@ Uint32 sdl_format; void *dest; - d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS; if (format == NULL) { + spa_zero(d->format); SDL_DestroyTexture(d->texture); - d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); - d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); + d->texture = NULL; } else { spa_debug_format(0, NULL, format); @@ -316,6 +315,9 @@ sdl_format = id_to_sdl_format(d->format.format); if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) return -EINVAL; + if (d->format.size.width == 0 || + d->format.size.height == 0) + return -EINVAL; d->texture = SDL_CreateTexture(d->renderer, sdl_format, @@ -325,9 +327,16 @@ SDL_LockTexture(d->texture, NULL, &dest, &d->stride); SDL_UnlockTexture(d->texture); + } + d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS; + if (format) { d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE); d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ); + } else { + d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); + d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); } + spa_node_emit_port_info(&d->hooks, direction, port_id, &d->info); d->info.change_mask = 0;
View file
pipewire-0.3.59.tar.gz/src/examples/export-source.c -> pipewire-0.3.60.tar.gz/src/examples/export-source.c
Changed
@@ -275,26 +275,31 @@ { struct data *d = object; - d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS; if (format == NULL) { - d->format.format = 0; - d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); - d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); - spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_OUTPUT, 0, &d->info); - return 0; - } + spa_zero(d->format); + } else { + spa_debug_format(0, NULL, format); - spa_debug_format(0, NULL, format); - - if (spa_format_audio_raw_parse(format, &d->format) < 0) - return -EINVAL; + if (spa_format_audio_raw_parse(format, &d->format) < 0) + return -EINVAL; - if (d->format.format != SPA_AUDIO_FORMAT_S16 && - d->format.format != SPA_AUDIO_FORMAT_F32) - return -EINVAL; + if (d->format.format != SPA_AUDIO_FORMAT_S16 && + d->format.format != SPA_AUDIO_FORMAT_F32) + return -EINVAL; + if (d->format.rate == 0 || + d->format.channels == 0 || + d->format.channels > SPA_AUDIO_MAX_CHANNELS) + return -EINVAL; + } - d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE); - d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ); + d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS; + if (format) { + d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE); + d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ); + } else { + d->params3 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); + d->params4 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); + } spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_OUTPUT, 0, &d->info); return 0;
View file
pipewire-0.3.59.tar.gz/src/examples/local-v4l2.c -> pipewire-0.3.60.tar.gz/src/examples/local-v4l2.c
Changed
@@ -207,28 +207,39 @@ Uint32 sdl_format; void *dest; - if (format == NULL) - return 0; - - spa_debug_format(0, NULL, format); - - spa_format_video_raw_parse(format, &d->format); - - sdl_format = id_to_sdl_format(d->format.format); - if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) - return -EINVAL; - - d->texture = SDL_CreateTexture(d->renderer, - sdl_format, - SDL_TEXTUREACCESS_STREAMING, - d->format.size.width, - d->format.size.height); - SDL_LockTexture(d->texture, NULL, &dest, &d->stride); - SDL_UnlockTexture(d->texture); + if (format == NULL) { + spa_zero(d->format); + SDL_DestroyTexture(d->texture); + d->texture = NULL; + } else { + spa_debug_format(0, NULL, format); + + spa_format_video_raw_parse(format, &d->format); + + sdl_format = id_to_sdl_format(d->format.format); + if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) + return -EINVAL; + if (d->format.size.width == 0 || + d->format.size.height == 0) + return -EINVAL; + + d->texture = SDL_CreateTexture(d->renderer, + sdl_format, + SDL_TEXTUREACCESS_STREAMING, + d->format.size.width, + d->format.size.height); + SDL_LockTexture(d->texture, NULL, &dest, &d->stride); + SDL_UnlockTexture(d->texture); + } d->info.change_mask = SPA_PORT_CHANGE_MASK_PARAMS; - d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE); - d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ); + if (format) { + d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE); + d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ); + } else { + d->params1 = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE); + d->params2 = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); + } spa_node_emit_port_info(&d->hooks, SPA_DIRECTION_INPUT, 0, &d->info); return 0;
View file
pipewire-0.3.59.tar.gz/src/examples/sdl.h -> pipewire-0.3.60.tar.gz/src/examples/sdl.h
Changed
@@ -130,25 +130,22 @@ static inline uint32_t sdl_format_to_id(Uint32 format) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) { - if (sdl_video_formatsi.format == format) - return sdl_video_formatsi.id; + SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) { + if (f->format == format) + return f->id; } return SPA_VIDEO_FORMAT_UNKNOWN; } static inline Uint32 id_to_sdl_format(uint32_t id) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) { - if (sdl_video_formatsi.id == id) - return sdl_video_formatsi.format; + SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) { + if (f->id == id) + return f->format; } return SDL_PIXELFORMAT_UNKNOWN; } - static inline struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_builder *b) { uint32_t i, c; @@ -178,8 +175,8 @@ spa_pod_builder_id(b, id); } /* then all the other ones SDL can convert from/to */ - for (i = 0; i < SPA_N_ELEMENTS(sdl_video_formats); i++) { - uint32_t id = sdl_video_formatsi.id; + SPA_FOR_EACH_ELEMENT_VAR(sdl_video_formats, f) { + uint32_t id = f->id; if (id != SPA_VIDEO_FORMAT_UNKNOWN) spa_pod_builder_id(b, id); }
View file
pipewire-0.3.59.tar.gz/src/examples/video-play-fixate.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-fixate.c
Changed
@@ -340,6 +340,10 @@ pw_stream_set_error(stream, -EINVAL, "unknown pixel format"); return; } + if (data->size.width == 0 || data->size.height == 0) { + pw_stream_set_error(stream, -EINVAL, "invalid size"); + return; + } data->texture = SDL_CreateTexture(data->renderer, sdl_format,
View file
pipewire-0.3.59.tar.gz/src/examples/video-play-pull.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-pull.c
Changed
@@ -388,6 +388,10 @@ pw_stream_set_error(stream, -EINVAL, "unknown pixel format"); return; } + if (data->size.width == 0 || data->size.height == 0) { + pw_stream_set_error(stream, -EINVAL, "invalid size"); + return; + } data->texture = SDL_CreateTexture(data->renderer, sdl_format,
View file
pipewire-0.3.59.tar.gz/src/examples/video-play-reneg.c -> pipewire-0.3.60.tar.gz/src/examples/video-play-reneg.c
Changed
@@ -233,6 +233,10 @@ pw_stream_set_error(stream, -EINVAL, "unknown pixel format"); return; } + if (data->size.width == 0 || data->size.height == 0) { + pw_stream_set_error(stream, -EINVAL, "invalid size"); + return; + } data->texture = SDL_CreateTexture(data->renderer, sdl_format,
View file
pipewire-0.3.59.tar.gz/src/examples/video-play.c -> pipewire-0.3.60.tar.gz/src/examples/video-play.c
Changed
@@ -336,6 +336,10 @@ pw_stream_set_error(stream, -EINVAL, "unknown pixel format"); return; } + if (data->size.width == 0 || data->size.height == 0) { + pw_stream_set_error(stream, -EINVAL, "invalid size"); + return; + } data->texture = SDL_CreateTexture(data->renderer, sdl_format,
View file
pipewire-0.3.59.tar.gz/src/gst/gstpipewiredeviceprovider.c -> pipewire-0.3.60.tar.gz/src/gst/gstpipewiredeviceprovider.c
Changed
@@ -491,6 +491,8 @@ gst_device_provider_hide_provider (provider, "pulsedeviceprovider"); else if (g_str_has_prefix(str, "v4l2:")) gst_device_provider_hide_provider (provider, "v4l2deviceprovider"); + else if (g_str_has_prefix(str, "libcamera:")) + gst_device_provider_hide_provider (provider, "libcameraprovider"); } }
View file
pipewire-0.3.59.tar.gz/src/modules/meson.build -> pipewire-0.3.60.tar.gz/src/modules/meson.build
Changed
@@ -26,6 +26,8 @@ 'module-rt.c', 'module-raop-discover.c', 'module-raop-sink.c', + 'module-rtp-source.c', + 'module-rtp-sink.c', 'module-session-manager.c', 'module-zeroconf-discover.c', 'module-roc-source.c', @@ -258,6 +260,8 @@ 'module-protocol-pulse/modules/module-roc-sink.c', 'module-protocol-pulse/modules/module-roc-sink-input.c', 'module-protocol-pulse/modules/module-roc-source.c', + 'module-protocol-pulse/modules/module-rtp-recv.c', + 'module-protocol-pulse/modules/module-rtp-send.c', 'module-protocol-pulse/modules/module-simple-protocol-tcp.c', 'module-protocol-pulse/modules/module-switch-on-connect.c', 'module-protocol-pulse/modules/module-tunnel-sink.c', @@ -482,6 +486,24 @@ roc_lib = cc.find_library('roc', has_headers: 'roc/config.h' , required: get_option('roc')) summary({'ROC': roc_lib.found()}, bool_yn: true, section: 'Streaming between daemons') +pipewire_module_rtp_source = shared_library('pipewire-module-rtp-source', + 'module-rtp-source.c' , + include_directories : configinc, + install : true, + install_dir : modules_install_dir, + install_rpath: modules_install_dir, + dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, +) + +pipewire_module_rtp_sink = shared_library('pipewire-module-rtp-sink', + 'module-rtp-sink.c' , + include_directories : configinc, + install : true, + install_dir : modules_install_dir, + install_rpath: modules_install_dir, + dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, +) + build_module_roc = roc_lib.found() if build_module_roc pipewire_module_roc_sink = shared_library('pipewire-module-roc-sink',
View file
pipewire-0.3.59.tar.gz/src/modules/module-avb/acmp.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/acmp.c
Changed
@@ -345,11 +345,10 @@ static inline const struct msg_info *find_msg_info(uint16_t type, const char *name) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(msg_info); i++) { - if ((name == NULL && type == msg_infoi.type) || - (name != NULL && spa_streq(name, msg_infoi.name))) - return &msg_infoi; + SPA_FOR_EACH_ELEMENT_VAR(msg_info, i) { + if ((name == NULL && type == i->type) || + (name != NULL && spa_streq(name, i->name))) + return i; } return NULL; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-avb/aecp-aem.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/aecp-aem.c
Changed
@@ -250,11 +250,10 @@ static inline const struct cmd_info *find_cmd_info(uint16_t type, const char *name) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(cmd_info); i++) { - if ((name == NULL && type == cmd_infoi.type) || - (name != NULL && spa_streq(name, cmd_infoi.name))) - return &cmd_infoi; + SPA_FOR_EACH_ELEMENT_VAR(cmd_info, i) { + if ((name == NULL && type == i->type) || + (name != NULL && spa_streq(name, i->name))) + return i; } return NULL; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-avb/aecp.c -> pipewire-0.3.60.tar.gz/src/modules/module-avb/aecp.c
Changed
@@ -67,11 +67,10 @@ static inline const struct msg_info *find_msg_info(uint16_t type, const char *name) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(msg_info); i++) { - if ((name == NULL && type == msg_infoi.type) || - (name != NULL && spa_streq(name, msg_infoi.name))) - return &msg_infoi; + SPA_FOR_EACH_ELEMENT_VAR(msg_info, i) { + if ((name == NULL && type == i->type) || + (name != NULL && spa_streq(name, i->name))) + return i; } return NULL; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-client-node/v0/client-node.c -> pipewire-0.3.60.tar.gz/src/modules/module-client-node/v0/client-node.c
Changed
@@ -1333,13 +1333,12 @@ { "pipewire.target.node", PW_KEY_NODE_TARGET, } }; - uint32_t i; const char *str; - for(i = 0; i < SPA_N_ELEMENTS(props); i++) { - if ((str = pw_properties_get(properties, propsi.from)) != NULL) { - pw_properties_set(properties, propsi.to, str); - pw_properties_set(properties, propsi.from, NULL); + SPA_FOR_EACH_ELEMENT_VAR(props, p) { + if ((str = pw_properties_get(properties, p->from)) != NULL) { + pw_properties_set(properties, p->to, str); + pw_properties_set(properties, p->from, NULL); } } }
View file
pipewire-0.3.59.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.60.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -43,6 +43,7 @@ #include <spa/param/audio/raw.h> #include <spa/param/profiler.h> #include <spa/pod/builder.h> +#include <spa/pod/dynamic.h> #include <spa/support/plugin.h> #include <spa/utils/json.h> #include <spa/utils/names.h> @@ -196,15 +197,18 @@ uint32_t max_buffer_size; uint32_t buffer_delay; + uint32_t current_delay; struct spa_handle *spa_handle; struct spa_plugin_loader *loader; + + bool monitor_mode; }; static void process(struct impl *impl) { struct pw_buffer *cout; - struct pw_buffer *pout; + struct pw_buffer *pout = NULL; float rec_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float); float play_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float); float play_delayed_bufimpl->info.channelsimpl->aec_blocksize / sizeof(float); @@ -218,7 +222,7 @@ uint32_t rindex, pindex, oindex, pdindex, avail; int32_t stride = 0; - if ((pout = pw_stream_dequeue_buffer(impl->playback)) == NULL) { + if (impl->playback != NULL && (pout = pw_stream_dequeue_buffer(impl->playback)) == NULL) { pw_log_debug("out of playback buffers: %m"); goto done; } @@ -256,23 +260,50 @@ impl->play_ringsize, pdindex % impl->play_ringsize, (void *)play_delayedi, size); - /* output to sink, just copy */ - dd = &pout->buffer->datasi; - memcpy(dd->data, playi, size); + if (pout != NULL) { + /* output to sink, just copy */ + dd = &pout->buffer->datasi; + memcpy(dd->data, playi, size); - dd->chunk->offset = 0; - dd->chunk->size = size; - dd->chunk->stride = stride; + dd->chunk->offset = 0; + dd->chunk->size = size; + dd->chunk->stride = stride; + } } spa_ringbuffer_read_update(&impl->rec_ring, rindex + size); spa_ringbuffer_read_update(&impl->play_ring, pindex + size); spa_ringbuffer_read_update(&impl->play_delayed_ring, pdindex + size); - pw_stream_queue_buffer(impl->playback, pout); + if (impl->playback != NULL) + pw_stream_queue_buffer(impl->playback, pout); - /* Now run the canceller */ - spa_audio_aec_run(impl->aec, rec, play_delayed, out, size / sizeof(float)); + if (SPA_UNLIKELY (impl->current_delay < impl->buffer_delay)) { + uint32_t delay_left = impl->buffer_delay - impl->current_delay; + uint32_t silence_size; + + /* don't run the canceller until play_buffer has been filled, + * copy silence to output in the meantime */ + silence_size = SPA_MIN(size, delay_left * sizeof(float)); + for (i = 0; i < impl->info.channels; i++) + memset(outi, 0, silence_size); + impl->current_delay += silence_size / sizeof(float); + pw_log_debug("current_delay %d", impl->current_delay); + + if (silence_size != size) { + const float *pdimpl->info.channels; + float *oimpl->info.channels; + + for (i = 0; i < impl->info.channels; i++) { + pdi = play_delayedi + delay_left; + oi = outi + delay_left; + } + spa_audio_aec_run(impl->aec, rec, pd, o, size / sizeof(float) - delay_left); + } + } else { + /* run the canceller */ + spa_audio_aec_run(impl->aec, rec, play_delayed, out, size / sizeof(float)); + } /* Next, copy over the output to the output ringbuffer */ avail = spa_ringbuffer_get_write_index(&impl->out_ring, &oindex); @@ -479,14 +510,55 @@ else pw_stream_update_params(impl->capture, params, 1); } +static struct spa_pod* get_props_param(struct impl* impl, struct spa_pod_builder* b) +{ + if (spa_audio_aec_get_params(impl->aec, NULL) > 0) { + struct spa_pod_frame f2; + spa_pod_builder_push_object( + b, &f0, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); + spa_pod_builder_prop(b, SPA_PROP_params, 0); + spa_pod_builder_push_struct(b, &f1); + + spa_audio_aec_get_params(impl->aec, b); + + spa_pod_builder_pop(b, &f1); + return spa_pod_builder_pop(b, &f0); + } + return NULL; +} -static void input_param_changed(void *data, uint32_t id, const struct spa_pod *param) +static void input_param_changed(void *data, uint32_t id, const struct spa_pod* param) { - struct impl *impl = data; + struct spa_pod_object* obj = (struct spa_pod_object*)param; + const struct spa_pod_prop* prop; + struct impl* impl = data; switch (id) { case SPA_PARAM_Latency: input_param_latency_changed(impl, param); break; + case SPA_PARAM_Props: + if (param != NULL) { + uint8_t buffer1024; + struct spa_pod_dynamic_builder b; + const struct spa_pod* params1; + SPA_POD_OBJECT_FOREACH(obj, prop) + { + if (prop->key == SPA_PROP_params) { + spa_audio_aec_set_params(impl->aec, &prop->value); + } + } + + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + params0 = get_props_param(impl, &b.b); + if (params0) { + pw_stream_update_params(impl->capture, params, 1); + pw_stream_update_params(impl->playback, params, 1); + } + spa_pod_dynamic_builder_clean(&b); + } else { + pw_log_warn("param is null"); + } + break; } } @@ -519,7 +591,11 @@ switch (state) { case PW_STREAM_STATE_PAUSED: pw_stream_flush(impl->sink, false); - pw_stream_flush(impl->playback, false); + if (impl->playback != NULL) + pw_stream_flush(impl->playback, false); + if (old == PW_STREAM_STATE_STREAMING) { + impl->current_delay = 0; + } break; case PW_STREAM_STATE_UNCONNECTED: pw_log_info("%p: output unconnected", impl); @@ -548,17 +624,40 @@ if (latency.direction == SPA_DIRECTION_INPUT) pw_stream_update_params(impl->sink, params, 1); - else + else if (impl->playback != NULL) pw_stream_update_params(impl->playback, params, 1); } static void output_param_changed(void *data, uint32_t id, const struct spa_pod *param) { + struct spa_pod_object *obj = (struct spa_pod_object *) param; + const struct spa_pod_prop *prop; struct impl *impl = data; switch (id) { case SPA_PARAM_Latency: output_param_latency_changed(impl, param); break; + case SPA_PARAM_Props: + if (param != NULL) { + uint8_t buffer1024; + struct spa_pod_dynamic_builder b; + const struct spa_pod* params1; + + SPA_POD_OBJECT_FOREACH(obj, prop) + { + if (prop->key == SPA_PROP_params) { + spa_audio_aec_set_params(impl->aec, &prop->value); + } + } + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); + params0 = get_props_param(impl, &b.b);
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain.c
Changed
@@ -785,10 +785,10 @@ spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0); if (p->hint & FC_HINT_BOOLEAN) { if (min == max) { - spa_pod_builder_bool(b, def <= 0.0 ? false : true); + spa_pod_builder_bool(b, def <= 0.0f ? false : true); } else { spa_pod_builder_push_choice(b, &f1, SPA_CHOICE_Enum, 0); - spa_pod_builder_bool(b, def <= 0.0 ? false : true); + spa_pod_builder_bool(b, def <= 0.0f ? false : true); spa_pod_builder_bool(b, false); spa_pod_builder_bool(b, true); spa_pod_builder_pop(b, &f1); @@ -844,7 +844,7 @@ spa_pod_builder_string(b, name); if (p->hint & FC_HINT_BOOLEAN) { - spa_pod_builder_bool(b, port->control_data <= 0.0 ? false : true); + spa_pod_builder_bool(b, port->control_data <= 0.0f ? false : true); } else if (p->hint & FC_HINT_INTEGER) { spa_pod_builder_int(b, port->control_data); } else { @@ -1002,6 +1002,7 @@ { struct impl *impl = data; struct graph *graph = &impl->graph; + int res; switch (id) { case SPA_PARAM_Format: @@ -1010,9 +1011,15 @@ } else { struct spa_audio_info_raw info; spa_zero(info); - spa_format_audio_raw_parse(param, &info); + if ((res = spa_format_audio_raw_parse(param, &info)) < 0) + goto error; + if (info.rate == 0) { + res = -EINVAL; + goto error; + } impl->rate = info.rate; - graph_instantiate(graph); + if ((res = graph_instantiate(graph)) < 0) + goto error; } break; case SPA_PARAM_Props: @@ -1023,6 +1030,11 @@ param_latency_changed(impl, param); break; } + return; + +error: + pw_stream_set_error(impl->capture, res, "can't start graph: %s", + spa_strerror(res)); } static const struct pw_stream_events in_stream_events = { @@ -1172,16 +1184,19 @@ else if (spa_streq(type, "ladspa")) { pl = load_ladspa_plugin(support, n_support, path, NULL); } -#ifdef HAVE_LILV else if (spa_streq(type, "lv2")) { +#ifdef HAVE_LILV pl = load_lv2_plugin(support, n_support, path, NULL); - } +#else + pw_log_error("filter-chain is compiled without lv2 support"); + pl = NULL; + errno = ENOTSUP; #endif - else { + } else { + pw_log_error("invalid plugin type '%s'", type); pl = NULL; errno = EINVAL; } - if (pl == NULL) goto exit; @@ -1501,7 +1516,6 @@ bool have_config = false; uint32_t i; int res; - float *data; while (spa_json_get_string(json, key, sizeof(key)) > 0) { if (spa_streq("type", key)) { @@ -1539,10 +1553,8 @@ break; } - if (spa_streq(type, "builtin")) { + if (spa_streq(type, "builtin")) snprintf(plugin, sizeof(plugin), "%s", "builtin"); - } else if (!spa_streq(type, "ladspa") && !spa_streq(type, "lv2")) - return -ENOTSUP; pw_log_info("loading type:%s plugin:%s label:%s", type, plugin, label); @@ -1562,6 +1574,10 @@ node->control_port = calloc(desc->n_control, sizeof(struct port)); node->notify_port = calloc(desc->n_notify, sizeof(struct port)); + pw_log_info("loaded n_input:%d n_output:%d n_control:%d n_notify:%d", + desc->n_input, desc->n_output, + desc->n_control, desc->n_notify); + for (i = 0; i < desc->n_input; i++) { struct port *port = &node->input_porti; port->node = node; @@ -1576,14 +1592,6 @@ port->idx = i; port->external = SPA_ID_INVALID; port->p = desc->outputi; - if ((data = port->audio_datai) == NULL) { - data = calloc(1, MAX_SAMPLES * sizeof(float)); - if (data == NULL) { - pw_log_error("cannot create port data: %m"); - return -errno; - } - } - port->audio_datai = data; spa_list_init(&port->link_list); } for (i = 0; i < desc->n_control; i++) { @@ -1629,6 +1637,26 @@ } } +static int port_ensure_data(struct port *port, uint32_t i) +{ + float *data; + if ((data = port->audio_datai) == NULL) { + data = calloc(1, MAX_SAMPLES * sizeof(float)); + if (data == NULL) { + pw_log_error("cannot create port data: %m"); + return -errno; + } + } + port->audio_datai = data; + return 0; +} + +static void port_free_data(struct port *port, uint32_t i) +{ + free(port->audio_datai); + port->audio_datai = NULL; +} + static void node_free(struct node *node) { uint32_t i, j; @@ -1636,7 +1664,7 @@ spa_list_remove(&node->link); for (i = 0; i < node->n_hndl; i++) { for (j = 0; j < node->desc->n_output; j++) - free(node->output_portj.audio_datai); + port_free_data(&node->output_portj, i); } node_cleanup(node); descriptor_unref(node->desc); @@ -1688,6 +1716,8 @@ spa_list_for_each(link, &port->link_list, input_link) { struct port *peer = link->output; + if ((res = port_ensure_data(peer, i)) < 0) + goto error; pw_log_info("connect input port %s%d:%s %p", node->name, i, d->portsport->p.name, peer->audio_datai); @@ -1696,6 +1726,8 @@ } for (j = 0; j < desc->n_output; j++) { port = &node->output_portj; + if ((res = port_ensure_data(port, i)) < 0) + goto error; pw_log_info("connect output port %s%d:%s %p", node->name, i, d->portsport->p.name, port->audio_datai); @@ -1938,6 +1970,8 @@ gh->hndl = &node->hndli; gh->desc = d; + } + for (i = 0; i < desc->n_output; i++) { spa_list_for_each(link, &node->output_porti.link_list, output_link) link->input->node->n_deps--; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/biquad.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/biquad.c
Changed
@@ -11,24 +11,6 @@ #include <math.h> #include "biquad.h" -#ifndef max -#define max(a, b) \ - ({ \ - __typeof__(a) _a = (a); \ - __typeof__(b) _b = (b); \ - _a > _b ? _a : _b; \ - }) -#endif - -#ifndef min -#define min(a, b) \ - ({ \ - __typeof__(a) _a = (a); \ - __typeof__(b) _b = (b); \ - _a < _b ? _a : _b; \ - }) -#endif - #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -47,7 +29,7 @@ static void biquad_lowpass(struct biquad *bq, double cutoff, double resonance) { /* Limit cutoff to 0 to 1. */ - cutoff = max(0.0, min(cutoff, 1.0)); + cutoff = fmax(0.0, fmin(cutoff, 1.0)); if (cutoff == 1 || cutoff == 0) { /* When cutoff is 1, the z-transform is 1. @@ -59,7 +41,7 @@ } /* Compute biquad coefficients for lowpass filter */ - resonance = max(0.0, resonance); /* can't go negative */ + resonance = fmax(0.0, resonance); /* can't go negative */ double g = pow(10.0, 0.05 * resonance); double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2); @@ -81,7 +63,7 @@ static void biquad_highpass(struct biquad *bq, double cutoff, double resonance) { /* Limit cutoff to 0 to 1. */ - cutoff = max(0.0, min(cutoff, 1.0)); + cutoff = fmax(0.0, fmin(cutoff, 1.0)); if (cutoff == 1 || cutoff == 0) { /* When cutoff is one, the z-transform is 0. */ @@ -95,7 +77,7 @@ } /* Compute biquad coefficients for highpass filter */ - resonance = max(0.0, resonance); /* can't go negative */ + resonance = fmax(0.0, resonance); /* can't go negative */ double g = pow(10.0, 0.05 * resonance); double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2); @@ -117,10 +99,10 @@ static void biquad_bandpass(struct biquad *bq, double frequency, double Q) { /* No negative frequencies allowed. */ - frequency = max(0.0, frequency); + frequency = fmax(0.0, frequency); /* Don't let Q go negative, which causes an unstable filter. */ - Q = max(0.0, Q); + Q = fmax(0.0, Q); if (frequency <= 0 || frequency >= 1) { /* When the cutoff is zero, the z-transform approaches 0, if Q @@ -158,7 +140,7 @@ static void biquad_lowshelf(struct biquad *bq, double frequency, double db_gain) { /* Clip frequencies to between 0 and 1, inclusive. */ - frequency = max(0.0, min(frequency, 1.0)); + frequency = fmax(0.0, fmin(frequency, 1.0)); double A = pow(10.0, db_gain / 40); @@ -195,7 +177,7 @@ double db_gain) { /* Clip frequencies to between 0 and 1, inclusive. */ - frequency = max(0.0, min(frequency, 1.0)); + frequency = fmax(0.0, fmin(frequency, 1.0)); double A = pow(10.0, db_gain / 40); @@ -232,10 +214,10 @@ double db_gain) { /* Clip frequencies to between 0 and 1, inclusive. */ - frequency = max(0.0, min(frequency, 1.0)); + frequency = fmax(0.0, fmin(frequency, 1.0)); /* Don't let Q go negative, which causes an unstable filter. */ - Q = max(0.0, Q); + Q = fmax(0.0, Q); double A = pow(10.0, db_gain / 40); @@ -270,10 +252,10 @@ static void biquad_notch(struct biquad *bq, double frequency, double Q) { /* Clip frequencies to between 0 and 1, inclusive. */ - frequency = max(0.0, min(frequency, 1.0)); + frequency = fmax(0.0, fmin(frequency, 1.0)); /* Don't let Q go negative, which causes an unstable filter. */ - Q = max(0.0, Q); + Q = fmax(0.0, Q); if (frequency <= 0 || frequency >= 1) { /* When frequency is 0 or 1, the z-transform is 1. */ @@ -306,10 +288,10 @@ static void biquad_allpass(struct biquad *bq, double frequency, double Q) { /* Clip frequencies to between 0 and 1, inclusive. */ - frequency = max(0.0, min(frequency, 1.0)); + frequency = fmax(0.0, fmin(frequency, 1.0)); /* Don't let Q go negative, which causes an unstable filter. */ - Q = max(0.0, Q); + Q = fmax(0.0, Q); if (frequency <= 0 || frequency >= 1) { /* When frequency is 0 or 1, the z-transform is 1. */
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/builtin_plugin.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/builtin_plugin.c
Changed
@@ -590,6 +590,7 @@ float gain = 1.0f; unsigned long rate; + errno = EINVAL; if (config == NULL) return NULL; @@ -599,42 +600,60 @@ while (spa_json_get_string(&it1, key, sizeof(key)) > 0) { if (spa_streq(key, "blocksize")) { - if (spa_json_get_int(&it1, &blocksize) <= 0) + if (spa_json_get_int(&it1, &blocksize) <= 0) { + pw_log_error("convolver:blocksize requires a number"); return NULL; + } } else if (spa_streq(key, "tailsize")) { - if (spa_json_get_int(&it1, &tailsize) <= 0) + if (spa_json_get_int(&it1, &tailsize) <= 0) { + pw_log_error("convolver:tailsize requires a number"); return NULL; + } } else if (spa_streq(key, "gain")) { - if (spa_json_get_float(&it1, &gain) <= 0) + if (spa_json_get_float(&it1, &gain) <= 0) { + pw_log_error("convolver:gain requires a number"); return NULL; + } } else if (spa_streq(key, "delay")) { - if (spa_json_get_int(&it1, &delay) <= 0) + if (spa_json_get_int(&it1, &delay) <= 0) { + pw_log_error("convolver:delay requires a number"); return NULL; + } } else if (spa_streq(key, "filename")) { - if (spa_json_get_string(&it1, filename, sizeof(filename)) <= 0) + if (spa_json_get_string(&it1, filename, sizeof(filename)) <= 0) { + pw_log_error("convolver:filename requires a string"); return NULL; + } } else if (spa_streq(key, "offset")) { - if (spa_json_get_int(&it1, &offset) <= 0) + if (spa_json_get_int(&it1, &offset) <= 0) { + pw_log_error("convolver:offset requires a number"); return NULL; + } } else if (spa_streq(key, "length")) { - if (spa_json_get_int(&it1, &length) <= 0) + if (spa_json_get_int(&it1, &length) <= 0) { + pw_log_error("convolver:length requires a number"); return NULL; + } } else if (spa_streq(key, "channel")) { - if (spa_json_get_int(&it1, &channel) <= 0) + if (spa_json_get_int(&it1, &channel) <= 0) { + pw_log_error("convolver:channel requires a number"); return NULL; + } } else if (spa_json_next(&it1, &val) < 0) break; } - if (!filename0) + if (!filename0) { + pw_log_error("convolver:filename was not given"); return NULL; + } if (delay < 0) delay = 0; @@ -656,15 +675,18 @@ "Consider forcing a filter rate.", rate, SampleRate); } } - if (samples == NULL) + if (samples == NULL) { + errno = ENOENT; return NULL; + } if (blocksize <= 0) blocksize = SPA_CLAMP(n_samples, 64, 256); if (tailsize <= 0) - tailsize = SPA_CLAMP(4096, blocksize, 4096); + tailsize = SPA_CLAMP(4096, blocksize, 32768); - pw_log_info("using %d:%d blocksize ir:%s", blocksize, tailsize, filename); + pw_log_info("using n_samples:%u %d:%d blocksize ir:%s", n_samples, + blocksize, tailsize, filename); impl = calloc(1, sizeof(*impl)); if (impl == NULL) @@ -775,8 +797,10 @@ while (spa_json_get_string(&it1, key, sizeof(key)) > 0) { if (spa_streq(key, "max-delay")) { - if (spa_json_get_float(&it1, &max_delay) <= 0) + if (spa_json_get_float(&it1, &max_delay) <= 0) { + pw_log_error("delay:max-delay requires a number"); return NULL; + } } else if (spa_json_next(&it1, &val) < 0) break; @@ -790,7 +814,7 @@ impl->rate = SampleRate; impl->buffer_samples = max_delay * impl->rate; - pw_log_info("%lu %d", impl->rate, impl->buffer_samples); + pw_log_info("max-delay:%f seconds rate:%lu samples:%d", max_delay, impl->rate, impl->buffer_samples); impl->buffer = calloc(impl->buffer_samples, sizeof(float)); if (impl->buffer == NULL) {
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
@@ -251,7 +251,7 @@ { int i, processed = 0; - if (conv->segCount == 0) { + if (conv == NULL || conv->segCount == 0) { fft_clear(output, len); return len; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/ladspa_plugin.c
Changed
@@ -22,6 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ +#include "config.h" + #include <dlfcn.h> #include <math.h> @@ -80,39 +82,39 @@ break; case LADSPA_HINT_DEFAULT_LOW: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - def = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25); + def = (LADSPA_Data) expf(logf(lower) * 0.75f + logf(upper) * 0.25f); else - def = (LADSPA_Data) (lower * 0.75 + upper * 0.25); + def = (LADSPA_Data) (lower * 0.75f + upper * 0.25f); break; case LADSPA_HINT_DEFAULT_MIDDLE: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - def = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5); + def = (LADSPA_Data) expf(logf(lower) * 0.5f + logf(upper) * 0.5f); else - def = (LADSPA_Data) (lower * 0.5 + upper * 0.5); + def = (LADSPA_Data) (lower * 0.5f + upper * 0.5f); break; case LADSPA_HINT_DEFAULT_HIGH: if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - def = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75); + def = (LADSPA_Data) expf(logf(lower) * 0.25f + logf(upper) * 0.75f); else - def = (LADSPA_Data) (lower * 0.25 + upper * 0.75); + def = (LADSPA_Data) (lower * 0.25f + upper * 0.75f); break; case LADSPA_HINT_DEFAULT_0: - def = 0; + def = 0.0f; break; case LADSPA_HINT_DEFAULT_1: - def = 1; + def = 1.0f; break; case LADSPA_HINT_DEFAULT_100: - def = 100; + def = 100.0f; break; case LADSPA_HINT_DEFAULT_440: - def = 440; + def = 440.0f; break; default: if (upper == lower) def = upper; else - def = SPA_CLAMP(0.5 * upper, lower, upper); + def = SPA_CLAMPF(0.5f * upper, lower, upper); break; } if (LADSPA_IS_HINT_INTEGER(hint)) @@ -238,7 +240,7 @@ search_dirs = getenv("LADSPA_PATH"); if (!search_dirs) - search_dirs = "/usr/lib64/ladspa"; + search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; /* * set the errno for the case when `ladspa_handle_load_by_path()`
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/pffft.c -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/pffft.c
Changed
@@ -25,7 +25,7 @@ Laboratory, the University Corporation for Atmospheric Research, nor the names of its sponsors or contributors may be used to endorse or promote products derived from this Software without - specific prior written permission. + specific prior written permission. - Redistributions of source code must retain the above copyright notices, this list of conditions, and the disclaimer below. @@ -52,7 +52,7 @@ */ /* - ChangeLog: + ChangeLog: - 2011/10/02, version 1: This is the very first release of this file. */ @@ -243,7 +243,7 @@ #define assertv4(v,f0,f1,f2,f3) assert(v.f0 == (f0) && v.f1 == (f1) && v.f2 == (f2) && v.f3 == (f3)) /* detect bugs with the vector support macros */ -static void validate_pffft_simd() +static void validate_pffft_simd(void) { float f16 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; v4sf_union a0, a1, a2, a3, t, u; @@ -301,7 +301,7 @@ assertv4(a3, 3, 7, 11, 15); } #else -static void validate_pffft_simd() +static void validate_pffft_simd(void) { } // allow test_pffft.c to call this function even when simd is not available.. #endif //!PFFFT_SIMD_DISABLE @@ -1421,7 +1421,7 @@ { PFFFT_Setup *s = (PFFFT_Setup *) malloc(sizeof(PFFFT_Setup)); int k, m; - /* unfortunately, the fft size must be a multiple of 16 for complex FFTs + /* unfortunately, the fft size must be a multiple of 16 for complex FFTs and 32 for real FFTs -- a lot of stuff would need to be rewritten to handle other cases (or maybe just switch to a scalar fft, I don't know..) */ if (transform == PFFFT_REAL) { @@ -1615,7 +1615,7 @@ 0 0 0 0 1 1 1 1 * i0 0 1 0 -1 1 0 -1 0 i1 0 0 0 0 1 -1 1 -1 i2 - 0 -1 0 1 1 0 -1 0 i3 + 0 -1 0 1 1 0 -1 0 i3 */ r0 = VADD(sr0, sr1); @@ -1719,7 +1719,7 @@ 0 0 0 0 1 1 1 1 * i0 0 -1 0 1 -1 0 1 0 i1 0 -1 0 1 1 0 -1 0 i2 - 0 0 0 0 -1 1 -1 1 i3 + 0 0 0 0 -1 1 -1 1 i3 */ //cerr << "matrix initial, before e , REAL:\n 1: " << r0 << "\n 1: " << r1 << "\n 1: " << r2 << "\n 1: " << r3 << "\n"; @@ -1832,7 +1832,7 @@ 0 0 0 0 1 -1 1 -1 * i0 0 -1 1 0 1 0 0 1 i1 0 0 0 0 1 1 -1 -1 i2 - 0 1 -1 0 1 0 0 1 i3 + 0 1 -1 0 1 0 0 1 i3 */ v4sf sr0 = VADD(r0, r3), dr0 = VSUB(r0, r3);
View file
pipewire-0.3.59.tar.gz/src/modules/module-filter-chain/pffft.h -> pipewire-0.3.60.tar.gz/src/modules/module-filter-chain/pffft.h
Changed
@@ -165,13 +165,13 @@ /* the float buffers must have the correct alignment (16-byte boundary on intel and powerpc). This function may be used to obtain such - correctly aligned buffers. + correctly aligned buffers. */ void *pffft_aligned_malloc(size_t nb_bytes); void pffft_aligned_free(void *); /* return 4 or 1 depending on whether support for SSE/Altivec instructions was enabled when building pffft.c */ - int pffft_simd_size(); + int pffft_simd_size(void); void pffft_select_cpu(int flags);
View file
pipewire-0.3.59.tar.gz/src/modules/module-loopback.c -> pipewire-0.3.60.tar.gz/src/modules/module-loopback.c
Changed
@@ -35,6 +35,7 @@ #include <spa/utils/result.h> #include <spa/utils/string.h> #include <spa/utils/json.h> +#include <spa/utils/ringbuffer.h> #include <spa/param/profiler.h> #include <spa/debug/pod.h> @@ -54,6 +55,7 @@ * ## Module Options * * - `node.description`: a human readable name for the loopback streams + * - `target.delay.sec`: delay in seconds as float (Since 0.3.60) * - `capture.props = {}`: properties to be passed to the input stream * - `playback.props = {}`: properties to be passed to the output stream * @@ -91,6 +93,7 @@ * { name = libpipewire-module-loopback * args = { * node.description = "CM106 Stereo Pair 2" + * #target.delay.sec = 1.5 * capture.props = { * node.name = "CM106_stereo_pair_2" * media.class = "Audio/Sink" @@ -128,6 +131,7 @@ " audio.rate=<sample rate> " " audio.channels=<number of channels> " " audio.position=<channel map> " + " target.delay.sec=<delay as seconds in float> " " capture.props=<properties> " " playback.props=<properties> " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, @@ -160,13 +164,21 @@ struct pw_stream *capture; struct spa_hook capture_listener; struct spa_audio_info_raw capture_info; + struct spa_latency_info capture_latency; struct pw_properties *playback_props; struct pw_stream *playback; struct spa_hook playback_listener; struct spa_audio_info_raw playback_info; + struct spa_latency_info playback_latency; unsigned int do_disconnect:1; + unsigned int recalc_delay:1; + + float target_delay; + struct spa_ringbuffer buffer; + uint8_t *buffer_data; + uint32_t buffer_size; }; static void capture_destroy(void *d) @@ -176,6 +188,28 @@ impl->capture = NULL; } +static void recalculate_delay(struct impl *impl) +{ + uint32_t target = impl->capture_info.rate * impl->target_delay, cdelay, pdelay; + uint32_t delay, w; + struct pw_time pwt; + + pw_stream_get_time_n(impl->playback, &pwt, sizeof(pwt)); + pdelay = pwt.delay; + pw_stream_get_time_n(impl->capture, &pwt, sizeof(pwt)); + cdelay = pwt.delay; + + delay = target - SPA_MIN(target, pdelay + cdelay); + delay = SPA_MIN(delay, impl->buffer_size / 4); + + spa_ringbuffer_get_write_index(&impl->buffer, &w); + spa_ringbuffer_read_update(&impl->buffer, w - (delay * 4)); + + pw_log_info("target:%d c:%d + p:%d + delay:%d = (%d)", + target, cdelay, pdelay, delay, + cdelay + pdelay + delay); +} + static void capture_process(void *d) { struct impl *impl = d; @@ -188,6 +222,11 @@ struct pw_buffer *in, *out; uint32_t i; + if (impl->recalc_delay) { + recalculate_delay(impl); + impl->recalc_delay = false; + } + if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL) pw_log_debug("out of capture buffers: %m"); @@ -199,6 +238,7 @@ int32_t stride = 0; struct spa_data *d; const void *srcin->buffer->n_datas; + uint32_t r, w, buffer_size; for (i = 0; i < in->buffer->n_datas; i++) { uint32_t offs, size; @@ -211,13 +251,33 @@ outsize = SPA_MIN(outsize, size); stride = SPA_MAX(stride, d->chunk->stride); } + if (impl->buffer_size > 0) { + buffer_size = impl->buffer_size; + spa_ringbuffer_get_write_index(&impl->buffer, &w); + for (i = 0; i < in->buffer->n_datas; i++) { + void *buffer_data = &impl->buffer_datai * buffer_size; + spa_ringbuffer_write_data(&impl->buffer, + buffer_data, buffer_size, + w % buffer_size, srci, outsize); + srci = buffer_data; + } + w += outsize; + spa_ringbuffer_write_update(&impl->buffer, w); + spa_ringbuffer_get_read_index(&impl->buffer, &r); + } else { + r = 0; + buffer_size = outsize; + } for (i = 0; i < out->buffer->n_datas; i++) { d = &out->buffer->datasi; outsize = SPA_MIN(outsize, d->maxsize); if (i < in->buffer->n_datas) - memcpy(d->data, srci, outsize); + spa_ringbuffer_read_data(&impl->buffer, + srci, buffer_size, + r % buffer_size, + d->data, outsize); else memset(d->data, 0, outsize); @@ -225,6 +285,10 @@ d->chunk->size = outsize; d->chunk->stride = stride; } + if (impl->buffer_size > 0) { + r += outsize; + spa_ringbuffer_read_update(&impl->buffer, r); + } } if (in != NULL) @@ -234,7 +298,7 @@ } static void param_latency_changed(struct impl *impl, const struct spa_pod *param, - struct pw_stream *other) + struct spa_latency_info *info, struct pw_stream *other) { struct spa_latency_info latency; uint8_t buffer1024; @@ -244,9 +308,13 @@ if (spa_latency_parse(param, &latency) < 0) return; + *info = latency; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); params0 = spa_latency_build(&b, SPA_PARAM_Latency, &latency); pw_stream_update_params(other, params, 1); + + impl->recalc_delay = true; } static void stream_state_changed(void *data, enum pw_stream_state old, @@ -257,6 +325,7 @@ case PW_STREAM_STATE_PAUSED: pw_stream_flush(impl->playback, false); pw_stream_flush(impl->capture, false); + impl->recalc_delay = true; break; case PW_STREAM_STATE_UNCONNECTED: pw_log_info("module %p: unconnected", impl); @@ -270,13 +339,53 @@ } } +static void recalculate_buffer(struct impl *impl) +{ + if (impl->target_delay > 0.0f) { + uint32_t delay = impl->capture_info.rate * impl->target_delay; + void *data; + + impl->buffer_size = (delay + (1u<<15)) * 4; + data = realloc(impl->buffer_data, impl->buffer_size * impl->capture_info.channels); + if (data == NULL) { + pw_log_warn("can't allocate delay buffer, delay disabled: %m"); + impl->buffer_size = 0; + free(impl->buffer_data); + } + impl->buffer_data = data; + spa_ringbuffer_init(&impl->buffer); + } else {
View file
pipewire-0.3.59.tar.gz/src/modules/module-pipe-tunnel.c -> pipewire-0.3.60.tar.gz/src/modules/module-pipe-tunnel.c
Changed
@@ -55,7 +55,7 @@ /** \page page_module_pipe_tunnel PipeWire Module: Unix Pipe Tunnel * * The pipe-tunnel module provides a source or sink that tunnels all audio to - * a unix pipe. + * or from a unix pipe respectively. * * ## Module Options * @@ -315,7 +315,7 @@ .process = capture_stream_process }; -static int create_stream(struct impl *impl) +static int create_stream(struct impl *impl) { int res; uint32_t n_params; @@ -664,6 +664,7 @@ copy_props(impl, props, PW_KEY_NODE_LATENCY); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS); + copy_props(impl, props, PW_KEY_TARGET_OBJECT); parse_audio_info(impl->stream_props, &impl->info);
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-native.c
Changed
@@ -228,6 +228,9 @@ hex = true; if (hex) spa_debug_mem(0, msg->data, msg->size); + + pw_logt_debug(mod_topic_connection, "%s ****", prefix); + } static void pre_demarshal(struct pw_protocol_native_connection *conn,
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-native/connection.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-native/connection.c
Changed
@@ -728,9 +728,12 @@ buf->n_fds = buf->msg.n_fds; if (mod_topic_connection->level >= SPA_LOG_LEVEL_DEBUG) { - pw_log_debug(">>>>>>>>> out: id:%d op:%d size:%d seq:%d", + pw_logt_debug(mod_topic_connection, + ">>>>>>>>> out: id:%d op:%d size:%d seq:%d", buf->msg.id, buf->msg.opcode, size, buf->msg.seq); spa_debug_pod(0, NULL, SPA_PTROFF(p, impl->hdr_size, struct spa_pod)); + pw_logt_debug(mod_topic_connection, + ">>>>>>>>> out: done"); } buf->seq = (buf->seq + 1) & SPA_ASYNC_SEQ_MASK;
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/client.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/client.c
Changed
@@ -266,17 +266,12 @@ int res = -errno; if (res == -EINTR) continue; - if (res != -EAGAIN && res != -EWOULDBLOCK) - pw_log_warn("client %p: send channel:%u %zu, error %d: %m", - client, m->channel, size, res); return res; } - client->out_index += sent; break; } } - return 0; } @@ -296,7 +291,6 @@ if (res != -EAGAIN && res != -EWOULDBLOCK) return res; } - return 0; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/extension.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/extension.c
Changed
@@ -37,12 +37,9 @@ const struct extension *extension_find(uint32_t index, const char *name) { - const struct extension *ext; - - SPA_FOR_EACH_ELEMENT(extensions, ext) { + SPA_FOR_EACH_ELEMENT_VAR(extensions, ext) { if (index == ext->index || spa_streq(name, ext->name)) return ext; } - return NULL; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/format.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/format.c
Changed
@@ -159,32 +159,28 @@ uint32_t format_paname2id(const char *name, size_t size) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) { - if (audio_formatsi.name != NULL && - strncmp(name, audio_formatsi.name, size) == 0) - return audio_formatsi.id; + SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) { + if (f->name != NULL && + strncmp(name, f->name, size) == 0) + return f->id; } return SPA_AUDIO_FORMAT_UNKNOWN; } enum sample_format format_id2pa(uint32_t id) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) { - if (id == audio_formatsi.id) - return audio_formatsi.pa; + SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) { + if (id == f->id) + return f->pa; } return SAMPLE_INVALID; } const char *format_id2paname(uint32_t id) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(audio_formats); i++) { - if (id == audio_formatsi.id && - audio_formatsi.name != NULL) - return audio_formatsi.name; + SPA_FOR_EACH_ELEMENT_VAR(audio_formats, f) { + if (id == f->id && f->name != NULL) + return f->name; } return "invalid"; } @@ -266,21 +262,18 @@ const char *channel_id2paname(uint32_t id, uint32_t *aux) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(audio_channels); i++) { - if (id == audio_channelsi.channel && - audio_channelsi.name != NULL) - return audio_channelsi.name; + SPA_FOR_EACH_ELEMENT_VAR(audio_channels, i) { + if (id == i->channel && i->name != NULL) + return i->name; } return audio_channelsCHANNEL_POSITION_AUX0 + ((*aux)++ & 31).name; } uint32_t channel_paname2id(const char *name, size_t size) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(audio_channels); i++) { - if (strncmp(name, audio_channelsi.name, size) == 0) - return audio_channelsi.channel; + SPA_FOR_EACH_ELEMENT_VAR(audio_channels, i) { + if (strncmp(name, i->name, size) == 0) + return i->channel; } return SPA_AUDIO_CHANNEL_UNKNOWN; } @@ -424,25 +417,6 @@ return ENCODING_ANY; } -static inline int -audio_raw_parse_opt(const struct spa_pod *format, struct spa_audio_info_raw *info) -{ - struct spa_pod *position = NULL; - int res; - info->flags = 0; - res = spa_pod_parse_object(format, - SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_AUDIO_format, SPA_POD_OPT_Id(&info->format), - SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), - SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), - SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); - if (position == NULL || - !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS)) - SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); - - return res; -} - int format_parse_param(const struct spa_pod *param, bool collect, struct sample_spec *ss, struct channel_map *map, const struct sample_spec *def_ss, const struct channel_map *def_map) @@ -458,14 +432,17 @@ switch (info.media_subtype) { case SPA_MEDIA_SUBTYPE_raw: + if (spa_format_audio_raw_parse(param, &info.info.raw) < 0) + return -ENOTSUP; if (def_ss != NULL) { if (ss != NULL) *ss = *def_ss; - if (audio_raw_parse_opt(param, &info.info.raw) < 0) - return -ENOTSUP; } else { - if (spa_format_audio_raw_parse(param, &info.info.raw) < 0) - return -ENOTSUP; + if (info.info.raw.format == 0 || + info.info.raw.rate == 0 || + info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + return -ENOTSUP; } break; case SPA_MEDIA_SUBTYPE_iec958:
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/manager.c
Changed
@@ -33,8 +33,6 @@ #include "log.h" #include "module-protocol-pulse/server.h" -#define MAX_PARAMS 32 - #define manager_emit_sync(m) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, sync, 0) #define manager_emit_added(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, added, 0, o) #define manager_emit_updated(m,o) spa_hook_list_call(&(m)->hooks, struct pw_manager_events, updated, 0, o) @@ -85,8 +83,6 @@ struct spa_hook proxy_listener; struct spa_hook object_listener; - int param_seqMAX_PARAMS; - struct spa_list data_list; }; @@ -113,7 +109,7 @@ } static struct pw_manager_param *add_param(struct spa_list *params, - int seq, int *param_seq, uint32_t id, const struct spa_pod *param) + int seq, uint32_t id, const struct spa_pod *param) { struct pw_manager_param *p; @@ -125,24 +121,12 @@ id = SPA_POD_OBJECT_ID(param); } - if (id >= MAX_PARAMS) { - pw_log_error("too big param id %d", id); - errno = EINVAL; - return NULL; - } - - if (seq != param_seqid) { - pw_log_debug("ignoring param %d, seq:%d != current_seq:%d", - id, seq, param_seqid); - errno = EBUSY; - return NULL; - } - p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0)); if (p == NULL) return NULL; p->id = id; + p->seq = seq; if (param != NULL) { p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod); memcpy(p->param, param, SPA_POD_SIZE(param)); @@ -167,7 +151,6 @@ return false; } - static struct object *find_object_by_id(struct manager *m, uint32_t id) { struct object *o; @@ -180,7 +163,19 @@ static void object_update_params(struct object *o) { - struct pw_manager_param *p; + struct pw_manager_param *p, *t; + uint32_t i; + + for (i = 0; i < o->this.n_params; i++) { + spa_list_for_each_safe(p, t, &o->pending_list, link) { + if (p->id == o->this.paramsi.id && + p->seq != o->this.paramsi.seq && + p->param != NULL) { + spa_list_remove(&p->link); + free(p); + } + } + } spa_list_consume(p, &o->pending_list, link) { spa_list_remove(&p->link); @@ -236,6 +231,8 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); info = o->this.info = pw_client_info_merge(o->this.info, info, o->this.changed == 0); + if (info == NULL) + return; if (info->change_mask & PW_CLIENT_CHANGE_MASK_PROPS) changed++; @@ -275,6 +272,8 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); info = o->this.info = pw_module_info_merge(o->this.info, info, o->this.changed == 0); + if (info == NULL) + return; if (info->change_mask & PW_MODULE_CHANGE_MASK_PROPS) changed++; @@ -314,6 +313,11 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); info = o->this.info = pw_device_info_merge(o->this.info, info, o->this.changed == 0); + if (info == NULL) + return; + + o->this.n_params = info->n_params; + o->this.params = info->params; if (info->change_mask & PW_DEVICE_CHANGE_MASK_PROPS) changed++; @@ -327,11 +331,6 @@ continue; info->paramsi.user = 0; - if (id >= MAX_PARAMS) { - pw_log_error("too big param id %d", id); - continue; - } - switch (id) { case SPA_PARAM_EnumProfile: case SPA_PARAM_Profile: @@ -341,14 +340,14 @@ case SPA_PARAM_Route: break; } - add_param(&o->pending_list, o->param_seqid, o->param_seq, id, NULL); + add_param(&o->pending_list, info->paramsi.seq, id, NULL); if (!(info->paramsi.flags & SPA_PARAM_INFO_READ)) continue; res = pw_device_enum_params((struct pw_device*)o->this.proxy, - ++o->param_seqid, id, 0, -1, NULL); + ++info->paramsi.seq, id, 0, -1, NULL); if (SPA_RESULT_IS_ASYNC(res)) - o->param_seqid = res; + info->paramsi.seq = res; } } if (changed) { @@ -385,7 +384,7 @@ struct manager *m = o->manager; struct pw_manager_param *p; - p = add_param(&o->pending_list, seq, o->param_seq, id, param); + p = add_param(&o->pending_list, seq, id, param); if (p == NULL) return; @@ -434,6 +433,11 @@ pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask); info = o->this.info = pw_node_info_merge(o->this.info, info, o->this.changed == 0); + if (info == NULL) + return; + + o->this.n_params = info->n_params; + o->this.params = info->params; if (info->change_mask & PW_NODE_CHANGE_MASK_STATE) changed++; @@ -450,20 +454,15 @@ continue; info->paramsi.user = 0; - if (id >= MAX_PARAMS) { - pw_log_error("too big param id %d", id); - continue; - } - changed++; - add_param(&o->pending_list, o->param_seqid, o->param_seq, id, NULL); + add_param(&o->pending_list, info->paramsi.seq, id, NULL); if (!(info->paramsi.flags & SPA_PARAM_INFO_READ)) continue; res = pw_node_enum_params((struct pw_node*)o->this.proxy, - ++o->param_seqid, id, 0, -1, NULL); + ++info->paramsi.seq, id, 0, -1, NULL); if (SPA_RESULT_IS_ASYNC(res)) - o->param_seqid = res; + info->paramsi.seq = res; } } if (changed) { @@ -477,7 +476,7 @@ const struct spa_pod *param) { struct object *o = data; - add_param(&o->pending_list, seq, o->param_seq, id, param); + add_param(&o->pending_list, seq, id, param); } static const struct pw_node_events node_events = { @@ -553,11 +552,10 @@ static const struct object_info *find_info(const char *type, uint32_t version) {
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/manager.h
Changed
@@ -72,6 +72,7 @@ struct pw_manager_param { uint32_t id; + int32_t seq; struct spa_list link; /**< link in manager_object param_list */ struct spa_pod *param; }; @@ -92,6 +93,9 @@ int changed; void *info; + struct spa_param_info *params; + uint32_t n_params; + struct spa_list param_list; unsigned int creating:1; unsigned int removing:1;
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-loopback.c
Changed
@@ -47,6 +47,7 @@ struct pw_properties *playback_props; struct spa_audio_info_raw info; + uint32_t latency_msec; }; static void module_destroy(void *data) @@ -68,6 +69,7 @@ FILE *f; char *args; size_t size, i; + char val256; pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index); pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index); @@ -88,6 +90,10 @@ fprintf(f, " "); } } + if (data->latency_msec != 0) + fprintf(f, " target.delay.sec = %s", + spa_json_format_float(val, sizeof(val), + data->latency_msec / 1000.0f)); fprintf(f, " capture.props = {"); pw_properties_serialize_dict(f, &data->capture_props->dict, 0); fprintf(f, " } playback.props = {"); @@ -204,15 +210,8 @@ pw_properties_set(props, "remix", NULL); } - if ((str = pw_properties_get(props, "latency_msec")) != NULL) { - /* Half the latency on each of the playback and capture streams */ - pw_properties_setf(capture_props, PW_KEY_NODE_LATENCY, "%s/2000", str); - pw_properties_setf(playback_props, PW_KEY_NODE_LATENCY, "%s/2000", str); - pw_properties_set(props, "latency_msec", NULL); - } else { - pw_properties_set(capture_props, PW_KEY_NODE_LATENCY, "100/1000"); - pw_properties_set(playback_props, PW_KEY_NODE_LATENCY, "100/1000"); - } + if ((str = pw_properties_get(props, "latency_msec")) != NULL) + d->latency_msec = atoi(str); if ((str = pw_properties_get(props, "sink_input_properties")) != NULL) { module_args_add_props(playback_props, str);
View file
pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-recv.c
Added
@@ -0,0 +1,165 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <spa/utils/hook.h> +#include <pipewire/pipewire.h> +#include <pipewire/private.h> + +#include "../defs.h" +#include "../module.h" + +#define NAME "rtp-recv" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +struct module_rtp_recv_data { + struct module *module; + + struct spa_hook mod_listener; + struct pw_impl_module *mod; + + struct pw_properties *stream_props; + struct pw_properties *global_props; +}; + +static void module_destroy(void *data) +{ + struct module_rtp_recv_data *d = data; + spa_hook_remove(&d->mod_listener); + d->mod = NULL; + module_schedule_unload(d->module); +} + +static const struct pw_impl_module_events module_events = { + PW_VERSION_IMPL_MODULE_EVENTS, + .destroy = module_destroy +}; + +static int module_rtp_recv_load(struct client *client, struct module *module) +{ + struct module_rtp_recv_data *data = module->user_data; + FILE *f; + char *args; + size_t size; + + pw_properties_setf(data->stream_props, "pulse.module.id", + "%u", module->index); + + if ((f = open_memstream(&args, &size)) == NULL) + return -errno; + + fprintf(f, "{"); + pw_properties_serialize_dict(f, &data->global_props->dict, 0); + fprintf(f, " stream.props = {"); + pw_properties_serialize_dict(f, &data->stream_props->dict, 0); + fprintf(f, " } }"); + fclose(f); + + data->mod = pw_context_load_module(module->impl->context, + "libpipewire-module-rtp-source", + args, NULL); + + free(args); + + if (data->mod == NULL) + return -errno; + + pw_impl_module_add_listener(data->mod, + &data->mod_listener, + &module_events, data); + + return 0; +} + +static int module_rtp_recv_unload(struct module *module) +{ + struct module_rtp_recv_data *d = module->user_data; + + if (d->mod) { + spa_hook_remove(&d->mod_listener); + pw_impl_module_destroy(d->mod); + d->mod = NULL; + } + + pw_properties_free(d->global_props); + pw_properties_free(d->stream_props); + + return 0; +} + +static const struct spa_dict_item module_rtp_recv_info = { + { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, + { PW_KEY_MODULE_DESCRIPTION, "Receive data from a network via RTP/SAP/SDP" }, + { PW_KEY_MODULE_USAGE, "sink=<name of the sink> " + "sap_address=<multicast address to listen on> " + "latency_msec=<latency in ms> " }, + { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, +}; + +static int module_rtp_recv_prepare(struct module * const module) +{ + struct module_rtp_recv_data * const d = module->user_data; + struct pw_properties * const props = module->props; + struct pw_properties *stream_props = NULL, *global_props = NULL; + const char *str; + int res; + + PW_LOG_TOPIC_INIT(mod_topic); + + stream_props = pw_properties_new(NULL, NULL); + global_props = pw_properties_new(NULL, NULL); + if (!stream_props || !global_props) { + res = -errno; + goto out; + } + if ((str = pw_properties_get(props, "sink")) != NULL) + pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); + + if ((str = pw_properties_get(props, "sap_address")) != NULL) + pw_properties_set(global_props, "sap.ip", str); + + if ((str = pw_properties_get(props, "latency_msec")) != NULL) + pw_properties_set(global_props, "sess.latency.msec", str); + + d->module = module; + d->stream_props = stream_props; + d->global_props = global_props; + + return 0; +out: + pw_properties_free(stream_props); + pw_properties_free(global_props); + + return res; +} + +DEFINE_MODULE_INFO(module_rtp_recv) = { + .name = "module-rtp-recv", + .prepare = module_rtp_recv_prepare, + .load = module_rtp_recv_load, + .unload = module_rtp_recv_unload, + .properties = &SPA_DICT_INIT_ARRAY(module_rtp_recv_info), + .data_size = sizeof(struct module_rtp_recv_data), +};
View file
pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-rtp-send.c
Added
@@ -0,0 +1,226 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <spa/utils/hook.h> +#include <pipewire/pipewire.h> +#include <pipewire/private.h> + +#include "../defs.h" +#include "../module.h" + +#define NAME "rtp-send" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +struct module_rtp_send_data { + struct module *module; + + struct spa_hook mod_listener; + struct pw_impl_module *mod; + + struct pw_properties *stream_props; + struct pw_properties *global_props; + struct spa_audio_info_raw info; +}; + +static void module_destroy(void *data) +{ + struct module_rtp_send_data *d = data; + spa_hook_remove(&d->mod_listener); + d->mod = NULL; + module_schedule_unload(d->module); +} + +static const struct pw_impl_module_events module_events = { + PW_VERSION_IMPL_MODULE_EVENTS, + .destroy = module_destroy +}; + +static int module_rtp_send_load(struct client *client, struct module *module) +{ + struct module_rtp_send_data *data = module->user_data; + FILE *f; + char *args; + size_t size; + uint32_t i; + + pw_properties_setf(data->stream_props, "pulse.module.id", + "%u", module->index); + + if ((f = open_memstream(&args, &size)) == NULL) + return -errno; + + fprintf(f, "{"); + pw_properties_serialize_dict(f, &data->global_props->dict, 0); + if (data->info.format != 0) + fprintf(f, " \"audio.format\": \"%s\"", format_id2name(data->info.format)); + if (data->info.rate != 0) + fprintf(f, " \"audio.rate\": %u,", data->info.rate); + if (data->info.channels != 0) { + fprintf(f, " \"audio.channels\": %u,", data->info.channels); + if (!(data->info.flags & SPA_AUDIO_FLAG_UNPOSITIONED)) { + fprintf(f, " \"audio.position\": "); + for (i = 0; i < data->info.channels; i++) + fprintf(f, "%s\"%s\"", i == 0 ? "" : ",", + channel_id2name(data->info.positioni)); + fprintf(f, " ,"); + } + } + fprintf(f, " stream.props = {"); + pw_properties_serialize_dict(f, &data->stream_props->dict, 0); + fprintf(f, " } }"); + fclose(f); + + data->mod = pw_context_load_module(module->impl->context, + "libpipewire-module-rtp-sink", + args, NULL); + + free(args); + + if (data->mod == NULL) + return -errno; + + pw_impl_module_add_listener(data->mod, + &data->mod_listener, + &module_events, data); + + return 0; +} + +static int module_rtp_send_unload(struct module *module) +{ + struct module_rtp_send_data *d = module->user_data; + + if (d->mod) { + spa_hook_remove(&d->mod_listener); + pw_impl_module_destroy(d->mod); + d->mod = NULL; + } + + pw_properties_free(d->global_props); + pw_properties_free(d->stream_props); + + return 0; +} + +static const struct spa_dict_item module_rtp_send_info = { + { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, + { PW_KEY_MODULE_DESCRIPTION, "Read data from source and send it to the network via RTP/SAP/SDP" }, + { PW_KEY_MODULE_USAGE, "source=<name of the source> " + "format=<sample format> " + "channels=<number of channels> " + "rate=<sample rate> " + "destination_ip=<destination IP address> " + "source_ip=<source IP address> " + "port=<port number> " + "mtu=<maximum transfer unit> " + "loop=<loopback to local host?> " + "ttl=<ttl value> " + "inhibit_auto_suspend=<always|never|only_with_non_monitor_sources> " + "stream_name=<name of the stream> " + "enable_opus=<enable OPUS codec>" }, + { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, +}; + +static int module_rtp_send_prepare(struct module * const module) +{ + struct module_rtp_send_data * const d = module->user_data; + struct pw_properties * const props = module->props; + struct pw_properties *stream_props = NULL, *global_props = NULL; + struct spa_audio_info_raw info = { 0 }; + const char *str; + int res; + + PW_LOG_TOPIC_INIT(mod_topic); + + stream_props = pw_properties_new(NULL, NULL); + global_props = pw_properties_new(NULL, NULL); + if (!stream_props || !global_props) { + res = -errno; + goto out; + } + + if ((str = pw_properties_get(props, "source")) != NULL) { + pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); + if (spa_strendswith(str, ".monitor")) { + pw_properties_setf(stream_props, PW_KEY_NODE_TARGET, + "%.*s", (int)strlen(str)-8, str); + pw_properties_set(stream_props, PW_KEY_STREAM_CAPTURE_SINK, + "true"); + } else { + pw_properties_set(stream_props, PW_KEY_NODE_TARGET, str); + } + } + if (module_args_to_audioinfo(module->impl, props, &info) < 0) { + res = -EINVAL; + goto out; + } + info.format = 0; + if ((str = pw_properties_get(props, "format")) != NULL) { + if ((info.format = format_paname2id(str, strlen(str))) == + SPA_AUDIO_FORMAT_UNKNOWN) { + pw_log_error("unknown format %s", str); + res = -EINVAL; + goto out; + } + } + + if ((str = pw_properties_get(props, "destination_ip")) != NULL) + pw_properties_set(global_props, "destination.ip", str); + if ((str = pw_properties_get(props, "source_ip")) != NULL) + pw_properties_set(global_props, "source.ip", str); + if ((str = pw_properties_get(props, "port")) != NULL) + pw_properties_set(global_props, "destination.port", str); + if ((str = pw_properties_get(props, "mtu")) != NULL) + pw_properties_set(global_props, "net.mtu", str); + if ((str = pw_properties_get(props, "loop")) != NULL) + pw_properties_set(global_props, "net.loop",
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-discover.c
Changed
@@ -40,6 +40,8 @@ struct spa_hook mod_listener; struct pw_impl_module *mod; + + uint32_t latency_msec; }; static void module_destroy(void *data) @@ -58,10 +60,25 @@ static int module_zeroconf_discover_load(struct client *client, struct module *module) { struct module_zeroconf_discover_data *data = module->user_data; + FILE *f; + char *args; + size_t size; + + if ((f = open_memstream(&args, &size)) == NULL) + return -errno; + + fprintf(f, "{"); + if (data->latency_msec > 0) + fprintf(f, " pulse.latency = %u ", data->latency_msec); + fprintf(f, "}"); + fclose(f); data->mod = pw_context_load_module(module->impl->context, "libpipewire-module-zeroconf-discover", - NULL, NULL); + args, NULL); + + free(args); + if (data->mod == NULL) return -errno; @@ -88,7 +105,8 @@ static const struct spa_dict_item module_zeroconf_discover_info = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.con>" }, { PW_KEY_MODULE_DESCRIPTION, "mDNS/DNS-SD Service Discovery" }, - { PW_KEY_MODULE_USAGE, "" }, + { PW_KEY_MODULE_USAGE, + "latency_msec=<fixed latency in ms> " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; @@ -96,9 +114,12 @@ { PW_LOG_TOPIC_INIT(mod_topic); + struct pw_properties * const props = module->props; struct module_zeroconf_discover_data * const data = module->user_data; data->module = module; + pw_properties_fetch_uint32(props, "latency_msec", &data->latency_msec); + return 0; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c
Changed
@@ -380,8 +380,7 @@ txt = avahi_string_list_add_pair(txt, "channel_map", channel_map_snprint(cm, sizeof(cm), &s->cm)); txt = avahi_string_list_add_pair(txt, "subtype", subtype_texts->subtype); - const struct mapping *m; - SPA_FOR_EACH_ELEMENT(mappings, m) { + SPA_FOR_EACH_ELEMENT_VAR(mappings, m) { const char *value = pw_properties_get(s->props, m->pw_key); if (value != NULL) txt = avahi_string_list_add_pair(txt, m->txt_key, value);
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -1428,15 +1428,16 @@ } if ((stream->attr.prebuf == 0 || do_flush) && !stream->corked) { if (avail > 0) { + avail = SPA_MIN((uint32_t)avail, size); spa_ringbuffer_read_data(&stream->ring, stream->buffer, MAXLENGTH, index % MAXLENGTH, - p, SPA_MIN((uint32_t)avail, size)); + p, avail); index += avail; + pd.read_inc = avail; + spa_ringbuffer_read_update(&stream->ring, index); } pd.playing_for = size; - pd.read_inc = size; - spa_ringbuffer_read_update(&stream->ring, index); } pw_log_debug("%p: %s underrun read:%u avail:%d max:%u", stream, client->name, index, avail, minreq);
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/quirks.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/quirks.c
Changed
@@ -38,10 +38,9 @@ { "force-s16-info", QUIRK_FORCE_S16_FORMAT }, { "remove-capture-dont-move", QUIRK_REMOVE_CAPTURE_DONT_MOVE }, }; - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(quirk_keys); ++i) { - if (spa_streq(str, quirk_keysi.key)) - return quirk_keysi.value; + SPA_FOR_EACH_ELEMENT_VAR(quirk_keys, i) { + if (spa_streq(str, i->key)) + return i->value; } return 0; }
View file
pipewire-0.3.59.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.60.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
@@ -616,7 +616,6 @@ pw_log_warn("server %p: unlink('%s') failed: %m", server, addr_un->sun_path); } - if (bind(fd, (const struct sockaddr *) addr_un, SUN_LEN(addr_un)) < 0) { res = -errno; pw_log_warn("server %p: bind() to '%s' failed: %m", @@ -624,6 +623,10 @@ goto error_close; } + if (chmod(addr_un->sun_path, 0777) < 0) + pw_log_warn("server %p: chmod('%s') failed: %m", + server, addr_un->sun_path); + if (listen(fd, server->listen_backlog) < 0) { res = -errno; pw_log_warn("server %p: listen() on '%s' failed: %m",
View file
pipewire-0.3.59.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.60.tar.gz/src/modules/module-pulse-tunnel.c
Changed
@@ -183,6 +183,8 @@ pa_context *pa_context; pa_stream *pa_stream; + struct ratelimit rate_limit; + uint32_t target_latency; uint32_t current_latency; uint32_t target_buffer; @@ -524,9 +526,10 @@ { struct impl *impl = userdata; int32_t avail; - uint32_t index, len, offset, l0, l1; + uint32_t index; + size_t size; pa_usec_t latency; - int negative; + int negative, res; if (impl->resync) { impl->resync = false; @@ -542,43 +545,54 @@ impl->current_latency += avail / impl->frame_size; while (avail < (int32_t)length) { + uint32_t maxsize = SPA_ROUND_DOWN(sizeof(impl->empty), impl->frame_size); /* send silence for the data we don't have */ - len = SPA_MIN(length - avail, sizeof(impl->empty)); - pa_stream_write(impl->pa_stream, - impl->empty, len, - NULL, 0, PA_SEEK_RELATIVE); - length -= len; + size = SPA_MIN(length - avail, maxsize); + if ((res = pa_stream_write(impl->pa_stream, + impl->empty, size, + NULL, 0, PA_SEEK_RELATIVE)) != 0) + pw_log_warn("error writing stream: %s", pa_strerror(res)); + length -= size; } - if (length > 0 && avail >= (int32_t)length) { - /* always send as much as is requested */ - len = length; - offset = index & RINGBUFFER_MASK; - l0 = SPA_MIN(len, RINGBUFFER_SIZE - offset); - l1 = len - l0; - - pa_stream_write(impl->pa_stream, - SPA_PTROFF(impl->buffer, offset, void), l0, - NULL, 0, PA_SEEK_RELATIVE); - - if (SPA_UNLIKELY(l1 > 0)) { - pa_stream_write(impl->pa_stream, - impl->buffer, l1, - NULL, 0, PA_SEEK_RELATIVE); - } - index += len; + while (length > 0 && avail >= (int32_t)length) { + void *data; + + size = length; + pa_stream_begin_write(impl->pa_stream, &data, &size); + + spa_ringbuffer_read_data(&impl->ring, + impl->buffer, RINGBUFFER_SIZE, + index & RINGBUFFER_MASK, + data, size); + + if ((res = pa_stream_write(impl->pa_stream, + data, size, NULL, 0, PA_SEEK_RELATIVE)) != 0) + pw_log_warn("error writing stream: %zd %s", size, + pa_strerror(res)); + + index += size; + length -= size; + avail -= size; spa_ringbuffer_read_update(&impl->ring, index); } } static void stream_underflow_cb(pa_stream *s, void *userdata) { struct impl *impl = userdata; - pw_log_warn("underflow"); + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN)) + pw_log_warn("underflow"); impl->resync = true; } static void stream_overflow_cb(pa_stream *s, void *userdata) { struct impl *impl = userdata; - pw_log_warn("overflow"); + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + if (ratelimit_test(&impl->rate_limit, SPA_TIMESPEC_TO_NSEC(&ts), SPA_LOG_LEVEL_WARN)) + pw_log_warn("overflow"); impl->resync = true; } @@ -606,13 +620,14 @@ static int create_pulse_stream(struct impl *impl) { pa_sample_spec ss; + pa_channel_map map; const char *server_address, *remote_node_target; pa_proplist *props = NULL; pa_mainloop_api *api; char stream_name1024; pa_buffer_attr bufferattr; int res = -EIO; - uint32_t latency_bytes; + uint32_t latency_bytes, i, aux = 0; if ((impl->pa_mainloop = pa_threaded_mainloop_new()) == NULL) goto error; @@ -659,10 +674,14 @@ ss.channels = impl->info.channels; ss.rate = impl->info.rate; + map.channels = impl->info.channels; + for (i = 0; i < map.channels; i++) + map.mapi = (pa_channel_position_t)channel_id2pa(impl->info.positioni, &aux); + snprintf(stream_name, sizeof(stream_name), _("Tunnel for %s@%s"), pw_get_user_name(), pw_get_host_name()); - if (!(impl->pa_stream = pa_stream_new(impl->pa_context, stream_name, &ss, NULL))) { + if (!(impl->pa_stream = pa_stream_new(impl->pa_context, stream_name, &ss, &map))) { res = pa_context_errno(impl->pa_context); goto error_unlock; } @@ -701,6 +720,8 @@ PA_STREAM_AUTO_TIMING_UPDATE); } else { bufferattr.tlength = latency_bytes / 2; + bufferattr.minreq = bufferattr.tlength / 4; + bufferattr.prebuf = bufferattr.tlength; res = pa_stream_connect_playback(impl->pa_stream, remote_node_target, &bufferattr, @@ -951,6 +972,8 @@ spa_ringbuffer_init(&impl->ring); impl->buffer = calloc(1, RINGBUFFER_SIZE); spa_dll_init(&impl->dll); + impl->rate_limit.interval = 2 * SPA_NSEC_PER_SEC; + impl->rate_limit.burst = 1; if ((str = pw_properties_get(props, "tunnel.mode")) != NULL) { if (spa_streq(str, "source")) {
View file
pipewire-0.3.59.tar.gz/src/modules/module-raop-sink.c -> pipewire-0.3.60.tar.gz/src/modules/module-raop-sink.c
Changed
@@ -108,12 +108,12 @@ * raop.hostname = "my-raop-device" * raop.port = 8190 * #raop.transport = "udp" - * raop.encryption = "RSA" + * raop.encryption.type = "RSA" * #raop.audio.codec = "PCM" * #raop.password = "****" * #audio.format = "S16" * #audio.rate = 44100 - * #audio.channels = 22 + * #audio.channels = 2 * #audio.position = FL FR * stream.props = { * # extra sink properties @@ -157,7 +157,7 @@ #define DEFAULT_CHANNELS 2 #define DEFAULT_POSITION " FL FR " -#define DEFAULT_LATENCY (DEFAULT_RATE*2) +#define DEFAULT_LATENCY 22050 #define MODULE_USAGE " raop.hostname=<name of host> " \ " raop.port=<remote port> " \ @@ -429,7 +429,7 @@ memset(dst, 0, len); break; } - if (impl->encryption != CRYPTO_NONE) + if (impl->encryption == CRYPTO_RSA) aes_encrypt(impl, dst, len); impl->rtptime += n_frames; @@ -472,7 +472,7 @@ memset(dst, 0, len); break; } - if (impl->encryption != CRYPTO_NONE) + if (impl->encryption == CRYPTO_RSA) aes_encrypt(impl, dst, len); pkt0 |= htonl((uint32_t) len + 12); @@ -724,9 +724,10 @@ } } -static void rtsp_flush_reply(void *data, int status, const struct spa_dict *headers) +static int rtsp_flush_reply(void *data, int status, const struct spa_dict *headers) { pw_log_info("reply %d", status); + return 0; } static int rtsp_do_flush(struct impl *impl) @@ -751,7 +752,7 @@ return res; } -static void rtsp_record_reply(void *data, int status, const struct spa_dict *headers) +static int rtsp_record_reply(void *data, int status, const struct spa_dict *headers) { struct impl *impl = data; const char *str; @@ -760,6 +761,7 @@ uint8_t buffer1024; struct spa_pod_builder b; struct spa_latency_info latency; + char progress128; pw_log_info("reply %d", status); @@ -784,6 +786,10 @@ impl->sync = 0; impl->sync_period = impl->info.rate / (impl->block_size / impl->frame_size); impl->recording = true; + + snprintf(progress, sizeof(progress), "progress: %s/%s/%s\r\n", "0", "0", "0"); + return pw_rtsp_client_send(impl->rtsp, "SET_PARAMETER", NULL, + "text/parameters", progress, NULL, NULL); } static int rtsp_do_record(struct impl *impl) @@ -837,7 +843,7 @@ pw_loop_update_io(impl->loop, impl->server_source, 0); } -static void rtsp_setup_reply(void *data, int status, const struct spa_dict *headers) +static int rtsp_setup_reply(void *data, int status, const struct spa_dict *headers) { struct impl *impl = data; const char *str, *state = NULL, *s; @@ -849,13 +855,13 @@ if ((str = spa_dict_lookup(headers, "Session")) == NULL) { pw_log_error("missing Session header"); - return; + return 0; } pw_properties_set(impl->headers, "Session", str); if ((str = spa_dict_lookup(headers, "Transport")) == NULL) { pw_log_error("missing Transport header"); - return; + return 0; } impl->server_port = control_port = timing_port = 0; @@ -872,18 +878,21 @@ } if (impl->server_port == 0) { pw_log_error("missing server port in Transport"); - return; + return 0; } - pw_getrandom(&impl->seq, sizeof(impl->seq), 0); - pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0); + if (pw_getrandom(&impl->seq, sizeof(impl->seq), 0) < 0 || + pw_getrandom(&impl->rtptime, sizeof(impl->rtptime), 0) < 0) { + pw_log_error("error generating random seq and rtptime: %m"); + return 0; + } pw_log_info("server port:%u", impl->server_port); switch (impl->protocol) { case PROTO_TCP: - if ((impl->server_fd = connect_socket(impl, SOCK_STREAM, -1, impl->server_port)) <= 0) - return; + if ((impl->server_fd = connect_socket(impl, SOCK_STREAM, -1, impl->server_port)) < 0) + return impl->server_fd; impl->server_source = pw_loop_add_io(impl->loop, impl->server_fd, SPA_IO_OUT, false, on_server_source_io, impl); @@ -892,16 +901,16 @@ case PROTO_UDP: if (control_port == 0 || timing_port == 0) { pw_log_error("missing UDP ports in Transport"); - return; + return 0; } pw_log_info("control:%u timing:%u", control_port, timing_port); - if ((impl->server_fd = connect_socket(impl, SOCK_DGRAM, -1, impl->server_port)) <= 0) - return; - if ((impl->control_fd = connect_socket(impl, SOCK_DGRAM, impl->control_fd, control_port)) <= 0) - return; - if ((impl->timing_fd = connect_socket(impl, SOCK_DGRAM, impl->timing_fd, timing_port)) <= 0) - return; + if ((impl->server_fd = connect_socket(impl, SOCK_DGRAM, -1, impl->server_port)) < 0) + return impl->server_fd; + if ((impl->control_fd = connect_socket(impl, SOCK_DGRAM, impl->control_fd, control_port)) < 0) + return impl->control_fd; + if ((impl->timing_fd = connect_socket(impl, SOCK_DGRAM, impl->timing_fd, timing_port)) < 0) + return impl->timing_fd; ntp = ntp_now(CLOCK_MONOTONIC); send_udp_timing_packet(impl, ntp, ntp, NULL, 0); @@ -914,8 +923,9 @@ rtsp_do_record(impl); break; default: - return; + return 0; } + return 0; } static int rtsp_do_setup(struct impl *impl) @@ -966,7 +976,7 @@ return -EIO; } -static void rtsp_announce_reply(void *data, int status, const struct spa_dict *headers) +static int rtsp_announce_reply(void *data, int status, const struct spa_dict *headers) { struct impl *impl = data; @@ -974,7 +984,7 @@ pw_properties_set(impl->headers, "Apple-Challenge", NULL); - rtsp_do_setup(impl); + return rtsp_do_setup(impl); } static void base64_encode(const uint8_t *data, size_t len, char *enc, char pad) @@ -1061,7 +1071,8 @@ int res, frames, i, ip_version; char *sdp; char local_ip256; - + int min_latency; + min_latency = DEFAULT_LATENCY; host = pw_properties_get(impl->props, "raop.hostname"); if (impl->protocol == PROTO_TCP) @@ -1088,10 +1099,26 @@ ip_version, host, frames); break;
View file
pipewire-0.3.59.tar.gz/src/modules/module-raop/rtsp-client.c -> pipewire-0.3.60.tar.gz/src/modules/module-raop/rtsp-client.c
Changed
@@ -45,7 +45,7 @@ size_t len; size_t offset; uint32_t cseq; - void (*reply) (void *user_data, int status, const struct spa_dict *headers); + int (*reply) (void *user_data, int status, const struct spa_dict *headers); void *user_data; }; @@ -133,6 +133,11 @@ return client->user_data; } +const char *pw_rtsp_client_get_url(struct pw_rtsp_client *client) +{ + return client->url; +} + void pw_rtsp_client_add_listener(struct pw_rtsp_client *client, struct spa_hook *listener, const struct pw_rtsp_client_events *events, void *data) @@ -282,16 +287,23 @@ static void dispatch_handler(struct pw_rtsp_client *client) { uint32_t cseq; + int res; + struct message *msg; + if (pw_properties_fetch_uint32(client->headers, "CSeq", &cseq) < 0) return; pw_log_info("received reply to request with cseq:%" PRIu32, cseq); - struct message *msg = find_pending(client, cseq); + msg = find_pending(client, cseq); if (msg) { - msg->reply(msg->user_data, client->status, &client->headers->dict); + res = msg->reply(msg->user_data, client->status, &client->headers->dict); spa_list_remove(&msg->link); free(msg); + + if (res < 0) + pw_log_warn("client %p: handle reply cseq:%u error: %s", + client, cseq, spa_strerror(res)); } else { pw_rtsp_client_emit_message(client, client->status, &client->headers->dict); @@ -554,7 +566,7 @@ int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url, const char *cmd, const struct spa_dict *headers, const char *content_type, const void *content, size_t content_length, - void (*reply) (void *user_data, int status, const struct spa_dict *headers), + int (*reply) (void *user_data, int status, const struct spa_dict *headers), void *user_data) { FILE *f; @@ -608,7 +620,7 @@ int pw_rtsp_client_send(struct pw_rtsp_client *client, const char *cmd, const struct spa_dict *headers, const char *content_type, const char *content, - void (*reply) (void *user_data, int status, const struct spa_dict *headers), + int (*reply) (void *user_data, int status, const struct spa_dict *headers), void *user_data) { const size_t content_length = content ? strlen(content) : 0;
View file
pipewire-0.3.59.tar.gz/src/modules/module-raop/rtsp-client.h -> pipewire-0.3.60.tar.gz/src/modules/module-raop/rtsp-client.h
Changed
@@ -57,6 +57,7 @@ void pw_rtsp_client_destroy(struct pw_rtsp_client *client); void *pw_rtsp_client_get_user_data(struct pw_rtsp_client *client); +const char *pw_rtsp_client_get_url(struct pw_rtsp_client *client); void pw_rtsp_client_add_listener(struct pw_rtsp_client *client, struct spa_hook *listener, @@ -74,13 +75,13 @@ int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url, const char *cmd, const struct spa_dict *headers, const char *content_type, const void *content, size_t content_length, - void (*reply) (void *user_data, int status, const struct spa_dict *headers), + int (*reply) (void *user_data, int status, const struct spa_dict *headers), void *user_data); int pw_rtsp_client_send(struct pw_rtsp_client *client, const char *cmd, const struct spa_dict *headers, const char *content_type, const char *content, - void (*reply) (void *user_data, int status, const struct spa_dict *headers), + int (*reply) (void *user_data, int status, const struct spa_dict *headers), void *user_data);
View file
pipewire-0.3.60.tar.gz/src/modules/module-rtp
Added
+(directory)
View file
pipewire-0.3.60.tar.gz/src/modules/module-rtp-sink.c
Added
@@ -0,0 +1,944 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include <limits.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#include <netinet/ip.h> +#include <net/if.h> +#include <ctype.h> + +#include <spa/param/audio/format-utils.h> +#include <spa/utils/hook.h> +#include <spa/utils/ringbuffer.h> +#include <spa/utils/json.h> +#include <spa/debug/pod.h> + +#include <pipewire/pipewire.h> +#include <pipewire/private.h> + +#include <module-rtp/sap.h> +#include <module-rtp/rtp.h> + + +/** \page page_module_rtp_sink PipeWire Module: RTP sink + * + * The `rtp-sink` module creates a PipeWire sink that sends audio + * RTP packets. + * + * ## Module Options + * + * Options specific to the behavior of this module + * + * - `sap.ip = <str>`: IP address of the SAP messages, default "224.0.0.56" + * - `sap.port = <int>`: port of the SAP messages, default 9875 + * - `source.ip =<str>`: source IP address, default "0.0.0.0" + * - `destination.ip =<str>`: destination IP address, default "224.0.0.56" + * - `destination.port =<int>`: destination port, default random beteen 46000 and 47024 + * - `local.ifname = <str>`: interface name to use + * - `net.mtu = <int>`: MTU to use, default 1280 + * - `net.ttl = <int>`: TTL to use, default 1 + * - `net.loop = <bool>`: loopback multicast, default false + * - `sess.name = <str>`: a session name + * - `stream.props = {}`: properties to be passed to the stream + * + * ## General options + * + * Options with well-known behavior: + * + * - \ref PW_KEY_REMOTE_NAME + * - \ref PW_KEY_AUDIO_FORMAT + * - \ref PW_KEY_AUDIO_RATE + * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_POSITION + * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_GROUP + * - \ref PW_KEY_NODE_LATENCY + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_MEDIA_CLASS + * + * ## Example configuration + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-rtp-sink + * args = { + * #sap.ip = "224.0.0.56" + * #sap.port = 9875 + * #source.ip = "0.0.0.0" + * #destination.ip = "224.0.0.56" + * #destination.port = 46000 + * #local.ifname = "eth0" + * #net.mtu = 1280 + * #net.ttl = 1 + * #net.loop = false + * #sess.name = "PipeWire RTP stream" + * #audio.format = "S16BE" + * #audio.rate = 48000 + * #audio.channels = 2 + * #audio.position = FL FR + * stream.props = { + * node.name = "rtp-sink" + * } + * } + *} + * + *\endcode + * + * \since 0.3.60 + */ + +#define NAME "rtp-sink" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +#define SAP_INTERVAL_SEC 5 +#define SAP_MIME_TYPE "application/sdp" + +#define BUFFER_SIZE (1u<<20) +#define BUFFER_MASK (BUFFER_SIZE-1) + +#define DEFAULT_SAP_IP "224.0.0.56" +#define DEFAULT_SAP_PORT 9875 + +#define DEFAULT_FORMAT "S16BE" +#define DEFAULT_RATE 48000 +#define DEFAULT_CHANNELS 2 +#define DEFAULT_POSITION " FL FR " + +#define DEFAULT_PORT 46000 +#define DEFAULT_SOURCE_IP "0.0.0.0" +#define DEFAULT_DESTINATION_IP "224.0.0.56" +#define DEFAULT_TTL 1 +#define DEFAULT_MTU 1280 +#define DEFAULT_LOOP false + +#define DEFAULT_MIN_PTIME 2 +#define DEFAULT_MAX_PTIME 20 + +#define USAGE "sap.ip=<SAP IP address to send announce, default:"DEFAULT_SAP_IP"> " \ + "sap.port=<SAP port to send on, default:"SPA_STRINGIFY(DEFAULT_SAP_PORT)"> " \ + "source.ip=<source IP address, default:"DEFAULT_SOURCE_IP"> " \ + "destination.ip=<destination IP address, default:"DEFAULT_DESTINATION_IP"> " \ + "local.ifname=<local interface name to use> " \ + "net.mtu=<desired MTU, default:"SPA_STRINGIFY(DEFAULT_MTU)"> " \ + "net.ttl=<desired TTL, default:"SPA_STRINGIFY(DEFAULT_TTL)"> " \ + "net.loop=<desired loopback, default:"SPA_STRINGIFY(DEFAULT_LOOP)"> " \ + "sess.name=<a name for the session> " \ + "audio.format=<format, default:"DEFAULT_FORMAT"> " \ + "audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> " \ + "audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> "\ + "audio.position=<channel map, default:"DEFAULT_POSITION"> " \ + "stream.props= { key=value ... }" + +static const struct spa_dict_item module_info = { + { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, + { PW_KEY_MODULE_DESCRIPTION, "RTP Sink" }, + { PW_KEY_MODULE_USAGE, USAGE }, + { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, +}; + +static const struct format_info { + uint32_t format; + uint32_t size; + const char *mime; +} format_info = { + { SPA_AUDIO_FORMAT_U8, 1, "L8" }, + { SPA_AUDIO_FORMAT_ALAW, 1, "PCMA" }, + { SPA_AUDIO_FORMAT_ULAW, 1, "PCMU" }, + { SPA_AUDIO_FORMAT_S16_BE, 2, "L16" }, + { SPA_AUDIO_FORMAT_S24_BE, 3, "L24" }, +}; + +static const struct format_info *find_format_info(uint32_t format) +{ + SPA_FOR_EACH_ELEMENT_VAR(format_info, f) + if (f->format == format) + return f; + return NULL; +} + +struct impl { + struct pw_impl_module *module; + struct spa_hook module_listener; + struct pw_properties *props; + struct pw_context *module_context; + + struct pw_loop *loop; + + struct pw_core *core; + struct spa_hook core_listener; + struct spa_hook core_proxy_listener;
View file
pipewire-0.3.60.tar.gz/src/modules/module-rtp-source.c
Added
@@ -0,0 +1,1101 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include <limits.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <net/if.h> +#include <ctype.h> + +#include <spa/param/audio/format-utils.h> +#include <spa/utils/hook.h> +#include <spa/utils/ringbuffer.h> +#include <spa/utils/dll.h> +#include <spa/debug/mem.h> + +#include <pipewire/pipewire.h> +#include <pipewire/private.h> + +#include <module-rtp/sap.h> +#include <module-rtp/rtp.h> + + +/** \page page_module_rtp_source PipeWire Module: RTP source + * + * The `rtp-source` module creates a PipeWire source that receives audio + * RTP packets. + * + * ## Module Options + * + * Options specific to the behavior of this module + * + * - `sap.ip = <str>`: IP address of the SAP messages, default "224.0.0.56" + * - `sap.port = <str>`: port of the SAP messages, default 9875 + * - `local.ifname = <str>`: interface name to use + * - `sess.latency.msec = <str>`: target network latency in milliseconds, default 100 + * - `stream.props = {}`: properties to be passed to the stream + * + * ## General options + * + * Options with well-known behavior: + * + * - \ref PW_KEY_NODE_NAME + * - \ref PW_KEY_NODE_DESCRIPTION + * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_MEDIA_CLASS + * + * ## Example configuration + *\code{.unparsed} + * context.modules = + * { name = libpipewire-module-rtp-source + * args = { + * #sap.ip = 224.0.0.56 + * #sap.port = 9875 + * #local.ifname = eth0 + * sess.latency.msec = 100 + * stream.props = { + * node.name = "rtp-source" + * #media.class = "Audio/Source" + * } + * } + * } + * + *\endcode + * + * \since 0.3.60 + */ + +#define NAME "rtp-source" + +PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); +#define PW_LOG_TOPIC_DEFAULT mod_topic + +#define SAP_MIME_TYPE "application/sdp" + +#define ERROR_MSEC 2 +#define MAX_SESSIONS 16 +#define CLEANUP_INTERVAL_SEC 20 + +#define DEFAULT_SAP_IP "224.0.0.56" +#define DEFAULT_SAP_PORT 9875 +#define DEFAULT_SESS_LATENCY 100 + +#define BUFFER_SIZE (1u<<22) +#define BUFFER_MASK (BUFFER_SIZE-1) + +#define USAGE "sap.ip=<SAP IP address to listen on, default "DEFAULT_SAP_IP"> " \ + "sap.port=<SAP port to listen on, default "SPA_STRINGIFY(DEFAULT_SAP_PORT)"> " \ + "local.ifname=<local interface name to use> " \ + "sess.latency.msec=<target network latency, default "SPA_STRINGIFY(DEFAULT_SESS_LATENCY)"> " \ + "stream.props= { key=value ... }" + +static const struct spa_dict_item module_info = { + { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, + { PW_KEY_MODULE_DESCRIPTION, "RTP Source" }, + { PW_KEY_MODULE_USAGE, USAGE }, + { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, +}; + +struct impl { + struct pw_impl_module *module; + struct spa_hook module_listener; + struct pw_properties *props; + struct pw_context *module_context; + + struct pw_loop *loop; + struct pw_loop *data_loop; + + struct pw_core *core; + struct spa_hook core_listener; + struct spa_hook core_proxy_listener; + + struct spa_source *timer; + struct spa_source *sap_source; + + struct pw_properties *stream_props; + + unsigned int do_disconnect:1; + + char *ifname; + char *sap_ip; + int sap_port; + int sess_latency_msec; + + struct spa_list sessions; + uint32_t n_sessions; +}; + +static const struct format_info { + uint32_t format; + uint32_t size; + const char *mime; +} format_info = { + { SPA_AUDIO_FORMAT_U8, 1, "L8" }, + { SPA_AUDIO_FORMAT_ALAW, 1, "PCMA" }, + { SPA_AUDIO_FORMAT_ULAW, 1, "PCMU" }, + { SPA_AUDIO_FORMAT_S16_BE, 2, "L16" }, + { SPA_AUDIO_FORMAT_S24_BE, 3, "L24" }, +}; + +static const struct format_info *find_format_info(const char *mime) +{ + SPA_FOR_EACH_ELEMENT_VAR(format_info, f) + if (spa_streq(f->mime, mime)) + return f; + return NULL; +} + +struct sdp_info { + uint16_t hash; + + char origin128; + char session256; + + struct sockaddr_storage sa; + socklen_t salen; + + uint16_t port; + uint8_t payload; + + const struct format_info *format_info; + struct spa_audio_info_raw info; + uint32_t stride; +}; + +struct session { + struct impl *impl; + struct spa_list link; + + uint64_t timestamp; + + struct sdp_info info; +
View file
pipewire-0.3.60.tar.gz/src/modules/module-rtp/rtp.h
Added
@@ -0,0 +1,78 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIPEWIRE_RTP_H +#define PIPEWIRE_RTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct rtp_header { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned cc:4; + unsigned x:1; + unsigned p:1; + unsigned v:2; + + unsigned pt:7; + unsigned m:1; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned v:2; + unsigned p:1; + unsigned x:1; + unsigned cc:4; + + unsigned m:1; + unsigned pt:7; +#else +#error "Unknown byte order" +#endif + uint16_t sequence_number; + uint32_t timestamp; + uint32_t ssrc; + uint32_t csrc0; +} __attribute__ ((packed)); + +struct rtp_payload { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned frame_count:4; + unsigned rfa0:1; + unsigned is_last_fragment:1; + unsigned is_first_fragment:1; + unsigned is_fragmented:1; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned is_fragmented:1; + unsigned is_first_fragment:1; + unsigned is_last_fragment:1; + unsigned rfa0:1; + unsigned frame_count:4; +#endif +} __attribute__ ((packed)); + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_RTP_H */
View file
pipewire-0.3.60.tar.gz/src/modules/module-rtp/sap.h
Added
@@ -0,0 +1,58 @@ +/* PipeWire + * + * Copyright © 2022 Wim Taymans <wim.taymans@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIPEWIRE_SAP_H +#define PIPEWIRE_SAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct sap_header { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned c:1; + unsigned e:1; + unsigned t:1; + unsigned r:1; + unsigned a:1; + unsigned v:3; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned v:3; + unsigned a:1; + unsigned r:1; + unsigned t:1; + unsigned e:1; + unsigned c:1; +#else +#error "Unknown byte order" +#endif + uint8_t auth_len; + uint16_t msg_id_hash; +} __attribute__ ((packed)); + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_SAP_H */
View file
pipewire-0.3.59.tar.gz/src/modules/module-x11-bell.c -> pipewire-0.3.60.tar.gz/src/modules/module-x11-bell.c
Changed
@@ -109,7 +109,7 @@ if (sample == NULL) sample = "bell-window-system"; - pw_log_debug("play sample %s", sample); + pw_log_info("play sample %s", sample); if ((res = ca_context_create(&ca)) < 0) { pw_log_error("canberra context create error: %s", ca_strerror(res));
View file
pipewire-0.3.59.tar.gz/src/modules/module-zeroconf-discover.c -> pipewire-0.3.60.tar.gz/src/modules/module-zeroconf-discover.c
Changed
@@ -54,7 +54,10 @@ * audio to/from remote PulseAudio servers. It also works with * module-protocol-pulse. * - * This module has no options. + * ## Module Options + * + * - `pulse.latency`: the latency to end-to-end latency in milliseconds to + * maintain (Default 200ms). * * ## Example configuration * @@ -72,7 +75,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic -#define MODULE_USAGE " " +#define MODULE_USAGE "pulse.latency=<latency in msec> " static const struct spa_dict_item module_props = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, @@ -348,6 +351,9 @@ _("%s on %s"), desc, fqdn); } + if ((str = pw_properties_get(impl->properties, "pulse.latency")) != NULL) + pw_properties_set(props, "pulse.latency", str); + if ((f = open_memstream(&args, &size)) == NULL) { pw_log_error("Can't open memstream: %m"); goto done;
View file
pipewire-0.3.59.tar.gz/src/pipewire/buffers.c -> pipewire-0.3.60.tar.gz/src/pipewire/buffers.c
Changed
@@ -255,6 +255,12 @@ struct port input = { innode, SPA_DIRECTION_INPUT, in_port_id }; int res; + if (flags & PW_BUFFERS_FLAG_IN_PRIORITY) { + struct port tmp = output; + output = input; + input = tmp; + } + res = param_filter(result, &input, &output, SPA_PARAM_Buffers, &b); if (res < 0) { pw_context_debug_port_params(context, input.node, input.direction,
View file
pipewire-0.3.59.tar.gz/src/pipewire/buffers.h -> pipewire-0.3.60.tar.gz/src/pipewire/buffers.h
Changed
@@ -48,6 +48,7 @@ #define PW_BUFFERS_FLAG_SHARED (1<<1) /**< buffers can be shared */ #define PW_BUFFERS_FLAG_DYNAMIC (1<<2) /**< buffers have dynamic data */ #define PW_BUFFERS_FLAG_SHARED_MEM (1<<3) /**< buffers need shared memory */ +#define PW_BUFFERS_FLAG_IN_PRIORITY (1<<4) /**< input parameters have priority */ struct pw_buffers { struct pw_memblock *mem; /**< allocated buffer memory */
View file
pipewire-0.3.59.tar.gz/src/pipewire/context.c -> pipewire-0.3.60.tar.gz/src/pipewire/context.c
Changed
@@ -968,13 +968,15 @@ return fa < fb ? -1 : (fa > fb ? 1 : 0); } -static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate) +static uint32_t find_best_rate(uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best) { uint32_t i; - for (i = 0; i < n_rates; i++) - if (ratesi == rate) - return true; - return false; + for (i = 0; i < n_rates; i++) { + if (SPA_ABS((int32_t)rate - (int32_t)ratesi) < + SPA_ABS((int32_t)rate - (int32_t)best)) + best = ratesi; + } + return best; } /* here we evaluate the complete state of the graph. @@ -1187,10 +1189,9 @@ * Start with the default rate. If the desired rate is * allowed, switch to it */ target_rate = def_rate; - if (rate.denom != 0 && rate.num == 1) { - if (rates_contains(rates, n_rates, rate.denom)) - target_rate = rate.denom; - } + if (rate.denom != 0 && rate.num == 1) + target_rate = find_best_rate(rates, n_rates, + rate.denom, target_rate); } if (target_rate != current_rate) {
View file
pipewire-0.3.59.tar.gz/src/pipewire/filter.c -> pipewire-0.3.60.tar.gz/src/pipewire/filter.c
Changed
@@ -419,16 +419,16 @@ spa_list_for_each(p, param_list, link) { struct spa_pod *param; - result.index = result.next++; - if (result.index < start) - continue; - param = p->param; if (param == NULL || p->id != id) continue; found = true; + result.index = result.next++; + if (result.index < start) + continue; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); if (spa_pod_filter(&b.b, &result.param, param, filter) == 0) { spa_node_emit_result(&d->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result);
View file
pipewire-0.3.59.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-device.c
Changed
@@ -235,7 +235,7 @@ if (d->end != -1) { if (d->pi && d->data.cache) { - pw_param_update(&impl->param_list, &impl->pending_list); + pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL); d->pi->user = 1; d->pi = NULL; } @@ -281,8 +281,8 @@ if (d->cache) { pw_log_debug("%p: add param %d", impl, r->id); if (d->count++ == 0) - pw_param_add(&impl->pending_list, r->id, NULL); - pw_param_add(&impl->pending_list, r->id, r->param); + pw_param_add(&impl->pending_list, seq, r->id, NULL); + pw_param_add(&impl->pending_list, seq, r->id, r->param); } break; } @@ -333,10 +333,10 @@ result.next = 0; spa_list_for_each(p, &impl->param_list, link) { - result.index = result.next++; if (p->id != param_id) continue; + result.index = result.next++; if (result.index < index) continue; @@ -364,7 +364,7 @@ spa_hook_remove(&listener); if (!SPA_RESULT_IS_ASYNC(res) && user_data.cache) { - pw_param_update(&impl->param_list, &impl->pending_list); + pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL); pi->user = 1; } }
View file
pipewire-0.3.59.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-link.c
Changed
@@ -517,6 +517,9 @@ if (output->node->remote || input->node->remote) alloc_flags |= PW_BUFFERS_FLAG_SHARED_MEM; + if (output->node->driver) + alloc_flags |= PW_BUFFERS_FLAG_IN_PRIORITY; + /* if output port can alloc buffers, alloc skeleton buffers */ if (SPA_FLAG_IS_SET(out_flags, SPA_PORT_FLAG_CAN_ALLOC_BUFFERS)) { SPA_FLAG_SET(alloc_flags, PW_BUFFERS_FLAG_NO_MEM); @@ -619,7 +622,8 @@ pw_log_debug("%p: activate activated:%d state:%s", this, impl->activated, pw_link_state_as_string(this->info.state)); - if (impl->activated || !this->prepared || !impl->inode->added || !impl->onode->active) + if (impl->activated || !this->prepared || !impl->inode->active || + !impl->inode->added || !impl->onode->active) return 0; if (!impl->io_set) {
View file
pipewire-0.3.59.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-node.c
Changed
@@ -158,19 +158,6 @@ this->rt.driver_target.node = NULL; } -static int -do_node_remove(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) -{ - struct pw_impl_node *this = user_data; - if (this->source.loop != NULL) { - spa_loop_remove_source(loop, &this->source); - remove_node(this); - } - this->added = false; - return 0; -} - static void node_deactivate(struct pw_impl_node *this) { struct pw_impl_port *port; @@ -185,7 +172,6 @@ spa_list_for_each(link, &port->links, output_link) pw_impl_link_deactivate(link); } - pw_loop_invoke(this->data_loop, do_node_remove, 1, NULL, 0, true, this); } static int idle_node(struct pw_impl_node *this) @@ -354,6 +340,19 @@ return 0; } +static int +do_node_remove(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_impl_node *this = user_data; + if (this->source.loop != NULL) { + spa_loop_remove_source(loop, &this->source); + remove_node(this); + } + this->added = false; + return 0; +} + static void node_update_state(struct pw_impl_node *node, enum pw_node_state state, int res, char *error) { struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); @@ -364,20 +363,29 @@ pw_log_debug("%p: start node driving:%d driver:%d added:%d", node, node->driving, node->driver, node->added); + if (res >= 0) { + pw_loop_invoke(node->data_loop, do_node_add, 1, NULL, 0, true, node); + } if (node->driving && node->driver) { res = spa_node_send_command(node->node, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start)); if (res < 0) { state = PW_NODE_STATE_ERROR; error = spa_aprintf("Start error: %s", spa_strerror(res)); + pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node); } } if (res >= 0) { - pw_loop_invoke(node->data_loop, do_node_add, 1, NULL, 0, true, node); /* now activate the inputs */ node_activate_inputs(node); } break; + case PW_NODE_STATE_IDLE: + case PW_NODE_STATE_SUSPENDED: + case PW_NODE_STATE_ERROR: + if (state != PW_NODE_STATE_IDLE || impl->pause_on_idle) + pw_loop_invoke(node->data_loop, do_node_remove, 1, NULL, 0, true, node); + break; default: break; } @@ -1624,8 +1632,13 @@ struct pw_node_target *t; struct pw_impl_port *p; - pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d", node, - node->driver, node->exported, driver, status); + pw_log_trace_fp("%p: ready driver:%d exported:%d %p status:%d added:%d", node, + node->driver, node->exported, driver, status, node->added); + + if (!node->added) { + pw_log_warn("%p: ready non-active node", node); + return -EIO; + } if (SPA_UNLIKELY(node == driver)) { struct pw_node_activation *a = node->rt.activation; @@ -1954,8 +1967,8 @@ d->callback(d->data, seq, r->id, r->index, r->next, r->param); if (d->cache) { if (d->count++ == 0) - pw_param_add(&impl->pending_list, r->id, NULL); - pw_param_add(&impl->pending_list, r->id, r->param); + pw_param_add(&impl->pending_list, seq, r->id, NULL); + pw_param_add(&impl->pending_list, seq, r->id, r->param); } } break; @@ -2007,10 +2020,10 @@ result.next = 0; spa_list_for_each(p, &impl->param_list, link) { - result.index = result.next++; if (p->id != param_id) continue; + result.index = result.next++; if (result.index < index) continue; @@ -2039,7 +2052,7 @@ spa_hook_remove(&listener); if (user_data.cache) { - pw_param_update(&impl->param_list, &impl->pending_list); + pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL); pi->user = 1; } }
View file
pipewire-0.3.59.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.60.tar.gz/src/pipewire/impl-port.c
Changed
@@ -1199,8 +1199,8 @@ d->callback(d->data, seq, r->id, r->index, r->next, r->param); if (d->cache) { if (d->count++ == 0) - pw_param_add(&impl->pending_list, r->id, NULL); - pw_param_add(&impl->pending_list, r->id, r->param); + pw_param_add(&impl->pending_list, seq, r->id, NULL); + pw_param_add(&impl->pending_list, seq, r->id, r->param); } } break; @@ -1253,10 +1253,10 @@ result.next = 0; spa_list_for_each(p, &impl->param_list, link) { - result.index = result.next++; if (p->id != param_id) continue; + result.index = result.next++; if (result.index < index) continue; @@ -1286,7 +1286,7 @@ spa_hook_remove(&listener); if (user_data.cache) { - pw_param_update(&impl->param_list, &impl->pending_list); + pw_param_update(&impl->param_list, &impl->pending_list, 0, NULL); pi->user = 1; } }
View file
pipewire-0.3.59.tar.gz/src/pipewire/introspect.c -> pipewire-0.3.60.tar.gz/src/pipewire/introspect.c
Changed
@@ -210,7 +210,7 @@ info->props = pw_spa_dict_copy(update->props); } if (update->change_mask & PW_NODE_CHANGE_MASK_PARAMS) { - uint32_t i, user, n_params = update->n_params; + uint32_t i, n_params = update->n_params; void *np; np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info)); @@ -222,15 +222,18 @@ info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { - user = reset ? 0 : info->paramsi.user; - if (info->paramsi.flags != update->paramsi.flags) - user++; - info->paramsi = update->paramsi; - info->paramsi.user = user; + info->paramsi.id = update->paramsi.id; + if (reset) + info->paramsi.user = 0; + if (info->paramsi.flags != update->paramsi.flags) { + info->paramsi.flags = update->paramsi.flags; + info->paramsi.user++; + } } info->n_params = n_params; for (; i < info->n_params; i++) { - info->paramsi = update->paramsi; + info->paramsi.id = update->paramsi.id; + info->paramsi.flags = update->paramsi.flags; info->paramsi.user = 1; } } @@ -280,7 +283,7 @@ info->props = pw_spa_dict_copy(update->props); } if (update->change_mask & PW_PORT_CHANGE_MASK_PARAMS) { - uint32_t i, user, n_params = update->n_params; + uint32_t i, n_params = update->n_params; void *np; np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info)); @@ -292,15 +295,18 @@ info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { - user = reset ? 0 : info->paramsi.user; - if (info->paramsi.flags != update->paramsi.flags) - user++; - info->paramsi = update->paramsi; - info->paramsi.user = user; + info->paramsi.id = update->paramsi.id; + if (reset) + info->paramsi.user = 0; + if (info->paramsi.flags != update->paramsi.flags) { + info->paramsi.flags = update->paramsi.flags; + info->paramsi.user++; + } } info->n_params = n_params; for (; i < info->n_params; i++) { - info->paramsi = update->paramsi; + info->paramsi.id = update->paramsi.id; + info->paramsi.flags = update->paramsi.flags; info->paramsi.user = 1; } } @@ -440,7 +446,7 @@ info->props = pw_spa_dict_copy(update->props); } if (update->change_mask & PW_DEVICE_CHANGE_MASK_PARAMS) { - uint32_t i, user, n_params = update->n_params; + uint32_t i, n_params = update->n_params; void *np; np = pw_reallocarray(info->params, n_params, sizeof(struct spa_param_info)); @@ -452,15 +458,18 @@ info->params = np; for (i = 0; i < SPA_MIN(info->n_params, n_params); i++) { - user = reset ? 0 : info->paramsi.user; - if (info->paramsi.flags != update->paramsi.flags) - user++; - info->paramsi = update->paramsi; - info->paramsi.user = user; + info->paramsi.id = update->paramsi.id; + if (reset) + info->paramsi.user = 0; + if (info->paramsi.flags != update->paramsi.flags) { + info->paramsi.flags = update->paramsi.flags; + info->paramsi.user++; + } } info->n_params = n_params; for (; i < info->n_params; i++) { - info->paramsi = update->paramsi; + info->paramsi.id = update->paramsi.id; + info->paramsi.flags = update->paramsi.flags; info->paramsi.user = 1; } }
View file
pipewire-0.3.59.tar.gz/src/pipewire/private.h -> pipewire-0.3.60.tar.gz/src/pipewire/private.h
Changed
@@ -104,6 +104,7 @@ struct pw_param { uint32_t id; + int32_t seq; struct spa_list link; struct spa_pod *param; }; @@ -123,7 +124,7 @@ return count; } -static inline struct pw_param *pw_param_add(struct spa_list *params, +static inline struct pw_param *pw_param_add(struct spa_list *params, int32_t seq, uint32_t id, const struct spa_pod *param) { struct pw_param *p; @@ -140,6 +141,7 @@ return NULL; p->id = id; + p->seq = seq; if (param != NULL) { p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod); memcpy(p->param, param, SPA_POD_SIZE(param)); @@ -151,10 +153,22 @@ return p; } -static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list) +static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list, + uint32_t n_params, struct spa_param_info *params) { - struct pw_param *p; + struct pw_param *p, *t; + uint32_t i; + for (i = 0; i < n_params; i++) { + spa_list_for_each_safe(p, t, pending_list, link) { + if (p->id == paramsi.id && + p->seq != paramsi.seq && + p->param != NULL) { + spa_list_remove(&p->link); + free(p); + } + } + } spa_list_consume(p, pending_list, link) { spa_list_remove(&p->link); if (p->param == NULL) {
View file
pipewire-0.3.59.tar.gz/src/pipewire/stream.c -> pipewire-0.3.60.tar.gz/src/pipewire/stream.c
Changed
@@ -544,16 +544,16 @@ spa_list_for_each(p, &d->param_list, link) { struct spa_pod *param; - result.index = result.next++; - if (result.index < start) - continue; - param = p->param; if (param == NULL || p->id != id) continue; found = true; + result.index = result.next++; + if (result.index < start) + continue; + spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 4096); if (spa_pod_filter(&b.b, &result.param, param, filter) == 0) { spa_node_emit_result(&d->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); @@ -2330,7 +2330,7 @@ struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); pw_loop_invoke(impl->context->data_loop, drain ? do_drain : do_flush, 1, NULL, 0, true, impl); - if (!drain) + if (!drain && impl->node != NULL) spa_node_send_command(impl->node->node, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Flush)); return 0;
View file
pipewire-0.3.59.tar.gz/src/pipewire/thread.c -> pipewire-0.3.60.tar.gz/src/pipewire/thread.c
Changed
@@ -116,6 +116,17 @@ *max = sched_get_priority_max(SCHED_OTHER); return 0; } +static int impl_acquire_rt(void *object, struct spa_thread *thread, int priority) +{ + pw_log_warn("acquire_rt thread:%p prio:%d not implemented", thread, priority); + return -ENOTSUP; +} + +static int impl_drop_rt(void *object, struct spa_thread *thread) +{ + pw_log_warn("drop_rt thread:%p not implemented", thread); + return -ENOTSUP; +} static struct { struct spa_thread_utils utils; @@ -128,7 +139,9 @@ { SPA_VERSION_THREAD_UTILS_METHODS, .create = impl_create, .join = impl_join, - .get_rt_range = impl_get_rt_range + .get_rt_range = impl_get_rt_range, + .acquire_rt = impl_acquire_rt, + .drop_rt = impl_drop_rt, } };
View file
pipewire-0.3.59.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.60.tar.gz/src/tools/pw-cat.c
Changed
@@ -174,20 +174,18 @@ static const struct format_info *format_info_by_name(const char *str) { - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) - if (spa_streq(str, format_infoi.name)) - return &format_infoi; + SPA_FOR_EACH_ELEMENT_VAR(format_info, i) + if (spa_streq(str, i->name)) + return i; return NULL; } static const struct format_info *format_info_by_sf_format(int format) { - uint32_t i; int sub_type = (format & SF_FORMAT_SUBMASK); - for (i = 0; i < SPA_N_ELEMENTS(format_info); i++) - if (format_infoi.sf_format == sub_type) - return &format_infoi; + SPA_FOR_EACH_ELEMENT_VAR(format_info, i) + if (i->sf_format == sub_type) + return i; return NULL; } @@ -431,10 +429,10 @@ int i, nch; char **ch; - for (i = 0; i < (int) SPA_N_ELEMENTS(maps); i++) { - if (spa_streq(mapsi.name, channel_map)) { - map->n_channels = mapsi.channels; - spa_memcpy(map->channels, &mapsi.values, + SPA_FOR_EACH_ELEMENT_VAR(maps, m) { + if (spa_streq(m->name, channel_map)) { + map->n_channels = m->channels; + spa_memcpy(map->channels, &m->values, map->n_channels * sizeof(unsigned int)); return 0; } @@ -1589,17 +1587,16 @@ case TYPE_DSD: { struct spa_audio_info_dsd info; - size_t i; spa_zero(info); info.channels = data.dsf.info.channels; info.rate = data.dsf.info.rate / 8; - for (i = 0; i < SPA_N_ELEMENTS(dsd_layouts); i++) { - if (dsd_layoutsi.type != data.dsf.info.channel_type) + SPA_FOR_EACH_ELEMENT_VAR(dsd_layouts, i) { + if (i->type != data.dsf.info.channel_type) continue; - info.channels = dsd_layoutsi.info.n_channels; - memcpy(info.position, dsd_layoutsi.info.position, + info.channels = i->info.n_channels; + memcpy(info.position, i->info.position, info.channels * sizeof(uint32_t)); } params0 = spa_format_audio_dsd_build(&b, SPA_PARAM_EnumFormat, &info);
View file
pipewire-0.3.59.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.60.tar.gz/src/tools/pw-cli.c
Changed
@@ -262,14 +262,11 @@ static bool do_help(struct data *data, const char *cmd, char *args, char **error) { - size_t i; - printf("Available commands:\n"); - for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) { + SPA_FOR_EACH_ELEMENT_VAR(command_list, c) { char cmd256; - snprintf(cmd, sizeof(cmd), "%s | %s", - command_listi.name, command_listi.alias); - printf("\t%-20.20s\t%s\n", cmd, command_listi.description); + snprintf(cmd, sizeof(cmd), "%s | %s", c->name, c->alias); + printf("\t%-20.20s\t%s\n", cmd, c->description); } return true; } @@ -1312,11 +1309,10 @@ static const struct class *find_class(const char *type, uint32_t version) { - size_t i; - for (i = 0; i < SPA_N_ELEMENTS(classes); i++) { - if (spa_streq(classesi->type, type) && - classesi->version <= version) - return classesi; + SPA_FOR_EACH_ELEMENT_VAR(classes, c) { + if (spa_streq((*c)->type, type) && + (*c)->version <= version) + return *c; } return NULL; } @@ -2110,7 +2106,6 @@ { char *a2; int n; - size_t i; char *p, *cmd, *args; if ((p = strchr(buf, '#'))) @@ -2128,10 +2123,10 @@ cmd = a0; args = n > 1 ? a1 : ""; - for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) { - if (spa_streq(command_listi.name, cmd) || - spa_streq(command_listi.alias, cmd)) { - return command_listi.func(data, cmd, args, error); + SPA_FOR_EACH_ELEMENT_VAR(command_list, c) { + if (spa_streq(c->name, cmd) || + spa_streq(c->alias, cmd)) { + return c->func(data, cmd, args, error); } } *error = spa_aprintf("Command \"%s\" does not exist. Type 'help' for usage.", cmd); @@ -2231,13 +2226,13 @@ return matches; } -static void readline_init() +static void readline_init(void) { rl_attempted_completion_function = readline_command_completion; rl_callback_handler_install(">> ", input_process_line); } -static void readline_cleanup() +static void readline_cleanup(void) { rl_callback_handler_remove(); }
View file
pipewire-0.3.59.tar.gz/src/tools/pw-dot.c -> pipewire-0.3.60.tar.gz/src/tools/pw-dot.c
Changed
@@ -94,7 +94,7 @@ struct spa_hook object_listener; }; -static char *dot_str_new() +static char *dot_str_new(void) { return strdup(""); }
View file
pipewire-0.3.59.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.60.tar.gz/src/tools/pw-dump.c
Changed
@@ -88,6 +88,7 @@ struct param { uint32_t id; + int32_t seq; struct spa_list link; struct spa_pod *param; }; @@ -116,6 +117,8 @@ const struct class *class; void *info; + struct spa_param_info *params; + uint32_t n_params; int changed; struct spa_list param_list; @@ -148,7 +151,8 @@ return count; } -static struct param *add_param(struct spa_list *params, uint32_t id, const struct spa_pod *param) +static struct param *add_param(struct spa_list *params, int seq, + uint32_t id, const struct spa_pod *param) { struct param *p; @@ -165,6 +169,7 @@ return NULL; p->id = id; + p->seq = seq; if (param != NULL) { p->param = SPA_PTROFF(p, sizeof(*p), struct spa_pod); memcpy(p->param, param, SPA_POD_SIZE(param)); @@ -187,17 +192,30 @@ return NULL; } -static void object_update_params(struct object *o) +static void object_update_params(struct spa_list *param_list, struct spa_list *pending_list, + uint32_t n_params, struct spa_param_info *params) { - struct param *p; + struct param *p, *t; + uint32_t i; + + for (i = 0; i < n_params; i++) { + spa_list_for_each_safe(p, t, pending_list, link) { + if (p->id == paramsi.id && + p->seq != paramsi.seq && + p->param != NULL) { + spa_list_remove(&p->link); + free(p); + } + } + } - spa_list_consume(p, &o->pending_list, link) { + spa_list_consume(p, pending_list, link) { spa_list_remove(&p->link); if (p->param == NULL) { - clear_params(&o->param_list, p->id); + clear_params(param_list, p->id); free(p); } else { - spa_list_append(&o->param_list, &p->link); + spa_list_append(param_list, &p->link); } } } @@ -587,9 +605,11 @@ struct object *o = data; int changed = 0; - pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); + pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); - info = o->info = pw_client_info_update(o->info, info); + info = o->info = pw_client_info_update(o->info, info); + if (info == NULL) + return; if (info->change_mask & PW_CLIENT_CHANGE_MASK_PROPS) changed++; @@ -644,12 +664,14 @@ static void module_event_info(void *data, const struct pw_module_info *info) { - struct object *o = data; + struct object *o = data; int changed = 0; - pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); + pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); - info = o->info = pw_module_info_update(o->info, info); + info = o->info = pw_module_info_update(o->info, info); + if (info == NULL) + return; if (info->change_mask & PW_MODULE_CHANGE_MASK_PROPS) changed++; @@ -704,12 +726,14 @@ static void factory_event_info(void *data, const struct pw_factory_info *info) { - struct object *o = data; + struct object *o = data; int changed = 0; - pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); + pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); - info = o->info = pw_factory_info_update(o->info, info); + info = o->info = pw_factory_info_update(o->info, info); + if (info == NULL) + return; if (info->change_mask & PW_FACTORY_CHANGE_MASK_PROPS) changed++; @@ -765,10 +789,16 @@ { struct object *o = data; uint32_t i, changed = 0; + int res; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); info = o->info = pw_device_info_update(o->info, info); + if (info == NULL) + return; + + o->params = info->params; + o->n_params = info->n_params; if (info->change_mask & PW_DEVICE_CHANGE_MASK_PROPS) changed++; @@ -782,12 +812,14 @@ info->paramsi.user = 0; changed++; - clear_params(&o->pending_list, id); + add_param(&o->pending_list, 0, id, NULL); if (!(info->paramsi.flags & SPA_PARAM_INFO_READ)) continue; - pw_device_enum_params((struct pw_device*)o->proxy, - 0, id, 0, -1, NULL); + res = pw_device_enum_params((struct pw_device*)o->proxy, + ++info->paramsi.seq, id, 0, -1, NULL); + if (SPA_RESULT_IS_ASYNC(res)) + info->paramsi.seq = res; } } if (changed) { @@ -801,7 +833,7 @@ const struct spa_pod *param) { struct object *o = data; - add_param(&o->pending_list, id, param); + add_param(&o->pending_list, seq, id, param); } static const struct pw_device_events device_events = { @@ -859,10 +891,16 @@ { struct object *o = data; uint32_t i, changed = 0; + int res; pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->id, info->change_mask); info = o->info = pw_node_info_update(o->info, info); + if (info == NULL) + return; + + o->params = info->params; + o->n_params = info->n_params; if (info->change_mask & PW_NODE_CHANGE_MASK_STATE) changed++; @@ -879,12 +917,14 @@ info->paramsi.user = 0; changed++; - add_param(&o->pending_list, id, NULL); + add_param(&o->pending_list, 0, id, NULL); if (!(info->paramsi.flags & SPA_PARAM_INFO_READ)) continue; - pw_node_enum_params((struct pw_node*)o->proxy, - 0, id, 0, -1, NULL); + res = pw_node_enum_params((struct pw_node*)o->proxy, + ++info->paramsi.seq, id, 0, -1, NULL); + if (SPA_RESULT_IS_ASYNC(res)) + info->paramsi.seq = res; } } if (changed) {
View file
pipewire-0.3.59.tar.gz/src/tools/pw-link.c -> pipewire-0.3.60.tar.gz/src/tools/pw-link.c
Changed
@@ -400,8 +400,16 @@ struct object *port_out = find_node_port(data, out_node, PW_DIRECTION_OUTPUT, port_id); struct object *port_in = find_node_port(data, in_node, PW_DIRECTION_INPUT, port_id); - if (!port_out || !port_in) - break; + if (!port_out && !port_in) { + fprintf(stderr, "Input & output port do not exist\n"); + goto no_port; + } else if (!port_in) { + fprintf(stderr, "Input port does not exist\n"); + goto no_port; + } else if (!port_out) { + fprintf(stderr, "Output port does not exist\n"); + goto no_port; + } pw_properties_setf(data->props, PW_KEY_LINK_OUTPUT_PORT, "%u", port_out->id); pw_properties_setf(data->props, PW_KEY_LINK_INPUT_PORT, "%u", port_in->id); @@ -422,6 +430,9 @@ pw_properties_setf(data->props, PW_KEY_LINK_INPUT_PORT, "%u", in_port); return create_link(data); + +no_port: + return -ENOENT; } static int do_unlink_ports(struct data *data)
View file
pipewire-0.3.59.tar.gz/src/tools/pw-loopback.c -> pipewire-0.3.60.tar.gz/src/tools/pw-loopback.c
Changed
@@ -57,6 +57,7 @@ uint32_t channels; uint32_t latency; + float delay; struct pw_properties *capture_props; struct pw_properties *playback_props; @@ -93,6 +94,7 @@ " -c, --channels Number of channels (default %d)\n" " -m, --channel-map Channel map (default '%s')\n" " -l, --latency Desired latency in ms\n" + " -d, --delay Desired delay in float s\n" " -C --capture Capture source to connect to\n" " --capture-props Capture stream properties\n" " -P --playback Playback sink to connect to\n" @@ -109,7 +111,7 @@ struct data data = { 0 }; struct pw_loop *l; const char *opt_remote = NULL; - char cname256; + char cname256, value256; char *args; size_t size; FILE *f; @@ -121,6 +123,7 @@ { "name", required_argument, NULL, 'n' }, { "channels", required_argument, NULL, 'c' }, { "latency", required_argument, NULL, 'l' }, + { "delay", required_argument, NULL, 'd' }, { "capture", required_argument, NULL, 'C' }, { "playback", required_argument, NULL, 'P' }, { "capture-props", required_argument, NULL, 'i' }, @@ -146,7 +149,7 @@ goto exit; } - while ((c = getopt_long(argc, argv, "hVr:n:g:c:m:l:C:P:i:o:", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hVr:n:g:c:m:l:d:C:P:i:o:", long_options, NULL)) != -1) { switch (c) { case 'h': show_help(&data, argv0, false); @@ -177,6 +180,9 @@ case 'l': data.latency = atoi(optarg) * DEFAULT_RATE / SPA_MSEC_PER_SEC; break; + case 'd': + data.delay = atof(optarg); + break; case 'C': pw_properties_set(data.capture_props, PW_KEY_NODE_TARGET, optarg); break; @@ -223,6 +229,9 @@ fprintf(f, " remote.name = \"%s\"", opt_remote); if (data.latency != 0) fprintf(f, " node.latency = %u/%u", data.latency, DEFAULT_RATE); + if (data.delay != 0.0f) + fprintf(f, " target.delay.sec = %s", + spa_json_format_float(value, sizeof(value), data.delay)); if (data.channels != 0) fprintf(f, " audio.channels = %u", data.channels); if (data.opt_channel_map != NULL)
View file
pipewire-0.3.59.tar.gz/src/tools/pw-top.c -> pipewire-0.3.60.tar.gz/src/tools/pw-top.c
Changed
@@ -62,8 +62,10 @@ struct node { struct spa_list link; + struct data *data; uint32_t id; char nameMAX_NAME+1; + enum pw_node_state state; struct measurement measurement; struct driver info; struct node *driver; @@ -73,6 +75,7 @@ char formatMAX_FORMAT+1; struct pw_proxy *proxy; struct spa_hook proxy_listener; + unsigned int inactive:1; struct spa_hook object_listener; }; @@ -95,6 +98,7 @@ int n_nodes; struct spa_list node_list; uint32_t generation; + unsigned pending_refresh:1; WINDOW *win; }; @@ -159,12 +163,29 @@ .destroy = on_node_destroy, }; +static void do_refresh(struct data *d); + +static void node_info(void *data, const struct pw_node_info *info) +{ + struct node *n = data; + + if (n->state != info->state) { + n->state = info->state; + do_refresh(n->data); + } +} + static void node_param(void *data, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct node *n = data; + if (param == NULL) { + spa_zero(n->format); + goto done; + } + switch (id) { case SPA_PARAM_Format: { @@ -177,17 +198,18 @@ switch(media_subtype) { case SPA_MEDIA_SUBTYPE_raw: { - struct spa_audio_info_raw info; + struct spa_audio_info_raw info = { 0 }; if (spa_format_audio_raw_parse(param, &info) >= 0) { snprintf(n->format, sizeof(n->format), "%6.6s %d %d", - spa_debug_type_find_short_name(spa_type_audio_format, info.format), + spa_debug_type_find_short_name( + spa_type_audio_format, info.format), info.channels, info.rate); } break; } case SPA_MEDIA_SUBTYPE_dsd: { - struct spa_audio_info_dsd info; + struct spa_audio_info_dsd info = { 0 }; if (spa_format_audio_dsd_parse(param, &info) >= 0) { snprintf(n->format, sizeof(n->format), "DSD%d %d ", 8 * info.rate / 44100, info.channels); @@ -195,13 +217,25 @@ } break; } + case SPA_MEDIA_SUBTYPE_iec958: + { + struct spa_audio_info_iec958 info = { 0 }; + if (spa_format_audio_iec958_parse(param, &info) >= 0) { + snprintf(n->format, sizeof(n->format), "IEC958 %s %d", + spa_debug_type_find_short_name( + spa_type_audio_iec958_codec, info.codec), + info.rate); + + } + break; + } } break; case SPA_MEDIA_TYPE_video: switch(media_subtype) { case SPA_MEDIA_SUBTYPE_raw: { - struct spa_video_info_raw info; + struct spa_video_info_raw info = { 0 }; if (spa_format_video_raw_parse(param, &info) >= 0) { snprintf(n->format, sizeof(n->format), "%6.6s %dx%d", spa_debug_type_find_short_name(spa_type_video_format, info.format), @@ -209,6 +243,24 @@ } break; } + case SPA_MEDIA_SUBTYPE_mjpg: + { + struct spa_video_info_mjpg info = { 0 }; + if (spa_format_video_mjpg_parse(param, &info) >= 0) { + snprintf(n->format, sizeof(n->format), "MJPG %dx%d", + info.size.width, info.size.height); + } + break; + } + case SPA_MEDIA_SUBTYPE_h264: + { + struct spa_video_info_h264 info = { 0 }; + if (spa_format_video_h264_parse(param, &info) >= 0) { + snprintf(n->format, sizeof(n->format), "H264 %dx%d", + info.size.width, info.size.height); + } + break; + } } break; case SPA_MEDIA_TYPE_application: @@ -224,10 +276,13 @@ default: break; } +done: + do_refresh(n->data); } static const struct pw_node_events node_events = { PW_VERSION_NODE, + .info = node_info, .param = node_param, }; @@ -242,6 +297,7 @@ strncpy(n->name, name, MAX_NAME); else snprintf(n->name, sizeof(n->name), "%u", id); + n->data = d; n->id = id; n->driver = n; n->proxy = pw_registry_bind(d->registry, id, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0); @@ -258,6 +314,7 @@ } spa_list_append(&d->node_list, &n->link); d->n_nodes++; + d->pending_refresh = true; return n; } @@ -268,6 +325,7 @@ pw_proxy_destroy(n->proxy); spa_list_remove(&n->link); d->n_nodes--; + d->pending_refresh = true; free(n); } @@ -332,7 +390,10 @@ return -ENOENT; n->measurement = m; - n->driver = point->driver; + if (n->driver != point->driver) { + n->driver = point->driver; + d->pending_refresh = true; + } n->generation = d->generation; if (m.status != 3) { n->errors++; @@ -342,9 +403,9 @@ return 0; } -static const char *print_time(char *buf, size_t len, uint64_t val) +static const char *print_time(char *buf, bool active, size_t len, uint64_t val) { - if (val == (uint64_t)-1) + if (val == (uint64_t)-1 || !active) snprintf(buf, len, " --- "); else if (val == (uint64_t)-2) snprintf(buf, len, " +++ "); @@ -357,9 +418,9 @@ return buf; } -static const char *print_perc(char *buf, size_t len, uint64_t val, float quantum) +static const char *print_perc(char *buf, bool active, size_t len, uint64_t val, float quantum) {
View file
pipewire-0.3.59.tar.gz/test/pwtest.c -> pipewire-0.3.60.tar.gz/test/pwtest.c
Changed
@@ -358,16 +358,13 @@ void pwtest_spa_plugin_destroy(struct pwtest_spa_plugin *plugin) { - void **dll; - struct spa_handle **hnd; - - SPA_FOR_EACH_ELEMENT(plugin->handles, hnd) { + SPA_FOR_EACH_ELEMENT_VAR(plugin->handles, hnd) { if (*hnd) { spa_handle_clear(*hnd); free(*hnd); } } - SPA_FOR_EACH_ELEMENT(plugin->dlls, dll) { + SPA_FOR_EACH_ELEMENT_VAR(plugin->dlls, dll) { if (*dll) dlclose(*dll); }
View file
pipewire-0.3.59.tar.gz/test/test-functional.c -> pipewire-0.3.60.tar.gz/test/test-functional.c
Changed
@@ -29,10 +29,8 @@ PWTEST(openal_info_test) { - int status; - #ifdef OPENAL_INFO_PATH - status = pwtest_spawn(OPENAL_INFO_PATH, (char *){ "openal-info", NULL }); + int status = pwtest_spawn(OPENAL_INFO_PATH, (char *){ "openal-info", NULL }); pwtest_int_eq(WEXITSTATUS(status), 0); return PWTEST_PASS; #else @@ -42,10 +40,8 @@ PWTEST(pactl_test) { - int status; - #ifdef PACTL_PATH - status = pwtest_spawn(PACTL_PATH, (char *){ "pactl", "info", NULL }); + int status = pwtest_spawn(PACTL_PATH, (char *){ "pactl", "info", NULL }); pwtest_int_eq(WEXITSTATUS(status), 0); return PWTEST_PASS; #else
View file
pipewire-0.3.59.tar.gz/test/test-spa-utils.c -> pipewire-0.3.60.tar.gz/test/test-spa-utils.c
Changed
@@ -184,9 +184,8 @@ #define check_traversal(array_) \ { \ - __typeof__(array_0) *it; \ int count = 0; \ - SPA_FOR_EACH_ELEMENT(array_, it) \ + SPA_FOR_EACH_ELEMENT_VAR(array_, it) \ *it = count++; \ for (size_t i = 0; i < SPA_N_ELEMENTS(array_); i++) \ pwtest_int_eq(array_i, i); \
View file
pipewire-0.3.59.tar.gz/test/test-utils.c -> pipewire-0.3.60.tar.gz/test/test-utils.c
Changed
@@ -172,9 +172,7 @@ }, }; - const struct test_case *tc; - - SPA_FOR_EACH_ELEMENT(test_cases, tc) { + SPA_FOR_EACH_ELEMENT_VAR(test_cases, tc) { const char *str = tc->input, *s; const char *state = NULL; size_t j = 0, len;
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
.