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 14
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Sep 7 13:36:51 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 0.3.57 + +------------------------------------------------------------------- Thu Jul 21 12:08:38 UTC 2022 - Bjørn Lie <zaitor@opensuse.org> - Update to version 0.3.56
View file
pipewire-aptx.spec
Changed
@@ -7,7 +7,7 @@ %define soversion 0_2 Name: pipewire-aptx -Version: 0.3.56 +Version: 0.3.57 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT @@ -20,6 +20,7 @@ BuildRequires: pkgconfig BuildRequires: pkgconfig(bluez) BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libfreeaptx) BuildRequires: pkgconfig(sbc)
View file
pipewire-0.3.56.tar.gz/.cirrus.yml -> pipewire-0.3.57.tar.gz/.cirrus.yml
Changed
@@ -1,7 +1,7 @@ task: freebsd_instance: matrix: - - image_family: freebsd-13-0-snap + - image_family: freebsd-13-1-snap env: # /usr/ports/Mk/Uses/localbase.mk localbase:ldflags LOCALBASE: /usr/local
View file
pipewire-0.3.56.tar.gz/NEWS -> pipewire-0.3.57.tar.gz/NEWS
Changed
@@ -1,3 +1,93 @@ +# PipeWire 0.3.57 (2022-09-02) + +This is a bugfix release that is API and ABI compatible with previous +0.3.x releases. + +## Highlights + +## PipeWire + - Support masking of conf.d/ files. (#2629) + - Add some more debug info to memfd. + - Improve data-loop invoke method. Also flush pending items. (#2631) + - Add a filter-chain systemd service file than can be used to start + custom filters placed in ~/.conf/pipewire/filter-chain.d/ (#2553) + - Improve triggered timestamps for remote nodes. + - Fix some potential cross compilation problems due to wrong + host_machine. + - Check return values of pw_getrandom(). + + +## Tools + - Updates to pw-cli manpages. (#2552) + - Remove the pw-cli dump command. It is mostly implemented as part of + wpctl status, pw-dump, pw-link, pw-top and others. + - Clean up resource in pw-cat correctly on errors. (#2651) + +## Modules + - Fix compilation of AVB on big-endian. Enable AVB only on Linux. + - Use org.freedesktop.portal.Realtime when available. This does the + correct PID/TID mappings to make realtime also work from flatpaks. + - Fix compilation of ROC module when headers are missing. (#2513) + - Improve some error cleanup paths in protocol-native. Improve connect + and disconnect. + - Fix a potential crash in FFT unload in filter-chain. + - Implement PIPEWIRE_NOTIFICATION_FD for notification when the socket + is ready. + - Try to use rtkit if set_nice() fails. + - Fix rate adjustement logic in pulse-tunnel. This would cause + increasing delays and hickups when using tunnels. (#2548) + - Handle disconnect in pulse-tunnel. + +## Bluetooth + - Add OPUS as a new vendor codec. Add OPUS-A2DP spec. PipeWire can now + send and reveive OPUS data over bluetooth. + - An AAC decoder was added so that PipeWire can now also function as + an A2DP AAC receiver. + +## SPA + - Tweak the resampler window function some more. (#2574) + - Improve format convert performance in some fallback cases. + - Fix rounding in format conversion on ARM NEON. + - Fix libcamera build error. (#2575) + - Fix some issues where the wrong samplerate was used. (#2614) + - Don't wait for more samples that can fit in the ringbuffer in ALSA. + - Improve buffer size handling in audioconvert, scale the buffers based + on the rate conversion and make things work with really large rate + conversions as well. + - Add more and better debug for ALSA devices. + - Improve channel mix: Filter FC and LFE when copying from a different + layout. Implement STEREO from FC. Avoid generating REAR from FC in PSD + mode. + - Fix rate match for sources. This fixes an error where follower sources + would generate many resync warnings. + - Improve ALSA format negotiation. If the ALSA node is not running and + there was a previously configured format, close and reopen the device + to enumerate and accept all possible formats again. (#2625). + +## ALSA + - The alsa plugin will now also save the volumes set with the control + API. This saves the volumes set with alsa-mixer, for example. + +## Pulse-server + - Flatpak apps with devices=all (Zoom) will now be granted Manager + permissions. + - Small tweaks to the amount of data sent to clients to work around an + issue in freerdp. + +## JACK + - Clean up the transport correctly when closing a client. (#2569) + - Match context properties in addition to node properties for the jack + client rules. (#2580) + - Make sure to return an error when disconnected from the server. (#2606) + - Fix thread cast problem in jack_client_thread_id(). + - Increase jack_client_name_size() length and make sure we have space for + the \0 byte. + - JACK clients from the same application will be added to the same group + so that they share the quantum and rate. + + +Older versions: + # PipeWire 0.3.56 (2022-07-19) This is a quick bugfix release that is API and ABI compatible with previous @@ -52,8 +142,6 @@ - Add the resampler delay to delay reporting as well. -Older versions: - # PipeWire 0.3.55 (2022-07-12) This is a quick bugfix release that is API and ABI compatible with previous
View file
pipewire-0.3.56.tar.gz/doc/tutorial3.c -> pipewire-0.3.57.tar.gz/doc/tutorial3.c
Changed
@@ -7,32 +7,36 @@ #include <pipewire/pipewire.h> /* roundtrip */ -static int roundtrip(struct pw_core *core, struct pw_main_loop *loop) +struct roundtrip_data { + int pending; + struct pw_main_loop *loop; +}; + +static void on_core_done(void *data, uint32_t id, int seq) +{ + struct roundtrip_data *d = data; + + if (id == PW_ID_CORE && seq == d->pending) + pw_main_loop_quit(d->loop); +} + +static void roundtrip(struct pw_core *core, struct pw_main_loop *loop) { - struct spa_hook core_listener; - int pending, done = 0; - void core_event_done(void *object, uint32_t id, int seq) { - if (id == PW_ID_CORE && seq == pending) { - done = 1; - pw_main_loop_quit(loop); - } - } - const struct pw_core_events core_events = { - PW_VERSION_CORE_EVENTS, - .done = core_event_done, - }; - - spa_zero(core_listener); - pw_core_add_listener(core, &core_listener, - &core_events, NULL); - - pending = pw_core_sync(core, PW_ID_CORE, 0); - - while (!done) { - pw_main_loop_run(loop); - } - spa_hook_remove(&core_listener); - return 0; + static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .done = on_core_done, + }; + + struct roundtrip_data d = { .loop = loop }; + struct spa_hook core_listener; + + pw_core_add_listener(core, &core_listener, &core_events, &d); + + d.pending = pw_core_sync(core, PW_ID_CORE, 0); + + pw_main_loop_run(loop); + + spa_hook_remove(&core_listener); } /* roundtrip */ @@ -50,37 +54,36 @@ int main(int argc, char *argv) { - struct pw_main_loop *loop; - struct pw_context *context; - struct pw_core *core; - struct pw_registry *registry; - struct spa_hook registry_listener; + struct pw_main_loop *loop; + struct pw_context *context; + struct pw_core *core; + struct pw_registry *registry; + struct spa_hook registry_listener; - pw_init(&argc, &argv); + pw_init(&argc, &argv); - loop = pw_main_loop_new(NULL /* properties */); - context = pw_context_new(pw_main_loop_get_loop(loop), - NULL /* properties */, - 0 /* user_data size */); + loop = pw_main_loop_new(NULL /* properties */); + context = pw_context_new(pw_main_loop_get_loop(loop), + NULL /* properties */, + 0 /* user_data size */); - core = pw_context_connect(context, - NULL /* properties */, - 0 /* user_data size */); + core = pw_context_connect(context, + NULL /* properties */, + 0 /* user_data size */); - registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, - 0 /* user_data size */); + registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, + 0 /* user_data size */); - spa_zero(registry_listener); - pw_registry_add_listener(registry, ®istry_listener, - ®istry_events, NULL); + pw_registry_add_listener(registry, ®istry_listener, + ®istry_events, NULL); - roundtrip(core, loop); + roundtrip(core, loop); - pw_proxy_destroy((struct pw_proxy*)registry); - pw_core_disconnect(core); - pw_context_destroy(context); - pw_main_loop_destroy(loop); + pw_proxy_destroy((struct pw_proxy*)registry); + pw_core_disconnect(core); + pw_context_destroy(context); + pw_main_loop_destroy(loop); - return 0; + return 0; } /* code */
View file
pipewire-0.3.56.tar.gz/doc/tutorial3.dox -> pipewire-0.3.57.tar.gz/doc/tutorial3.dox
Changed
@@ -15,10 +15,9 @@ Let's take a look at what this method does. \code{.c} - struct spa_hook core_listener; - spa_zero(core_listener); - pw_core_add_listener(core, &core_listener, - &core_events, NULL); + struct spa_hook core_listener; + + pw_core_add_listener(core, &core_listener, &core_events, &d); \endcode First of all we add a listener for the events of the core @@ -26,37 +25,31 @@ tutorial. This is the event handler: \code{.c} - int pending, done = 0; - - void core_event_done(void *data, uint32_t id, int seq) { - if (id == PW_ID_CORE && seq == pending) { - done = 1; - pw_main_loop_quit(loop); - } - } - const struct pw_core_events core_events = { - PW_VERSION_CORE_EVENTS, - .done = core_event_done, - }; +static void on_core_done(void *data, uint32_t id, int seq) +{ + struct roundtrip_data *d = data; + + if (id == PW_ID_CORE && seq == d->pending) + pw_main_loop_quit(d->loop); +} \endcode -When the done event is received for an object with id `PW_ID_CORE` -and a certain sequence number `seq`, this function will set the done -variable to 1 and call `pw_main_loop_quit()`. +When the done event is received for an object with id `PW_ID_CORE` and +a certain sequence number `seq`, this function will call `pw_main_loop_quit()`. Next we do: \code{.c} - pending = pw_core_sync(core, PW_ID_CORE, 0); + d.pending = pw_core_sync(core, PW_ID_CORE, 0); \endcode This triggers the `sync` method on the core object with id `PW_ID_CORE` and sequence number 0. Because this is a method on a proxy object, it will be executed -asynchronously and the returns value will reflect this. PipeWire +asynchronously and the return value will reflect this. PipeWire uses the return values of the underlying SPA (Simple Plugin API) -helper objects (See also error codes(spa-design.md#error-codes)). +helper objects (See also \ref page_spa_design ). Because all messages on the PipeWire server are handled sequentially, the sync method will be executed after all previous methods are @@ -68,9 +61,7 @@ receive the events: \code{.c} - while (!done) { - pw_main_loop_run(loop); - } + pw_main_loop_run(loop); \endcode When we get the done event, we can compare it to the sync method @@ -79,7 +70,7 @@ remove the listener: \code{.c} - spa_hook_remove(&core_listener); + spa_hook_remove(&core_listener); \endcode If we add this roundtrip method to our code and call it instead of the @@ -100,7 +91,7 @@ created them: \code{.c} - pw_proxy_destroy((struct pw_proxy*)registry); + pw_proxy_destroy((struct pw_proxy*)registry); \endcode The registry is a proxy and can be destroyed with the generic proxy destroy @@ -110,7 +101,7 @@ We can disconnect from the server with: \code{.c} - pw_core_disconnect(core); + pw_core_disconnect(core); \endcode This will also destroy the core proxy object and will remove the proxies @@ -119,8 +110,8 @@ We can finally destroy our context and mainloop to conclude this tutorial: \code{.c} - pw_context_destroy(context); - pw_main_loop_destroy(loop); + pw_context_destroy(context); + pw_main_loop_destroy(loop); \endcode \ref page_tutorial2 | \ref page_tutorial "Index" | \ref page_tutorial4
View file
pipewire-0.3.56.tar.gz/man/pw-cli.1.rst.in -> pipewire-0.3.57.tar.gz/man/pw-cli.1.rst.in
Changed
@@ -34,17 +34,20 @@ GENERAL COMMANDS ================ -help - Show a quick help on the commands available. +help | h + Show a quick help on the commands available. It also lists the aliases + for many commands. -quit +quit | q Exit from **pw-cli** MODULE MANAGEMENT ================= -| Modules are loaded and unloaded in the local instance and can add -| functionality or objects to the local instance. +| Modules are loaded and unloaded in the local instance, thus the pw-cli +| binary itself and can add functionality or objects to the local +| instance. It is not possible in PipeWire to load modules in another +| instance. load-module *name* *arguments...* Load a module specified by its name and arguments. For most @@ -105,14 +108,22 @@ This command returns a *node variable*. -destroy-node *node-var* - Destroy a node. - export-node *node-id* *remote-var* Export a node from the local instance to the specified instance. When no instance is specified, the node will be exported to the current instance. +DEVICE MANAGEMENT +================= + +create-device *factory-name* *properties...* + Create a device from a factory in the current instance. + + Properties are key=value pairs separated by whitespace. + + This command returns a *device variable*. + + LINK MANAGEMENT =============== @@ -125,8 +136,44 @@ This command returns a *link variable*. -destroy-link *link-var* - Destroy a link. +GLOBALS MANAGEMENT +================== + +destroy *object-id* + Destroy a global object. + + +PARAMETER MANAGEMENT +==================== + +enum-params *object-id* *param-id* + Enumerate params of an object. + + *param-id* can also be given as the param short name. + +set-param *object-id* *param-id* *param-json* + Set param of an object. + + *param-id* can also be given as the param short name. + +PERMISSION MANAGEMENT +===================== + +permissions *client-id* *object-id* *permission* + Set permissions for a client. + + *object-id* can be *-1* to set the default permissions. + +get-permissions *client-id* + Get permissions of a client. + + +COMMAND MANAGEMENT +================== + +send-command *object-id* + Send a command to an object. + EXAMPLES ========
View file
pipewire-0.3.56.tar.gz/meson.build -> pipewire-0.3.57.tar.gz/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '0.3.56', + version : '0.3.57', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.59.0', default_options : 'warning_level=3', @@ -295,6 +295,11 @@ cap_lib = dependency('libcap', required : false) cdata.set('HAVE_LIBCAP', cap_lib.found()) +glib2_dep = dependency('glib-2.0', required : get_option('flatpak')) +summary({'GLib-2.0 (Flatpak support)': glib2_dep.found()}, bool_yn: true, section: 'Misc dependencies') +flatpak_support = glib2_dep.found() +cdata.set('HAVE_GLIB2', flatpak_support) + gst_option = get_option('gstreamer') gst_deps_def = { 'glib-2.0': {'version': '>=2.32.0'}, @@ -337,11 +342,11 @@ cdata.set('HAVE_WEBRTC', webrtc_dep.found()) # On FreeBSD and MidnightBSD, epoll-shim library is required for eventfd() and timerfd() -epoll_shim_dep = (build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd' +epoll_shim_dep = (host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd' ? dependency('epoll-shim', required: true) : dependency('', required: false)) -libinotify_dep = (build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd' +libinotify_dep = (host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd' ? dependency('libinotify', required: true) : dependency('', required: false)) @@ -356,7 +361,7 @@ alsa_dep = dependency('alsa', version : '>=1.1.7', required: need_alsa) summary({'pipewire-alsa': alsa_dep.found()}, bool_yn: true) -if build_machine.system() == 'freebsd' or build_machine.system() == 'midnightbsd' +if host_machine.system() == 'freebsd' or host_machine.system() == 'midnightbsd' # On FreeBSD and MidnightBSD the OpenSSL library may come from base or a package. # Check for a package first and fallback to the base library if we can't find it via pkgconfig openssl_lib = dependency('openssl', required: false)
View file
pipewire-0.3.56.tar.gz/meson_options.txt -> pipewire-0.3.57.tar.gz/meson_options.txt
Changed
@@ -116,6 +116,10 @@ description: 'Enable LC3plus open source codec implementation', type: 'feature', value: 'auto') +option('bluez5-codec-opus', + description: 'Enable Opus open source codec implementation', + type: 'feature', + value: 'auto') option('control', description: 'Enable control spa plugin integration', type: 'feature', @@ -249,3 +253,7 @@ description: 'Enable AVB code', type: 'feature', value: 'auto') +option('flatpak', + description: 'Enable Flatpak support', + type: 'feature', + value: 'enabled')
View file
pipewire-0.3.56.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> pipewire-0.3.57.tar.gz/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
@@ -532,6 +532,7 @@ spa_pod_builder_add(&b, SPA_PARAM_ROUTE_index, SPA_POD_Int(id), SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id), + SPA_PARAM_ROUTE_save, SPA_POD_Bool(true), 0); spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
View file
pipewire-0.3.56.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.57.tar.gz/pipewire-jack/src/pipewire-jack.c
Changed
@@ -62,7 +62,7 @@ #define DEFAULT_RT_MAX 88 -#define JACK_CLIENT_NAME_SIZE 128 +#define JACK_CLIENT_NAME_SIZE 256 #define JACK_PORT_NAME_SIZE 256 #define JACK_PORT_TYPE_SIZE 32 #define MONITOR_EXT " Monitor" @@ -800,7 +800,7 @@ } else { \ if (c->active) \ (expr); \ - pw_log_debug("skip " #callback \ + pw_log_debug("skip " #callback \ " cb:%p active:%d", c->callback, \ c->active); \ } \ @@ -817,6 +817,9 @@ res = c->callback(__VA_ARGS__); \ c->rt_locked = false; \ pthread_mutex_unlock(&c->rt_lock); \ + } else { \ + pw_log_debug("skip " #callback \ + " cb:%p", c->callback); \ } \ } \ res; \ @@ -871,6 +874,8 @@ pw_log_warn("sync requested from callback"); return 0; } + if (client->last_res == -EPIPE) + return -EPIPE; client->last_res = 0; client->pending_sync = pw_proxy_sync((struct pw_proxy*)client->core, client->pending_sync); @@ -3279,7 +3284,7 @@ "jack.properties", client->props); pw_context_conf_section_match_rules(client->context.context, "jack.rules", - &client->props->dict, execute_match, client); + &client->context.context->properties->dict, execute_match, client); support = pw_context_get_support(client->context.context, &n_support); @@ -3356,6 +3361,8 @@ } if (pw_properties_get(client->props, PW_KEY_NODE_NAME) == NULL) pw_properties_set(client->props, PW_KEY_NODE_NAME, client_name); + if (pw_properties_get(client->props, PW_KEY_NODE_GROUP) == NULL) + pw_properties_setf(client->props, PW_KEY_NODE_GROUP, "jack-%d", getpid()); if (pw_properties_get(client->props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(client->props, PW_KEY_NODE_DESCRIPTION, client_name); if (pw_properties_get(client->props, PW_KEY_MEDIA_TYPE) == NULL) @@ -3492,6 +3499,8 @@ res = jack_deactivate(client); + clean_transport(c); + if (c->context.loop) pw_thread_loop_stop(c->context.loop); @@ -3577,8 +3586,9 @@ SPA_EXPORT int jack_client_name_size (void) { - pw_log_trace("%d", JACK_CLIENT_NAME_SIZE); - return JACK_CLIENT_NAME_SIZE; + /* The JACK API specifies that this value includes the final NULL character. */ + pw_log_trace("%d", JACK_CLIENT_NAME_SIZE+1); + return JACK_CLIENT_NAME_SIZE+1; } SPA_EXPORT @@ -3765,12 +3775,12 @@ struct client *c = (struct client *) client; void *thr; - spa_return_val_if_fail(c != NULL, -EINVAL); + 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 (pthread_t) thr; } SPA_EXPORT
View file
pipewire-0.3.56.tar.gz/po/LINGUAS -> pipewire-0.3.57.tar.gz/po/LINGUAS
Changed
@@ -21,6 +21,7 @@ id it ja +ka kk kn ko
View file
pipewire-0.3.56.tar.gz/po/ca.po -> pipewire-0.3.57.tar.gz/po/ca.po
Changed
@@ -5,6 +5,7 @@ # Xavier Conde Rueda <xavi.conde@gmail.com>, 2008. # Agustí Grau <fletxa@gmail.com>, 2009. # Judith Pintó Subirada <judithp@gmail.com> +# Jordi Mas i Herǹandez, <jmas@softcatala.org>, 2022 # # This file is translated according to the glossary and style guide of # Softcatalà. If you plan to modify this file, please read first the page @@ -26,11 +27,10 @@ msgid "" msgstr "" "Project-Id-Version: pipewire\n" -"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/" -"issues/new\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: 2012-01-30 09:52+0000\n" -"Last-Translator: Josep Torné Llavall <josep.torne@gmail.com>\n" +"PO-Revision-Date: 2022-09-01 19:24+0000\n" +"Last-Translator: Jordi Mas i Herǹandez, <jmas@softcatala.org>,\n" "Language-Team: Catalan <fedora@softcatala.net>\n" "Language: ca\n" "MIME-Version: 1.0\n" @@ -45,14 +45,18 @@ " --version Show version\n" " -c, --config Load config (Default %s)\n" msgstr "" +"%s opcions\n" +" -h, --help Mostra aquesta ajuda\n" +" --version Mostra la versió\n" +" -c, --config Carrega la configuració (predeterminada %s)\n" #: src/daemon/pipewire.desktop.in:4 msgid "PipeWire Media System" -msgstr "" +msgstr "Sistema multimèdia PipeWire" #: src/daemon/pipewire.desktop.in:5 msgid "Start the PipeWire Media System" -msgstr "" +msgstr "Inicia el sistema multimèdia PipeWire" #: src/examples/media-session/alsa-monitor.c:526 #: spa/plugins/alsa/acp/compat.c:187 @@ -66,7 +70,7 @@ #: src/examples/media-session/alsa-monitor.c:539 msgid "Unknown device" -msgstr "" +msgstr "Dispositiu desconegut" #: src/tools/pw-cat.c:991 #, c-format @@ -77,9 +81,13 @@ " -v, --verbose Enable verbose operations\n" "\n" msgstr "" +"%s opcions <fitxer>\n" +" -h, --help Mostra aquesta ajuda\n" +" --version Mostra la versió\n" +" -v, --verbose Habilita les operacions detallades\n" #: src/tools/pw-cat.c:998 -#, c-format +#, c-format, fuzzy msgid "" " -R, --remote Remote daemon name\n" " --media-type Set media type (default %s)\n" @@ -90,42 +98,58 @@ " --latency Set node latency (default %s)\n" " Xunit (unit = s, ms, us, ns)\n" " or direct samples (256)\n" -" the rate is the one of the source " -"file\n" +" the rate is the one of the source file\n" " --list-targets List available targets for --target\n" "\n" msgstr "" +"-R, --remote Nom del dimoni remot\n" +" --media-type Estableix el tipus de mitjà (per defecte %s)\n" +" --media-category Estableix la categoria dels mitjans (per defecte %s)\n" +" --media-role Estableix el rol del mitjà (per defecte %s)\n" +" --target Estableix l'objectiu del node (per defecte %s)\n" +" 0 vol dir que no enllaça\n" +" --latency Estableix latència del node (per defecte %s)\n" +" Xunit (unitat = s, ms, us, ns)\n" +" o mostres directes (256)\n" +" la taxa és la del fitxer d'origen\n" +" --list-targets Llista d'objectius disponibles per a --target" #: src/tools/pw-cat.c:1016 -#, c-format +#, c-format, fuzzy msgid "" -" --rate Sample rate (req. for rec) (default " -"%u)\n" -" --channels Number of channels (req. for rec) " -"(default %u)\n" +" --rate Sample rate (req. for rec) (default %u)\n" +" --channels Number of channels (req. for rec) (default %u)\n" " --channel-map Channel map\n" -" one of: \"stereo\", " -"\"surround-51\",... or\n" -" comma separated list of channel " -"names: eg. \"FL,FR\"\n" -" --format Sample format %s (req. for rec) " -"(default %s)\n" +" one of: \"stereo\", \"surround-51\",... or\n" +" comma separated list of channel names: eg. \"FL,FR\"\n" +" --format Sample format %s (req. for rec) (default %s)\n" " --volume Stream volume 0-1.0 (default %.3f)\n" -" -q --quality Resampler quality (0 - 15) (default " -"%d)\n" +" -q --quality Resampler quality (0 - 15) (default %d)\n" "\n" msgstr "" +"--rate Freqüència de mostreig (req. per rec) (predeterminat %u)\n" +" --channels Nombre de canals (req. per rec) (predeterminat %u)\n" +" --channel-map Mapa de canals\n" +" un dels següents: \"estèreo\", \"surround-51\",... o\n" +" Llista separada per comes dels noms dels canals: per exemple. \"FL,FR\"\n" +" --format Format de mostra %s (req. per a rec) (predeterminat %s)\n" +" --volume Volum de flux 0-1.0 (predeterminat %.3f)\n" +" -q --qualitat Remostrador de qualitat (0 - 15) (per defecte %d)" #: src/tools/pw-cat.c:1033 +#, fuzzy msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" " -m, --midi Midi mode\n" "\n" msgstr "" +"-p, --playback Mode de reproducció\n" +" -r, --record mode d'enregistrament\n" +" -m, --midi Mode MIDI" #: src/tools/pw-cli.c:2932 -#, c-format +#, c-format, fuzzy msgid "" "%s options command\n" " -h, --help Show this help\n" @@ -134,10 +158,15 @@ " -r, --remote Remote daemon name\n" "\n" msgstr "" +"%s opcions ordre\n" +" -h, --help Mostra aquesta ajuda\n" +" --version Mostra la versió\n" +" -d, --daemon Inicia com a dimoni (fals predeterminat)\n" +" -r, --remote Nom del dimoni remot" #: spa/plugins/alsa/acp/acp.c:290 msgid "Pro Audio" -msgstr "" +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 @@ -252,25 +281,23 @@ #: spa/plugins/alsa/acp/alsa-mixer.c:2801 msgid "Dock Microphone" -msgstr "" +msgstr "Micròfon de l'acoblador" #: spa/plugins/alsa/acp/alsa-mixer.c:2803 msgid "Headset Microphone" -msgstr "" +msgstr "Micròfon d'auriculars" #: spa/plugins/alsa/acp/alsa-mixer.c:2807 msgid "Analog Output" msgstr "Sortida analògica" #: spa/plugins/alsa/acp/alsa-mixer.c:2809 -#, fuzzy msgid "Headphones 2" -msgstr "Auriculars" +msgstr "Auriculars 2" #: spa/plugins/alsa/acp/alsa-mixer.c:2810 -#, fuzzy msgid "Headphones Mono Output" -msgstr "Sortida mono analògica" +msgstr "Sortida mono dels auriculars" #: spa/plugins/alsa/acp/alsa-mixer.c:2811 msgid "Line Out" @@ -297,49 +324,41 @@ msgstr "Entrada digital (S/PDIF)" #: spa/plugins/alsa/acp/alsa-mixer.c:2817 -#, fuzzy msgid "Multichannel Input" -msgstr "Multicanal" +msgstr "Entrada multicanal" #: spa/plugins/alsa/acp/alsa-mixer.c:2818
View file
pipewire-0.3.56.tar.gz/po/gl.po -> pipewire-0.3.57.tar.gz/po/gl.po
Changed
@@ -4,25 +4,31 @@ # Translators: # bassball93 <bassball93@gmail.com>, 2011. # mbouzada <mbouzada@gmail.com>, 2011. -# Fran Dieguez <frandieguez@gnome.org>, 2012, 2019. # Marcos Lans <marcoslansgarza@gmail.com>, 2018. +# Fran Dieguez <frandieguez@gnome.org>, 2012-2022. +# msgid "" msgstr "" "Project-Id-Version: PipeWire\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: 2019-02-20 01:36+0200\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" +"issues\n" +"POT-Creation-Date: 2022-07-10 03:27+0000\n" +"PO-Revision-Date: 2022-08-23 09:47+0200\n" "Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n" -"Language-Team: Galician\n" +"Language-Team: Galician <Proxecto Trasno <proxecto@trasno.gal>>\n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Virtaal 0.7.1\n" - -#: src/daemon/pipewire.c:43 +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Generator: Gtranslator 40.0\n" +"X-DL-Team: gl\n" +"X-DL-Module: PipeWire\n" +"X-DL-Branch: master\n" +"X-DL-Domain: po\n" +"X-DL-State: Translating\n" + +#: src/daemon/pipewire.c:46 #, c-format msgid "" "%s options\n" @@ -30,6 +36,11 @@ " --version Show version\n" " -c, --config Load config (Default %s)\n" msgstr "" +"%s opcións\n" +" -h, --help Mostra esta axuda\n" +" --version Mostrar versión\n" +" -c, --config Cargar configuración (Predeterminado " +"%s)\n" #: src/daemon/pipewire.desktop.in:4 msgid "PipeWire Media System" @@ -39,31 +50,52 @@ msgid "Start the PipeWire Media System" msgstr "Iniciar o Sistema multimedia PipeWire" -#: src/examples/media-session/alsa-monitor.c:526 -#: spa/plugins/alsa/acp/compat.c:187 -msgid "Built-in Audio" -msgstr "Audio interno" +#: 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 a %s/%s" -#: src/examples/media-session/alsa-monitor.c:530 -#: spa/plugins/alsa/acp/compat.c:192 -msgid "Modem" -msgstr "Módem" +#: src/modules/module-fallback-sink.c:51 +#| msgid "Game Output" +msgid "Dummy Output" +msgstr "Saída de proba" -#: src/examples/media-session/alsa-monitor.c:539 +#: src/modules/module-pulse-tunnel.c:648 +#, c-format +msgid "Tunnel for %s@%s" +msgstr "Túnel para %s@%s" + +#: src/modules/module-zeroconf-discover.c:332 msgid "Unknown device" -msgstr "" +msgstr "Dispositivo descoñecido" + +#: src/modules/module-zeroconf-discover.c:344 +#, c-format +msgid "%s on %s@%s" +msgstr "%s en %s@%s" + +#: src/modules/module-zeroconf-discover.c:348 +#, c-format +msgid "%s on %s" +msgstr "%s en %s" -#: src/tools/pw-cat.c:991 +#: 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 opcións <ficheiro>|-\n" +" -h, --help Mostrar esta axuda\n" +" --version Mostrar versión\n" +" -v, --verbose Activar operacións verbosas\n" +"\n" -#: src/tools/pw-cat.c:998 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -77,11 +109,29 @@ " 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" +" --media-type Estabelecer o tipo de medio (por " +"omisión %s)\n" +" --media-category Estabelecer a categoría multimedia " +"(por omisión %s)\n" +" --media-role Estabelecer o rol multimedia (por " +"omisión %s)\n" +" --target Estabelecer o nodo obxectivo (por " +"omisión %s)\n" +" 0 significa non ligar\n" +" --latency Estabelecer a latencia do nodo (por " +"omisión %s)\n" +" Xunit (unidade = s, ms, us, ns)\n" +" ou mostras directas samples (256)\n" +" a taxa é un dos ficheiros de " +"orixe\n" +" -P --properties Estabelecer as propiedades do nodo\n" +"\n" -#: src/tools/pw-cat.c:1016 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -100,16 +150,38 @@ "%d)\n" "\n" msgstr "" +" --rate Taxa de mostreo (solicitudes por " +"segundo) (por omisión %u)\n" +" --channels Número de canles (solicitudes por " +"segundo) (por omisión %u)\n" +" --channel-map Mapa de canles\n" +" un de: \"stereo\", " +"\"surround-51\",... or\n" +" lista separada por comas dos " +"nomes das canles: p.ex. \"FL,FR\"\n" +" --format Formato de mostras %s (solicitudes " +"por segundo) (por omisión %s)\n" +" --volume Volume do fluxo 0-1.0 (por omisión " +"%.3f)\n" +" -q --quality Calidade do remostreador (0 - 15) " +"(por omisión %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 Modo de reprodución\n" +" -r, --record Modo de grabación\n" +" -m, --midi Modo MIDI\n" +" -d, --dsd Modo DSD\n" +"\n" -#: src/tools/pw-cli.c:2932 +#: src/tools/pw-cli.c:3165 #, c-format msgid "" "%s options command\n" @@ -119,355 +191,352 @@ " -r, --remote Remote daemon name\n" "\n" msgstr "" +"%s opcións orde\n" +" -h, --help Mostrar esta axuda\n" +" --version Mostrar versión\n"
View file
pipewire-0.3.57.tar.gz/po/ka.po
Added
@@ -0,0 +1,661 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the pipewire package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: pipewire\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/" +"issues/new\n" +"POT-Creation-Date: 2022-06-30 12:50+0200\n" +"PO-Revision-Date: 2022-07-25 13:11+0200\n" +"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n" +"Language-Team: Georgian <(nothing)>\n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"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.1\n" + +#: src/daemon/pipewire.c:46 +#, c-format +msgid "" +"%s options\n" +" -h, --help Show this help\n" +" --version Show version\n" +" -c, --config Load config (Default %s)\n" +msgstr "" +"%s პარამეტრები\n" +" -h, --help ამ დახმარების ჩვენება\n" +" --version ვერსიის ჩვენება\n" +" -c, --config ჩატვირთვის კონფიგურაცია (ნაგულისხმები %s)\n" + +#: 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 -მდე" + +#: src/modules/module-fallback-sink.c:51 +msgid "Dummy Output" +msgstr "ნულოვანი გამოყვანა" + +#: src/modules/module-pulse-tunnel.c:648 +#, c-format +msgid "Tunnel for %s@%s" +msgstr "გვირაბი %s@%s-სთვის" + +#: src/modules/module-zeroconf-discover.c:332 +msgid "Unknown device" +msgstr "უცნობი მოწყობილობა" + +#: src/modules/module-zeroconf-discover.c:344 +#, c-format +msgid "%s on %s@%s" +msgstr "%s %s@%s -ზე" + +#: src/modules/module-zeroconf-discover.c:348 +#, c-format +msgid "%s on %s" +msgstr "%s %s-ზე" + +#: src/tools/pw-cat.c:784 +#, c-format +msgid "" +"%s options <file>|-\n" +" -h, --help Show this help\n" +" --version Show version\n" +" -v, --verbose Enable verbose operations\n" +"\n" +msgstr "" +"%s პარამეტრები <ფაილი>|-\n" +" -h, --help ამ დახმარების ჩვენება\n" +" --version ვერსიის ჩვენება\n" +" -v, --verbose დამატებითი შეტყობინებების გამოტანა\n" +"\n" + +#: src/tools/pw-cat.c:791 +#, c-format +msgid "" +" -R, --remote Remote daemon name\n" +" --media-type Set media type (default %s)\n" +" --media-category Set media category (default %s)\n" +" --media-role Set media role (default %s)\n" +" --target Set node target (default %s)\n" +" 0 means don't link\n" +" --latency Set node latency (default %s)\n" +" Xunit (unit = s, ms, us, ns)\n" +" or direct samples (256)\n" +" the rate is the one of the source " +"file\n" +" -P --properties Set node properties\n" +"\n" +msgstr "" +" -R, --remote დაშორებული დემონის სახელი\n" +" --media-type მედიის ტიპის დაყენება (ნაგულისხმები %s)\n" +" --media-category მედია კატეგორიის დაყენება (ნაგულისხმები %s)\n" +" --media-role მედიის როლის დაყენება (ნაგულისხმები %s)\n" +" --target კვანძის სამიზნის დაყენება (ნაგულისხმები %s)\n" +" 0 ნიშნავს არ მიბმა\n" +" --latency კვანძის შეყოვნების დაყენება (ნაგულისხმები %s)\n" +" Xunit (ერთეული = s, ms, us, ns)\n" +" ან პირდაპირი ნიმუშები (256)\n" +" მაჩვენებელი არის ერთ-ერთი წყაროს " +"ფაილი\n" +" -P --properties კვანძის თვისებების დაყენება\n" + +#: src/tools/pw-cat.c:809 +#, c-format +msgid "" +" --rate Sample rate (req. for rec) (default " +"%u)\n" +" --channels Number of channels (req. for rec) " +"(default %u)\n" +" --channel-map Channel map\n" +" one of: \"stereo\", " +"\"surround-51\",... or\n" +" comma separated list of channel " +"names: eg. \"FL,FR\"\n" +" --format Sample format %s (req. for rec) " +"(default %s)\n" +" --volume Stream volume 0-1.0 (default %.3f)\n" +" -q --quality Resampler quality (0 - 15) (default " +"%d)\n" +"\n" +msgstr "" +" --rate სემპლის_სიჩქარე (მოთხოვნილება rec.) (ნაგულისხმები %u)\n" +" --channels არხების რაოდენობა (მოთხოვნილი ჩანაწერისთვის) (ნაგულისხმები " +"%u)\n" +" --channel-map არხის რუკა\n" +" ერთ-ერთი: \"stereo\", " +"\"surround-51\",... ან\n" +" მძიმით გამოყოფილი არხის " +"სახელების სია: მაგ. \"FL, FR\"\n" +" --format ნიმუშის ფორმატი %s (მოთხოვნილება rec.) " +"(ნაგულისხმები %s)\n" +" --volume ნაკადის მოცულობა 0-1.0 (ნაგულისხმები %.3f)\n" +" -q --quality Resampler ხარისხი (0 - 15) " +"(ნაგულისხმები %d)\n" + +#: 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 დაკვრის რეჟიმი\n" +" -r, -- record ჩაწერის რეჟიმი\n" +" -m, --midi Midi რეჟიმი\n" +" -d, --dsd DSD რეჟიმი\n" +"\n" + +#: src/tools/pw-cli.c:3165 +#, c-format +msgid "" +"%s options command\n" +" -h, --help Show this help\n" +" --version Show version\n" +" -d, --daemon Start as daemon (Default false)\n" +" -r, --remote Remote daemon name\n" +"\n" +msgstr "" +"%s პარამეტრები ბრძანება\n" +" -h, --help ამ დახმარების ჩვენება\n" +" --version ვერსიის ჩვენება\n" +" -d, --daemon დაწყება როგორც დემონი (ნაგულისხმები " +"false)\n" +" -r, --remote დაშორებული დემონის სახელი\n" + +#: spa/plugins/alsa/acp/acp.c:321 +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 +msgid "Off" +msgstr "გამორთული" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2652 +msgid "Input" +msgstr "შეყვანა" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2653 +msgid "Docking Station Input" +msgstr "Docking Station-ის შეყვანა" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2654 +msgid "Docking Station Microphone" +msgstr "Docking Station-ის მიკროფონი" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2655 +msgid "Docking Station Line In" +msgstr "Docking Station Line In" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2656 +#: spa/plugins/alsa/acp/alsa-mixer.c:2747
View file
pipewire-0.3.56.tar.gz/po/pl.po -> pipewire-0.3.57.tar.gz/po/pl.po
Changed
@@ -8,8 +8,8 @@ "Project-Id-Version: pipewire\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2022-05-20 15:26+0000\n" -"PO-Revision-Date: 2022-05-21 12:49+0200\n" +"POT-Creation-Date: 2022-08-27 13:57+0000\n" +"PO-Revision-Date: 2022-08-27 16:00+0200\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <community-poland@mozilla.org>\n" "Language: pl\n" @@ -41,8 +41,8 @@ msgid "Start the PipeWire Media System" msgstr "Uruchomienie systemu multimediów PipeWire" -#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:183 -#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:183 +#: 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" @@ -51,7 +51,7 @@ msgid "Dummy Output" msgstr "Głuche wyjście" -#: src/modules/module-pulse-tunnel.c:639 +#: src/modules/module-pulse-tunnel.c:648 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunel dla %s@%s" @@ -70,7 +70,7 @@ msgid "%s on %s" msgstr "%s na %s" -#: src/tools/pw-cat.c:872 +#: src/tools/pw-cat.c:784 #, c-format msgid "" "%s options <file>|-\n" @@ -85,7 +85,7 @@ " -v, --verbose Wyświetla więcej komunikatów\n" "\n" -#: src/tools/pw-cat.c:879 +#: src/tools/pw-cat.c:791 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -122,7 +122,7 @@ " -P --properties Ustawia właściwości węzła\n" "\n" -#: src/tools/pw-cat.c:897 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -158,7 +158,7 @@ "(domyślnie %d)\n" "\n" -#: src/tools/pw-cat.c:914 +#: src/tools/pw-cat.c:826 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" @@ -172,7 +172,7 @@ " -d, --dsd Tryb DSD\n" "\n" -#: src/tools/pw-cli.c:3139 +#: src/tools/pw-cli.c:2255 #, c-format msgid "" "%s options command\n" @@ -195,7 +195,7 @@ msgstr "Dźwięk w zastosowaniach profesjonalnych" #: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1161 +#: spa/plugins/bluez5/bluez5-device.c:1188 msgid "Off" msgstr "Wyłączone" @@ -222,7 +222,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:1360 msgid "Microphone" msgstr "Mikrofon" @@ -288,7 +288,7 @@ msgstr "Brak podbicia basów" #: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:1335 +#: spa/plugins/bluez5/bluez5-device.c:1366 msgid "Speaker" msgstr "Głośnik" @@ -403,7 +403,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:1348 msgid "Headset" msgstr "Słuchawki z mikrofonem" @@ -527,7 +527,7 @@ msgid "%s Input" msgstr "Wejście %s" -#: 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 " @@ -552,7 +552,7 @@ "Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem " "programistom usługi ALSA." -#: 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" @@ -577,7 +577,7 @@ "Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem " "programistom usługi ALSA." -#: 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 " @@ -590,7 +590,7 @@ "Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem " "programistom usługi ALSA." -#: 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 " @@ -615,7 +615,7 @@ "Prawdopodobnie jest to błąd sterownika ALSA „%s”. Proszę zgłosić ten problem " "programistom usługi ALSA." -#: spa/plugins/alsa/acp/channelmap.h:464 +#: spa/plugins/alsa/acp/channelmap.h:457 msgid "(invalid)" msgstr "(nieprawidłowe)" @@ -627,61 +627,77 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1172 +#: spa/plugins/bluez5/bluez5-device.c:1199 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "Bramka dźwięku (źródło A2DP i AG HSP/HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1197 +#: spa/plugins/bluez5/bluez5-device.c:1224 #, c-format msgid "High Fidelity Playback (A2DP Sink, codec %s)" msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1200 +#: spa/plugins/bluez5/bluez5-device.c:1227 #, c-format msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)" msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1208 +#: spa/plugins/bluez5/bluez5-device.c:1235 msgid "High Fidelity Playback (A2DP Sink)" msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP)" -#: spa/plugins/bluez5/bluez5-device.c:1210 +#: spa/plugins/bluez5/bluez5-device.c:1237 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP)" -#: spa/plugins/bluez5/bluez5-device.c:1238 +#: spa/plugins/bluez5/bluez5-device.c:1265 #, c-format msgid "Headset Head Unit (HSP/HFP, codec %s)" msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1243 +#: spa/plugins/bluez5/bluez5-device.c:1270 msgid "Headset Head Unit (HSP/HFP)" msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1325
View file
pipewire-0.3.56.tar.gz/po/sv.po -> pipewire-0.3.57.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-05-20 15:26+0000\n" -"PO-Revision-Date: 2022-05-23 11:01+0200\n" +"POT-Creation-Date: 2022-07-19 15:27+0000\n" +"PO-Revision-Date: 2022-07-10 10:22+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.0.1\n" +"X-Generator: Poedit 3.1\n" #: src/daemon/pipewire.c:46 #, c-format @@ -51,8 +51,8 @@ msgid "Start the PipeWire Media System" msgstr "Starta mediasystemet PipeWire" -#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:183 -#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:183 +#: 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 "Tunnel till %s/%s" @@ -61,7 +61,7 @@ msgid "Dummy Output" msgstr "Attrapputgång" -#: src/modules/module-pulse-tunnel.c:639 +#: src/modules/module-pulse-tunnel.c:648 #, c-format msgid "Tunnel for %s@%s" msgstr "Tunnel för %s@%s" @@ -80,7 +80,7 @@ msgid "%s on %s" msgstr "%s på %s" -#: src/tools/pw-cat.c:872 +#: src/tools/pw-cat.c:784 #, c-format msgid "" "%s options <file>|-\n" @@ -95,7 +95,7 @@ " -v, --verbose Aktivera utförliga operationer\n" "\n" -#: src/tools/pw-cat.c:879 +#: src/tools/pw-cat.c:791 #, 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:897 +#: src/tools/pw-cat.c:809 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -160,7 +160,7 @@ "%d)\n" "\n" -#: src/tools/pw-cat.c:914 +#: src/tools/pw-cat.c:826 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:3139 +#: src/tools/pw-cli.c:3165 #, c-format msgid "" "%s options command\n" @@ -195,8 +195,8 @@ msgid "Pro Audio" msgstr "Professionellt ljud" -#: spa/plugins/alsa/acp/acp.c:444 spa/plugins/alsa/acp/alsa-mixer.c:4648 -#: spa/plugins/bluez5/bluez5-device.c:1161 +#: spa/plugins/alsa/acp/acp.c:446 spa/plugins/alsa/acp/alsa-mixer.c:4648 +#: spa/plugins/bluez5/bluez5-device.c:1188 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:1330 +#: spa/plugins/bluez5/bluez5-device.c:1360 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:1335 +#: spa/plugins/bluez5/bluez5-device.c:1366 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:1320 +#: spa/plugins/bluez5/bluez5-device.c:1348 msgid "Headset" msgstr "Headset" @@ -554,13 +554,13 @@ #: spa/plugins/alsa/acp/alsa-util.c:1239 #, 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 "" @@ -610,7 +610,7 @@ "Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera " "problemet till ALSA-utvecklarna." -#: spa/plugins/alsa/acp/channelmap.h:464 +#: spa/plugins/alsa/acp/channelmap.h:457 msgid "(invalid)" msgstr "(ogiltig)" @@ -622,61 +622,77 @@ msgid "Modem" msgstr "Modem" -#: spa/plugins/bluez5/bluez5-device.c:1172 +#: spa/plugins/bluez5/bluez5-device.c:1199 msgid "Audio Gateway (A2DP Source & HSP/HFP AG)" msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)" -#: spa/plugins/bluez5/bluez5-device.c:1197 +#: spa/plugins/bluez5/bluez5-device.c:1224 #, 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:1200 +#: spa/plugins/bluez5/bluez5-device.c:1227 #, 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:1208 +#: spa/plugins/bluez5/bluez5-device.c:1235 msgid "High Fidelity Playback (A2DP Sink)" msgstr "High fidelity-uppspelning (A2DP-utgång)" -#: spa/plugins/bluez5/bluez5-device.c:1210 +#: spa/plugins/bluez5/bluez5-device.c:1237 msgid "High Fidelity Duplex (A2DP Source/Sink)" msgstr "High fidelity duplex (A2DP-källa/utgång)" -#: spa/plugins/bluez5/bluez5-device.c:1238 +#: spa/plugins/bluez5/bluez5-device.c:1265 #, c-format msgid "Headset Head Unit (HSP/HFP, codec %s)" msgstr "Headset-huvudenhet (HSP/HFP, kodek %s)" -#: spa/plugins/bluez5/bluez5-device.c:1243 +#: spa/plugins/bluez5/bluez5-device.c:1270 msgid "Headset Head Unit (HSP/HFP)" msgstr "Headset-huvudenhet (HSP/HFP)" -#: spa/plugins/bluez5/bluez5-device.c:1325 +#: spa/plugins/bluez5/bluez5-device.c:1349 +#: spa/plugins/bluez5/bluez5-device.c:1354 +#: spa/plugins/bluez5/bluez5-device.c:1361 +#: spa/plugins/bluez5/bluez5-device.c:1367 +#: spa/plugins/bluez5/bluez5-device.c:1373 +#: spa/plugins/bluez5/bluez5-device.c:1379 +#: spa/plugins/bluez5/bluez5-device.c:1385
View file
pipewire-0.3.56.tar.gz/spa/include/spa/interfaces/audio/aec.h -> pipewire-0.3.57.tar.gz/spa/include/spa/interfaces/audio/aec.h
Changed
@@ -68,9 +68,9 @@ const struct spa_audio_aec_events *events, void *data); - int (*init) (void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info); - int (*run) (void *data, const float *rec, const float *play, float *out, uint32_t n_samples); - int (*set_props) (void *data, const struct spa_dict *args); + int (*init) (void *object, const struct spa_dict *args, const struct spa_audio_info_raw *info); + int (*run) (void *object, const float *rec, const float *play, float *out, uint32_t n_samples); + int (*set_props) (void *object, const struct spa_dict *args); }; #define spa_audio_aec_method(o,method,version,...) \
View file
pipewire-0.3.56.tar.gz/spa/include/spa/param/bluetooth/audio.h -> pipewire-0.3.57.tar.gz/spa/include/spa/param/bluetooth/audio.h
Changed
@@ -49,6 +49,11 @@ SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, /* HFP */ SPA_BLUETOOTH_AUDIO_CODEC_CVSD = 0x100,
View file
pipewire-0.3.56.tar.gz/spa/include/spa/param/bluetooth/type-info.h -> pipewire-0.3.57.tar.gz/spa/include/spa/param/bluetooth/type-info.h
Changed
@@ -53,6 +53,11 @@ { SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "faststream", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "faststream_duplex", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "lc3plus_hr", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_51", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_71", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_duplex", NULL }, + { SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "opus_05_pro", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_CVSD, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "cvsd", NULL }, { SPA_BLUETOOTH_AUDIO_CODEC_MSBC, SPA_TYPE_Int, SPA_TYPE_INFO_BLUETOOTH_AUDIO_CODEC_BASE "msbc", NULL },
View file
pipewire-0.3.56.tar.gz/spa/include/spa/utils/defs.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/defs.h
Changed
@@ -147,6 +147,12 @@ SPA_MIN(SPA_MAX(_v, _low), _high); \ }) +#define SPA_CLAMPF(v,low,high) \ +({ \ + fminf(fmaxf(v, low), high); \ +}) + + #define SPA_SWAP(a,b) \ ({ \ __typeof__(a) _t = (a); \ @@ -209,6 +215,7 @@ #define SPA_SENTINEL __attribute__((__sentinel__)) #define SPA_UNUSED __attribute__ ((unused)) #define SPA_NORETURN __attribute__ ((noreturn)) +#define SPA_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) #else #define SPA_PRINTF_FUNC(fmt, arg1) #define SPA_FORMAT_ARG_FUNC(arg1) @@ -218,6 +225,7 @@ #define SPA_SENTINEL #define SPA_UNUSED #define SPA_NORETURN +#define SPA_WARN_UNUSED_RESULT #endif #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
View file
pipewire-0.3.56.tar.gz/spa/include/spa/utils/hook.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/hook.h
Changed
@@ -382,7 +382,8 @@ /** Remove a hook */ static inline void spa_hook_remove(struct spa_hook *hook) { - spa_list_remove(&hook->link); + if (spa_list_is_initialized(&hook->link)) + spa_list_remove(&hook->link); if (hook->removed) hook->removed(hook); }
View file
pipewire-0.3.56.tar.gz/spa/include/spa/utils/list.h -> pipewire-0.3.57.tar.gz/spa/include/spa/utils/list.h
Changed
@@ -51,6 +51,11 @@ *list = SPA_LIST_INIT(list); } +static inline int spa_list_is_initialized(struct spa_list *list) +{ + return !!list->prev; +} + #define spa_list_is_empty(l) ((l)->next == (l)) static inline void spa_list_insert(struct spa_list *list, struct spa_list *elem)
View file
pipewire-0.3.56.tar.gz/spa/meson.build -> pipewire-0.3.57.tar.gz/spa/meson.build
Changed
@@ -62,6 +62,8 @@ endif endif summary({'LC3plus': lc3plus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') + opus_dep = dependency('opus', required : get_option('bluez5-codec-opus')) + summary({'Opus': opus_dep.found()}, bool_yn: true, section: 'Bluetooth audio codecs') 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.56.tar.gz/spa/plugins/aec/aec-null.c -> pipewire-0.3.57.tar.gz/spa/plugins/aec/aec-null.c
Changed
@@ -58,19 +58,18 @@ return 0; } -static struct spa_audio_aec_methods impl_aec = { +static const struct spa_audio_aec_methods impl_aec = { + SPA_VERSION_AUDIO_AEC, .init = null_init, .run = null_run, }; static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface) { - struct impl *impl; - spa_return_val_if_fail(handle != NULL, -EINVAL); spa_return_val_if_fail(interface != NULL, -EINVAL); - impl = (struct impl *) handle; + struct impl *impl = (struct impl *) handle; if (spa_streq(type, SPA_TYPE_INTERFACE_AUDIO_AEC)) *interface = &impl->aec; @@ -101,15 +100,13 @@ const struct spa_support *support, uint32_t n_support) { - struct impl *impl; - spa_return_val_if_fail(factory != NULL, -EINVAL); spa_return_val_if_fail(handle != NULL, -EINVAL); handle->get_interface = impl_get_interface; handle->clear = impl_clear; - impl = (struct impl *) handle; + struct impl *impl = (struct impl *) handle; impl->aec.iface = SPA_INTERFACE_INIT( SPA_TYPE_INTERFACE_AUDIO_AEC, @@ -119,7 +116,7 @@ impl->aec.info = NULL; impl->aec.latency = NULL; - impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); + impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); spa_log_topic_init(impl->log, &log_topic); spa_hook_list_init(&impl->hooks_list); @@ -151,7 +148,7 @@ return 1; } -const struct spa_handle_factory spa_aec_null_factory = { +static const struct spa_handle_factory spa_aec_null_factory = { SPA_VERSION_HANDLE_FACTORY, SPA_NAME_AEC, NULL, @@ -160,7 +157,6 @@ impl_enum_interface_info, }; - SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) {
View file
pipewire-0.3.56.tar.gz/spa/plugins/aec/aec-webrtc.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/aec/aec-webrtc.cpp
Changed
@@ -50,19 +50,17 @@ #undef SPA_LOG_TOPIC_DEFAULT #define SPA_LOG_TOPIC_DEFAULT &log_topic -static bool webrtc_get_spa_bool(const struct spa_dict *args, const char *key, bool default_value) { - const char *str_val; - bool value = default_value; - str_val = spa_dict_lookup(args, key); - if (str_val != NULL) - value =spa_atob(str_val); - - return value; +static bool webrtc_get_spa_bool(const struct spa_dict *args, const char *key, bool default_value) +{ + if (auto str = spa_dict_lookup(args, key)) + return spa_atob(str); + + return default_value; } -static int webrtc_init(void *data, const struct spa_dict *args, const struct spa_audio_info_raw *info) +static int webrtc_init(void *object, const struct spa_dict *args, const struct spa_audio_info_raw *info) { - auto impl = reinterpret_cast<struct impl_data*>(data); + auto impl = static_cast<struct impl_data*>(object); bool extended_filter = webrtc_get_spa_bool(args, "webrtc.extended_filter", true); bool delay_agnostic = webrtc_get_spa_bool(args, "webrtc.delay_agnostic", true); @@ -122,9 +120,9 @@ return 0; } -static int webrtc_run(void *data, const float *rec, const float *play, float *out, uint32_t n_samples) +static int webrtc_run(void *object, const float *rec, const float *play, float *out, uint32_t n_samples) { - auto impl = reinterpret_cast<struct impl_data*>(data); + auto impl = static_cast<struct impl_data*>(object); webrtc::StreamConfig config = webrtc::StreamConfig(impl->info.rate, impl->info.channels, false); unsigned int num_blocks = n_samples * 1000 / impl->info.rate / 10; @@ -160,7 +158,7 @@ return 0; } -static struct spa_audio_aec_methods impl_aec = { +static const struct spa_audio_aec_methods impl_aec = { SPA_VERSION_AUDIO_AEC_METHODS, .add_listener = NULL, .init = webrtc_init, @@ -220,7 +218,7 @@ impl->aec.info = NULL; impl->aec.latency = "480/48000", - impl->log = (struct spa_log*)spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); + impl->log = static_cast<struct spa_log *>(spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log)); spa_log_topic_init(impl->log, &log_topic); return 0; @@ -250,7 +248,7 @@ return 1; } -const struct spa_handle_factory spa_aec_webrtc_factory = { +static const struct spa_handle_factory spa_aec_webrtc_factory = { SPA_VERSION_HANDLE_FACTORY, SPA_NAME_AEC, NULL, @@ -259,7 +257,6 @@ impl_enum_interface_info, }; - SPA_EXPORT int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) {
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/acp.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/acp.c
Changed
@@ -382,8 +382,7 @@ 0, NULL, NULL, false))) { pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm); pa_proplist_setf(m->output_proplist, "clock.name", "api.alsa.%u", index); - snd_pcm_close(m->output_pcm); - m->output_pcm = NULL; + pa_alsa_close(&m->output_pcm); m->supported = true; pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX); } @@ -413,8 +412,7 @@ 0, NULL, NULL, false))) { pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm); pa_proplist_setf(m->input_proplist, "clock.name", "api.alsa.%u", index); - snd_pcm_close(m->input_pcm); - m->input_pcm = NULL; + pa_alsa_close(&m->input_pcm); m->supported = true; pa_channel_map_init_auto(&m->channel_map, m->sample_spec.channels, PA_CHANNEL_MAP_AUX); } @@ -1058,6 +1056,9 @@ uint32_t i; int res; + if (!dev->mixer_handle) + return 0; + if ((res = pa_alsa_path_get_volume(dev->mixer_path, dev->mixer_handle, &dev->mapping->channel_map, &r)) < 0) return res; @@ -1089,6 +1090,9 @@ dev->real_volume = *v; + if (!dev->mixer_handle) + return; + /* Shift up by the base volume */ pa_sw_cvolume_divide_scalar(&r, &dev->real_volume, dev->base_volume); @@ -1139,6 +1143,9 @@ bool mute; int res; + if (!dev->mixer_handle) + return 0; + if ((res = pa_alsa_path_get_mute(dev->mixer_path, dev->mixer_handle, &mute)) < 0) return res; @@ -1157,6 +1164,10 @@ static void set_mute(pa_alsa_device *dev, bool mute) { dev->muted = mute; + + if (!dev->mixer_handle) + return; + pa_alsa_path_set_mute(dev->mixer_path, dev->mixer_handle, mute); } @@ -1735,7 +1746,8 @@ setting = data->setting; } - pa_alsa_path_select(d->mixer_path, setting, d->mixer_handle, d->muted); + if (d->mixer_handle) + pa_alsa_path_select(d->mixer_path, setting, d->mixer_handle, d->muted); if (d->set_mute) d->set_mute(d, d->muted);
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-mixer.c
Changed
@@ -4966,8 +4966,7 @@ continue; pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm); - snd_pcm_close(m->output_pcm); - m->output_pcm = NULL; + pa_alsa_close(&m->output_pcm); } if (to_be_finalized->input_mappings) @@ -4986,8 +4985,7 @@ continue; pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm); - snd_pcm_close(m->input_pcm); - m->input_pcm = NULL; + pa_alsa_close(&m->input_pcm); } }
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-ucm.c
Changed
@@ -1941,8 +1941,7 @@ continue; pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm); - snd_pcm_close(m->output_pcm); - m->output_pcm = NULL; + pa_alsa_close(&m->output_pcm); } PA_IDXSET_FOREACH(m, p->input_mappings, idx) { @@ -1953,8 +1952,7 @@ continue; pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm); - snd_pcm_close(m->input_pcm); - m->input_pcm = NULL; + pa_alsa_close(&m->input_pcm); } }
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-util.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-util.c
Changed
@@ -656,6 +656,20 @@ return pcm_handle; } +int pa_alsa_close(snd_pcm_t **pcm) +{ + int err; + pa_assert(pcm); + pa_log_info("ALSA device close %p", *pcm); + if (*pcm == NULL) + return 0; + if ((err = snd_pcm_close(*pcm)) < 0) { + pa_log_warn("ALSA close failed: %s", snd_strerror(err)); + } + *pcm = NULL; + return err; +} + snd_pcm_t *pa_alsa_open_by_device_string( const char *device, char **dev, @@ -691,8 +705,8 @@ pa_log_info("Error opening PCM device %s: %s", d, pa_alsa_strerror(err)); goto fail; } - - pa_log_debug("Managed to open %s", d); + pa_log_info("ALSA device open '%s' %s: %p", d, + mode == SND_PCM_STREAM_CAPTURE ? "capture" : "playback", pcm_handle); if ((err = pa_alsa_set_hw_params( pcm_handle, @@ -707,7 +721,7 @@ if (!reformat) { reformat = true; - snd_pcm_close(pcm_handle); + pa_alsa_close(&pcm_handle); continue; } @@ -721,12 +735,12 @@ reformat = false; - snd_pcm_close(pcm_handle); + pa_alsa_close(&pcm_handle); continue; } pa_log_info("Failed to set hardware parameters on %s: %s", d, pa_alsa_strerror(err)); - snd_pcm_close(pcm_handle); + pa_alsa_close(&pcm_handle); goto fail; } @@ -734,7 +748,7 @@ if (ss->channels > PA_CHANNELS_MAX) { pa_log("Device %s has %u channels, but PulseAudio supports only %u channels. Unable to use the device.", d, ss->channels, PA_CHANNELS_MAX); - snd_pcm_close(pcm_handle); + pa_alsa_close(&pcm_handle); goto fail; }
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/acp/alsa-util.h -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/acp/alsa-util.h
Changed
@@ -115,6 +115,7 @@ void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm); void pa_alsa_dump_status(snd_pcm_t *pcm); #endif +int pa_alsa_close(snd_pcm_t **pcm); void pa_alsa_refcnt_inc(void); void pa_alsa_refcnt_dec(void);
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm-sink.c
Changed
@@ -798,38 +798,38 @@ static int impl_node_process(void *object) { struct state *this = object; - struct spa_io_buffers *input; + struct spa_io_buffers *io; spa_return_val_if_fail(this != NULL, -EINVAL); - input = this->io; - spa_return_val_if_fail(input != NULL, -EIO); + if ((io = this->io) == NULL) + return -EIO; - spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, input->status, - input->buffer_id, this->n_buffers); + spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, io->status, + io->buffer_id, this->n_buffers); if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) { - input->status = SPA_STATUS_NEED_DATA; + io->status = SPA_STATUS_NEED_DATA; return SPA_STATUS_HAVE_DATA; } - if (input->status == SPA_STATUS_HAVE_DATA && - input->buffer_id < this->n_buffers) { - struct buffer *b = &this->buffersinput->buffer_id; + if (io->status == SPA_STATUS_HAVE_DATA && + io->buffer_id < this->n_buffers) { + struct buffer *b = &this->buffersio->buffer_id; if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) { spa_log_warn(this->log, "%p: buffer %u in use", - this, input->buffer_id); - input->status = -EINVAL; + this, io->buffer_id); + io->status = -EINVAL; return -EINVAL; } - spa_log_trace_fp(this->log, "%p: queue buffer %u", this, input->buffer_id); + spa_log_trace_fp(this->log, "%p: queue buffer %u", this, io->buffer_id); spa_list_append(&this->ready, &b->link); SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT); - input->buffer_id = SPA_ID_INVALID; + io->buffer_id = SPA_ID_INVALID; spa_alsa_write(this); - input->status = SPA_STATUS_OK; + io->status = SPA_STATUS_OK; } return SPA_STATUS_HAVE_DATA; }
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm-source.c
Changed
@@ -753,8 +753,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); - io = this->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = this->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, "%p; status %d", this, io->status);
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -10,6 +10,7 @@ #include <spa/pod/filter.h> #include <spa/utils/string.h> +#include <spa/utils/result.h> #include <spa/support/system.h> #include <spa/utils/keys.h> @@ -442,9 +443,31 @@ return changed; } +#define CHECK(s,msg,...) if ((err = (s)) < 0) { spa_log_error(state->log, msg ": %s", ##__VA_ARGS__, snd_strerror(err)); return err; } + +static ssize_t log_write(void *cookie, const char *buf, size_t size) +{ + struct state *state = cookie; + int len; + + while (size > 0) { + len = strcspn(buf, "\n"); + if (len > 0) + spa_log_debug(state->log, "%.*s", (int)len, buf); + buf += len + 1; + size -= len + 1; + } + return size; +} + +static cookie_io_functions_t io_funcs = { + .write = log_write, +}; + int spa_alsa_init(struct state *state, const struct spa_dict *info) { uint32_t i; + int err; snd_config_update_free_global(); @@ -481,20 +504,31 @@ spa_log_error(state->log, "can't create card %u", state->card_index); return -errno; } + state->log_file = fopencookie(state, "w", io_funcs); + if (state->log_file == NULL) { + spa_log_error(state->log, "can't create log file"); + return -errno; + } + CHECK(snd_output_stdio_attach(&state->output, state->log_file, 0), "attach failed"); + return 0; } int spa_alsa_clear(struct state *state) { + int err; + release_card(state->card); state->card = NULL; state->card_index = SPA_ID_INVALID; - return 0; -} + if ((err = snd_output_close(state->output)) < 0) + spa_log_warn(state->log, "output close failed: %s", snd_strerror(err)); + fclose(state->log_file); -#define CHECK(s,msg,...) if ((err = (s)) < 0) { spa_log_error(state->log, msg ": %s", ##__VA_ARGS__, snd_strerror(err)); return err; } + return err; +} int spa_alsa_open(struct state *state, const char *params) { @@ -505,8 +539,6 @@ if (state->opened) return 0; - CHECK(snd_output_stdio_attach(&state->output, stderr, 0), "attach failed"); - spa_scnprintf(device_name, sizeof(device_name), "%s%s%s", state->card->ucm_prefix ? state->card->ucm_prefix : "", props->device, params ? params : ""); @@ -538,6 +570,8 @@ return 0; error_exit_close: + spa_log_info(state->log, "%p: Device '%s' closing: %s", state, state->props.device, + spa_strerror(err)); snd_pcm_close(state->hndl); return err; } @@ -556,9 +590,6 @@ spa_log_warn(state->log, "%s: close failed: %s", state->props.device, snd_strerror(err)); - if ((err = snd_output_close(state->output)) < 0) - spa_log_warn(state->log, "output close failed: %s", snd_strerror(err)); - spa_system_close(state->data_system, state->timerfd); if (state->have_format) @@ -763,6 +794,9 @@ CHECK(snd_pcm_hw_params_get_rate_min(params, &min, &dir), "get_rate_min"); CHECK(snd_pcm_hw_params_get_rate_max(params, &max, &dir), "get_rate_max"); + spa_log_debug(state->log, "min:%u max:%u min-allowed:%u scale:%u all:%d", + min, max, min_allowed_rate, scale, all); + min_allowed_rate /= scale; min = SPA_MAX(min_allowed_rate, min); @@ -782,6 +816,9 @@ rate = SPA_CLAMP(rate, min, max); + spa_log_debug(state->log, "rate:%u multi:%d card:%d def:%d", + rate, state->multi_rate, state->card->rate, state->default_rate); + spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_rate, 0); spa_pod_builder_push_choice(b, &f0, SPA_CHOICE_None, 0); @@ -833,7 +870,8 @@ CHECK(snd_pcm_hw_params_get_channels_min(params, &min), "get_channels_min"); CHECK(snd_pcm_hw_params_get_channels_max(params, &max), "get_channels_max"); - spa_log_debug(state->log, "channels (%d %d)", min, max); + spa_log_debug(state->log, "channels (%d %d) default:%d all:%d", + min, max, state->default_channels, all); if (state->default_channels != 0 && !all) { if (min < state->default_channels) @@ -914,6 +952,14 @@ return 1; } +static void debug_hw_params(struct state *state, const char *prefix, snd_pcm_hw_params_t *params) +{ + if (SPA_UNLIKELY(spa_log_level_topic_enabled(state->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_DEBUG))) { + spa_log_debug(state->log, "%s:", prefix); + snd_pcm_hw_params_dump(params, state->output); + fflush(state->log_file); + } +} static int enum_pcm_formats(struct state *state, uint32_t index, uint32_t *next, struct spa_pod **result, struct spa_pod_builder *b) { @@ -931,6 +977,8 @@ snd_pcm_hw_params_alloca(¶ms); CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available"); + debug_hw_params(state, __func__, params); + CHECK(snd_pcm_hw_params_set_rate_resample(hndl, params, 0), "set_rate_resample"); if (state->default_channels != 0) { @@ -1077,6 +1125,8 @@ snd_pcm_hw_params_alloca(¶ms); CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available"); + debug_hw_params(state, __func__, params); + CHECK(snd_pcm_hw_params_set_rate_resample(hndl, params, 0), "set_rate_resample"); spa_pod_builder_push_object(b, &f0, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat); @@ -1138,6 +1188,8 @@ snd_pcm_hw_params_alloca(¶ms); CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available"); + debug_hw_params(state, __func__, params); + snd_pcm_format_mask_alloca(&fmask); snd_pcm_hw_params_get_format_mask(params, fmask); @@ -1197,7 +1249,12 @@ struct spa_result_node_params result; uint32_t count = 0; + spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened, + state->have_format, state->started); + opened = state->opened; + if (!state->started && state->have_format) + spa_alsa_close(state); if ((err = spa_alsa_open(state, NULL)) < 0) return err; @@ -1258,6 +1315,9 @@ bool match = true, planar = false, is_batch; char spdif_params128 = ""; + spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened, + state->have_format, state->started); + state->use_mmap = !state->disable_mmap; switch (fmt->media_subtype) { @@ -1370,6 +1430,8 @@ return -EINVAL;
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-pcm.h -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -106,6 +106,8 @@ struct spa_system *data_system; struct spa_loop *data_loop; + FILE *log_file; + uint32_t card_index; struct card *card; snd_pcm_stream_t stream;
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/alsa-seq.c -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/alsa-seq.c
Changed
@@ -186,7 +186,7 @@ static void debug_event(struct seq_state *state, snd_seq_event_t *ev) { - if (SPA_LIKELY(!spa_log_level_enabled(state->log, SPA_LOG_LEVEL_TRACE))) + if (SPA_LIKELY(!spa_log_level_topic_enabled(state->log, SPA_LOG_TOPIC_DEFAULT, SPA_LOG_LEVEL_TRACE))) return; spa_log_trace(state->log, "event type:%d flags:0x%x", ev->type, ev->flags);
View file
pipewire-0.3.56.tar.gz/spa/plugins/alsa/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/alsa/meson.build
Changed
@@ -34,13 +34,18 @@ install : true, ) - executable('test-timer', 'test-timer.c' , dependencies : spa_dep, alsa_dep, mathlib, epoll_shim_dep , install : false, ) +executable('test-hw-params', + 'test-hw-params.c' , + dependencies : spa_dep, alsa_dep, mathlib , + install : false, +) + if libudev_dep.found() install_data(alsa_udevrules, install_dir : udevrulesdir,
View file
pipewire-0.3.57.tar.gz/spa/plugins/alsa/test-hw-params.c
Added
@@ -0,0 +1,173 @@ +/* Spa + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdbool.h> +#include <limits.h> +#include <getopt.h> +#include <math.h> + +#include <alsa/asoundlib.h> + +#include <spa/utils/defs.h> + +#define DEFAULT_DEVICE "default" + + +struct state { + const char *device; + snd_output_t *output; + snd_pcm_t *hndl; +}; + +#define CHECK(s,msg,...) { \ + int __err; \ + if ((__err = (s)) < 0) { \ + fprintf(stderr, msg ": %s\n", ##__VA_ARGS__, snd_strerror(__err)); \ + return __err; \ + } \ +} + +static const char *get_class(snd_pcm_class_t c) +{ + switch (c) { + case SND_PCM_CLASS_GENERIC: + return "generic"; + case SND_PCM_CLASS_MULTI: + return "multichannel"; + case SND_PCM_CLASS_MODEM: + return "modem"; + case SND_PCM_CLASS_DIGITIZER: + return "digitizer"; + default: + return "unknown"; + } +} + +static const char *get_subclass(snd_pcm_subclass_t c) +{ + switch (c) { + case SND_PCM_SUBCLASS_GENERIC_MIX: + return "generic-mix"; + case SND_PCM_SUBCLASS_MULTI_MIX: + return "multichannel-mix"; + default: + return "unknown"; + } +} + +static void show_help(const char *name, bool error) +{ + fprintf(error ? stderr : stdout, "%s options\n" + " -h, --help Show this help\n" + " -D, --device device name (default '%s')\n" + " -C, --capture capture mode (default playback)\n", + name, DEFAULT_DEVICE); +} + +int main(int argc, char *argv) +{ + struct state state = { 0, }; + snd_pcm_hw_params_t *hparams; + snd_pcm_info_t *info; + snd_pcm_sync_id_t sync; + snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; + snd_pcm_chmap_query_t **maps; + int c, i; + static const struct option long_options = { + { "help", no_argument, NULL, 'h' }, + { "device", required_argument, NULL, 'D' }, + { "capture", no_argument, NULL, 'C' }, + { NULL, 0, NULL, 0} + }; + state.device = DEFAULT_DEVICE; + + while ((c = getopt_long(argc, argv, "hD:C", long_options, NULL)) != -1) { + switch (c) { + case 'h': + show_help(argv0, false); + return 0; + case 'D': + state.device = optarg; + break; + case 'C': + stream = SND_PCM_STREAM_CAPTURE; + break; + default: + show_help(argv0, true); + return -1; + } + } + + CHECK(snd_output_stdio_attach(&state.output, stdout, 0), "attach failed"); + + fprintf(stdout, "opening device: '%s'\n", state.device); + + CHECK(snd_pcm_open(&state.hndl, state.device, stream, 0), + "open %s failed", state.device); + + snd_pcm_info_alloca(&info); + snd_pcm_info(state.hndl, info); + + fprintf(stdout, "info:\n"); + fprintf(stdout, " device: %u\n", snd_pcm_info_get_device(info)); + fprintf(stdout, " subdevice: %u\n", snd_pcm_info_get_subdevice(info)); + fprintf(stdout, " stream: %s\n", snd_pcm_stream_name(snd_pcm_info_get_stream(info))); + fprintf(stdout, " card: %d\n", snd_pcm_info_get_card(info)); + fprintf(stdout, " id: '%s'\n", snd_pcm_info_get_id(info)); + fprintf(stdout, " name: '%s'\n", snd_pcm_info_get_name(info)); + fprintf(stdout, " subdevice name: '%s'\n", snd_pcm_info_get_subdevice_name(info)); + fprintf(stdout, " class: %s\n", get_class(snd_pcm_info_get_class(info))); + fprintf(stdout, " subclass: %s\n", get_subclass(snd_pcm_info_get_subclass(info))); + fprintf(stdout, " subdevice count: %u\n", snd_pcm_info_get_subdevices_count(info)); + fprintf(stdout, " subdevice avail: %u\n", snd_pcm_info_get_subdevices_avail(info)); + sync = snd_pcm_info_get_sync(info); + fprintf(stdout, " sync: %08x:%08x:%08x:%08x\n", + sync.id320, sync.id321, sync.id322,sync.id323); + + /* channel maps */ + if ((maps = snd_pcm_query_chmaps(state.hndl)) != NULL) { + fprintf(stdout, "channels:\n"); + + for (i = 0; mapsi; i++) { + snd_pcm_chmap_t* map = &mapsi->map; + char buf2048; + + snd_pcm_chmap_print(map, sizeof(buf), buf); + + fprintf(stdout, " %d: %s\n", map->channels, buf); + } + snd_pcm_free_chmaps(maps); + } + + /* hw params */ + snd_pcm_hw_params_alloca(&hparams); + snd_pcm_hw_params_any(state.hndl, hparams); + + snd_pcm_hw_params_dump(hparams, state.output); + + snd_pcm_close(state.hndl); + + return EXIT_SUCCESS; +}
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -909,8 +909,7 @@ } break; case SPA_PROP_rate: - if (spa_pod_get_double(&prop->value, &p->rate) == 0) - changed++; + spa_pod_get_double(&prop->value, &p->rate); break; case SPA_PROP_params: changed += parse_prop_params(this, &prop->value); @@ -1471,26 +1470,29 @@ rate = this->io_position ? this->io_position->clock.rate.denom : DEFAULT_RATE; - if (in->format.info.raw.rate == 0 && in->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) + /* in DSP mode we always convert to the DSP rate */ + if (in->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) in->format.info.raw.rate = rate; - if (out->format.info.raw.rate == 0 && out->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) + if (out->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) out->format.info.raw.rate = rate; + /* try to passthrough the rates */ if (in->format.info.raw.rate == 0) in->format.info.raw.rate = out->format.info.raw.rate; else if (out->format.info.raw.rate == 0) out->format.info.raw.rate = in->format.info.raw.rate; - if (in->format.info.raw.rate == 0 && out->format.info.raw.rate == 0) - return -EINVAL; - if (in->format.info.raw.channels == 0 && out->format.info.raw.channels == 0) - return -EINVAL; - + /* try to passthrough the channels */ if (in->format.info.raw.channels == 0) in->format.info.raw.channels = out->format.info.raw.channels; else if (out->format.info.raw.channels == 0) out->format.info.raw.channels = in->format.info.raw.channels; + if (in->format.info.raw.rate == 0 || out->format.info.raw.rate == 0) + return -EINVAL; + if (in->format.info.raw.channels == 0 || out->format.info.raw.channels == 0) + return -EINVAL; + if ((res = setup_in_convert(this)) < 0) return res; if ((res = setup_channelmix(this)) < 0) @@ -1722,21 +1724,51 @@ param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); break; case SPA_PARAM_Buffers: + { + uint32_t size; + struct dir *dir; + if (!port->have_format) return -EIO; if (result.index > 0) return 0; + dir = &this->dirdirection; + if (dir->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) { + /* DSP ports always use the quantum_limit as the buffer + * size. */ + size = this->quantum_limit; + } else { + uint32_t irate, orate; + /* Convert ports are scaled so that they can always + * provide one quantum of data */ + irate = dir->format.info.raw.rate; + + /* collect the other port rate */ + dir = &this->dirSPA_DIRECTION_REVERSE(direction); + if (dir->mode == SPA_PARAM_PORT_CONFIG_MODE_dsp) + orate = this->io_position ? this->io_position->clock.rate.denom : DEFAULT_RATE; + else + orate = dir->format.info.raw.rate; + + /* always keep some extra room for adaptive resampling */ + size = this->quantum_limit * 2; + /* scale the buffer size when we can. */ + if (irate != 0 && orate != 0) + size = size * (irate + orate - 1) / orate; + } + param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS), SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(port->blocks), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int( - this->quantum_limit * port->stride, + size * port->stride, 16 * port->stride, INT32_MAX), SPA_PARAM_BUFFERS_stride, SPA_POD_Int(port->stride)); break; + } case SPA_PARAM_Meta: switch (result.index) { case 0: @@ -2193,15 +2225,22 @@ return end ? 1 : 0; } +static uint32_t resample_get_in_size(struct impl *this, bool passthrough, uint32_t out_size) +{ + uint32_t match_size = passthrough ? out_size : resample_in_len(&this->resample, out_size); + spa_log_trace_fp(this->log, "%p: current match %u", this, match_size); + return match_size; +} + static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t out_size, uint32_t in_queued) { - double rate = this->rate_scale / this->props.rate; uint32_t delay, match_size; if (passthrough) { delay = 0; match_size = out_size; } else { + double rate = this->rate_scale / this->props.rate; if (this->io_rate_match && SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)) rate *= this->io_rate_match->rate; @@ -2470,16 +2509,16 @@ /* calculate how many samples we are going to consume. */ if (this->direction == SPA_DIRECTION_INPUT) { - uint32_t n_in; - /* then figure out how much input samples we need to consume */ - n_in = resample_update_rate_match(this, resample_passthrough, n_out, 0); if (!in_avail || this->drained) { + /* no input, ask for more, update rate-match first */ + resample_update_rate_match(this, resample_passthrough, n_out, 0); spa_log_trace_fp(this->log, "%p: no input drained:%d", this, this->drained); - /* no input, ask for more */ res |= this->drained ? SPA_STATUS_DRAINED : SPA_STATUS_NEED_DATA; return res; } - n_samples = SPA_MIN(n_samples, n_in); + /* else figure out how much input samples we need to consume */ + n_samples = SPA_MIN(n_samples, + resample_get_in_size(this, resample_passthrough, n_out)); } else { /* in merge mode we consume one duration of samples */ n_samples = SPA_MIN(n_samples, quant_samples);
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/channelmix-ops.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/channelmix-ops.c
Changed
@@ -200,6 +200,7 @@ matrixii= 1.0f; } src_mask = dst_mask = ~0LU; + filter_fc = filter_lfe = true; goto done; } else { spa_log_debug(mix->log, "matching channels"); @@ -398,6 +399,15 @@ spa_log_debug(mix->log, "unassigned upmix %08"PRIx64" lfe:%f", unassigned, mix->lfe_cutoff); + if (unassigned & STEREO) { + if ((src_mask & FRONT) == FRONT) { + spa_log_debug(mix->log, "produce STEREO from FC"); + _MATRIX(FL,FC) += clev; + _MATRIX(FR,FC) += clev; + } else { + spa_log_warn(mix->log, "can't produce STEREO"); + } + } if (unassigned & FRONT) { if ((src_mask & STEREO) == STEREO) { spa_log_debug(mix->log, "produce FC from STEREO"); @@ -431,10 +441,13 @@ spa_log_debug(mix->log, "produce SIDE from STEREO"); _MATRIX(SL,FL) += slev; _MATRIX(SR,FR) += slev; - } else if ((src_mask & FRONT) == FRONT) { + } else if ((src_mask & FRONT) == FRONT && + mix->upmix == CHANNELMIX_UPMIX_SIMPLE) { spa_log_debug(mix->log, "produce SIDE from FC"); _MATRIX(SL,FC) += clev; _MATRIX(SR,FC) += clev; + } else { + spa_log_debug(mix->log, "won't produce SIDE"); } } if (unassigned & REAR) { @@ -446,10 +459,13 @@ spa_log_debug(mix->log, "produce REAR from STEREO"); _MATRIX(RL,FL) += slev; _MATRIX(RR,FR) += slev; - } else if ((src_mask & FRONT) == FRONT) { + } else if ((src_mask & FRONT) == FRONT && + mix->upmix == CHANNELMIX_UPMIX_SIMPLE) { spa_log_debug(mix->log, "produce REAR from FC"); _MATRIX(RL,FC) += clev; _MATRIX(RR,FC) += clev; + } else { + spa_log_debug(mix->log, "won't produce SIDE"); } }
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops-avx2.c
Changed
@@ -362,7 +362,7 @@ float *d0 = dst0, *d1 = dst1, *d2 = dst2, *d3 = dst3; uint32_t n, unrolled; __m256i in4, t4; - __m256 out4, factor = _mm256_set1_ps(1.0f / S32_SCALE); + __m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE); __m256i mask1 = _mm256_setr_epi64x(0*n_channels, 0*n_channels+2, 4*n_channels, 4*n_channels+2); __m256i mask2 = _mm256_setr_epi64x(1*n_channels, 1*n_channels+2, 5*n_channels, 5*n_channels+2); __m256i mask3 = _mm256_setr_epi64x(2*n_channels, 2*n_channels+2, 6*n_channels, 6*n_channels+2); @@ -391,6 +391,11 @@ in2 = _mm256_unpacklo_epi64(t1, t3); /* c0 c1 c2 c3 c4 c5 c6 c7 */ in3 = _mm256_unpackhi_epi64(t1, t3); /* d0 d1 d2 d3 d4 d5 d6 d7 */ + in0 = _mm256_srai_epi32(in0, 8); + in1 = _mm256_srai_epi32(in1, 8); + in2 = _mm256_srai_epi32(in2, 8); + in3 = _mm256_srai_epi32(in3, 8); + out0 = _mm256_cvtepi32_ps(in0); out1 = _mm256_cvtepi32_ps(in1); out2 = _mm256_cvtepi32_ps(in2); @@ -409,11 +414,11 @@ s += 8*n_channels; } for(; n < n_samples; n++) { - __m128 out4, factor = _mm_set1_ps(1.0f / S32_SCALE); - out0 = _mm_cvtsi32_ss(factor, s0); - out1 = _mm_cvtsi32_ss(factor, s1); - out2 = _mm_cvtsi32_ss(factor, s2); - out3 = _mm_cvtsi32_ss(factor, s3); + __m128 out4, factor = _mm_set1_ps(1.0f / S24_SCALE); + out0 = _mm_cvtsi32_ss(factor, s0 >> 8); + out1 = _mm_cvtsi32_ss(factor, s1 >> 8); + out2 = _mm_cvtsi32_ss(factor, s2 >> 8); + out3 = _mm_cvtsi32_ss(factor, s3 >> 8); out0 = _mm_mul_ss(out0, factor); out1 = _mm_mul_ss(out1, factor); out2 = _mm_mul_ss(out2, factor); @@ -434,7 +439,7 @@ float *d0 = dst0, *d1 = dst1; uint32_t n, unrolled; __m256i in4, t4; - __m256 out4, factor = _mm256_set1_ps(1.0f / S32_SCALE); + __m256 out4, factor = _mm256_set1_ps(1.0f / S24_SCALE); __m256i perm = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7); __m256i mask1 = _mm256_setr_epi64x(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels); __m256i mask2 = _mm256_setr_epi64x(4*n_channels, 5*n_channels, 6*n_channels, 7*n_channels); @@ -455,6 +460,9 @@ in0 = _mm256_permute2x128_si256(t0, t1, 0 | (2 << 4)); in1 = _mm256_permute2x128_si256(t0, t1, 1 | (3 << 4)); + in0 = _mm256_srai_epi32(in0, 8); + in1 = _mm256_srai_epi32(in1, 8); + out0 = _mm256_cvtepi32_ps(in0); out1 = _mm256_cvtepi32_ps(in1); @@ -467,9 +475,9 @@ s += 8*n_channels; } for(; n < n_samples; n++) { - __m128 out2, factor = _mm_set1_ps(1.0f / S32_SCALE); - out0 = _mm_cvtsi32_ss(factor, s0); - out1 = _mm_cvtsi32_ss(factor, s1); + __m128 out2, factor = _mm_set1_ps(1.0f / S24_SCALE); + out0 = _mm_cvtsi32_ss(factor, s0 >> 8); + out1 = _mm_cvtsi32_ss(factor, s1 >> 8); out0 = _mm_mul_ss(out0, factor); out1 = _mm_mul_ss(out1, factor); _mm_store_ss(&d0n, out0); @@ -486,7 +494,7 @@ float *d0 = dst0; uint32_t n, unrolled; __m256i in2; - __m256 out2, factor = _mm256_set1_ps(1.0f / S32_SCALE); + __m256 out2, factor = _mm256_set1_ps(1.0f / S24_SCALE); __m256i mask1 = _mm256_setr_epi64x(0*n_channels, 1*n_channels, 2*n_channels, 3*n_channels); __m256i mask2 = _mm256_setr_epi64x(4*n_channels, 5*n_channels, 6*n_channels, 7*n_channels); @@ -503,6 +511,9 @@ _mm256_i64gather_epi32(&s 8*n_channels, mask1, 4), _mm256_i64gather_epi32(&s 8*n_channels, mask2, 4)); + in0 = _mm256_srai_epi32(in0, 8); + in1 = _mm256_srai_epi32(in1, 8); + out0 = _mm256_cvtepi32_ps(in0); out1 = _mm256_cvtepi32_ps(in1); @@ -515,8 +526,8 @@ s += 16*n_channels; } for(; n < n_samples; n++) { - __m128 out, factor = _mm_set1_ps(1.0f / S32_SCALE); - out = _mm_cvtsi32_ss(factor, s0); + __m128 out, factor = _mm_set1_ps(1.0f / S24_SCALE); + out = _mm_cvtsi32_ss(factor, s0 >> 8); out = _mm_mul_ss(out, factor); _mm_store_ss(&d0n, out); s += n_channels;
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops-neon.c
Changed
@@ -26,6 +26,8 @@ #include <stdio.h> #include <math.h> +#include <arm_neon.h> + #include "fmt-ops.h" void @@ -289,16 +291,19 @@ #ifdef __aarch64__ asm volatile( + " dup v2.4s, %wscale\n" " cmp %n_samples, #0\n" " beq 2f\n" "1:" " ld1 { v0.4s }, %s0, #16\n" " ld1 { v1.4s }, %s1, #16\n" " subs %n_samples, %n_samples, #4\n" - " fcvtzs v0.4s, v0.4s, #31\n" - " fcvtzs v1.4s, v1.4s, #31\n" - " sqrshrn v0.4h, v0.4s, #16\n" - " sqrshrn v1.4h, v1.4s, #16\n" + " sqadd v0.4s, v0.4s, v2.4s\n" + " sqadd v1.4s, v1.4s, v2.4s\n" + " fcvtns v0.4s, v0.4s\n" + " fcvtns v1.4s, v1.4s\n" + " sqxtn v0.4h, v0.4s\n" + " sqxtn v1.4h, v1.4s\n" " st2 { v0.h, v1.h }0, %d, %stride\n" " st2 { v0.h, v1.h }1, %d, %stride\n" " st2 { v0.h, v1.h }2, %d, %stride\n" @@ -311,29 +316,42 @@ " ld1 { v0.s }0, %s0, #4\n" " ld1 { v2.s }0, %s1, #4\n" " subs %remainder, %remainder, #1\n" - " fcvtzs v0.4s, v0.4s, #31\n" - " fcvtzs v1.4s, v1.4s, #31\n" - " sqrshrn v0.4h, v0.4s, #16\n" - " sqrshrn v1.4h, v1.4s, #16\n" + " sqadd v0.4s, v0.4s, v2.4s\n" + " sqadd v1.4s, v1.4s, v2.4s\n" + " fcvtns v0.4s, v0.4s\n" + " fcvtns v1.4s, v1.4s\n" + " sqxtn v0.4h, v0.4s\n" + " sqxtn v1.4h, v1.4s\n" " st2 { v0.h, v1.h }0, %d, %stride\n" " bne 3b\n" "4:" : d "+r" (d), s0 "+r" (s0), s1 "+r" (s1), n_samples "+r" (n_samples), remainder "+r" (remainder) - : stride "r" (stride) + : stride "r" (stride), + scale "r" (15 << 23) : "cc", "v0", "v1"); #else + float32x4_t pos = vdupq_n_f32(0.4999999f / S16_SCALE); + float32x4_t neg = vdupq_n_f32(-0.4999999f / S16_SCALE); + asm volatile( + " veor q2, q2, q2\n" " cmp %n_samples, #0\n" " beq 2f\n" "1:" " vld1.32 { q0 }, %s0!\n" " vld1.32 { q1 }, %s1!\n" " subs %n_samples, %n_samples, #4\n" - " vcvt.s32.f32 q0, q0, #31\n" - " vcvt.s32.f32 q1, q1, #31\n" - " vqrshrn.s32 d0, q0, #16\n" - " vqrshrn.s32 d1, q1, #16\n" + " vcgt.f32 q3, q0, q2\n" + " vcgt.f32 q4, q0, q2\n" + " vbsl q3, %qpos, %qneg\n" + " vbsl q4, %qpos, %qneg\n" + " vadd.f32 q0, q0, q3\n" + " vadd.f32 q1, q1, q4\n" + " vcvt.s32.f32 q0, q0, #15\n" + " vcvt.s32.f32 q1, q1, #15\n" + " vqmovn.s32 d0, q0\n" + " vqmovn.s32 d1, q1\n" " vst2.16 { d00, d10 }, %d, %stride\n" " vst2.16 { d01, d11 }, %d, %stride\n" " vst2.16 { d02, d12 }, %d, %stride\n" @@ -346,17 +364,25 @@ " vld1.32 { d00 }, %s0!\n" " vld1.32 { d20 }, %s1!\n" " subs %remainder, %remainder, #1\n" - " vcvt.s32.f32 q0, q0, #31\n" - " vcvt.s32.f32 q1, q1, #31\n" - " vqrshrn.s32 d0, q0, #16\n" - " vqrshrn.s32 d1, q1, #16\n" + " vcgt.f32 q3, q0, q2\n" + " vcgt.f32 q4, q0, q2\n" + " vbsl q3, %qpos, %qneg\n" + " vbsl q4, %qpos, %qneg\n" + " vadd.f32 q0, q0, q3\n" + " vadd.f32 q1, q1, q4\n" + " vcvt.s32.f32 q0, q0, #15\n" + " vcvt.s32.f32 q1, q1, #15\n" + " vqmovn.s32 d0, q0\n" + " vqmovn.s32 d1, q1\n" " vst2.16 { d00, d10 }, %d, %stride\n" " bne 3b\n" "4:" : d "+r" (d), s0 "+r" (s0), s1 "+r" (s1), n_samples "+r" (n_samples), remainder "+r" (remainder) - : stride "r" (stride) - : "cc", "q0", "q1"); + : stride "r" (stride), + pos"w"(pos), + neg"w"(neg) + : "cc", "q0", "q1", "q2", "q3", "q4"); #endif } @@ -372,13 +398,15 @@ #ifdef __aarch64__ asm volatile( + " dup v2.4s, %wscale\n" " cmp %n_samples, #0\n" " beq 2f\n" "1:" " ld1 { v0.4s }, %s, #16\n" " subs %n_samples, %n_samples, #4\n" - " fcvtzs v0.4s, v0.4s, #31\n" - " sqrshrn v0.4h, v0.4s, #16\n" + " sqadd v0.4s, v0.4s, v2.4s\n" + " fcvtns v0.4s, v0.4s\n" + " sqxtn v0.4h, v0.4s\n" " st1 { v0.h }0, %d, %stride\n" " st1 { v0.h }1, %d, %stride\n" " st1 { v0.h }2, %d, %stride\n" @@ -390,24 +418,33 @@ "3:" " ld1 { v0.s }0, %s, #4\n" " subs %remainder, %remainder, #1\n" - " fcvtzs v0.4s, v0.4s, #31\n" - " sqrshrn v0.4h, v0.4s, #16\n" + " sqadd v0.4s, v0.4s, v2.4s\n" + " fcvtns v0.4s, v0.4s\n" + " sqxtn v0.4h, v0.4s\n" " st1 { v0.h }0, %d, %stride\n" " bne 3b\n" "4:" : d "+r" (d), s "+r" (s), n_samples "+r" (n_samples), remainder "+r" (remainder) - : stride "r" (stride) + : stride "r" (stride), + scale "r" (15 << 23) : "cc", "v0"); #else + float32x4_t pos = vdupq_n_f32(0.4999999f / S16_SCALE); + float32x4_t neg = vdupq_n_f32(-0.4999999f / S16_SCALE); + asm volatile( + " veor q1, q1, q1\n" " cmp %n_samples, #0\n" " beq 2f\n" "1:" " vld1.32 { q0 }, %s!\n" " subs %n_samples, %n_samples, #4\n" - " vcvt.s32.f32 q0, q0, #31\n" - " vqrshrn.s32 d0, q0, #16\n" + " vcgt.f32 q2, q0, q1\n" + " vbsl q2, %qpos, %qneg\n" + " vadd.f32 q0, q0, q2\n" + " vcvt.s32.f32 q0, q0, #15\n" + " vqmovn.s32 d0, q0\n" " vst1.16 { d00 }, %d, %stride\n" " vst1.16 { d01 }, %d, %stride\n" " vst1.16 { d02 }, %d, %stride\n" @@ -419,15 +456,20 @@ "3:" " vld1.32 { d00 }, %s!\n" " subs %remainder, %remainder, #1\n" - " vcvt.s32.f32 q0, q0, #31\n" - " vqrshrn.s32 d0, q0, #16\n" + " vcgt.f32 q2, q0, q1\n" + " vbsl q2, %qpos, %qneg\n" + " vadd.f32 q0, q0, q2\n" + " vcvt.s32.f32 q0, q0, #15\n" + " vqmovn.s32 d0, q0\n" " vst1.16 { d00 }, %d, %stride\n" " bne 3b\n" "4:" : d "+r" (d), s "+r" (s), n_samples "+r" (n_samples), remainder "+r" (remainder) - : stride "r" (stride) - : "cc", "q0"); + : stride "r" (stride), + pos"w"(pos), + neg"w"(neg) + : "cc", "q0", "q1", "q2"); #endif }
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/fmt-ops.h -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/fmt-ops.h
Changed
@@ -40,7 +40,7 @@ #define ITOF(type,v,scale,offs) \ (((type)(v)) * (1.0f / (scale)) - (offs)) #define FTOI(type,v,scale,offs,noise,min,max) \ - (type)f32_round(SPA_CLAMP((v) * (scale) + (offs) + (noise), min, max)) + (type)f32_round(SPA_CLAMPF((v) * (scale) + (offs) + (noise), min, max)) #define FMT_OPS_MAX_ALIGN 32 @@ -119,9 +119,8 @@ #define F32_TO_S24_32S(v) bswap_32(F32_TO_S24_32(v)) #define F32_TO_S24_32S_D(v,d) bswap_32(F32_TO_S24_32_D(v,d)) -#define S32_MIN -2147483648 -#define S32_MAX 2147483647 -#define S32_SCALE 2147483648.f +#define S32_MIN (S24_MIN * 256) +#define S32_MAX (S24_MAX * 256) #define S32_TO_F32(v) ITOF(int32_t, (v) >> 8, S24_SCALE, 0.0f) #define S32S_TO_F32(v) S32_TO_F32(bswap_32(v)) #define F32_TO_S32(v) (F32_TO_S24_32(v) << 8)
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/resample-native.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/resample-native.c
Changed
@@ -68,14 +68,15 @@ } static inline double window_cosh(double x, double n_taps) { - double R = 190.0, r; - double A = (-325.1E-6 * R + 0.1677) * R - 3.149; + double r; + double A = 16.97789; double x2; x = 2.0 * x / n_taps; x2 = x * x; if (x2 >= 1.0) return 0.0; - r = cosh(A * sqrt(1 - x2)) / cosh(A); + /* doi:10.1109/RME.2008.4595727 with tweak */ + r = (exp(A * sqrt(1 - x2)) - 1) / (exp(A) - 1); return r; }
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/test-fmt-ops.c
Changed
@@ -242,6 +242,12 @@ false, true, conv_f32d_to_s16_avx2); } #endif +#if defined(HAVE_NEON) + if (cpu_flags & SPA_CPU_FLAG_NEON) { + run_test("test_f32d_s16_neon", in, sizeof(in0), out, sizeof(out0), SPA_N_ELEMENTS(out), + false, true, conv_f32d_to_s16_neon); + } +#endif } static void test_s16_f32(void) @@ -269,6 +275,12 @@ true, false, conv_s16_to_f32d_avx2); } #endif +#if defined(HAVE_NEON) + if (cpu_flags & SPA_CPU_FLAG_NEON) { + run_test("test_s16_f32d_neon", in, sizeof(in0), out, sizeof(out0), SPA_N_ELEMENTS(out), + true, false, conv_s16_to_f32d_neon); + } +#endif } static void test_f32_u32(void)
View file
pipewire-0.3.56.tar.gz/spa/plugins/audioconvert/test-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/audioconvert/test-source.c
Changed
@@ -749,9 +749,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = GET_OUT_PORT(this, 0); - - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, NAME " %p: status %d", this, io->status);
View file
pipewire-0.3.56.tar.gz/spa/plugins/audiomixer/audiomixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiomixer/audiomixer.c
Changed
@@ -730,8 +730,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); outport = GET_OUT_PORT(this, 0); - outio = outport->io; - spa_return_val_if_fail(outio != NULL, -EIO); + if ((outio = outport->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, "%p: status %p %d %d", this, outio, outio->status, outio->buffer_id);
View file
pipewire-0.3.56.tar.gz/spa/plugins/audiomixer/mixer-dsp.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiomixer/mixer-dsp.c
Changed
@@ -675,8 +675,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); outport = GET_OUT_PORT(this, 0); - outio = outport->io; - spa_return_val_if_fail(outio != NULL, -EIO); + if ((outio = outport->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, "%p: status %p %d %d", this, outio, outio->status, outio->buffer_id);
View file
pipewire-0.3.56.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/audiotestsrc/audiotestsrc.c
Changed
@@ -931,7 +931,8 @@ port = &this->port; io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (port->io_control) process_control(this, &port->io_control->sequence);
View file
pipewire-0.3.56.tar.gz/spa/plugins/avb/avb-pcm-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avb-pcm-sink.c
Changed
@@ -699,40 +699,39 @@ { struct state *this = object; struct port *port; - struct spa_io_buffers *input; + struct spa_io_buffers *io; spa_return_val_if_fail(this != NULL, -EINVAL); port = GET_PORT(this, SPA_DIRECTION_INPUT, 0); + if ((io = port->io) == NULL) + return -EIO; - input = port->io; - spa_return_val_if_fail(input != NULL, -EIO); - - spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, input->status, - input->buffer_id, port->n_buffers); + spa_log_trace_fp(this->log, "%p: process %d %d/%d", this, io->status, + io->buffer_id, port->n_buffers); if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) { - input->status = SPA_STATUS_NEED_DATA; + io->status = SPA_STATUS_NEED_DATA; return SPA_STATUS_HAVE_DATA; } - if (input->status == SPA_STATUS_HAVE_DATA && - input->buffer_id < port->n_buffers) { - struct buffer *b = &port->buffersinput->buffer_id; + if (io->status == SPA_STATUS_HAVE_DATA && + io->buffer_id < port->n_buffers) { + struct buffer *b = &port->buffersio->buffer_id; if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) { spa_log_warn(this->log, "%p: buffer %u in use", - this, input->buffer_id); - input->status = -EINVAL; + this, io->buffer_id); + io->status = -EINVAL; return -EINVAL; } - spa_log_trace_fp(this->log, "%p: queue buffer %u", this, input->buffer_id); + spa_log_trace_fp(this->log, "%p: queue buffer %u", this, io->buffer_id); spa_list_append(&port->ready, &b->link); SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT); - input->buffer_id = SPA_ID_INVALID; + io->buffer_id = SPA_ID_INVALID; spa_avb_write(this); - input->status = SPA_STATUS_OK; + io->status = SPA_STATUS_OK; } return SPA_STATUS_HAVE_DATA; }
View file
pipewire-0.3.56.tar.gz/spa/plugins/avb/avb-pcm-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avb-pcm-source.c
Changed
@@ -705,9 +705,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = GET_PORT(this, SPA_DIRECTION_OUTPUT, 0); - - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, "%p: process %d %d/%d %d", this, io->status, io->buffer_id, port->n_buffers, this->following);
View file
pipewire-0.3.56.tar.gz/spa/plugins/avb/avbtp/packets.h -> pipewire-0.3.57.tar.gz/spa/plugins/avb/avbtp/packets.h
Changed
@@ -116,7 +116,7 @@ unsigned gv:1; unsigned tv:1; - uint8_t seq_number; + uint8_t seq_num; unsigned _r2:7; unsigned tu:1;
View file
pipewire-0.3.57.tar.gz/spa/plugins/bluez5/README-OPUS-A2DP.md
Added
@@ -0,0 +1,321 @@ +--- +title: OPUS-A2DP-0.5 specification +author: Pauli Virtanen <pav@iki.fi> +date: Jun 4, 2022 +--- + +# OPUS-A2DP-0.5 specification + +DRAFT + +In this file, we specify how to use Opus as an A2DP vendor codec. We +will call this "OPUS-A2DP-0.5". There is no previous public +specification for using Opus as an A2DP vendor codec (to my +knowledge), which is why we need this one. + +_TOC_ + +# A2DP Codec Capabilities + +The A2DP capability structure is as follows. + +Integer fields and multi-byte bitfields are laid out in **little +endian** order. All integer fields are unsigned. + +Each entry may have different meaning when present as a capability. +Below, we indicate this by abbreviations CAP/SNK for sink capability, +CAP/SRC for source capability, CAP for capability as either, and SEL +for the selected value by SRC. + +Bits in fields marked RFA (Reserved For Additions) shall be set to +zero. + +The capability and configuration structure is as follows: + +| Octet | Bits | Meaning | +|-------|------|-----------------------------------------------| +| 0-5 | 0-7 | Vendor ID Part | +| 6-7 | 0-7 | Channel Configuration | +| 8-11 | 0-7 | Audio Location Configuration | +| 12-14 | 0-7 | Limits Configuration | +| 15-16 | 0-7 | Return Direction Channel Configuration | +| 17-20 | 0-7 | Return Direction Audio Location Configuration | +| 21-23 | 0-7 | Return Direction Limits Configuration | + +See `a2dp-codec-caps.h` for definition as C structs. + +## Vendor ID Part + +The fixed value + +| Octet | Bits | Meaning | +|-------|------|-------------------------------| +| 0-3 | 0-7 | A2DP Vendor ID (0x05F1) | +| 4-5 | 0-7 | A2DP Vendor Codec ID (0x1005) | + +The Vendor ID is that of the Linux Foundation, and we are using it +here unofficially. + +## Channel Configuration + +The channel configuration consists of the channel count and a bitfield +indicating which of them are encoded in coupled streams. + +| Octet | Bits | Meaning | +|-------|------|------------------------------------------------------------| +| 6 | 0-7 | Channel Count. CAP: maximum number supported. SEL: actual. | +| 7 | 0-7 | Coupled Stream Count. CAP: 0. SEL: actual. | + +The Channel Count indicates the number of logical channels encoded in +the data stream. + +The Coupled Stream Count indicates the number of streams that encode a +coupled (left & right) channel pair. The count shall satisfy +`(Channel Count) >= 2*(Coupled Stream Count)`. +The Stream Count is `(Channel Count) - (Coupled Stream Count)`. + +Streams and Coupled Streams have the same meaning as in Sec. 5.1.1 of +Opus Multistream RFC7845. + +The logical Channels are identified by a Channel Index *j* such that `0 <= j +< (Channel Count)`. The channels `0 <= j < 2*(Coupled Stream Count)` +are encoded in the *k*-th stream of the payload, where `k = floor(j/2)` and +`j mod 2` determines which of the two channels of the stream the logical +channel is. The channels `2*(Coupled Stream Count) <= j < (Channel Count)` +are encoded in the *k*-th stream of the payload, where `k = j - (Coupled Stream Count)`. +The prescription here is identical to RFC7845 with channel mapping +`mappingj = j`. + +The semantic meaning for each channel is determined by their Audio +Location. + +## Audio Location Configuration + +The channel audio location specification is similar to the location +bitfield of the `Audio_Channel_Allocation` LTV structure in Bluetooth +SIG Assigned Numbers, Generic Audio used in the LE Audio. + +| Octet | Bits | Meaning | +|-------|------|------------------------------------------------------| +| 8-11 | 0-7 | Audio Location bitfield. CAP: available. SEL: actual | + +The values specified in CAP are informative, and SEL may contain bits +that were not set in CAP. SNK shall handle unsupported audio +locations. It may do this for example by ignoring unsupported channels +or via suitable up/downmixing. Hence, SRC may transmit channels with +audio locations that are not marked supported by SNK. The maximum +Channel Count however shall not be exceeded. + +The audio location bitfield values defined in Assigned Numbers, +Generic Audio are: + +| Channel Order | Bitmask | Audio Location | +|---------------|------------|-------------------------| +| 0 | 0x00000001 | Front Left | +| 1 | 0x00000002 | Front Right | +| 2 | 0x00000400 | Side Left | +| 3 | 0x00000800 | Side Right | +| 4 | 0x00000010 | Back Left | +| 5 | 0x00000020 | Back Right | +| 6 | 0x00000040 | Front Left of Center | +| 7 | 0x00000080 | Front Right of Center | +| 8 | 0x00001000 | Top Front Left | +| 9 | 0x00002000 | Top Front Right | +| 10 | 0x00040000 | Top Side Left | +| 11 | 0x00080000 | Top Side Right | +| 12 | 0x00010000 | Top Back Left | +| 13 | 0x00020000 | Top Back Right | +| 14 | 0x00400000 | Bottom Front Left | +| 15 | 0x00800000 | Bottom Front Right | +| 16 | 0x01000000 | Front Left Wide | +| 17 | 0x02000000 | Front Right Wide | +| 18 | 0x04000000 | Left Surround | +| 19 | 0x08000000 | Right Surround | +| 20 | 0x00000004 | Front Center | +| 21 | 0x00000100 | Back Center | +| 22 | 0x00004000 | Top Front Center | +| 23 | 0x00008000 | Top Center | +| 24 | 0x00100000 | Top Back Center | +| 25 | 0x00200000 | Bottom Front Center | +| 26 | 0x00000008 | Low Frequency Effects 1 | +| 27 | 0x00000200 | Low Frequency Effects 2 | +| 28 | 0x10000000 | RFA | +| 29 | 0x20000000 | RFA | +| 30 | 0x40000000 | RFA | +| 31 | 0x80000000 | RFA | + +In addition, we define a specific Channel Order for each. The bits +set in the bitfield define audio locations for the streams present in the +payload. The set bit with the smallest Channel Order value defines the +audio location for the Channel Index *j=0*, the bit with the next +lowest Channel Order value defines the audio location for the Channel +Index *j=1*, and so forth. + +When the Channel Count is larger than the number of bits set in the +Audio Location bitfield, the audio locations of the remaining channels +are unspecified. Implementations may handle them as appropriate for +their use case, considering them as AUX0-AUXN, or in the case of +Channel Count = 1, as the single mono audio channel. + +When the Channel Count is smaller than the number of bits set in the +Audio Location bitfield, the audio locations for the channels are +assigned as above, and remaining excess bits shall be ignored. + +The channel ordering defined here is compatible with the internal +stream ordering in the reference Opus Multistream surround encoder +Mapping Family 0 and 1 output. This allows making use of its surround +masking and LFE handling capabilities. The stream ordering of the +reference Opus surround encoder, although being unchanged since its +addition in 2013, is an internal detail of the +encoder. Implementations using the surround encoder shall check that +the mapping table used by the encoder corresponds to the above channel +ordering. + +For reference, we list the Audio Location bitfield values +corresponding to the different channel counts in Opus Mapping Family 0 +and 1 surround encoder output, and the expected mapping table: + +| Mapping Family | Channel Count | Audio Location Value | Stream Ordering | Mapping Table | +|----------------|---------------|----------------------|---------------------------------|--------------------------| +| 0 | 1 | 0x00000000 | mono | {0} | +| 0 | 2 | 0x00000003 | FL, FR | {0, 1} | +| 1 | 1 | 0x00000000 | mono | {0} | +| 1 | 2 | 0x00000003 | FL, FR | {0, 1} | +| 1 | 3 | 0x00000007 | FL, FR, FC | {0, 2, 1} | +| 1 | 4 | 0x00000033 | FL, FR, BL, BR | {0, 1, 2, 3} | +| 1 | 5 | 0x00000037 | FL, FR, BL, BR, FC | {0, 4, 1, 2, 3} | +| 1 | 6 | 0x0000003f | FL, FR, BL, BR, FC, LFE | {0, 4, 1, 2, 3, 5} | +| 1 | 7 | 0x00000d0f | FL, FR, SL, SR, FC, BC, LFE | {0, 4, 1, 2, 3, 5, 6} | +| 1 | 8 | 0x00000c3f | FL, FR, SL, SR, BL, BR, FC, LFE | {0, 6, 1, 2, 3, 4, 5, 7} | + +The Mapping Table in the table indicates the mapping table selected by +`opus_multistream_surround_encoder_create` (Opus 1.3.1). If the +encoder outputs a different mapping table in a future Opus encoder +release, the channel ordering will be incorrect, and the surround +encoder can not be used. We expect that the probability of the Opus +encoder authors making such changes is negligible. + +## Limits Configuration +
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
@@ -31,10 +31,16 @@ #include <spa/utils/dict.h> #include <fdk-aac/aacenc_lib.h> +#include <fdk-aac/aacdecoder_lib.h> #include "rtp.h" #include "a2dp-codecs.h" +static struct spa_log *log; +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.aac"); +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &log_topic + #define DEFAULT_AAC_BITRATE 320000 #define MIN_AAC_BITRATE 64000 @@ -44,6 +50,7 @@ struct impl { HANDLE_AACENCODER aacenc; + HANDLE_AACDECODER aacdec; struct rtp_header *header; @@ -170,7 +177,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -289,7 +296,7 @@ return 0; } -static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings) +static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings) { struct props *p = calloc(1, sizeof(struct props)); const char *str; @@ -412,11 +419,39 @@ this->codesize = enc_info.frameLength * this->channels * this->samplesize; + this->aacdec = aacDecoder_Open(TT_MP4_LATM_MCP1, 1); + if (!this->aacdec) { + res = -EINVAL; + goto error; + } + +#ifdef AACDECODER_LIB_VL0 + res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MIN_OUTPUT_CHANNELS, this->channels); + if (res != AAC_DEC_OK) { + spa_log_debug(log, "Couldn't set min output channels: 0x%04X", res); + goto error; + } + + res = aacDecoder_SetParam(this->aacdec, AAC_PCM_MAX_OUTPUT_CHANNELS, this->channels); + if (res != AAC_DEC_OK) { + spa_log_debug(log, "Couldn't set max output channels: 0x%04X", res); + goto error; + } +#else + res = aacDecoder_SetParam(this->aacdec, AAC_PCM_OUTPUT_CHANNELS, this->channels); + if (res != AAC_DEC_OK) { + spa_log_debug(log, "Couldn't set output channels: 0x%04X", res); + goto error; + } +#endif + return this; error: if (this && this->aacenc) aacEncClose(&this->aacenc); + if (this && this->aacdec) + aacDecoder_Close(this->aacdec); free(this); errno = -res; return NULL; @@ -427,6 +462,8 @@ struct impl *this = data; if (this->aacenc) aacEncClose(&this->aacenc); + if (this->aacdec) + aacDecoder_Close(this->aacdec); free(this); } @@ -502,6 +539,55 @@ return out_args.numInSamples * this->samplesize; } +static int codec_start_decode (void *data, + const void *src, size_t src_size, uint16_t *seqnum, uint32_t *timestamp) +{ + const struct rtp_header *header = src; + size_t header_size = sizeof(struct rtp_header); + + spa_return_val_if_fail (src_size > header_size, -EINVAL); + + if (seqnum) + *seqnum = ntohs(header->sequence_number); + if (timestamp) + *timestamp = ntohl(header->timestamp); + + return header_size; +} + +static int codec_decode(void *data, + const void *src, size_t src_size, + void *dst, size_t dst_size, + size_t *dst_out) +{ + struct impl *this = data; + uint data_size = (uint)src_size; + uint bytes_valid = data_size; + CStreamInfo *aacinf; + int res; + + res = aacDecoder_Fill(this->aacdec, (UCHAR **)&src, &data_size, &bytes_valid); + if (res != AAC_DEC_OK) { + spa_log_debug(log, "AAC buffer fill error: 0x%04X", res); + return -EINVAL; + } + + res = aacDecoder_DecodeFrame(this->aacdec, dst, dst_size, 0); + if (res != AAC_DEC_OK) { + spa_log_debug(log, "AAC decode frame error: 0x%04X", res); + return -EINVAL; + } + + aacinf = aacDecoder_GetStreamInfo(this->aacdec); + if (!aacinf) { + spa_log_debug(log, "AAC get stream info failed"); + return -EINVAL; + } + *dst_out = aacinf->frameSize * aacinf->numChannels * this->samplesize; + + return src_size - bytes_valid; +} + static int codec_abr_process (void *data, size_t unsent) { return -ENOTSUP; @@ -538,6 +624,12 @@ return codec_change_bitrate(this, (this->cur_bitrate * 4) / 3); } +static void codec_set_log(struct spa_log *global_log) +{ + log = global_log; + spa_log_topic_init(log, &log_topic); +} + const struct a2dp_codec a2dp_codec_aac = { .id = SPA_BLUETOOTH_AUDIO_CODEC_AAC, .codec_id = A2DP_CODEC_MPEG24, @@ -554,9 +646,12 @@ .get_block_size = codec_get_block_size, .start_encode = codec_start_encode, .encode = codec_encode, + .start_decode = codec_start_decode, + .decode = codec_decode, .abr_process = codec_abr_process, .reduce_bitpool = codec_reduce_bitpool, .increase_bitpool = codec_increase_bitpool, + .set_log = codec_set_log, }; A2DP_CODEC_EXPORT_DEF(
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-aptx.c
Changed
@@ -218,7 +218,7 @@ return actual_conf_size; } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -458,7 +458,7 @@ * When connected as SRC to SNK, aptX-LL sink may send back mSBC data. */ -static int msbc_enum_config(const struct a2dp_codec *codec, +static int msbc_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -710,6 +710,11 @@ .increase_bitpool = msbc_increase_bitpool, }; +static const struct spa_dict_item duplex_info_items = { + { "duplex.boost", "true" }, +}; +static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items); + const struct a2dp_codec a2dp_codec_aptx_ll_duplex_0 = { APTX_LL_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX, @@ -718,6 +723,7 @@ .name = "aptx_ll_duplex", .endpoint_name = "aptx_ll_duplex_0", .duplex_codec = &aptx_ll_msbc, + .info = &duplex_info, }; const struct a2dp_codec a2dp_codec_aptx_ll_duplex_1 = { @@ -728,6 +734,7 @@ .name = "aptx_ll_duplex", .endpoint_name = "aptx_ll_duplex_1", .duplex_codec = &aptx_ll_msbc, + .info = &duplex_info, }; A2DP_CODEC_EXPORT_DEF(
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-caps.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-caps.h
Changed
@@ -233,6 +233,54 @@ #define LC3PLUS_HR_SAMPLING_FREQ_48000 (1 << 8) #define LC3PLUS_HR_SAMPLING_FREQ_96000 (1 << 7) +#define OPUS_05_VENDOR_ID 0x000005f1 +#define OPUS_05_CODEC_ID 0x1005 + +#define OPUS_05_MAPPING_FAMILY_0 (1 << 0) +#define OPUS_05_MAPPING_FAMILY_1 (1 << 1) +#define OPUS_05_MAPPING_FAMILY_255 (1 << 2) + +#define OPUS_05_FRAME_DURATION_25 (1 << 0) +#define OPUS_05_FRAME_DURATION_50 (1 << 1) +#define OPUS_05_FRAME_DURATION_100 (1 << 2) +#define OPUS_05_FRAME_DURATION_200 (1 << 3) +#define OPUS_05_FRAME_DURATION_400 (1 << 4) + +#define OPUS_05_GET_UINT16(a, field) \ + (((a).field ## 2 << 8) | (a).field ## 1) +#define OPUS_05_INIT_UINT16(field, v) \ + .field ## 1 = ((v) & 0xff), \ + .field ## 2 = (((v) >> 8) & 0xff), +#define OPUS_05_SET_UINT16(a, field, v) \ + do { \ + (a).field ## 1 = ((v) & 0xff); \ + (a).field ## 2 = (((v) >> 8) & 0xff); \ + } while (0) +#define OPUS_05_GET_UINT32(a, field) \ + (((a).field ## 4 << 24) | ((a).field ## 3 << 16) | \ + ((a).field ## 2 << 8) | (a).field ## 1) +#define OPUS_05_INIT_UINT32(field, v) \ + .field ## 1 = ((v) & 0xff), \ + .field ## 2 = (((v) >> 8) & 0xff), \ + .field ## 3 = (((v) >> 16) & 0xff), \ + .field ## 4 = (((v) >> 24) & 0xff), +#define OPUS_05_SET_UINT32(a, field, v) \ + do { \ + (a).field ## 1 = ((v) & 0xff); \ + (a).field ## 2 = (((v) >> 8) & 0xff); \ + (a).field ## 3 = (((v) >> 16) & 0xff); \ + (a).field ## 4 = (((v) >> 24) & 0xff); \ + } while (0) + +#define OPUS_05_GET_LOCATION(a) OPUS_05_GET_UINT32(a, location) +#define OPUS_05_INIT_LOCATION(v) OPUS_05_INIT_UINT32(location, v) +#define OPUS_05_SET_LOCATION(a, v) OPUS_05_SET_UINT32(a, location, v) + +#define OPUS_05_GET_BITRATE(a) OPUS_05_GET_UINT16(a, bitrate) +#define OPUS_05_INIT_BITRATE(v) OPUS_05_INIT_UINT16(bitrate, v) +#define OPUS_05_SET_BITRATE(a, v) OPUS_05_SET_UINT16(a, bitrate, v) + + typedef struct { uint32_t vendor_id; uint16_t codec_id; @@ -391,4 +439,22 @@ uint8_t frequency2; } __attribute__ ((packed)) a2dp_lc3plus_hr_t; +typedef struct { + uint8_t channels; + uint8_t coupled_streams; + uint8_t location1; + uint8_t location2; + uint8_t location3; + uint8_t location4; + uint8_t frame_duration; + uint8_t bitrate1; + uint8_t bitrate2; +} __attribute__ ((packed)) a2dp_opus_05_direction_t; + +typedef struct { + a2dp_vendor_codec_t info; + a2dp_opus_05_direction_t main; + a2dp_opus_05_direction_t bidi; +} __attribute__ ((packed)) a2dp_opus_05_t; + #endif
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-faststream.c
Changed
@@ -129,7 +129,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -372,7 +372,7 @@ * When connected as SRC to SNK, FastStream sink may send back SBC data. */ -static int duplex_enum_config(const struct a2dp_codec *codec, +static int duplex_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -614,17 +614,23 @@ .reduce_bitpool = codec_reduce_bitpool, \ .increase_bitpool = codec_increase_bitpool -const struct a2dp_codec a2dp_codec_faststream = { +static const struct a2dp_codec a2dp_codec_faststream = { FASTSTREAM_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, .name = "faststream", }; +static const struct spa_dict_item duplex_info_items = { + { "duplex.boost", "true" }, +}; +static const struct spa_dict duplex_info = SPA_DICT_INIT_ARRAY(duplex_info_items); + const struct a2dp_codec a2dp_codec_faststream_duplex = { FASTSTREAM_COMMON_DEFS, .id = SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, .name = "faststream_duplex", .duplex_codec = &duplex_codec, + .info = &duplex_info, }; A2DP_CODEC_EXPORT_DEF(
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
@@ -150,8 +150,8 @@ return sizeof(conf); } -static int codec_caps_preference_cmp(const struct a2dp_codec *codec, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info) +static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings) { a2dp_lc3plus_hr_t conf1, conf2; a2dp_lc3plus_hr_t *conf; @@ -160,7 +160,7 @@ /* Order selected configurations by preference */ res1 = codec->select_config(codec, 0, caps1, caps1_size, info, NULL, (uint8_t *)&conf1); - res2 = codec->select_config(codec, 0, caps2, caps2_size, info , NULL, (uint8_t *)&conf2); + res2 = codec->select_config(codec, 0, caps2, caps2_size, info, NULL, (uint8_t *)&conf2); #define PREFER_EXPR(expr) \ do { \ @@ -190,7 +190,7 @@ #undef PREFER_BOOL } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) {
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-ldac.c
Changed
@@ -150,7 +150,7 @@ return sizeof(conf); } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) { @@ -284,7 +284,7 @@ return LDACBT_EQMID_AUTO; } -static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings) +static void *codec_init_props(const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings) { struct props *p = calloc(1, sizeof(struct props)); const char *str; @@ -469,10 +469,10 @@ error_errno: res = -errno; error: - if (this->ldac) + if (this && this->ldac) ldacBT_free_handle(this->ldac); #ifdef ENABLE_LDAC_ABR - if (this->ldac_abr) + if (this && this->ldac_abr) ldac_ABR_free_handle(this->ldac_abr); #endif free(this);
View file
pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-opus.c
Added
@@ -0,0 +1,1437 @@ +/* Spa A2DP Opus Codec + * + * Copyright © 2020 Wim Taymans + * Copyright © 2022 Pauli Virtanen + * + * 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 <unistd.h> +#include <string.h> +#include <stddef.h> +#include <errno.h> +#include <arpa/inet.h> +#if __BYTE_ORDER != __LITTLE_ENDIAN +#include <byteswap.h> +#endif + +#include <spa/debug/types.h> +#include <spa/param/audio/type-info.h> +#include <spa/param/audio/raw.h> +#include <spa/utils/string.h> +#include <spa/utils/dict.h> +#include <spa/param/audio/format.h> +#include <spa/param/audio/format-utils.h> + +#include <opus.h> +#include <opus_multistream.h> + +#include "rtp.h" +#include "a2dp-codecs.h" + +static struct spa_log *log; +static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.codecs.opus"); +#undef SPA_LOG_TOPIC_DEFAULT +#define SPA_LOG_TOPIC_DEFAULT &log_topic + +#define BUFSIZE_FROM_BITRATE(frame_dms,bitrate) ((bitrate)/8 * (frame_dms) / 10000 * 5/4) /* estimate */ + +/* + * Opus CVBR target bitrate. When connecting, it is set to the INITIAL + * value, and after that adjusted according to link quality between the MIN and + * MAX values. The bitrate adjusts up to either MAX or the value at + * which the socket buffer starts filling up, whichever is lower. + * + * With perfect connection quality, the target bitrate converges to the MAX + * value. Under realistic conditions, the upper limit may often be as low as + * 300-500kbit/s, so the INITIAL values are not higher than this. + * + * The MAX is here set to 2-2.5x and INITIAL to 1.5x the upper Opus recommended + * values 1, to be safer quality-wise for CVBR, and MIN to the lower + * recommended value. + * + * 1 https://wiki.xiph.org/Opus_Recommended_Settings + */ +#define BITRATE_INITIAL 192000 +#define BITRATE_MAX 320000 +#define BITRATE_MIN 96000 + +#define BITRATE_INITIAL_51 384000 +#define BITRATE_MAX_51 600000 +#define BITRATE_MIN_51 128000 + +#define BITRATE_INITIAL_71 450000 +#define BITRATE_MAX_71 900000 +#define BITRATE_MIN_71 256000 + +#define BITRATE_DUPLEX_BIDI 160000 + +#define OPUS_05_MAX_BYTES (15 * 1024) + +struct props { + uint32_t channels; + uint32_t coupled_streams; + uint32_t location; + uint32_t max_bitrate; + uint8_t frame_duration; + int application; + + uint32_t bidi_channels; + uint32_t bidi_coupled_streams; + uint32_t bidi_location; + uint32_t bidi_max_bitrate; + uint32_t bidi_frame_duration; + int bidi_application; +}; + +struct dec_data { + int fragment_size; + int fragment_count; + uint8_t fragmentOPUS_05_MAX_BYTES; +}; + +struct abr { + uint64_t now; + uint64_t last_update; + + uint32_t buffer_level; + uint32_t packet_size; + uint32_t total_size; + bool bad; + + uint64_t last_change; + uint64_t retry_interval; + + bool prev_bad; +}; + +struct enc_data { + struct rtp_header *header; + struct rtp_payload *payload; + + struct abr abr; + + int samples; + int codesize; + + int packet_size; + int fragment_size; + int fragment_count; + void *fragment; + + int bitrate_min; + int bitrate_max; + + int bitrate; + int next_bitrate; + + int frame_dms; + int application; +}; + +struct impl { + OpusMSEncoder *enc; + OpusMSDecoder *dec; + + int mtu; + int samplerate; + int application; + + uint8_t channels; + uint8_t streams; + uint8_t coupled_streams; + + bool is_bidi; + + struct dec_data d; + struct enc_data e; +}; + +struct audio_location { + uint32_t mask; + enum spa_audio_channel position; +}; + +struct surround_encoder_mapping { + uint8_t channels; + uint8_t coupled_streams; + uint32_t location; + uint8_t mapping8; /**< permutation streams -> vorbis order */ + uint8_t inv_mapping8; /**< permutation vorbis order -> streams */ +}; + +/* Bluetooth SIG, Assigned Numbers, Generic Audio, Audio Location Definitions */ +#define BT_AUDIO_LOCATION_FL 0x00000001 /* Front Left */ +#define BT_AUDIO_LOCATION_FR 0x00000002 /* Front Right */ +#define BT_AUDIO_LOCATION_FC 0x00000004 /* Front Center */ +#define BT_AUDIO_LOCATION_LFE 0x00000008 /* Low Frequency Effects 1 */ +#define BT_AUDIO_LOCATION_RL 0x00000010 /* Back Left */ +#define BT_AUDIO_LOCATION_RR 0x00000020 /* Back Right */ +#define BT_AUDIO_LOCATION_FLC 0x00000040 /* Front Left of Center */ +#define BT_AUDIO_LOCATION_FRC 0x00000080 /* Front Right of Center */ +#define BT_AUDIO_LOCATION_RC 0x00000100 /* Back Center */ +#define BT_AUDIO_LOCATION_LFE2 0x00000200 /* Low Frequency Effects 2 */ +#define BT_AUDIO_LOCATION_SL 0x00000400 /* Side Left */ +#define BT_AUDIO_LOCATION_SR 0x00000800 /* Side Right */ +#define BT_AUDIO_LOCATION_TFL 0x00001000 /* Top Front Left */ +#define BT_AUDIO_LOCATION_TFR 0x00002000 /* Top Front Right */ +#define BT_AUDIO_LOCATION_TFC 0x00004000 /* Top Front Center */ +#define BT_AUDIO_LOCATION_TC 0x00008000 /* Top Center */ +#define BT_AUDIO_LOCATION_TRL 0x00010000 /* Top Back Left */ +#define BT_AUDIO_LOCATION_TRR 0x00020000 /* Top Back Right */ +#define BT_AUDIO_LOCATION_TSL 0x00040000 /* Top Side Left */
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codec-sbc.c
Changed
@@ -229,8 +229,8 @@ return sizeof(conf); } -static int codec_caps_preference_cmp(const struct a2dp_codec *codec, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info) +static int codec_caps_preference_cmp(const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, const struct spa_dict *global_settings) { a2dp_sbc_t conf1, conf2; a2dp_sbc_t *conf; @@ -356,7 +356,7 @@ return this->sbc.bitpool; } -static int codec_enum_config(const struct a2dp_codec *codec, +static int codec_enum_config(const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *b, struct spa_pod **param) {
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codecs.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codecs.c
Changed
@@ -62,7 +62,8 @@ bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id, const void *caps, size_t caps_size, - const struct a2dp_codec_audio_info *info) + const struct a2dp_codec_audio_info *info, + const struct spa_dict *global_settings) { uint8_t configA2DP_MAX_CAPS_SIZE; int res; @@ -73,7 +74,7 @@ if (caps == NULL) return false; - res = codec->select_config(codec, 0, caps, caps_size, info, NULL, config); + res = codec->select_config(codec, 0, caps, caps_size, info, global_settings, config); if (res < 0) return false;
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-codecs.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-codecs.h
Changed
@@ -33,6 +33,7 @@ #include <spa/support/plugin.h> #include <spa/pod/pod.h> #include <spa/pod/builder.h> +#include <spa/support/log.h> #include "a2dp-codec-caps.h" @@ -43,7 +44,7 @@ #define SPA_TYPE_INTERFACE_Bluez5CodecA2DP SPA_TYPE_INFO_INTERFACE_BASE "Bluez5:Codec:A2DP:Private" -#define SPA_VERSION_BLUEZ5_CODEC_A2DP 1 +#define SPA_VERSION_BLUEZ5_CODEC_A2DP 5 struct spa_bluez5_codec_a2dp { struct spa_interface iface; @@ -62,6 +63,7 @@ extern const char *codec_plugin_factory_name; #endif +#define A2DP_CODEC_FLAG_SINK (1 << 0) #define A2DP_CODEC_DEFAULT_RATE 48000 #define A2DP_CODEC_DEFAULT_CHANNELS 2 @@ -96,8 +98,8 @@ int (*select_config) (const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info, - const struct spa_dict *settings, uint8_t configA2DP_MAX_CAPS_SIZE); - int (*enum_config) (const struct a2dp_codec *codec, + const struct spa_dict *global_settings, uint8_t configA2DP_MAX_CAPS_SIZE); + int (*enum_config) (const struct a2dp_codec *codec, uint32_t flags, const void *caps, size_t caps_size, uint32_t id, uint32_t idx, struct spa_pod_builder *builder, struct spa_pod **param); int (*validate_config) (const struct a2dp_codec *codec, uint32_t flags, @@ -109,10 +111,11 @@ * The caps handed in correspond to this codec_id, but are * otherwise not checked beforehand. */ - int (*caps_preference_cmp) (const struct a2dp_codec *codec, const void *caps1, size_t caps1_size, - const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info); + int (*caps_preference_cmp) (const struct a2dp_codec *codec, uint32_t flags, const void *caps1, size_t caps1_size, + const void *caps2, size_t caps2_size, const struct a2dp_codec_audio_info *info, + const struct spa_dict *global_settings); - void *(*init_props) (const struct a2dp_codec *codec, const struct spa_dict *settings); + void *(*init_props) (const struct a2dp_codec *codec, uint32_t flags, const struct spa_dict *settings); void (*clear_props) (void *); int (*enum_props) (void *props, const struct spa_dict *settings, uint32_t id, uint32_t idx, struct spa_pod_builder *builder, struct spa_pod **param); @@ -144,6 +147,8 @@ int (*reduce_bitpool) (void *data); int (*increase_bitpool) (void *data); + + void (*set_log) (struct spa_log *global_log); }; struct a2dp_codec_config { @@ -156,6 +161,7 @@ uint32_t cap, int preferred_value); bool a2dp_codec_check_caps(const struct a2dp_codec *codec, unsigned int codec_id, - const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info); + const void *caps, size_t caps_size, const struct a2dp_codec_audio_info *info, + const struct spa_dict *global_settings); #endif
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-sink.c
Changed
@@ -137,6 +137,8 @@ unsigned int started:1; unsigned int following:1; + unsigned int is_duplex:1; + struct spa_source source; int timerfd; struct spa_source flush_source; @@ -908,7 +910,8 @@ for (i = 0; i < size; i++) spa_log_debug(this->log, " %d: %02x", i, confi); - this->codec_data = this->codec->init(this->codec, 0, + this->codec_data = this->codec->init(this->codec, + this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0, this->transport->configuration, this->transport->configuration_len, &port->current_format, @@ -1195,6 +1198,7 @@ return -EIO; if ((res = this->codec->enum_config(this->codec, + this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0, this->transport->configuration, this->transport->configuration_len, id, result.index, &b, ¶m)) != 1) @@ -1457,8 +1461,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) { io->status = SPA_STATUS_NEED_DATA; @@ -1697,6 +1701,9 @@ spa_list_init(&port->ready); + if (info && (str = spa_dict_lookup(info, "api.bluez5.a2dp-duplex")) != NULL) + this->is_duplex = spa_atob(str); + if (info && (str = spa_dict_lookup(info, SPA_KEY_API_BLUEZ5_TRANSPORT))) sscanf(str, "pointer:%p", &this->transport); @@ -1708,9 +1715,20 @@ spa_log_error(this->log, "a transport codec is needed"); return -EINVAL; } + this->codec = this->transport->a2dp_codec; + + if (this->is_duplex) { + if (!this->codec->duplex_codec) { + spa_log_error(this->log, "transport codec doesn't support duplex"); + return -EINVAL; + } + this->codec = this->codec->duplex_codec; + } + if (this->codec->init_props != NULL) this->codec_props = this->codec->init_props(this->codec, + this->is_duplex ? A2DP_CODEC_FLAG_SINK : 0, this->transport->device->settings); reset_props(this, &this->props);
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/a2dp-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/a2dp-source.c
Changed
@@ -142,6 +142,7 @@ unsigned int is_input:1; unsigned int is_duplex:1; + unsigned int use_duplex_source:1; int fd; struct spa_source source; @@ -629,7 +630,8 @@ this->transport_acquired = true; - this->codec_data = this->codec->init(this->codec, 0, + this->codec_data = this->codec->init(this->codec, + this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK, this->transport->configuration, this->transport->configuration_len, &port->current_format, @@ -668,7 +670,7 @@ this->source.data = this; - if (!this->is_duplex) { + if (!this->use_duplex_source) { this->source.fd = this->transport->fd; this->source.func = a2dp_on_ready_read; this->source.mask = SPA_IO_IN; @@ -683,7 +685,8 @@ * XXX: The reason for this should be found and fixed. * XXX: To work around this, for now we just do the stupid thing and poll * XXX: on a timer, chosen so that it's fast enough for the aptX-LL codec - * XXX: we currently support (which sends mSBC data). + * XXX: we currently support (which sends mSBC data), and also for Opus + * XXX: forward stream. */ this->source.fd = this->duplex_timerfd; this->source.func = a2dp_on_duplex_timeout; @@ -691,7 +694,7 @@ this->source.rmask = 0; spa_loop_add_source(this->data_loop, &this->source); - this->duplex_timeout = SPA_NSEC_PER_MSEC * 75/10; + this->duplex_timeout = SPA_NSEC_PER_MSEC * 25/10; set_duplex_timeout(this, this->duplex_timeout); } @@ -718,13 +721,13 @@ if (this->started) return 0; + spa_return_val_if_fail(this->transport != NULL, -EIO); + this->following = is_following(this); spa_log_debug(this->log, "%p: start state:%d following:%d", this, this->transport->state, this->following); - spa_return_val_if_fail(this->transport != NULL, -EIO); - if (this->transport->state >= SPA_BT_TRANSPORT_STATE_PENDING || this->is_duplex) res = transport_start(this); @@ -965,6 +968,7 @@ return -EIO; if ((res = this->codec->enum_config(this->codec, + this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK, this->transport->configuration, this->transport->configuration_len, id, result.index, &b, ¶m)) != 1) @@ -1341,8 +1345,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; spa_log_trace(this->log, "%p status:%d", this, io->status); @@ -1575,9 +1579,11 @@ this->codec = this->codec->duplex_codec; this->is_input = true; } + this->use_duplex_source = this->is_duplex || (this->codec->duplex_codec != NULL); if (this->codec->init_props != NULL) this->codec_props = this->codec->init_props(this->codec, + this->is_duplex ? 0 : A2DP_CODEC_FLAG_SINK, this->transport->device->settings); spa_bt_transport_add_listener(this->transport, @@ -1586,7 +1592,7 @@ this->timerfd = spa_system_timerfd_create(this->data_system, CLOCK_MONOTONIC, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); - if (this->is_duplex) { + if (this->use_duplex_source) { this->duplex_timerfd = spa_system_timerfd_create(this->data_system, CLOCK_MONOTONIC, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); } else {
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez-hardware.conf -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez-hardware.conf
Changed
@@ -39,6 +39,7 @@ { name = "Motorola DC800", no-features = sbc-xq }, # #pipewire-1590 { name = "Motorola S305", no-features = sbc-xq }, # #pipewire-1590 { name = "Soundcore Life P2-L", no-features = msbc-alt1, msbc-alt1-rtl }, + { name = "Soundcore Motion B", no-features = hw-volume }, { name = "SoundCore mini", no-features = hw-volume }, # #pipewire-1686 { name = "SoundCore 2", no-features = sbc-xq }, # #pipewire-2291 { name = "Tribit MAXSound Plus", no-features = hw-volume }, # #pipewire-1592
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -125,6 +125,10 @@ struct spa_bt_quirks *quirks; +#define MAX_SETTINGS 128 + struct spa_dict_item global_setting_itemsMAX_SETTINGS; + struct spa_dict global_settings; + /* A reference audio info for A2DP codec configuration. */ struct a2dp_codec_audio_info default_audio_info; }; @@ -437,18 +441,21 @@ return 0; } -static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint) +static const struct a2dp_codec *a2dp_endpoint_to_codec(struct spa_bt_monitor *monitor, const char *endpoint, bool *sink) { const char *ep_name; const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs; int i; - if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) + if (spa_strstartswith(endpoint, A2DP_SINK_ENDPOINT "/")) { ep_name = endpoint + strlen(A2DP_SINK_ENDPOINT "/"); - else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) + *sink = true; + } else if (spa_strstartswith(endpoint, A2DP_SOURCE_ENDPOINT "/")) { ep_name = endpoint + strlen(A2DP_SOURCE_ENDPOINT "/"); - else + *sink = false; + } else { return NULL; + } for (i = 0; a2dp_codecsi; i++) { const struct a2dp_codec *codec = a2dp_codecsi; @@ -486,6 +493,7 @@ DBusError err; int i, size, res; const struct a2dp_codec *codec; + bool sink; dbus_error_init(&err); @@ -501,14 +509,15 @@ for (i = 0; i < size; i++) spa_log_debug(monitor->log, " %d: %02x", i, capi); - codec = a2dp_endpoint_to_codec(monitor, path); + codec = a2dp_endpoint_to_codec(monitor, path, &sink); if (codec != NULL) /* FIXME: We can't determine which device the SelectConfiguration() * call is associated with, therefore device settings are not passed. * This causes inconsistency with SelectConfiguration() triggered * by codec switching. */ - res = codec->select_config(codec, 0, cap, size, &monitor->default_audio_info, NULL, config); + res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, cap, size, &monitor->default_audio_info, + &monitor->global_settings, config); else res = -ENOTSUP; @@ -1543,7 +1552,7 @@ return device->adapter && device->address; } -bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec) +bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink) { struct spa_bt_monitor *monitor = device->monitor; struct spa_bt_remote_endpoint *ep; @@ -1579,15 +1588,22 @@ } spa_list_for_each(ep, &device->remote_endpoint_list, device_link) { + const enum spa_bt_profile profile = spa_bt_profile_from_uuid(ep->uuid); + const enum spa_bt_profile expected = sink ? + SPA_BT_PROFILE_A2DP_SINK : SPA_BT_PROFILE_A2DP_SOURCE; + + if (profile != expected) + continue; + if (a2dp_codec_check_caps(codec, ep->codec, ep->capabilities, ep->capabilities_len, - &ep->monitor->default_audio_info)) + &ep->monitor->default_audio_info, &monitor->global_settings)) return true; } return false; } -const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count) +const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink) { struct spa_bt_monitor *monitor = device->monitor; const struct a2dp_codec * const * const a2dp_codecs = monitor->a2dp_codecs; @@ -1603,7 +1619,7 @@ j = 0; for (i = 0; a2dp_codecsi != NULL; ++i) { - if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecsi)) { + if (spa_bt_device_supports_a2dp_codec(device, a2dp_codecsi, sink)) { supported_codecsj = a2dp_codecsi; ++j; } @@ -2511,7 +2527,7 @@ .set_volume = transport_set_volume, }; -static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, int key_type_int, void* key, const char* variant_type_str, const char* array_type_str, int array_type_int, void* data, int data_size); +static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, const char* key, const char* variant_type_str, const char* array_type_str, int array_type_int, void* data, int data_size); static void a2dp_codec_switch_reply(DBusPendingCall *pending, void *userdata); @@ -2569,10 +2585,10 @@ char *local_endpoint = NULL; int res, config_size; dbus_bool_t dbus_ret; - const char *str; DBusMessage *m; DBusMessageIter iter, d; int i; + bool sink; /* Try setting configuration for current codec on current endpoint in list */ @@ -2603,8 +2619,10 @@ if (sw->profile & SPA_BT_PROFILE_A2DP_SINK) { local_endpoint_base = A2DP_SOURCE_ENDPOINT; + sink = false; } else if (sw->profile & SPA_BT_PROFILE_A2DP_SOURCE) { local_endpoint_base = A2DP_SINK_ENDPOINT; + sink = true; } else { spa_log_debug(sw->device->monitor->log, "a2dp codec switch %p: bad profile (%d), try next", sw, sw->profile); @@ -2630,9 +2648,9 @@ } } - res = codec->select_config(codec, 0, ep->capabilities, ep->capabilities_len, + res = codec->select_config(codec, sink ? A2DP_CODEC_FLAG_SINK : 0, ep->capabilities, ep->capabilities_len, &sw->device->monitor->default_audio_info, - sw->device->settings, config); + &sw->device->monitor->global_settings, config); if (res < 0) { spa_log_debug(sw->device->monitor->log, "a2dp codec switch %p: incompatible capabilities (%d), try next", sw, res); @@ -2659,8 +2677,7 @@ dbus_message_iter_init_append(m, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &local_endpoint); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &d); - str = "Capabilities"; - append_basic_array_variant_dict_entry(&d, DBUS_TYPE_STRING, &str, "ay", "y", DBUS_TYPE_BYTE, config, config_size); + append_basic_array_variant_dict_entry(&d, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, config, config_size); dbus_message_iter_close_container(&iter, &d); spa_assert(sw->pending == NULL); @@ -2878,6 +2895,7 @@ const struct a2dp_codec *codec = *sw->codec_iter; const char *path1 = *(char **)a, *path2 = *(char **)b; struct spa_bt_remote_endpoint *ep1, *ep2; + uint32_t flags; ep1 = device_remote_endpoint_find(sw->device, path1); ep2 = device_remote_endpoint_find(sw->device, path2); @@ -2886,6 +2904,10 @@ ep1 = NULL; if (ep2 != NULL && (ep2->uuid == NULL || ep2->codec != codec->codec_id || ep2->capabilities == NULL)) ep2 = NULL; + if (ep1 && ep2 && !spa_streq(ep1->uuid, ep2->uuid)) { + ep1 = NULL; + ep2 = NULL; + } if (ep1 == NULL && ep2 == NULL) return 0; @@ -2894,8 +2916,11 @@ else if (ep2 == NULL) return -1; - return codec->caps_preference_cmp(codec, ep1->capabilities, ep1->capabilities_len, - ep2->capabilities, ep2->capabilities_len, &sw->device->monitor->default_audio_info); + flags = spa_streq(ep1->uuid, SPA_BT_UUID_A2DP_SOURCE) ? A2DP_CODEC_FLAG_SINK : 0; + + return codec->caps_preference_cmp(codec, flags, ep1->capabilities, ep1->capabilities_len, + ep2->capabilities, ep2->capabilities_len, &sw->device->monitor->default_audio_info, + &sw->device->monitor->global_settings); } /* Ensure there's a transport for at least one of the listed codecs */ @@ -2913,7 +2938,7 @@ } for (i = 0; codecsi != NULL; ++i) { - if (spa_bt_device_supports_a2dp_codec(device, codecsi)) { + if (spa_bt_device_supports_a2dp_codec(device, codecsi, true)) { preferred_codec = codecsi;
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/bluez5-device.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -301,6 +301,8 @@ static float get_soft_volume_boost(struct node *node) { + const struct a2dp_codec *codec = node->transport ? node->transport->a2dp_codec : NULL; + /* * For A2DP duplex, the duplex microphone channel sometimes does not appear * to have hardware gain, and input volume is very low. @@ -310,7 +312,8 @@ * If this causes clipping, the user can just reduce the mic volume to * bring SW gain below 1. */ - if (node->a2dp_duplex && node->transport && + if (node->a2dp_duplex && node->transport && codec && codec->info && + spa_atob(spa_dict_lookup(codec->info, "duplex.boost")) && node->id == DEVICE_ID_SOURCE && !node->transport->volumesSPA_BT_VOLUME_ID_RX.active) return 10.0f; /* 20 dB boost */ @@ -912,7 +915,7 @@ if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SINK) { free(this->supported_codecs); this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs( - this->bt_dev, &this->supported_codec_count); + this->bt_dev, &this->supported_codec_count, true); } switch (this->profile) { @@ -1127,7 +1130,7 @@ if (this->supported_codecs) free(this->supported_codecs); this->supported_codecs = spa_bt_device_get_supported_a2dp_codecs( - this->bt_dev, &this->supported_codec_count); + this->bt_dev, &this->supported_codec_count, true); /* Prefer A2DP, then HFP, then null, but select AG if the device appears not to have A2DP_SINK or any HEAD_UNIT profile */
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/codec-loader.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/codec-loader.c
Changed
@@ -63,6 +63,11 @@ SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX, SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX, + SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO, }; size_t i; for (i = 0; i < SPA_N_ELEMENTS(order); ++i) @@ -138,6 +143,9 @@ spa_log_debug(impl->log, "loaded A2DP codec %s from %s", c->name, factory_name); + if (c->set_log) + c->set_log(impl->log); + impl->codecsimpl->n_codecs++ = c; ++n_codecs; @@ -171,7 +179,8 @@ A2DP_CODEC_FACTORY_LIB("faststream"), A2DP_CODEC_FACTORY_LIB("ldac"), A2DP_CODEC_FACTORY_LIB("sbc"), - A2DP_CODEC_FACTORY_LIB("lc3plus") + A2DP_CODEC_FACTORY_LIB("lc3plus"), + A2DP_CODEC_FACTORY_LIB("opus") #undef A2DP_CODEC_FACTORY_LIB };
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/decode-buffer.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/decode-buffer.h
Changed
@@ -389,7 +389,8 @@ static void spa_bt_decode_buffer_process(struct spa_bt_decode_buffer *this, uint32_t samples, uint32_t duration) { const uint32_t data_size = samples * this->frame_size; - const int32_t max_level = SPA_MAX(8 * this->packet_size.max, (int32_t)duration); + const int32_t packet_size = SPA_CLAMP(this->packet_size.max, 0, INT32_MAX/8); + const int32_t max_level = SPA_MAX(8 * packet_size, (int32_t)duration); uint32_t avail; if (SPA_UNLIKELY(duration != this->prev_duration)) { @@ -405,8 +406,8 @@ spa_log_trace(this->log, "%p buffering size:%d", this, (int)size); if (this->received && - this->packet_size.max > 0 && - size >= SPA_MAX(3*this->packet_size.max, (int32_t)duration)) + packet_size > 0 && + size >= SPA_MAX(3*packet_size, (int32_t)duration)) this->buffering = false; else return; @@ -428,7 +429,7 @@ spa_bt_ptp_update(&this->spike, this->ctl.avg - level, this->prev_consumed); /* Update target level */ - target = BUFFERING_TARGET(this->spike.max, this->packet_size.max); + target = BUFFERING_TARGET(this->spike.max, packet_size); if (level > SPA_MAX(4 * target, 2*(int32_t)duration) && avail > data_size) {
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/defs.h -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/defs.h
Changed
@@ -134,13 +134,13 @@ #define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported" -#define SPA_BT_UUID_A2DP_SOURCE "0000110A-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_A2DP_SINK "0000110B-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_HSP_HS "00001108-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_HSP_HS_ALT "00001131-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_HSP_AG "00001112-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_HFP_HF "0000111E-0000-1000-8000-00805F9B34FB" -#define SPA_BT_UUID_HFP_AG "0000111F-0000-1000-8000-00805F9B34FB" +#define SPA_BT_UUID_A2DP_SOURCE "0000110a-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_A2DP_SINK "0000110b-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_HSP_HS "00001108-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_HSP_HS_ALT "00001131-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_HSP_AG "00001112-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_HFP_HF "0000111e-0000-1000-8000-00805f9b34fb" +#define SPA_BT_UUID_HFP_AG "0000111f-0000-1000-8000-00805f9b34fb" #define PROFILE_HSP_AG "/Profile/HSPAG" #define PROFILE_HSP_HS "/Profile/HSPHS" @@ -490,8 +490,8 @@ int spa_bt_device_connect_profile(struct spa_bt_device *device, enum spa_bt_profile profile); int spa_bt_device_check_profiles(struct spa_bt_device *device, bool force); int spa_bt_device_ensure_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec * const *codecs); -bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec); -const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count); +bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struct a2dp_codec *codec, bool sink); +const struct a2dp_codec **spa_bt_device_get_supported_a2dp_codecs(struct spa_bt_device *device, size_t *count, bool sink); int spa_bt_device_ensure_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_supports_hfp_codec(struct spa_bt_device *device, unsigned int codec); int spa_bt_device_release_transports(struct spa_bt_device *device);
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/meson.build
Changed
@@ -111,8 +111,6 @@ endif if get_option('bluez5-codec-lc3plus').allowed() and lc3plus_dep.found() - lc3plus_args = codec_args - lc3plus_dep = lc3plus_dep bluez_codec_lc3plus = shared_library('spa-codec-bluez5-lc3plus', 'a2dp-codec-lc3plus.c', 'a2dp-codecs.c' , include_directories : configinc , @@ -121,3 +119,15 @@ install : true, install_dir : spa_plugindir / 'bluez5') endif + +if get_option('bluez5-codec-opus').allowed() and opus_dep.found() + opus_args = codec_args + opus_dep = opus_dep + bluez_codec_opus = shared_library('spa-codec-bluez5-opus', + 'a2dp-codec-opus.c', 'a2dp-codecs.c' , + include_directories : configinc , + c_args : opus_args, + dependencies : spa_dep, opus_dep, mathlib , + install : true, + install_dir : spa_plugindir / 'bluez5') +endif
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/sco-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/sco-sink.c
Changed
@@ -1147,8 +1147,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status == SPA_STATUS_HAVE_DATA && io->buffer_id < port->n_buffers) { struct buffer *b = &port->buffersio->buffer_id;
View file
pipewire-0.3.56.tar.gz/spa/plugins/bluez5/sco-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/bluez5/sco-source.c
Changed
@@ -542,6 +542,15 @@ return 0; } + if (size_read % port->frame_size != 0) { + /* Unaligned data: reception or adapter problem. + * Consider the whole packet lost and report. + */ + spa_log_debug(this->log, + "received bad Bluetooth SCO CVSD packet"); + return 0; + } + packet = spa_bt_decode_buffer_get_write(&port->buffer, &avail); avail = SPA_MIN(avail, (uint32_t)size_read); spa_memmove(packet, read_data, avail); @@ -1286,8 +1295,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; /* Return if we already have a buffer */ if (io->status == SPA_STATUS_HAVE_DATA)
View file
pipewire-0.3.56.tar.gz/spa/plugins/control/mixer.c -> pipewire-0.3.57.tar.gz/spa/plugins/control/mixer.c
Changed
@@ -587,8 +587,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); outport = GET_OUT_PORT(this, 0); - outio = outport->io; - spa_return_val_if_fail(outio != NULL, -EIO); + if ((outio = outport->io) == NULL) + return -EIO; spa_log_trace_fp(this->log, NAME " %p: status %p %d %d", this, outio, outio->status, outio->buffer_id);
View file
pipewire-0.3.56.tar.gz/spa/plugins/libcamera/libcamera-device.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/libcamera/libcamera-device.cpp
Changed
@@ -78,35 +78,32 @@ std::shared_ptr<Camera> camera; }; -std::string cameraModel(const Camera *camera) +static std::string cameraModel(const Camera *camera) { const ControlList &props = camera->properties(); - std::string name; - if (props.contains(properties::Model)) - name = props.get(properties::Model); - else - name = camera->id(); - return name; + + if (auto model = props.get(properties::Model)) + return std::move(model.value()); + + return camera->id(); } -std::string cameraLoc(const Camera *camera) +static const char *cameraLoc(const Camera *camera) { const ControlList &props = camera->properties(); - std::string location; - if (props.contains(properties::Location)) { - switch (props.get(properties::Location)) { + + if (auto location = props.get(properties::Location)) { + switch (location.value()) { case properties::CameraLocationFront: - location = "front"; - break; + return "front"; case properties::CameraLocationBack: - location = "back"; - break; + return "back"; case properties::CameraLocationExternal: - location = "external"; - break; + return "external"; } } - return location; + + return nullptr; } static int emit_info(struct impl *impl, bool full) @@ -116,7 +113,7 @@ uint32_t n_items = 0; struct spa_device_info info; struct spa_param_info params2; - char path256, location10, model256, name256; + char path256, model256, name256; info = SPA_DEVICE_INFO_INIT(); @@ -127,9 +124,11 @@ ADD_ITEM(SPA_KEY_OBJECT_PATH, path); ADD_ITEM(SPA_KEY_DEVICE_API, "libcamera"); ADD_ITEM(SPA_KEY_MEDIA_CLASS, "Video/Device"); - ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, (char *)impl->props.device); - snprintf(location, sizeof(location), "%s", cameraLoc(impl->camera.get()).c_str()); - ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location); + ADD_ITEM(SPA_KEY_API_LIBCAMERA_PATH, impl->props.device); + + if (auto location = cameraLoc(impl->camera.get())) + ADD_ITEM(SPA_KEY_API_LIBCAMERA_LOCATION, location); + snprintf(model, sizeof(model), "%s", cameraModel(impl->camera.get()).c_str()); ADD_ITEM(SPA_KEY_DEVICE_PRODUCT_NAME, model); ADD_ITEM(SPA_KEY_DEVICE_DESCRIPTION, model);
View file
pipewire-0.3.56.tar.gz/spa/plugins/libcamera/libcamera-source.cpp -> pipewire-0.3.57.tar.gz/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -823,8 +823,8 @@ spa_return_val_if_fail(impl != NULL, -EINVAL); port = GET_OUT_PORT(impl, 0); - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (port->control) process_control(impl, &port->control->sequence);
View file
pipewire-0.3.56.tar.gz/spa/plugins/meson.build -> pipewire-0.3.57.tar.gz/spa/plugins/meson.build
Changed
@@ -1,7 +1,7 @@ if alsa_dep.found() subdir('alsa') endif -if get_option('avb').allowed() +if get_option('avb').require(host_machine.system() == 'linux', error_message: 'AVB support is only available on Linux').allowed() subdir('avb') endif if get_option('audioconvert').allowed() @@ -55,4 +55,4 @@ subdir('libcamera') endif -subdir('aec') \ No newline at end of file +subdir('aec')
View file
pipewire-0.3.56.tar.gz/spa/plugins/support/loop.c -> pipewire-0.3.57.tar.gz/spa/plugins/support/loop.c
Changed
@@ -350,6 +350,7 @@ if (--impl->enter_count == 0) { impl->thread = 0; + flush_items(impl); impl->polling = false; } }
View file
pipewire-0.3.56.tar.gz/spa/plugins/support/null-audio-sink.c -> pipewire-0.3.57.tar.gz/spa/plugins/support/null-audio-sink.c
Changed
@@ -737,9 +737,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status != SPA_STATUS_HAVE_DATA) return io->status;
View file
pipewire-0.3.56.tar.gz/spa/plugins/test/fakesink.c -> pipewire-0.3.57.tar.gz/spa/plugins/test/fakesink.c
Changed
@@ -639,9 +639,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status == SPA_STATUS_HAVE_DATA && io->buffer_id < port->n_buffers) { struct buffer *b = &port->buffersio->buffer_id;
View file
pipewire-0.3.56.tar.gz/spa/plugins/test/fakesrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/test/fakesrc.c
Changed
@@ -680,8 +680,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA;
View file
pipewire-0.3.56.tar.gz/spa/plugins/v4l2/v4l2-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/v4l2/v4l2-source.c
Changed
@@ -879,8 +879,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = GET_OUT_PORT(this, 0); - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (port->control) process_control(this, &port->control->sequence);
View file
pipewire-0.3.56.tar.gz/spa/plugins/videotestsrc/videotestsrc.c -> pipewire-0.3.57.tar.gz/spa/plugins/videotestsrc/videotestsrc.c
Changed
@@ -787,8 +787,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA;
View file
pipewire-0.3.56.tar.gz/spa/plugins/volume/volume.c -> pipewire-0.3.57.tar.gz/spa/plugins/volume/volume.c
Changed
@@ -679,8 +679,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); out_port = GET_OUT_PORT(this, 0); - output = out_port->io; - spa_return_val_if_fail(output != NULL, -EIO); + if ((output = out_port->io) == NULL) + return -EIO; if (output->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA; @@ -692,8 +692,8 @@ } in_port = GET_IN_PORT(this, 0); - input = in_port->io; - spa_return_val_if_fail(input != NULL, -EIO); + if ((input = in_port->io) == NULL) + return -EIO; if (input->status != SPA_STATUS_HAVE_DATA) return SPA_STATUS_NEED_DATA;
View file
pipewire-0.3.56.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c -> pipewire-0.3.57.tar.gz/spa/plugins/vulkan/vulkan-compute-filter.c
Changed
@@ -578,8 +578,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); inport = &this->portSPA_DIRECTION_INPUT; - inio = inport->io; - spa_return_val_if_fail(inio != NULL, -EIO); + if ((inio = inport->io) == NULL) + return -EIO; if (inio->status != SPA_STATUS_HAVE_DATA) return inio->status; @@ -590,8 +590,8 @@ } outport = &this->portSPA_DIRECTION_OUTPUT; - outio = outport->io; - spa_return_val_if_fail(outio != NULL, -EIO); + if ((outio = outport->io) == NULL) + return -EIO; if (outio->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA;
View file
pipewire-0.3.56.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c -> pipewire-0.3.57.tar.gz/spa/plugins/vulkan/vulkan-compute-source.c
Changed
@@ -802,8 +802,8 @@ spa_return_val_if_fail(this != NULL, -EINVAL); port = &this->port; - io = port->io; - spa_return_val_if_fail(io != NULL, -EIO); + if ((io = port->io) == NULL) + return -EIO; if (io->status == SPA_STATUS_HAVE_DATA) return SPA_STATUS_HAVE_DATA;
View file
pipewire-0.3.57.tar.gz/src/daemon/systemd/user/filter-chain.service.in
Added
@@ -0,0 +1,21 @@ +Unit +Description=PipeWire filter chain daemon + +After=pipewire.service pipewire-session-manager.service +BindsTo=pipewire.service + +Service +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +RestrictNamespaces=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service +Type=simple +ExecStart=@PW_BINARY@ -c filter-chain.conf +Restart=on-failure +Slice=session.slice + +Install +Also=pipewire.socket +WantedBy=default.target
View file
pipewire-0.3.56.tar.gz/src/daemon/systemd/user/meson.build -> pipewire-0.3.57.tar.gz/src/daemon/systemd/user/meson.build
Changed
@@ -20,3 +20,8 @@ output : 'pipewire-pulse.service', configuration : systemd_config, install_dir : systemd_user_services_dir) + +configure_file(input : 'filter-chain.service.in', + output : 'filter-chain.service', + configuration : systemd_config, + install_dir : systemd_user_services_dir)
View file
pipewire-0.3.56.tar.gz/src/gst/gstpipewiresrc.c -> pipewire-0.3.57.tar.gz/src/gst/gstpipewiresrc.c
Changed
@@ -568,19 +568,23 @@ meta->height = crop->region.size.height; } } - gst_buffer_add_parent_buffer_meta (buf, data->buf); - gst_buffer_unref (data->buf); for (i = 0; i < b->buffer->n_datas; i++) { struct spa_data *d = &b->buffer->datasi; GstMemory *pmem = gst_buffer_peek_memory (data->buf, i); if (pmem) { - GstMemory *mem = gst_memory_share (pmem, d->chunk->offset, d->chunk->size); + GstMemory *mem; + if (!pwsrc->always_copy) + mem = gst_memory_share (pmem, d->chunk->offset, d->chunk->size); + else + mem = gst_memory_copy (pmem, d->chunk->offset, d->chunk->size); gst_buffer_insert_memory (buf, i, mem); - spa_assert_se(mem->size <= mem->maxsize); } if (d->chunk->flags & SPA_CHUNK_FLAG_CORRUPTED) GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_CORRUPTED); } + if (!pwsrc->always_copy) + gst_buffer_add_parent_buffer_meta (buf, data->buf); + gst_buffer_unref (data->buf); return buf; } @@ -1091,12 +1095,7 @@ } pw_thread_loop_unlock (pwsrc->core->loop); - if (pwsrc->always_copy) { - *buffer = gst_buffer_copy_deep (buf); - gst_buffer_unref (buf); - } - else - *buffer = buf; + *buffer = buf; if (pwsrc->is_live) base_time = GST_ELEMENT_CAST (psrc)->base_time;
View file
pipewire-0.3.57.tar.gz/src/modules/flatpak-utils.h
Added
@@ -0,0 +1,156 @@ +/* PipeWire + * + * Copyright © 2018 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef FLATPAK_UTILS_H +#define FLATPAK_UTILS_H + +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif + +#include "config.h" + +#ifdef HAVE_GLIB2 +#include <glib.h> +#endif + +#include <spa/utils/result.h> +#include <pipewire/log.h> + +static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **app_id, char **devices) +{ +#ifdef HAVE_GLIB2 + /* + * See flatpak-metadata(5) + * + * The .flatpak-info file is in GLib key_file .ini format. + */ + g_autoptr(GKeyFile) metadata = NULL; + char *s; + + metadata = g_key_file_new(); + if (!g_key_file_load_from_data(metadata, buf, size, G_KEY_FILE_NONE, NULL)) + return -EINVAL; + + if (app_id) { + s = g_key_file_get_value(metadata, "Application", "name", NULL); + *app_id = s ? strdup(s) : NULL; + g_free(s); + } + + if (devices) { + s = g_key_file_get_value(metadata, "Context", "devices", NULL); + *devices = s ? strdup(s) : NULL; + g_free(s); + } + + return 0; +#else + return -ENOTSUP; +#endif +} + +static int pw_check_flatpak(pid_t pid, char **app_id, char **devices) +{ +#if defined(__linux__) + char root_path2048; + int root_fd, info_fd, res; + struct stat stat_buf; + + if (app_id) + *app_id = NULL; + if (devices) + *devices = NULL; + + snprintf(root_path, sizeof(root_path), "/proc/%d/root", (int)pid); + root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); + if (root_fd == -1) { + res = -errno; + if (res == -EACCES) { + struct statfs buf; + /* Access to the root dir isn't allowed. This can happen if the root is on a fuse + * filesystem, such as in a toolbox container. We will never have a fuse rootfs + * in the flatpak case, so in that case its safe to ignore this and + * continue to detect other types of apps. */ + if (statfs(root_path, &buf) == 0 && + buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */ + return 0; + } + /* Not able to open the root dir shouldn't happen. Probably the app died and + * we're failing due to /proc/$pid not existing. In that case fail instead + * of treating this as privileged. */ + pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); + return res; + } + info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY); + close (root_fd); + if (info_fd == -1) { + if (errno == ENOENT) { + pw_log_debug("no .flatpak-info, client on the host"); + /* No file => on the host */ + return 0; + } + res = -errno; + pw_log_error("error opening .flatpak-info: %m"); + return res; + } + if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { + /* Some weird fd => failure, assume sandboxed */ + pw_log_error("error fstat .flatpak-info: %m"); + } else if (app_id || devices) { + /* Parse the application ID if needed */ + const size_t size = stat_buf.st_size; + + if (size > 0) { + void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0); + if (buf != MAP_FAILED) { + res = pw_check_flatpak_parse_metadata(buf, size, app_id, devices); + munmap(buf, size); + } else { + res = -errno; + } + } else { + res = -EINVAL; + } + + if (res == -EINVAL) + pw_log_error("PID %d .flatpak-info file is malformed", + (int)pid); + else if (res < 0) + pw_log_error("PID %d .flatpak-info parsing failed: %s", + (int)pid, spa_strerror(res)); + } + close(info_fd); + return 1; +#else + return 0; +#endif +} + +#endif /* FLATPAK_UTILS_H */
View file
pipewire-0.3.56.tar.gz/src/modules/meson.build -> pipewire-0.3.57.tar.gz/src/modules/meson.build
Changed
@@ -33,12 +33,17 @@ 'module-x11-bell.c', +pipewire_module_access_deps = spa_dep, mathlib, dl_lib, pipewire_dep +if flatpak_support + pipewire_module_access_deps += glib2_dep +endif + pipewire_module_access = shared_library('pipewire-module-access', 'module-access.c' , include_directories : configinc, install : true, install_dir : modules_install_dir, install_rpath: modules_install_dir, - dependencies : spa_dep, mathlib, dl_lib, pipewire_dep, + dependencies : pipewire_module_access_deps ) pipewire_module_loopback = shared_library('pipewire-module-loopback', @@ -277,6 +282,10 @@ cdata.set('HAVE_AVAHI', true) endif +if flatpak_support + pipewire_module_protocol_pulse_deps += glib2_dep +endif + pipewire_module_protocol_pulse = shared_library('pipewire-module-protocol-pulse', pipewire_module_protocol_pulse_sources, include_directories : configinc, @@ -470,7 +479,7 @@ endif summary({'raop-sink (requires OpenSSL)': build_module_raop}, bool_yn: true, section: 'Optional Modules') -roc_lib = cc.find_library('roc', required: get_option('roc')) +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') build_module_roc = roc_lib.found() @@ -518,7 +527,7 @@ dependencies : mathlib, dl_lib, rt_lib, pipewire_dep, ) -build_module_avb = get_option('avb').allowed() +build_module_avb = get_option('avb').require(host_machine.system() == 'linux', error_message: 'AVB support is only available on Linux').allowed() if build_module_avb pipewire_module_avb = shared_library('pipewire-module-avb', 'module-avb.c',
View file
pipewire-0.3.56.tar.gz/src/modules/module-access.c -> pipewire-0.3.57.tar.gz/src/modules/module-access.c
Changed
@@ -46,6 +46,8 @@ #include <pipewire/impl.h> #include <pipewire/private.h> +#include "flatpak-utils.h" + /** \page page_module_access PipeWire Module: Access * * @@ -75,6 +77,9 @@ * on an external actor to update that property once permission is * granted or rejected. * + * For connections from applications running inside Flatpak not mediated + * by a portal, the `access` module itself sets the `pipewire.access.portal.app_id` + * property to the Flatpak application ID. * * ## Module Options * @@ -184,54 +189,6 @@ return res; } -#if defined(__linux__) -static int check_flatpak(struct pw_impl_client *client, int pid) -{ - char root_path2048; - int root_fd, info_fd, res; - struct stat stat_buf; - - sprintf(root_path, "/proc/%u/root", pid); - root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); - if (root_fd == -1) { - res = -errno; - if (res == -EACCES) { - struct statfs buf; - /* Access to the root dir isn't allowed. This can happen if the root is on a fuse - * filesystem, such as in a toolbox container. We will never have a fuse rootfs - * in the flatpak case, so in that case its safe to ignore this and - * continue to detect other types of apps. */ - if (statfs(root_path, &buf) == 0 && - buf.f_type == 0x65735546) /* FUSE_SUPER_MAGIC */ - return 0; - } - /* Not able to open the root dir shouldn't happen. Probably the app died and - * we're failing due to /proc/$pid not existing. In that case fail instead - * of treating this as privileged. */ - pw_log_info("failed to open \"%s\": %s", root_path, spa_strerror(res)); - return res; - } - info_fd = openat (root_fd, ".flatpak-info", O_RDONLY | O_CLOEXEC | O_NOCTTY); - close (root_fd); - if (info_fd == -1) { - if (errno == ENOENT) { - pw_log_debug("no .flatpak-info, client on the host"); - /* No file => on the host */ - return 0; - } - res = -errno; - pw_log_error("error opening .flatpak-info: %m"); - return res; - } - if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { - /* Some weird fd => failure, assume sandboxed */ - pw_log_error("error fstat .flatpak-info: %m"); - } - close(info_fd); - return 1; -} -#endif - static void context_check_access(void *data, struct pw_impl_client *client) { @@ -240,6 +197,8 @@ struct spa_dict_item items2; const struct pw_properties *props; const char *str, *access; + char *flatpak_app_id = NULL; + int nitems = 0; int pid, res; pid = -EINVAL; @@ -298,8 +257,7 @@ (access = pw_properties_get(impl->properties, "access.force")) != NULL) goto wait_permissions; -#if defined(__linux__) - res = check_flatpak(client, pid); + res = pw_check_flatpak(pid, &flatpak_app_id, NULL); if (res != 0) { if (res < 0) { if (res == -EACCES) { @@ -313,9 +271,11 @@ pw_log_debug(" %p: flatpak client %p added", impl, client); } access = "flatpak"; + itemsnitems++ = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id", + flatpak_app_id); goto wait_permissions; } -#endif + if ((access = pw_properties_get(props, PW_KEY_CLIENT_ACCESS)) == NULL) access = "unrestricted"; @@ -326,24 +286,28 @@ granted: pw_log_info("%p: client %p '%s' access granted", impl, client, access); - items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); + itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); + pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); permissions0 = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_ALL); pw_impl_client_update_permissions(client, 1, permissions); - return; + goto done; wait_permissions: pw_log_info("%p: client %p wait for '%s' permissions", impl, client, access); - items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); - return; + itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); + pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); + goto done; rejected: pw_resource_error(pw_impl_client_get_core_resource(client), res, access); - items0 = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); - pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); + itemsnitems++ = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); + pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, nitems)); + goto done; + +done: + free(flatpak_app_id); return; }
View file
pipewire-0.3.56.tar.gz/src/modules/module-avb/aaf.h -> pipewire-0.3.57.tar.gz/src/modules/module-avb/aaf.h
Changed
@@ -35,7 +35,7 @@ unsigned gv:1; unsigned tv:1; - uint8_t seq_number; + uint8_t seq_num; unsigned _r2:7; unsigned tu:1;
View file
pipewire-0.3.56.tar.gz/src/modules/module-avb/iec61883.h -> pipewire-0.3.57.tar.gz/src/modules/module-avb/iec61883.h
Changed
@@ -37,7 +37,7 @@ unsigned gv:1; unsigned tv:1; - uint8_t seq_number; + uint8_t seq_num; unsigned _r2:7; unsigned tu:1;
View file
pipewire-0.3.56.tar.gz/src/modules/module-avb/maap.c -> pipewire-0.3.57.tar.gz/src/modules/module-avb/maap.c
Changed
@@ -421,7 +421,10 @@ maap->server = server; pw_log_info("0x%"PRIx64" %d", server->entity_id, server->ifindex); - pw_getrandom(maap->xsubi, sizeof(maap->xsubi), 0); + if (pw_getrandom(maap->xsubi, sizeof(maap->xsubi), 0) != sizeof(maap->xsubi)) { + res = -errno; + goto error_free; + } load_state(maap); maap->source = pw_loop_add_io(server->impl->loop, fd, SPA_IO_IN, true, on_socket_data, maap);
View file
pipewire-0.3.56.tar.gz/src/modules/module-client-node/remote-node.c -> pipewire-0.3.57.tar.gz/src/modules/module-client-node/remote-node.c
Changed
@@ -857,14 +857,8 @@ { struct link *link = user_data; struct spa_system *data_system = link->data->context->data_system; - struct timespec ts = { 0, 0 }; - - pw_log_trace_fp("link %p: signal", link); - - spa_system_clock_gettime(data_system, CLOCK_MONOTONIC, &ts); - link->target.activation->status = PW_NODE_ACTIVATION_TRIGGERED; - link->target.activation->signal_time = SPA_TIMESPEC_TO_NSEC(&ts); + pw_log_trace_fp("link %p: signal %p", link, link->target.activation); if (SPA_UNLIKELY(spa_system_eventfd_write(data_system, link->signalfd, 1) < 0)) pw_log_warn("link %p: write failed %m", link); @@ -930,7 +924,7 @@ link->map = mm; link->target.activation = ptr; link->signalfd = signalfd; - link->target.signal = link_signal_func; + link->target.signal_func = link_signal_func; link->target.data = link; link->target.node = NULL; spa_list_append(&data->links, &link->link);
View file
pipewire-0.3.56.tar.gz/src/modules/module-echo-cancel.c -> pipewire-0.3.57.tar.gz/src/modules/module-echo-cancel.c
Changed
@@ -993,8 +993,6 @@ goto error; } - (void)SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_AUDIO_AEC, (struct spa_audio_aec *)impl->aec); - pw_log_info("Using plugin AEC %s", impl->aec->name); if ((str = pw_properties_get(props, "aec.args")) != NULL)
View file
pipewire-0.3.56.tar.gz/src/modules/module-filter-chain/convolver.c -> pipewire-0.3.57.tar.gz/src/modules/module-filter-chain/convolver.c
Changed
@@ -232,9 +232,12 @@ fft_cpx_free(&conv->segmentsi); fft_cpx_free(&conv->segmentsIri); } - fft_destroy(conv->fft); - fft_destroy(conv->ifft); - fft_free(conv->fft_buffer); + if (conv->fft) + fft_destroy(conv->fft); + if (conv->ifft) + fft_destroy(conv->ifft); + if (conv->fft_buffer) + fft_free(conv->fft_buffer); free(conv->segments); free(conv->segmentsIr); fft_cpx_free(&conv->pre_mult);
View file
pipewire-0.3.56.tar.gz/src/modules/module-filter-chain/lv2_plugin.c -> pipewire-0.3.57.tar.gz/src/modules/module-filter-chain/lv2_plugin.c
Changed
@@ -37,9 +37,9 @@ #include <lilv/lilv.h> #include <lv2/lv2plug.in/ns/ext/atom/atom.h> #include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h> -#include "lv2/lv2plug.in/ns/ext/worker/worker.h" -#include "lv2/lv2plug.in/ns/ext/options/options.h" -#include "lv2/lv2plug.in/ns/ext/parameters/parameters.h" +#include <lv2/lv2plug.in/ns/ext/worker/worker.h> +#include <lv2/lv2plug.in/ns/ext/options/options.h> +#include <lv2/lv2plug.in/ns/ext/parameters/parameters.h> #include "plugin.h"
View file
pipewire-0.3.56.tar.gz/src/modules/module-protocol-native.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-native.c
Changed
@@ -103,6 +103,11 @@ * - XDG_RUNTIME_DIR * - USERPROFILE * + * The socket address will be written into the notification file descriptor + * if the following environment variable is set: + * + * - PIPEWIRE_NOTIFICATION_FD + * * When a client connect, the connection will be made to: * * - PIPEWIRE_REMOTE : the environment with the remote name @@ -605,12 +610,15 @@ if (client == NULL) goto exit; - this = pw_impl_client_get_user_data(client); spa_list_append(&s->this.client_list, &this->protocol_link); this->server = s; this->client = client; + pw_map_init(&this->compat_v2.types, 0, 32); + + pw_impl_client_add_listener(client, &this->client_listener, &client_events, this); + this->source = pw_loop_add_io(pw_context_get_main_loop(context), fd, SPA_IO_ERR | SPA_IO_HUP, true, connection_data, this); @@ -625,15 +633,11 @@ goto cleanup_client; } - pw_map_init(&this->compat_v2.types, 0, 32); - pw_protocol_native_connection_add_listener(this->connection, &this->conn_listener, &server_conn_events, this); - pw_impl_client_add_listener(client, &this->client_listener, &client_events, this); - if ((res = pw_impl_client_register(client, NULL)) < 0) goto cleanup_client; @@ -761,6 +765,44 @@ } } +static int write_socket_address(struct server *s) +{ + long v; + int fd, res = 0; + char *endptr; + const char *env = getenv("PIPEWIRE_NOTIFICATION_FD"); + + if (env == NULL || env0 == '\0') + return 0; + + errno = 0; + v = strtol(env, &endptr, 10); + if (endptr0 != '\0') + errno = EINVAL; + if (errno != 0) { + res = -errno; + pw_log_error("server %p: strtol() failed with error: %m", s); + goto error; + } + fd = (int)v; + if (v != fd) { + res = -ERANGE; + pw_log_error("server %p: invalid fd %ld: %s", s, v, spa_strerror(res)); + goto error; + } + if (dprintf(fd, "%s\n", s->addr.sun_path) < 0) { + res = -errno; + pw_log_error("server %p: dprintf() failed with error: %m", s); + goto error; + } + close(fd); + unsetenv("PIPEWIRE_NOTIFICATION_FD"); + return 0; + +error: + return res; +} + static int add_socket(struct pw_protocol *protocol, struct server *s) { socklen_t size; @@ -815,6 +857,12 @@ } } + res = write_socket_address(s); + if (res < 0) { + pw_log_error("server %p: failed to write socket address: %s", s, + spa_strerror(res)); + goto error_close; + } s->activated = activated; s->loop = pw_context_get_main_loop(protocol->context); if (s->loop == NULL) { @@ -990,35 +1038,9 @@ goto done; } -static void on_client_connection_destroy(void *data) -{ - struct client *impl = data; - spa_hook_remove(&impl->conn_listener); -} - -static void on_client_need_flush(void *data) -{ - struct client *impl = data; - - pw_log_trace("need flush"); - impl->need_flush = true; - - if (impl->source && !(impl->source->mask & SPA_IO_OUT)) { - pw_loop_update_io(impl->context->main_loop, - impl->source, impl->source->mask | SPA_IO_OUT); - } -} - -static const struct pw_protocol_native_connection_events client_conn_events = { - PW_VERSION_PROTOCOL_NATIVE_CONNECTION_EVENTS, - .destroy = on_client_connection_destroy, - .need_flush = on_client_need_flush, -}; - static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_close) { struct client *impl = SPA_CONTAINER_OF(client, struct client, this); - int res; impl->connected = false; impl->disconnecting = false; @@ -1028,23 +1050,10 @@ fd, SPA_IO_IN | SPA_IO_OUT | SPA_IO_HUP | SPA_IO_ERR, do_close, on_remote_data, impl); - if (impl->source == NULL) { - res = -errno; - goto error_cleanup; - } + if (impl->source == NULL) + return -errno; - pw_protocol_native_connection_add_listener(impl->connection, - &impl->conn_listener, - &client_conn_events, - impl); return 0; - -error_cleanup: - if (impl->connection) { - pw_protocol_native_connection_destroy(impl->connection); - impl->connection = NULL; - } - return res; } static void impl_disconnect(struct pw_protocol_client *client) @@ -1057,9 +1066,7 @@ pw_loop_destroy_source(impl->context->main_loop, impl->source); impl->source = NULL; - if (impl->connection) - pw_protocol_native_connection_destroy(impl->connection); - impl->connection = NULL; + pw_protocol_native_connection_set_fd(impl->connection, -1); } static void impl_destroy(struct pw_protocol_client *client) @@ -1068,6 +1075,10 @@ impl_disconnect(client); + if (impl->connection) + pw_protocol_native_connection_destroy(impl->connection); + impl->connection = NULL; + spa_list_remove(&client->link); client_unref(impl); } @@ -1134,6 +1145,31 @@ goto done; } +static void on_client_connection_destroy(void *data) +{ + struct client *impl = data; + spa_hook_remove(&impl->conn_listener); +} + +static void on_client_need_flush(void *data) +{ + struct client *impl = data;
View file
pipewire-0.3.56.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -668,15 +668,16 @@ attr->fragsize = SPA_ROUND_UP(attr->fragsize, frame_size); attr->fragsize = SPA_MAX(attr->fragsize, minfrag); - attr->tlength = attr->minreq = attr->prebuf = 0; + /* pulseaudio configures the source to half of the fragsize. It also + * immediately sends chunks to clients. Configure a 2/3 of the fragsize + * as the latency. */ + latency = attr->fragsize * 2 / 3; + + if (s->adjust_latency) + attr->fragsize = SPA_ROUND_UP(latency, frame_size); + + attr->tlength = attr->prebuf = 0; - if (s->early_requests) { - latency = attr->fragsize; - } else if (s->adjust_latency) { - latency = attr->fragsize; - } else { - latency = attr->fragsize; - } /* make sure can queue at least to fragsize without overruns */ if (attr->maxlength < attr->fragsize * 4) attr->maxlength = attr->fragsize * 4;
View file
pipewire-0.3.56.tar.gz/src/modules/module-protocol-pulse/server.c -> pipewire-0.3.57.tar.gz/src/modules/module-protocol-pulse/server.c
Changed
@@ -60,6 +60,7 @@ #include "server.h" #include "stream.h" #include "utils.h" +#include "flatpak-utils.h" #define LISTEN_BACKLOG 32 #define MAX_CLIENTS 64 @@ -417,14 +418,47 @@ client_access = server->client_access; if (server->addr.ss_family == AF_UNIX) { + char *app_id = NULL, *devices = NULL; + #ifdef SO_PRIORITY val = 6; if (setsockopt(client_fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)) < 0) pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); #endif pid = get_client_pid(client, client_fd); - if (pid != 0 && check_flatpak(client, pid) == 1) + if (pid != 0 && pw_check_flatpak(pid, &app_id, &devices) == 1) { + /* + * XXX: we should really use Portal client access here + * + * However, session managers currently support only camera + * permissions, and the XDG Portal doesn't have a "Sound Manager" + * permission defined. So for now, use access=flatpak, and determine + * extra permissions here. + * + * The application has access to the Pulseaudio socket, + * and with real PA it would always then have full sound access. + * We'll restrict the full access here behind devices=all; + * if the application can access all devices it can then + * also sound and camera devices directly, so granting also the + * Manager permissions here is reasonable. + * + * The "Manager" permission in any case is also currently not safe + * as the session manager does not check any permission store + * for it. + */ client_access = "flatpak"; + pw_properties_set(client->props, "pipewire.access.portal.app_id", + app_id); + + if (devices && (spa_streq(devices, "all") || + spa_strstartswith(devices, "all;") || + strstr(devices, ";all;"))) + pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, "Manager"); + else + pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, NULL); + } + free(devices); + free(app_id); } else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {
View file
pipewire-0.3.56.tar.gz/src/modules/module-pulse-tunnel.c -> pipewire-0.3.57.tar.gz/src/modules/module-pulse-tunnel.c
Changed
@@ -278,7 +278,7 @@ } else { float error, corr; - error = (float)(impl->current_latency) - (float)impl->target_latency; + error = (float)impl->target_latency - (float)impl->current_latency; error = SPA_CLAMP(error, -impl->max_error, impl->max_error); corr = spa_dll_update(&impl->dll, error); @@ -422,33 +422,47 @@ static void context_state_cb(pa_context *c, void *userdata) { struct impl *impl = userdata; + bool do_destroy = false; switch (pa_context_get_state(c)) { - case PA_CONTEXT_READY: case PA_CONTEXT_TERMINATED: case PA_CONTEXT_FAILED: + do_destroy = true; + SPA_FALLTHROUGH; + case PA_CONTEXT_READY: pa_threaded_mainloop_signal(impl->pa_mainloop, 0); break; case PA_CONTEXT_UNCONNECTED: + do_destroy = true; + break; case PA_CONTEXT_CONNECTING: case PA_CONTEXT_AUTHORIZING: case PA_CONTEXT_SETTING_NAME: break; } + if (do_destroy) + pw_impl_module_schedule_destroy(impl->module); } static void stream_state_cb(pa_stream *s, void * userdata) { struct impl *impl = userdata; + bool do_destroy = false; switch (pa_stream_get_state(s)) { - case PA_STREAM_READY: case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: + do_destroy = true; + SPA_FALLTHROUGH; + case PA_STREAM_READY: pa_threaded_mainloop_signal(impl->pa_mainloop, 0); break; case PA_STREAM_UNCONNECTED: + do_destroy = true; + break; case PA_STREAM_CREATING: break; } + if (do_destroy) + pw_impl_module_schedule_destroy(impl->module); } static void stream_read_request_cb(pa_stream *s, size_t length, void *userdata)
View file
pipewire-0.3.56.tar.gz/src/modules/module-rt.c -> pipewire-0.3.57.tar.gz/src/modules/module-rt.c
Changed
@@ -153,6 +153,11 @@ #ifdef HAVE_DBUS #define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1" #define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1" +#define RTKIT_INTERFACE "org.freedesktop.RealtimeKit1" + +#define XDG_PORTAL_SERVICE_NAME "org.freedesktop.portal.Desktop" +#define XDG_PORTAL_OBJECT_PATH "/org/freedesktop/portal/desktop" +#define XDG_PORTAL_INTERFACE "org.freedesktop.portal.Realtime" /** \cond */ struct pw_rtkit_bus { @@ -184,7 +189,11 @@ #ifdef HAVE_DBUS bool use_rtkit; - struct pw_rtkit_bus *system_bus; + /* For D-Bus. These are const static. */ + const char* service_name; + const char* object_path; + const char* interface; + struct pw_rtkit_bus *rtkit_bus; /* These are only for the RTKit implementation to fill in the `thread` * struct. Since there's barely any overhead here we'll do this @@ -215,7 +224,7 @@ } #ifdef HAVE_DBUS -struct pw_rtkit_bus *pw_rtkit_bus_get_system(void) +struct pw_rtkit_bus *pw_rtkit_bus_get(DBusBusType bus_type) { struct pw_rtkit_bus *bus; DBusError error; @@ -231,7 +240,7 @@ if (bus == NULL) return NULL; - bus->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + bus->bus = dbus_bus_get_private(bus_type, &error); if (bus->bus == NULL) goto error; @@ -241,12 +250,41 @@ error: free(bus); - pw_log_error("Failed to connect to system bus: %s", error.message); + pw_log_error("Failed to connect to %s bus: %s", + bus_type == DBUS_BUS_SYSTEM ? "system" : "session", error.message); dbus_error_free(&error); errno = ECONNREFUSED; return NULL; } +struct pw_rtkit_bus *pw_rtkit_bus_get_system(void) +{ + return pw_rtkit_bus_get(DBUS_BUS_SYSTEM); +} + +struct pw_rtkit_bus *pw_rtkit_bus_get_session(void) +{ + return pw_rtkit_bus_get(DBUS_BUS_SESSION); +} + +bool pw_rtkit_check_xdg_portal(struct pw_rtkit_bus *system_bus) +{ + DBusError error; + bool ret = true; + + dbus_error_init(&error); + + if (!dbus_bus_name_has_owner(system_bus->bus, XDG_PORTAL_SERVICE_NAME, &error)) { + pw_log_warn("Can't find xdg-portal: %s", error.name); + ret = false; + goto finish; + } +finish: + dbus_error_free(&error); + + return ret; +} + void pw_rtkit_bus_free(struct pw_rtkit_bus *system_bus) { dbus_connection_close(system_bus->bus); @@ -270,7 +308,7 @@ return -EIO; } -static long long rtkit_get_int_property(struct pw_rtkit_bus *connection, const char *propname, +static long long rtkit_get_int_property(struct impl *impl, const char *propname, long long *propval) { DBusMessage *m = NULL, *r = NULL; @@ -280,19 +318,19 @@ DBusError error; int current_type; long long ret; - const char *interfacestr = "org.freedesktop.RealtimeKit1"; + struct pw_rtkit_bus *connection = impl->rtkit_bus; dbus_error_init(&error); - if (!(m = dbus_message_new_method_call(RTKIT_SERVICE_NAME, - RTKIT_OBJECT_PATH, + if (!(m = dbus_message_new_method_call(impl->service_name, + impl->object_path, "org.freedesktop.DBus.Properties", "Get"))) { ret = -ENOMEM; goto finish; } if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &interfacestr, + DBUS_TYPE_STRING, &impl->interface, DBUS_TYPE_STRING, &propname, DBUS_TYPE_INVALID)) { ret = -ENOMEM; goto finish; @@ -349,60 +387,63 @@ return ret; } -int pw_rtkit_get_max_realtime_priority(struct pw_rtkit_bus *connection) +int pw_rtkit_get_max_realtime_priority(struct impl *impl) { long long retval; int err; - err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval); + err = rtkit_get_int_property(impl, "MaxRealtimePriority", &retval); return err < 0 ? err : retval; } -int pw_rtkit_get_min_nice_level(struct pw_rtkit_bus *connection, int *min_nice_level) +int pw_rtkit_get_min_nice_level(struct impl *impl, int *min_nice_level) { long long retval; int err; - err = rtkit_get_int_property(connection, "MinNiceLevel", &retval); + err = rtkit_get_int_property(impl, "MinNiceLevel", &retval); if (err >= 0) *min_nice_level = retval; return err; } -long long pw_rtkit_get_rttime_usec_max(struct pw_rtkit_bus *connection) +long long pw_rtkit_get_rttime_usec_max(struct impl *impl) { long long retval; int err; - err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval); + err = rtkit_get_int_property(impl, "RTTimeUSecMax", &retval); return err < 0 ? err : retval; } -int pw_rtkit_make_realtime(struct pw_rtkit_bus *connection, pid_t thread, int priority) +int pw_rtkit_make_realtime(struct impl *impl, pid_t thread, int priority) { DBusMessage *m = NULL, *r = NULL; + dbus_uint64_t pid; dbus_uint64_t u64; dbus_uint32_t u32; DBusError error; int ret; + struct pw_rtkit_bus *connection = impl->rtkit_bus; dbus_error_init(&error); if (thread == 0) thread = _gettid(); - if (!(m = dbus_message_new_method_call(RTKIT_SERVICE_NAME, - RTKIT_OBJECT_PATH, - "org.freedesktop.RealtimeKit1", - "MakeThreadRealtime"))) { + if (!(m = dbus_message_new_method_call(impl->service_name, + impl->object_path, impl->interface, + "MakeThreadRealtimeWithPID"))) { ret = -ENOMEM; goto finish; } + pid = (dbus_uint64_t) getpid(); u64 = (dbus_uint64_t) thread; u32 = (dbus_uint32_t) priority; if (!dbus_message_append_args(m, + DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &u64, DBUS_TYPE_UINT32, &u32, DBUS_TYPE_INVALID)) { ret = -ENOMEM; @@ -435,31 +476,34 @@ return ret; } -int pw_rtkit_make_high_priority(struct pw_rtkit_bus *connection, pid_t thread, int nice_level) +int pw_rtkit_make_high_priority(struct impl *impl, pid_t thread, int nice_level)
View file
pipewire-0.3.56.tar.gz/src/pipewire/conf.c -> pipewire-0.3.57.tar.gz/src/pipewire/conf.c
Changed
@@ -39,8 +39,10 @@ #include <pwd.h> #endif #if defined(__FreeBSD__) || defined(__MidnightBSD__) +#ifndef O_PATH #define O_PATH 0 #endif +#endif #include <spa/utils/result.h> #include <spa/utils/string.h> @@ -190,6 +192,9 @@ return -ENOENT; } + if (pw_check_option("no-config", "true")) + goto no_config; + if ((res = get_envconf_path(path, size, prefix, name)) != 0) { if ((*level)++ == 0) return res; @@ -198,20 +203,18 @@ if (*level == 0) { (*level)++; - if ((res = get_confdata_path(path, size, prefix, name)) != 0) + if ((res = get_homeconf_path(path, size, prefix, name)) != 0) return res; } - if (pw_check_option("no-config", "true")) - return 0; - if (*level == 1) { (*level)++; if ((res = get_configdir_path(path, size, prefix, name)) != 0) return res; } if (*level == 2) { +no_config: (*level)++; - if ((res = get_homeconf_path(path, size, prefix, name)) != 0) + if ((res = get_confdata_path(path, size, prefix, name)) != 0) return res; } return 0; @@ -405,12 +408,17 @@ if (fstat(fd, &sbuf) < 0) goto error_close; - if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) - goto error_close; - close(fd); - count = pw_properties_update_string(conf, data, sbuf.st_size); - munmap(data, sbuf.st_size); + if (sbuf.st_size > 0) { + if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) + goto error_close; + + count = pw_properties_update_string(conf, data, sbuf.st_size); + munmap(data, sbuf.st_size); + } else { + count = 0; + } + close(fd); pw_log_info("%p: loaded config '%s' with %d items", conf, path, count); @@ -423,13 +431,33 @@ return -errno; } +static bool check_override(struct pw_properties *conf, const char *name, int level) +{ + const struct spa_dict_item *it; + + spa_dict_for_each(it, &conf->dict) { + int lev, idx; + + if (!spa_streq(name, it->value)) + continue; + if (sscanf(it->key, "override.%d.%d.config.name", &lev, &idx) != 2) + continue; + if (lev < level) + return false; + } + return true; +} + static void add_override(struct pw_properties *conf, struct pw_properties *override, - const char *path, int level, int index) + const char *path, const char *name, int level, int index) { const struct spa_dict_item *it; char key1024; + snprintf(key, sizeof(key), "override.%d.%d.config.path", level, index); pw_properties_set(conf, key, path); + snprintf(key, sizeof(key), "override.%d.%d.config.name", level, index); + pw_properties_set(conf, key, name); spa_dict_for_each(it, &override->dict) { snprintf(key, sizeof(key), "override.%d.%d.%s", level, index, it->key); pw_properties_set(conf, key, it->value); @@ -488,10 +516,16 @@ return -errno; for (i = 0; i < n; i++) { - snprintf(fname, sizeof(fname), "%s/%s", path, entriesi->d_name); - if (conf_load(fname, override) >= 0) - add_override(conf, override, fname, level, i); - pw_properties_clear(override); + const char *name = entriesi->d_name; + + snprintf(fname, sizeof(fname), "%s/%s", path, name); + if (check_override(conf, name, level)) { + if (conf_load(fname, override) >= 0) + add_override(conf, override, fname, name, level, i); + pw_properties_clear(override); + } else { + pw_log_info("skip override %s with lower priority", fname); + } free(entriesi); } free(entries); @@ -891,6 +925,75 @@ return 0; } +static int try_load_conf(const char *conf_prefix, const char *conf_name, + struct pw_properties *conf) +{ + int res; + + if (conf_name == NULL) + return -EINVAL; + if (spa_streq(conf_name, "null")) + return 0; + if ((res = pw_conf_load_conf(conf_prefix, conf_name, conf)) < 0) { + bool skip_prefix = conf_prefix == NULL || conf_name0 == '/'; + pw_log_warn("can't load config %s%s%s: %s", + skip_prefix ? "" : conf_prefix, + skip_prefix ? "" : "/", + conf_name, spa_strerror(res)); + } + return res; +} + +SPA_EXPORT +int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_properties *conf) +{ + const char *conf_prefix, *conf_name; + int res; + + conf_prefix = getenv("PIPEWIRE_CONFIG_PREFIX"); + if (conf_prefix == NULL) + conf_prefix = pw_properties_get(props, PW_KEY_CONFIG_PREFIX); + + conf_name = getenv("PIPEWIRE_CONFIG_NAME"); + if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) { + conf_name = pw_properties_get(props, PW_KEY_CONFIG_NAME); + if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) { + conf_name = "client.conf"; + if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) { + pw_log_error("can't load default config %s: %s", + conf_name, spa_strerror(res)); + return res; + } + } + } + + conf_name = pw_properties_get(props, PW_KEY_CONFIG_OVERRIDE_NAME); + if (conf_name != NULL) { + struct pw_properties *override; + const char *path, *name; + + override = pw_properties_new(NULL, NULL); + if (override == NULL) { + res = -errno; + return res; + } + + conf_prefix = pw_properties_get(props, PW_KEY_CONFIG_OVERRIDE_PREFIX); + if ((res = try_load_conf(conf_prefix, conf_name, override)) < 0) { + pw_log_error("can't load default override config %s: %s", + conf_name, spa_strerror(res)); + pw_properties_free (override); + return res; + } + path = pw_properties_get(override, "config.path"); + name = pw_properties_get(override, "config.name"); + add_override(conf, override, path, name, 0, 1); + pw_properties_free(override); + } + + return res; +} + SPA_EXPORT int pw_context_conf_update_props(struct pw_context *context, const char *section, struct pw_properties *props)
View file
pipewire-0.3.56.tar.gz/src/pipewire/conf.h -> pipewire-0.3.57.tar.gz/src/pipewire/conf.h
Changed
@@ -33,6 +33,7 @@ * \{ */ +int pw_conf_load_conf_for_context(struct pw_properties *props, struct pw_properties *conf); int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties *conf); int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf); int pw_conf_save_state(const char *prefix, const char *name, const struct pw_properties *conf);
View file
pipewire-0.3.56.tar.gz/src/pipewire/context.c -> pipewire-0.3.57.tar.gz/src/pipewire/context.c
Changed
@@ -101,26 +101,6 @@ pw_properties_set(properties, PW_KEY_CORE_NAME, context->core->info.name); } -static int try_load_conf(struct pw_context *this, const char *conf_prefix, - const char *conf_name, struct pw_properties *conf) -{ - int res; - - if (conf_name == NULL) - return -EINVAL; - if (spa_streq(conf_name, "null")) - return 0; - if ((res = pw_conf_load_conf(conf_prefix, conf_name, conf)) < 0) { - bool skip_prefix = conf_prefix == NULL || conf_name0 == '/'; - pw_log_warn("%p: can't load config %s%s%s: %s", - this, - skip_prefix ? "" : conf_prefix, - skip_prefix ? "" : "/", - conf_name, spa_strerror(res)); - } - return res; -} - static int context_set_freewheel(struct pw_context *context, bool freewheel) { struct spa_thread *thr; @@ -211,7 +191,7 @@ { struct impl *impl; struct pw_context *this; - const char *lib, *str, *conf_prefix, *conf_name; + const char *lib, *str; void *dbus_iface = NULL; uint32_t n_support; struct pw_properties *pr, *conf; @@ -270,23 +250,8 @@ goto error_free; } this->conf = conf; - - conf_prefix = getenv("PIPEWIRE_CONFIG_PREFIX"); - if (conf_prefix == NULL) - conf_prefix = pw_properties_get(properties, PW_KEY_CONFIG_PREFIX); - - conf_name = getenv("PIPEWIRE_CONFIG_NAME"); - if (try_load_conf(this, conf_prefix, conf_name, conf) < 0) { - conf_name = pw_properties_get(properties, PW_KEY_CONFIG_NAME); - if (try_load_conf(this, conf_prefix, conf_name, conf) < 0) { - conf_name = "client.conf"; - if ((res = try_load_conf(this, conf_prefix, conf_name, conf)) < 0) { - pw_log_error("%p: can't load config %s: %s", - this, conf_name, spa_strerror(res)); - goto error_free; - } - } - } + if ((res = pw_conf_load_conf_for_context (properties, conf)) < 0) + goto error_free; n_support = pw_get_support(this->support, SPA_N_ELEMENTS(this->support) - 6); cpu = spa_support_find(this->support, n_support, SPA_TYPE_INTERFACE_CPU); @@ -627,98 +592,6 @@ return global; } -/** Find a port to link with - * - * \param context a context - * \param other_port a port to find a link with - * \param id the id of a port or PW_ID_ANY - * \param props extra properties - * \param n_format_filters number of filters - * \param format_filters array of format filters - * \paramout error an error when something is wrong - * \return a port that can be used to link to \a otherport or NULL on error - */ -struct pw_impl_port *pw_context_find_port(struct pw_context *context, - struct pw_impl_port *other_port, - uint32_t id, - struct pw_properties *props, - uint32_t n_format_filters, - struct spa_pod **format_filters, - char **error) -{ - struct pw_impl_port *best = NULL; - bool have_id; - struct pw_impl_node *n; - - have_id = id != PW_ID_ANY; - - pw_log_debug("%p: id:%u", context, id); - - spa_list_for_each(n, &context->node_list, link) { - if (n->global == NULL) - continue; - - if (other_port->node == n) - continue; - - if (!global_can_read(context, n->global)) - continue; - - pw_log_debug("%p: node id:%d", context, n->global->id); - - if (have_id) { - if (n->global->id == id) { - pw_log_debug("%p: id:%u matches node %p", context, id, n); - - best = - pw_impl_node_find_port(n, - pw_direction_reverse(other_port->direction), - PW_ID_ANY); - if (best) - break; - } - } else { - struct pw_impl_port *p, *pin, *pout; - uint8_t buf4096; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf)); - struct spa_pod *dummy; - - p = pw_impl_node_find_port(n, - pw_direction_reverse(other_port->direction), - PW_ID_ANY); - if (p == NULL) - continue; - - if (p->direction == PW_DIRECTION_OUTPUT) { - pin = other_port; - pout = p; - } else { - pin = p; - pout = other_port; - } - - if (pw_context_find_format(context, - pout, - pin, - props, - n_format_filters, - format_filters, - &dummy, - &b, - error) < 0) { - free(*error); - continue; - } - best = p; - break; - } - } - if (best == NULL) { - *error = spa_aprintf("No matching Node found"); - } - return best; -} - SPA_PRINTF_FUNC(7, 8) int pw_context_debug_port_params(struct pw_context *this, struct spa_node *node, enum spa_direction direction, uint32_t port_id, uint32_t id, int err, const char *debug, ...) @@ -1382,6 +1255,9 @@ * panding change. Apply the change to the position now so * that we have the right values when we change the node * states of the driver and followers to RUNNING below */ + pw_log_debug("%p: apply duration:%"PRIu64" rate:%u/%u", context, + n->current_quantum, n->current_rate.num, + n->current_rate.denom); n->rt.position->clock.duration = n->current_quantum; n->rt.position->clock.rate = n->current_rate; n->current_pending = false;
View file
pipewire-0.3.56.tar.gz/src/pipewire/data-loop.c -> pipewire-0.3.57.tar.gz/src/pipewire/data-loop.c
Changed
@@ -274,12 +274,7 @@ spa_invoke_func_t func, uint32_t seq, const void *data, size_t size, bool block, void *user_data) { - int res; - if (loop->running) - res = pw_loop_invoke(loop->loop, func, seq, data, size, block, user_data); - else - res = func(loop->loop->loop, false, seq, data, size, user_data); - return res; + return pw_loop_invoke(loop->loop, func, seq, data, size, block, user_data); } /** Set a thread utils implementation.
View file
pipewire-0.3.56.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-link.c
Changed
@@ -281,8 +281,10 @@ /* find a common format for the ports */ if ((res = pw_context_find_format(context, output, input, NULL, 0, NULL, - &format, &b, &error)) < 0) + &format, &b, &error)) < 0) { + format = NULL; goto error; + } format = spa_pod_copy(format); spa_pod_fixate(format); @@ -1262,7 +1264,7 @@ impl->inode = input_node; } - this->rt.target.signal = impl->inode->rt.target.signal; + this->rt.target.signal_func = impl->inode->rt.target.signal_func; this->rt.target.data = impl->inode->rt.target.data; pw_log_debug("%p: constructed out:%p:%d.%d -> in:%p:%d.%d", impl,
View file
pipewire-0.3.56.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-node.c
Changed
@@ -1047,7 +1047,7 @@ if (pw_node_activation_state_dec(state, 1)) { a->status = PW_NODE_ACTIVATION_TRIGGERED; a->signal_time = nsec; - t->signal(t->data); + t->signal_func(t->data); } } return 0; @@ -1145,7 +1145,7 @@ this->name, this->info.id, cmd - 1); pw_log_trace_fp("%p: got process", this); - this->rt.target.signal(this->rt.target.data); + this->rt.target.signal_func(this->rt.target.data); } } @@ -1262,9 +1262,9 @@ this->rt.activation = this->activation->map->ptr; this->rt.target.activation = this->rt.activation; this->rt.target.node = this; - this->rt.target.signal = process_node; + this->rt.target.signal_func = process_node; this->rt.target.data = this; - this->rt.driver_target.signal = process_node; + this->rt.driver_target.signal_func = process_node; reset_position(this, &this->rt.activation->position); this->rt.activation->sync_timeout = DEFAULT_SYNC_TIMEOUT; @@ -1613,7 +1613,7 @@ state->pending, state->required); dump_states(node); } - node->rt.target.signal(node->rt.target.data); + node->rt.target.signal_func(node->rt.target.data); } if (node->current_pending) {
View file
pipewire-0.3.56.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.57.tar.gz/src/pipewire/impl-port.c
Changed
@@ -209,6 +209,7 @@ int pw_impl_port_init_mix(struct pw_impl_port *port, struct pw_impl_port_mix *mix) { uint32_t port_id; + struct pw_impl_node *node = port->node; int res = 0; port_id = pw_map_insert_new(&port->mix_port_map, mix); @@ -252,6 +253,13 @@ port->n_mix, port->port_id, mix->port.port_id, mix->io, spa_strerror(res)); + if (port->n_mix == 1) { + pw_log_debug("%p: setting port io", port); + spa_node_port_set_io(node->node, + port->direction, port->port_id, + SPA_IO_Buffers, + &port->rt.io, sizeof(port->rt.io)); + } return res; error_remove_port: @@ -266,6 +274,7 @@ { int res = 0; uint32_t port_id = mix->port.port_id; + struct pw_impl_node *node = port->node; pw_map_remove(&port->mix_port_map, port_id); spa_list_remove(&mix->link); @@ -280,6 +289,13 @@ pw_log_debug("%p: release mix %d %d.%d", port, port->n_mix, port->port_id, mix->port.port_id); + if (port->n_mix == 0) { + pw_log_debug("%p: clearing port io", port); + spa_node_port_set_io(node->node, + port->direction, port->port_id, + SPA_IO_Buffers, + NULL, sizeof(port->rt.io)); + } return res; } @@ -1025,12 +1041,7 @@ if (control) { pw_log_debug("%p: setting node control", port); } else { - pw_log_debug("%p: setting node io", port); - spa_node_port_set_io(node->node, - port->direction, port->port_id, - SPA_IO_Buffers, - &port->rt.io, sizeof(port->rt.io)); - + pw_log_debug("%p: setting mixer io", port); spa_node_port_set_io(port->mix, pw_direction_reverse(port->direction), 0, SPA_IO_Buffers,
View file
pipewire-0.3.56.tar.gz/src/pipewire/keys.h -> pipewire-0.3.57.tar.gz/src/pipewire/keys.h
Changed
@@ -76,6 +76,8 @@ /* config */ #define PW_KEY_CONFIG_PREFIX "config.prefix" /**< a config prefix directory */ #define PW_KEY_CONFIG_NAME "config.name" /**< a config file name */ +#define PW_KEY_CONFIG_OVERRIDE_PREFIX "config.override.prefix" /**< a config override prefix directory */ +#define PW_KEY_CONFIG_OVERRIDE_NAME "config.override.name" /**< a config override file name */ /* context */ #define PW_KEY_CONTEXT_PROFILE_MODULES "context.profile.modules" /**< a context profile for modules, deprecated */ @@ -170,7 +172,10 @@ #define PW_KEY_NODE_FORCE_RATE "node.force-rate" /**< force a rate while the node is * active */ -#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node */ +#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node. The node is + * initially linked to node.target or + * target.object or the default node. If the + * targets is removed, the node is destroyed */ #define PW_KEY_NODE_ALWAYS_PROCESS "node.always-process" /**< process even when unlinked */ #define PW_KEY_NODE_WANT_DRIVER "node.want-driver" /**< the node wants to be grouped with a driver * node in order to schedule the graph. */
View file
pipewire-0.3.56.tar.gz/src/pipewire/mem.c -> pipewire-0.3.57.tar.gz/src/pipewire/mem.c
Changed
@@ -485,7 +485,12 @@ spa_list_init(&b->memmaps); #ifdef HAVE_MEMFD_CREATE - b->this.fd = memfd_create("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING); + char name128; + snprintf(name, sizeof(name), + "pipewire-memfd:flags=0x%08x,type=%" PRIu32 ",size=%zu", + (unsigned int) flags, type, size); + + b->this.fd = memfd_create(name, MFD_CLOEXEC | MFD_ALLOW_SEALING); if (b->this.fd == -1) { res = -errno; pw_log_error("%p: Failed to create memfd: %m", pool); @@ -499,7 +504,11 @@ goto error_free; } #else - char filename = "/dev/shm/pipewire-tmpfile.XXXXXX"; + char filename128; + snprintf(filename, sizeof(filename), + "/dev/shm/pipewire-tmpfile:flags=0x%08x,type=%" PRIu32 ",size=%zu:XXXXXX", + (unsigned int) flags, type, size); + b->this.fd = mkostemp(filename, O_CLOEXEC); if (b->this.fd == -1) { res = -errno;
View file
pipewire-0.3.56.tar.gz/src/pipewire/meson.build -> pipewire-0.3.57.tar.gz/src/pipewire/meson.build
Changed
@@ -94,7 +94,7 @@ '-DOLD_MEDIA_SESSION_WORKAROUND=1' -if build_machine.system() != 'freebsd' and build_machine.system() != 'midnightbsd' +if host_machine.system() != 'freebsd' and host_machine.system() != 'midnightbsd' libpipewire_c_args += '-D_POSIX_C_SOURCE'
View file
pipewire-0.3.56.tar.gz/src/pipewire/private.h -> pipewire-0.3.57.tar.gz/src/pipewire/private.h
Changed
@@ -573,7 +573,7 @@ struct spa_list link; struct pw_impl_node *node; struct pw_node_activation *activation; - int (*signal) (void *data); + int (*signal_func) (void *data); void *data; unsigned int active:1; }; @@ -1153,16 +1153,6 @@ struct spa_pod_builder *builder, char **error); -/** Find a ports compatible with \a other_port and the format filters */ -struct pw_impl_port * -pw_context_find_port(struct pw_context *context, - struct pw_impl_port *other_port, - uint32_t id, - struct pw_properties *props, - uint32_t n_format_filters, - struct spa_pod **format_filters, - char **error); - int pw_context_debug_port_params(struct pw_context *context, struct spa_node *node, enum spa_direction direction, uint32_t port_id, uint32_t id, int err, const char *debug, ...);
View file
pipewire-0.3.56.tar.gz/src/pipewire/stream.c -> pipewire-0.3.57.tar.gz/src/pipewire/stream.c
Changed
@@ -1261,11 +1261,9 @@ { struct spa_pod_prop *prop; struct spa_pod_object *obj = (struct spa_pod_object *) param; - union { - float f; - double d; - bool b; - } value; + float value_f; + double value_d; + bool value_b; float *values; uint32_t i, n_values; @@ -1278,24 +1276,24 @@ switch (c->container) { case SPA_TYPE_Float: - if (spa_pod_get_float(&prop->value, &value.f) < 0) + if (spa_pod_get_float(&prop->value, &value_f) < 0) continue; n_values = 1; - values = &value.f; + values = &value_f; break; case SPA_TYPE_Double: - if (spa_pod_get_double(&prop->value, &value.d) < 0) + if (spa_pod_get_double(&prop->value, &value_d) < 0) continue; n_values = 1; - value.f = value.d; - values = &value.f; + value_f = value_d; + values = &value_f; break; case SPA_TYPE_Bool: - if (spa_pod_get_bool(&prop->value, &value.b) < 0) + if (spa_pod_get_bool(&prop->value, &value_b) < 0) continue; - value.f = value.b ? 1.0f : 0.0f; + value_f = value_b ? 1.0f : 0.0f; n_values = 1; - values = &value.f; + values = &value_f; break; case SPA_TYPE_Array: if ((values = spa_pod_get_array(&prop->value, &n_values)) == NULL ||
View file
pipewire-0.3.56.tar.gz/src/pipewire/utils.c -> pipewire-0.3.57.tar.gz/src/pipewire/utils.c
Changed
@@ -154,6 +154,7 @@ ssize_t pw_getrandom(void *buf, size_t buflen, unsigned int flags) { ssize_t bytes; + int read_errno; #ifdef HAVE_GETRANDOM bytes = getrandom(buf, buflen, flags); @@ -165,7 +166,9 @@ if (fd < 0) return -1; bytes = read(fd, buf, buflen); + read_errno = errno; close(fd); + errno = read_errno; return bytes; }
View file
pipewire-0.3.56.tar.gz/src/pipewire/utils.h -> pipewire-0.3.57.tar.gz/src/pipewire/utils.h
Changed
@@ -86,6 +86,7 @@ }) #endif +SPA_WARN_UNUSED_RESULT ssize_t pw_getrandom(void *buf, size_t buflen, unsigned int flags); void* pw_reallocarray(void *ptr, size_t nmemb, size_t size);
View file
pipewire-0.3.56.tar.gz/src/tools/pw-cat.c -> pipewire-0.3.57.tar.gz/src/tools/pw-cat.c
Changed
@@ -1663,6 +1663,7 @@ pw_stream_destroy(data.stream); } error_no_stream: +error_bad_file: spa_hook_remove(&data.core_listener); pw_core_disconnect(data.core); error_ctx_connect_failed: @@ -1671,7 +1672,6 @@ pw_main_loop_destroy(data.loop); error_no_props: error_no_main_loop: -error_bad_file: pw_properties_free(data.props); if (data.file) sf_close(data.file);
View file
pipewire-0.3.56.tar.gz/src/tools/pw-cli.c -> pipewire-0.3.57.tar.gz/src/tools/pw-cli.c
Changed
@@ -226,7 +226,6 @@ static bool do_permissions(struct data *data, const char *cmd, char *args, char **error); static bool do_get_permissions(struct data *data, const char *cmd, char *args, char **error); static bool do_send_command(struct data *data, const char *cmd, char *args, char **error); -static bool do_dump(struct data *data, const char *cmd, char *args, char **error); static bool do_quit(struct data *data, const char *cmd, char *args, char **error); #define DUMP_NAMES "Core|Module|Device|Node|Port|Factory|Client|Link|Session|Endpoint|EndpointStream" @@ -251,8 +250,6 @@ { "permissions", "sp", "Set permissions for a client <client-id> <object> <permission>", do_permissions }, { "get-permissions", "gp", "Get permissions of a client <client-id>", do_get_permissions }, { "send-command", "c", "Send a command <object-id>", do_send_command }, - { "dump", "D", "Dump objects in ways that are cleaner for humans to understand " - "short|deep|resolve|notype -sdrt all|"DUMP_NAMES"|<id>", do_dump }, { "quit", "q", "Quit", do_quit }, }; @@ -269,7 +266,10 @@ printf("Available commands:\n"); for (i = 0; i < SPA_N_ELEMENTS(command_list); i++) { - printf("\t%-20.20s\t%s\n", command_listi.name, command_listi.description); + 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); } return true; } @@ -1929,20 +1929,6 @@ return true; } -static const char * -pw_interface_short(const char *type) -{ - size_t ilen; - - ilen = strlen(PW_TYPE_INFO_INTERFACE_BASE); - - if (!type || strlen(type) <= ilen || - memcmp(type, PW_TYPE_INFO_INTERFACE_BASE, ilen)) - return NULL; - - return type + ilen; -} - static struct global * obj_global(struct remote_data *rd, uint32_t id) { @@ -2001,20 +1987,6 @@ return NULL; } -static struct spa_dict * -obj_props(struct remote_data *rd, uint32_t id) -{ - struct global *global; - - if (!rd) - return NULL; - - global = obj_global(rd, id); - if (!global) - return NULL; - return global_props(global); -} - static const char * global_lookup(struct global *global, const char *key) { @@ -2026,16 +1998,6 @@ return spa_dict_lookup(dict, key); } -static const char * -obj_lookup(struct remote_data *rd, uint32_t id, const char *key) -{ - struct spa_dict *dict; - - dict = obj_props(rd, id); - if (!dict) - return NULL; - return spa_dict_lookup(dict, key); -} static int children_of(struct remote_data *rd, uint32_t parent_id, @@ -2135,67 +2097,6 @@ return count; } -#ifndef BIT -#define BIT(x) (1U << (x)) -#endif - -enum dump_flags { - is_default = 0, - is_short = BIT(0), - is_deep = BIT(1), - is_resolve = BIT(2), - is_notype = BIT(3) -}; - -static const char * const dump_types = { - PW_TYPE_INTERFACE_Core, - PW_TYPE_INTERFACE_Module, - PW_TYPE_INTERFACE_Device, - PW_TYPE_INTERFACE_Node, - PW_TYPE_INTERFACE_Port, - PW_TYPE_INTERFACE_Factory, - PW_TYPE_INTERFACE_Client, - PW_TYPE_INTERFACE_Link, - PW_TYPE_INTERFACE_Session, - PW_TYPE_INTERFACE_Endpoint, - PW_TYPE_INTERFACE_EndpointStream, -}; - -int dump_type_index(const char *type) -{ - unsigned int i; - - if (!type) - return -1; - - for (i = 0; i < SPA_N_ELEMENTS(dump_types); i++) { - if (spa_streq(dump_typesi, type)) - return (int)i; - } - - return -1; -} - -static inline unsigned int dump_type_count(void) -{ - return SPA_N_ELEMENTS(dump_types); -} - -static const char *name_to_dump_type(const char *name) -{ - unsigned int i; - - if (!name) - return NULL; - - for (i = 0; i < SPA_N_ELEMENTS(dump_types); i++) { - if (!strcasecmp(name, pw_interface_short(dump_typesi))) - return dump_typesi; - } - - return NULL; -} - #define INDENT(_level) \ ({ \ int __level = (_level); \ @@ -2205,817 +2106,6 @@ (const char *)_indent; \ }) -static void -dump(struct data *data, struct global *global, - enum dump_flags flags, int level); - -static void -dump_properties(struct data *data, struct global *global, - enum dump_flags flags, int level) -{ - struct remote_data *rd = data->current; - struct spa_dict *props; - const struct spa_dict_item *item; - const char *ind; - int id; - const char *extra; - - if (!global) - return; - - props = global_props(global); - if (!props || !props->n_items) - return; - - ind = INDENT(level + 2); - spa_dict_for_each(item, props) { - printf("%s%s = \"%s\"", - ind, item->key, item->value); - - extra = NULL; - if (spa_streq(global->type, PW_TYPE_INTERFACE_Port) && spa_streq(item->key, PW_KEY_NODE_ID)) { - id = atoi(item->value); - if (id >= 0) - extra = obj_lookup(rd, id, PW_KEY_NODE_NAME); - } else if (spa_streq(global->type, PW_TYPE_INTERFACE_Factory) && spa_streq(item->key, PW_KEY_MODULE_ID)) { - id = atoi(item->value); - if (id >= 0) - extra = obj_lookup(rd, id, PW_KEY_MODULE_NAME); - } else if (spa_streq(global->type, PW_TYPE_INTERFACE_Device) && spa_streq(item->key, PW_KEY_FACTORY_ID)) { - id = atoi(item->value); - if (id >= 0) - extra = obj_lookup(rd, id, PW_KEY_FACTORY_NAME);
View file
pipewire-0.3.56.tar.gz/test/test-spa-utils.c -> pipewire-0.3.57.tar.gz/test/test-spa-utils.c
Changed
@@ -419,6 +419,12 @@ } pwtest_int_eq(count, 4); pwtest_int_eq(hook_free_count, 4); + + /* remove a zeroed hook */ + struct spa_hook hook; + spa_zero(hook); + spa_hook_remove(&hook); + return PWTEST_PASS; }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.