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 60
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Sat Nov 15 13:00:32 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.5.83 + +------------------------------------------------------------------- Sun Nov 2 11:28:58 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.5.81
View file
pipewire-aptx.spec
Changed
@@ -8,7 +8,7 @@ %define minimum_version 1.5.0 Name: pipewire-aptx -Version: 1.5.81 +Version: 1.5.83 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
_service:download_files:pipewire-1.5.81.tar.bz2/.gitlab-ci.yml -> _service:download_files:pipewire-1.5.83.tar.bz2/.gitlab-ci.yml
Changed
@@ -38,7 +38,7 @@ .fedora: variables: # Update this tag when you want to trigger a rebuild - FDO_DISTRIBUTION_TAG: '2025-10-15.0' + FDO_DISTRIBUTION_TAG: '2025-10-22.0' FDO_DISTRIBUTION_VERSION: '42' FDO_DISTRIBUTION_PACKAGES: >- alsa-lib-devel @@ -48,6 +48,7 @@ dbus-devel doxygen fdk-aac-free-devel + file findutils gcc gcc-c++
View file
_service:download_files:pipewire-1.5.81.tar.bz2/NEWS -> _service:download_files:pipewire-1.5.83.tar.bz2/NEWS
Changed
@@ -1,3 +1,76 @@ +# PipeWire 1.5.83 (2025-11-06) + +This is the third 1.6 release candidate that is API and ABI +compatible with previous 1.4.x, 1.2.x and 1.0.x releases. + +Changes since the last pre-release: + +## Highlights + - Include the NEWS and updated version number. + + +Older versions: + +# PipeWire 1.5.82 (2025-11-06) + +This is the second 1.6 release candidate that is API and ABI +compatible with previous 1.4.x, 1.2.x and 1.0.x releases. + +Changes since the last pre-release: + +## Highlights + - The max channel limit is now a compile time option. + - The SAP and RTP module have seen some robustness improvements. + - Add audio.layout propperty. + - Cleanups to the code here and there. + +## PipeWire + - Handle Tags more like Latency with a NULL param when no ports are linked + and some sort of (empty) Tag when the ports are linked. + +## Modules + - Improve the echo-cancel module to keep the streams more aligned + and cause less latency. + - Improve format parsing errors in most modules. + - The RTP module now has extra code for better network robustness, including + cases when network interfaces are not yet up and running, and multicast + sockets are silently kicked out of IGMP groups. + - The direct timestamp mode in the RTP module was effectively broken and is + now fixed. + - Add support for audio.layout. + - Add multichannel support to ROC. + +## SPA + - Rework the maximum number of channel handling. Because this is a + potential ABI break, it is now a compile time option with new + functions to handle more than the previous 64 channels. + - The 64 channel limit was removed from the noise shaper. + - spa_strbuf is used in more places instead of custom snprintf code. + - The volume ramp code was simplified. + - The driver node now has properties to configure the clock. + - The adapter will try to renegotiate when the driver changes. + - Fix relaxed array parsing with od number of elements. (#4944) + - audio.layout was added to set the channel positions to some + predefined layouts. + - Added more POD choice checks to ensure the right amount of values + are present in the choice. + - Fix __has_attribute usage. (#4962) + - Thread RESET_ON_FORK is now disabled for JACK application so that + forking will preserve any real-time thread priorities, like JACK. + (#4966) + - Fix some compilation issues. (#4960 and #4961). + +## Pulse-server + - Fix missing subscription events on device port changes. + - Increase min.quantum to 256/48000. (#4875) + +## GStreamer + - Avoid overflow in clock time calculations. + - Fix renegotiation. + +## Docs + - Swap the name and id of device.product + # PipeWire 1.5.81 (2025-10-16) This is the first 1.6 release candidate that is API and ABI @@ -166,8 +239,11 @@ ## Bluetooth - Telephony improvements. - ASHA support was added. - - Add packet loss correction with spandsp for some codecs. - - Synchronisation between ISO streams in the same group. + - Packet loss concealment was added. + - Improved synchronisation between LE Audio streams in the same group. + - Improved LE Audio device compatibility. + - LC3-24kHz voice codec was added (used by Airpods) + - LDAC decoding support added (requires separate decoder library) ## Pulse-server - The SUSPEND event is now correctly generated. fail-on-suspend is @@ -193,9 +269,6 @@ ## Docs - Document the client-node flow a bit more. - -Older versions: - # PipeWire 1.4.0 (2025-03-06) This is the 1.4 release that is API and ABI compatible with previous
View file
_service:download_files:pipewire-1.5.81.tar.bz2/doc/dox/api/spa-pod.dox -> _service:download_files:pipewire-1.5.83.tar.bz2/doc/dox/api/spa-pod.dox
Changed
@@ -33,7 +33,7 @@ - `SPA_TYPE_Bytes`: A byte array. - `SPA_TYPE_Rectangle`: A rectangle with width and height. - `SPA_TYPE_Fraction`: A fraction with numerator and denominator. -- `SPA_TYPE_Bitmap`: An array of bits. +- `SPA_TYPE_Bitmap`: An array of bits. Deprecated and unused. POD's can be grouped together in these container types: @@ -435,10 +435,11 @@ \endcode `spa_pod_get_values()` is a useful function. It returns a -`struct spa_pod*` with and array of values. For normal POD's -and choice none values, it simply returns the POD and one value. -For other choice values it returns the choice type and an array -of values: +`struct spa_pod*` with and array of values. For invalid PODs +it returns the POD and no values. For normal PODs it returns +the POD and one value. For choice values it returns the choice +type and an array of values. If the choice doesn't fit even a +single value, the array will have no values. \code{.c} struct spa_pod *value;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/doc/dox/config/pipewire-props.7.md -> _service:download_files:pipewire-1.5.83.tar.bz2/doc/dox/config/pipewire-props.7.md
Changed
@@ -174,12 +174,12 @@ @PAR@ device-prop device.product.id # integer \parblock -\copydoc PW_KEY_DEVICE_PRODUCT_NAME +\copydoc PW_KEY_DEVICE_PRODUCT_ID \endparblock @PAR@ device-prop device.product.name # string \parblock -\copydoc PW_KEY_DEVICE_PRODUCT_ID +\copydoc PW_KEY_DEVICE_PRODUCT_NAME \endparblock @PAR@ device-prop device.class # string @@ -843,6 +843,9 @@ @PAR@ node-prop audio.position # JSON array of strings The audio position of the channels in the device. This is auto detected based on the profile. You can configure an array of channel positions, like " FL, FR ". +@PAR@ node-prop audio.layout # string +The audio layout of the channels in the device. You can use any of the predefined layouts, like "Stereo", "5.1" etc. + @PAR@ node-prop audio.allowed-rates # JSON array of integers \parblock The allowed audio rates to open the device with. Default is " ", which means the device can be opened in any supported rate.
View file
_service:download_files:pipewire-1.5.81.tar.bz2/meson.build -> _service:download_files:pipewire-1.5.83.tar.bz2/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '1.5.81', + version : '1.5.83', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3', @@ -115,10 +115,11 @@ '-Werror=old-style-definition', '-Werror=missing-parameter-type', '-Werror=strict-prototypes', + '-DSPA_AUDIO_MAX_CHANNELS=128u', add_project_arguments(cc.get_supported_arguments(cc_flags), language: 'c') - -cc_flags_native = cc_native.get_supported_arguments(cc_flags) +add_project_arguments(cc_native.get_supported_arguments(cc_flags), + language: 'c', native: true) have_cpp = add_languages('cpp', native: false, required : false)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/pipewire-alsa/alsa-plugins/ctl_pipewire.c -> _service:download_files:pipewire-1.5.83.tar.bz2/pipewire-alsa/alsa-plugins/ctl_pipewire.c
Changed
@@ -22,9 +22,11 @@ #define VOLUME_MIN ((uint32_t) 0U) #define VOLUME_MAX ((uint32_t) 0x10000U) +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + struct volume { uint32_t channels; - long valuesSPA_AUDIO_MAX_CHANNELS; + long valuesMAX_CHANNELS; }; typedef struct { @@ -498,7 +500,7 @@ spa_pod_builder_push_object(b, &f0, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); if (volume) { - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; uint32_t i, n_volumes = 0; n_volumes = volume->channels; @@ -850,11 +852,11 @@ break; case SPA_PROP_channelVolumes: { - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; uint32_t n_volumes, i; n_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - volumes, SPA_AUDIO_MAX_CHANNELS); + volumes, SPA_N_ELEMENTS(volumes)); g->node.channel_volume.channels = n_volumes; for (i = 0; i < n_volumes; i++)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/pipewire-alsa/alsa-plugins/pcm_pipewire.c -> _service:download_files:pipewire-1.5.83.tar.bz2/pipewire-alsa/alsa-plugins/pcm_pipewire.c
Changed
@@ -31,6 +31,7 @@ #define MAX_BUFFERS 64u #define MAX_RATE (48000*8) +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define MIN_PERIOD 64 @@ -642,7 +643,7 @@ #define _FORMAT_BE(p, fmt) p ? SPA_AUDIO_FORMAT_UNKNOWN : SPA_AUDIO_FORMAT_ ## fmt ## _OE #endif -static int set_default_channels(uint32_t channels, uint32_t positionSPA_AUDIO_MAX_CHANNELS) +static int set_default_channels(uint32_t channels, uint32_t positionMAX_CHANNELS) { switch (channels) { case 8: @@ -915,12 +916,16 @@ default: return -EINVAL; } + if (map->channels > MAX_CHANNELS) + return -ENOTSUP; + for (i = 0; i < map->channels; i++) { + char buf8; positioni = chmap_to_channel(map->posi); pw_log_debug("map %d: %s / %s", i, snd_pcm_chmap_name(map->posi), - spa_debug_type_find_short_name(spa_type_audio_channel, - positioni)); + spa_type_audio_channel_make_short_name(positioni, + buf, sizeof(buf), "UNK")); } return 1; } @@ -1097,7 +1102,7 @@ { "alsa.rate", SND_PCM_IOPLUG_HW_RATE, TYPE_MIN_MAX, { 1, MAX_RATE }, 2, collect_int }, { "alsa.channels", SND_PCM_IOPLUG_HW_CHANNELS, TYPE_MIN_MAX, - { 1, SPA_AUDIO_MAX_CHANNELS }, 2, collect_int }, + { 1, MAX_CHANNELS }, 2, collect_int }, { "alsa.buffer-bytes", SND_PCM_IOPLUG_HW_BUFFER_BYTES, TYPE_MIN_MAX, { MIN_BUFFER_BYTES, MAX_BUFFER_BYTES }, 2, collect_int }, { "alsa.period-bytes", SND_PCM_IOPLUG_HW_PERIOD_BYTES, TYPE_MIN_MAX,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/pipewire-jack/src/pipewire-jack.c -> _service:download_files:pipewire-1.5.83.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
@@ -4299,6 +4299,7 @@ client->props = pw_properties_new( PW_KEY_LOOP_CANCEL, "true", + SPA_KEY_THREAD_RESET_ON_FORK, "false", PW_KEY_REMOTE_NAME, client->server_name, PW_KEY_CLIENT_NAME, client_name, PW_KEY_CLIENT_API, "jack",
View file
_service:download_files:pipewire-1.5.81.tar.bz2/po/tr.po -> _service:download_files:pipewire-1.5.83.tar.bz2/po/tr.po
Changed
@@ -1,46 +1,51 @@ # Turkish translation for PipeWire. -# Copyright (C) 2014-2024 PipeWire's COPYRIGHT HOLDER +# Copyright (C) 2014-2025 PipeWire's COPYRIGHT HOLDER # This file is distributed under the same license as the PipeWire package. # # Necdet Yücel <necdetyucel@gmail.com>, 2014. # Kaan Özdinçer <kaanozdincer@gmail.com>, 2014. # Muhammet Kara <muhammetk@gmail.com>, 2015, 2016, 2017. # Oğuz Ersen <oguz@ersen.moe>, 2021-2022. -# Sabri Ünal <libreajans@gmail.com>, 2024. +# Sabri Ünal <yakushabb@gmail.com>, 2024, 2025. # msgid "" msgstr "" "Project-Id-Version: PipeWire master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-02-25 03:43+0300\n" -"PO-Revision-Date: 2024-02-25 03:49+0300\n" -"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" +"issues\n" +"POT-Creation-Date: 2025-10-24 15:37+0000\n" +"PO-Revision-Date: 2025-10-24 20:15+0300\n" +"Last-Translator: Sabri Ünal <yakushabb@gmail.com>\n" "Language-Team: Türkçe <takim@gnome.org.tr>\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.4.2\n" +"X-Generator: Poedit 3.8\n" -#: src/daemon/pipewire.c:26 +#: src/daemon/pipewire.c:29 #, c-format msgid "" "%s options\n" " -h, --help Show this help\n" +" -v, --verbose Increase verbosity by one level\n" " --version Show version\n" " -c, --config Load config (Default %s)\n" +" -P --properties Set context properties\n" msgstr "" "%s seçenekler\n" " -h, --help Bu yardımı göster\n" +" -v, --verbose Ayrıntı düzeyini bir düzey artır\n" " --version Sürümü göster\n" " -c, --config Yapılandırmayı yükle (Öntanımlı %s)\n" +" -P --properties Bağlam özelliklerini ayarla\n" -#: src/daemon/pipewire.desktop.in:4 +#: src/daemon/pipewire.desktop.in:3 msgid "PipeWire Media System" msgstr "PipeWire Ortam Sistemi" -#: src/daemon/pipewire.desktop.in:5 +#: src/daemon/pipewire.desktop.in:4 msgid "Start the PipeWire Media System" msgstr "PipeWire Ortam Sistemini Başlat" @@ -54,26 +59,26 @@ msgid "Dummy Output" msgstr "Temsili Çıkış" -#: src/modules/module-pulse-tunnel.c:774 +#: src/modules/module-pulse-tunnel.c:760 #, c-format msgid "Tunnel for %s@%s" msgstr "%s@%s için tünel" -#: src/modules/module-zeroconf-discover.c:315 +#: src/modules/module-zeroconf-discover.c:320 msgid "Unknown device" msgstr "Bilinmeyen aygıt" -#: src/modules/module-zeroconf-discover.c:327 +#: src/modules/module-zeroconf-discover.c:332 #, c-format msgid "%s on %s@%s" msgstr "%s, %s@%s" -#: src/modules/module-zeroconf-discover.c:331 +#: src/modules/module-zeroconf-discover.c:336 #, c-format msgid "%s on %s" msgstr "%s, %s" -#: src/tools/pw-cat.c:991 +#: src/tools/pw-cat.c:1096 #, c-format msgid "" "%s options <file>|-\n" @@ -88,7 +93,7 @@ " -v, --verbose Ayrıntılı işlemleri etkinleştir\n" "\n" -#: src/tools/pw-cat.c:998 +#: src/tools/pw-cat.c:1103 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -122,7 +127,7 @@ " -P --properties Düğüm özelliklerini ayarla\n" "\n" -#: src/tools/pw-cat.c:1016 +#: src/tools/pw-cat.c:1121 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -139,6 +144,10 @@ " --volume Stream volume 0-1.0 (default %.3f)\n" " -q --quality Resampler quality (0 - 15) (default " "%d)\n" +" -a, --raw RAW mode\n" +" -M, --force-midi Force midi format, one of \"midi\" " +"or \"ump\", (default ump)\n" +" -n, --sample-count COUNT Stop after COUNT samples\n" "\n" msgstr "" " --rate Örnekleme oranı (kayıt için gerekli) " @@ -156,15 +165,21 @@ "%.3f)\n" " -q --quality Yeniden örnekleyici kalitesi (0 - " "15) (öntanımlı %d)\n" +" -a, --raw HAM kipi\n" +" -M, --force-midi Midi biçimini zorla, ikisinden " +"birisi \"midi\" ya da\"ump\", (öntanımlı ump)\n" +" -n, --sample-count COUNT COUNT örnekleme sonrası dur\n" "\n" -#: src/tools/pw-cat.c:1033 +#: src/tools/pw-cat.c:1141 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" " -m, --midi Midi mode\n" " -d, --dsd DSD mode\n" " -o, --encoded Encoded mode\n" +" -s, --sysex SysEx mode\n" +" -c, --midi-clip MIDI clip mode\n" "\n" msgstr "" " -p, --playback Çalma kipi\n" @@ -172,9 +187,11 @@ " -m, --midi Midi kipi\n" " -d, --dsd DSD kipi\n" " -o, --encoded Kodlanmış kip\n" +" -s, --sysex SysEx kipi\n" +" -c, --midi-clip MIDI klip kipi\n" "\n" -#: src/tools/pw-cli.c:2252 +#: src/tools/pw-cli.c:2386 #, c-format msgid "" "%s options command\n" @@ -193,195 +210,203 @@ " -r, --remote Uzak arka plan programı adı\n" " -m, --monitor Etkinliği izle\n" -#: spa/plugins/alsa/acp/acp.c:327 +#: spa/plugins/alsa/acp/acp.c:361 msgid "Pro Audio" msgstr "Profesyonel Ses" -#: spa/plugins/alsa/acp/acp.c:488 spa/plugins/alsa/acp/alsa-mixer.c:4633 -#: spa/plugins/bluez5/bluez5-device.c:1701 +#: spa/plugins/alsa/acp/acp.c:537 spa/plugins/alsa/acp/alsa-mixer.c:4699 +#: spa/plugins/bluez5/bluez5-device.c:1976 msgid "Off" msgstr "Kapalı" -#: spa/plugins/alsa/acp/alsa-mixer.c:2652 +#: spa/plugins/alsa/acp/acp.c:620 +#, c-format +msgid "%s ALSA UCM error" +msgstr "%s ALSA UCM hatası" + +#: spa/plugins/alsa/acp/alsa-mixer.c:2721 msgid "Input" msgstr "Giriş" -#: spa/plugins/alsa/acp/alsa-mixer.c:2653 +#: spa/plugins/alsa/acp/alsa-mixer.c:2722 msgid "Docking Station Input" msgstr "Yerleştirme İstasyonu Girişi" -#: spa/plugins/alsa/acp/alsa-mixer.c:2654 +#: spa/plugins/alsa/acp/alsa-mixer.c:2723 msgid "Docking Station Microphone" msgstr "Yerleştirme İstasyonu Mikrofonu" -#: spa/plugins/alsa/acp/alsa-mixer.c:2655 +#: spa/plugins/alsa/acp/alsa-mixer.c:2724 msgid "Docking Station Line In" msgstr "Yerleştirme İstasyonu Hat Girişi"
View file
_service:download_files:pipewire-1.5.81.tar.bz2/po/zh_CN.po -> _service:download_files:pipewire-1.5.83.tar.bz2/po/zh_CN.po
Changed
@@ -13,8 +13,8 @@ "Project-Id-Version: pipewire.master-tx\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/" "issues\n" -"POT-Creation-Date: 2025-09-21 15:33+0000\n" -"PO-Revision-Date: 2025-09-22 08:53+0800\n" +"POT-Creation-Date: 2025-11-04 15:35+0000\n" +"PO-Revision-Date: 2025-11-05 07:47+0800\n" "Last-Translator: lumingzh <lumingzh@qq.com>\n" "Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n" "Language: zh_CN\n" @@ -60,7 +60,7 @@ msgid "Dummy Output" msgstr "虚拟输出" -#: src/modules/module-pulse-tunnel.c:760 +#: src/modules/module-pulse-tunnel.c:761 #, c-format msgid "Tunnel for %s@%s" msgstr "用于 %s@%s 的隧道" @@ -79,7 +79,7 @@ msgid "%s on %s" msgstr "%2$s 上的 %1$s" -#: src/tools/pw-cat.c:1084 +#: src/tools/pw-cat.c:1096 #, c-format msgid "" "%s options <file>|-\n" @@ -94,7 +94,7 @@ " -v, --verbose 输出详细操作\n" "\n" -#: src/tools/pw-cat.c:1091 +#: src/tools/pw-cat.c:1103 #, c-format msgid "" " -R, --remote Remote daemon name\n" @@ -126,7 +126,7 @@ " -P --properties 设置节点属性\n" "\n" -#: src/tools/pw-cat.c:1109 +#: src/tools/pw-cat.c:1121 #, c-format msgid "" " --rate Sample rate (req. for rec) (default " @@ -166,7 +166,7 @@ " -n, --sample-count COUNT 计数采样后停止\n" "\n" -#: src/tools/pw-cat.c:1129 +#: src/tools/pw-cat.c:1141 msgid "" " -p, --playback Playback mode\n" " -r, --record Recording mode\n" @@ -204,203 +204,203 @@ " -m, --monitor 监视器活动\n" "\n" -#: spa/plugins/alsa/acp/acp.c:351 +#: spa/plugins/alsa/acp/acp.c:361 msgid "Pro Audio" msgstr "专业音频" -#: spa/plugins/alsa/acp/acp.c:527 spa/plugins/alsa/acp/alsa-mixer.c:4635 -#: spa/plugins/bluez5/bluez5-device.c:1974 +#: spa/plugins/alsa/acp/acp.c:537 spa/plugins/alsa/acp/alsa-mixer.c:4699 +#: spa/plugins/bluez5/bluez5-device.c:1976 msgid "Off" msgstr "关" -#: spa/plugins/alsa/acp/acp.c:610 +#: spa/plugins/alsa/acp/acp.c:620 #, c-format msgid "%s ALSA UCM error" msgstr "%s ALSA UCM 错误" -#: spa/plugins/alsa/acp/alsa-mixer.c:2652 +#: spa/plugins/alsa/acp/alsa-mixer.c:2721 msgid "Input" msgstr "输入" -#: spa/plugins/alsa/acp/alsa-mixer.c:2653 +#: spa/plugins/alsa/acp/alsa-mixer.c:2722 msgid "Docking Station Input" msgstr "扩展坞输入" -#: spa/plugins/alsa/acp/alsa-mixer.c:2654 +#: spa/plugins/alsa/acp/alsa-mixer.c:2723 msgid "Docking Station Microphone" msgstr "扩展坞话筒" -#: spa/plugins/alsa/acp/alsa-mixer.c:2655 +#: spa/plugins/alsa/acp/alsa-mixer.c:2724 msgid "Docking Station Line In" msgstr "扩展坞线输入" -#: spa/plugins/alsa/acp/alsa-mixer.c:2656 -#: spa/plugins/alsa/acp/alsa-mixer.c:2747 +#: spa/plugins/alsa/acp/alsa-mixer.c:2725 +#: spa/plugins/alsa/acp/alsa-mixer.c:2816 msgid "Line In" msgstr "输入插孔" -#: spa/plugins/alsa/acp/alsa-mixer.c:2657 -#: spa/plugins/alsa/acp/alsa-mixer.c:2741 -#: spa/plugins/bluez5/bluez5-device.c:2372 +#: spa/plugins/alsa/acp/alsa-mixer.c:2726 +#: spa/plugins/alsa/acp/alsa-mixer.c:2810 +#: spa/plugins/bluez5/bluez5-device.c:2374 msgid "Microphone" msgstr "话筒" -#: spa/plugins/alsa/acp/alsa-mixer.c:2658 -#: spa/plugins/alsa/acp/alsa-mixer.c:2742 +#: spa/plugins/alsa/acp/alsa-mixer.c:2727 +#: spa/plugins/alsa/acp/alsa-mixer.c:2811 msgid "Front Microphone" msgstr "前麦克风" -#: spa/plugins/alsa/acp/alsa-mixer.c:2659 -#: spa/plugins/alsa/acp/alsa-mixer.c:2743 +#: spa/plugins/alsa/acp/alsa-mixer.c:2728 +#: spa/plugins/alsa/acp/alsa-mixer.c:2812 msgid "Rear Microphone" msgstr "后麦克风" -#: spa/plugins/alsa/acp/alsa-mixer.c:2660 +#: spa/plugins/alsa/acp/alsa-mixer.c:2729 msgid "External Microphone" msgstr "外部话筒" -#: spa/plugins/alsa/acp/alsa-mixer.c:2661 -#: spa/plugins/alsa/acp/alsa-mixer.c:2745 +#: spa/plugins/alsa/acp/alsa-mixer.c:2730 +#: spa/plugins/alsa/acp/alsa-mixer.c:2814 msgid "Internal Microphone" msgstr "内部话筒" -#: spa/plugins/alsa/acp/alsa-mixer.c:2662 -#: spa/plugins/alsa/acp/alsa-mixer.c:2748 +#: spa/plugins/alsa/acp/alsa-mixer.c:2731 +#: spa/plugins/alsa/acp/alsa-mixer.c:2817 msgid "Radio" msgstr "无线电" -#: spa/plugins/alsa/acp/alsa-mixer.c:2663 -#: spa/plugins/alsa/acp/alsa-mixer.c:2749 +#: spa/plugins/alsa/acp/alsa-mixer.c:2732 +#: spa/plugins/alsa/acp/alsa-mixer.c:2818 msgid "Video" msgstr "视频" -#: spa/plugins/alsa/acp/alsa-mixer.c:2664 +#: spa/plugins/alsa/acp/alsa-mixer.c:2733 msgid "Automatic Gain Control" msgstr "自动增益控制" -#: spa/plugins/alsa/acp/alsa-mixer.c:2665 +#: spa/plugins/alsa/acp/alsa-mixer.c:2734 msgid "No Automatic Gain Control" msgstr "无自动增益控制" -#: spa/plugins/alsa/acp/alsa-mixer.c:2666 +#: spa/plugins/alsa/acp/alsa-mixer.c:2735 msgid "Boost" msgstr "增强" -#: spa/plugins/alsa/acp/alsa-mixer.c:2667 +#: spa/plugins/alsa/acp/alsa-mixer.c:2736 msgid "No Boost" msgstr "无增强" -#: spa/plugins/alsa/acp/alsa-mixer.c:2668 +#: spa/plugins/alsa/acp/alsa-mixer.c:2737 msgid "Amplifier" msgstr "功放" -#: spa/plugins/alsa/acp/alsa-mixer.c:2669 +#: spa/plugins/alsa/acp/alsa-mixer.c:2738 msgid "No Amplifier" msgstr "无功放" -#: spa/plugins/alsa/acp/alsa-mixer.c:2670 +#: spa/plugins/alsa/acp/alsa-mixer.c:2739 msgid "Bass Boost" msgstr "重低音增强" -#: spa/plugins/alsa/acp/alsa-mixer.c:2671 +#: spa/plugins/alsa/acp/alsa-mixer.c:2740 msgid "No Bass Boost" msgstr "无重低音增强" -#: spa/plugins/alsa/acp/alsa-mixer.c:2672 -#: spa/plugins/bluez5/bluez5-device.c:2378 +#: spa/plugins/alsa/acp/alsa-mixer.c:2741 +#: spa/plugins/bluez5/bluez5-device.c:2380 msgid "Speaker" msgstr "扬声器"
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/examples/adapter-control.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/examples/adapter-control.c
Changed
@@ -578,7 +578,7 @@ SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT), SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp), SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param)); - if ((res = spa_node_set_param(data->source_node, SPA_PARAM_PortConfig, 0, param) < 0)) { + if ((res = spa_node_set_param(data->source_node, SPA_PARAM_PortConfig, 0, param)) < 0) { printf("can't setup source node %d\n", res); return res; } @@ -647,7 +647,7 @@ SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param)); - if ((res = spa_node_set_param(data->sink_node, SPA_PARAM_PortConfig, 0, param) < 0)) { + if ((res = spa_node_set_param(data->sink_node, SPA_PARAM_PortConfig, 0, param)) < 0) { printf("can't setup sink node %d\n", res); return res; } @@ -987,7 +987,7 @@ setlocale(LC_ALL, ""); - while ((c = getopt_long(argc, argv, "hdmstiac:", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "hd:m:s:t:i:a:c:", long_options, NULL)) != -1) { switch (c) { case 'h': show_help(&data, argv0, false);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/debug/format.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/debug/format.h
Changed
@@ -164,8 +164,7 @@ type = val->type; size = val->size; - if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1 || - size < spa_pod_type_size(type)) + if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1) continue; vals = SPA_POD_BODY(val);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/dsd-utils.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/dsd-utils.h
Changed
@@ -42,7 +42,7 @@ SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); if (position == NULL || - !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS)) + !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_N_ELEMENTS(info->position))) SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); return res;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/format-utils.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/format-utils.h
Changed
@@ -46,20 +46,61 @@ #endif #endif +SPA_API_AUDIO_FORMAT_UTILS bool +spa_format_audio_ext_valid_size(uint32_t media_subtype, size_t size) +{ + switch (media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + return size >= offsetof(struct spa_audio_info, info.raw) && + SPA_AUDIO_INFO_RAW_VALID_SIZE(size - offsetof(struct spa_audio_info, info.raw)); + +#define _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(format) \ + case SPA_MEDIA_SUBTYPE_ ## format: \ + return size >= offsetof(struct spa_audio_info, info.format) + sizeof(struct spa_audio_info_ ## format); + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dsp) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(iec958) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dsd) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(mp3) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(aac) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(vorbis) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(wma) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ra) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(amr) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(alac) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(flac) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ape) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(ac3) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(eac3) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(truehd) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(dts) + _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE(mpegh) +#undef _SPA_FORMAT_AUDIO_EXT_VALID_SIZE_CASE + } + return false; +} + SPA_API_AUDIO_FORMAT_UTILS int -spa_format_audio_parse(const struct spa_pod *format, struct spa_audio_info *info) +spa_format_audio_ext_parse(const struct spa_pod *format, struct spa_audio_info *info, size_t size) { int res; + uint32_t media_type, media_subtype; - if ((res = spa_format_parse(format, &info->media_type, &info->media_subtype)) < 0) + if ((res = spa_format_parse(format, &media_type, &media_subtype)) < 0) return res; - if (info->media_type != SPA_MEDIA_TYPE_audio) + if (media_type != SPA_MEDIA_TYPE_audio) return -EINVAL; - switch (info->media_subtype) { + if (!spa_format_audio_ext_valid_size(media_subtype, size)) + return -EINVAL; + + info->media_type = media_type; + info->media_subtype = media_subtype; + + switch (media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - return spa_format_audio_raw_parse(format, &info->info.raw); + return spa_format_audio_raw_ext_parse(format, &info->info.raw, + size - offsetof(struct spa_audio_info, info.raw)); case SPA_MEDIA_SUBTYPE_dsp: return spa_format_audio_dsp_parse(format, &info->info.dsp); case SPA_MEDIA_SUBTYPE_iec958: @@ -98,13 +139,25 @@ return -ENOTSUP; } +SPA_API_AUDIO_FORMAT_UTILS int +spa_format_audio_parse(const struct spa_pod *format, struct spa_audio_info *info) +{ + return spa_format_audio_ext_parse(format, info, sizeof(*info)); +} + SPA_API_AUDIO_FORMAT_UTILS struct spa_pod * -spa_format_audio_build(struct spa_pod_builder *builder, uint32_t id, - const struct spa_audio_info *info) +spa_format_audio_ext_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info *info, size_t size) { + if (!spa_format_audio_ext_valid_size(info->media_subtype, size)) { + errno = EINVAL; + return NULL; + } + switch (info->media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - return spa_format_audio_raw_build(builder, id, &info->info.raw); + return spa_format_audio_raw_ext_build(builder, id, &info->info.raw, + size - offsetof(struct spa_audio_info, info.raw)); case SPA_MEDIA_SUBTYPE_dsp: return spa_format_audio_dsp_build(builder, id, &info->info.dsp); case SPA_MEDIA_SUBTYPE_iec958: @@ -143,6 +196,13 @@ errno = ENOTSUP; return NULL; } + +SPA_API_AUDIO_FORMAT_UTILS struct spa_pod * +spa_format_audio_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info *info) +{ + return spa_format_audio_ext_build(builder, id, info, sizeof(*info)); +} /** * \} */
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/format.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/format.h
Changed
@@ -59,6 +59,8 @@ struct spa_audio_info_dts dts; struct spa_audio_info_mpegh mpegh; } info; + + /* padding follows here when info has flexible size */ }; /**
View file
_service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/layout-types.h
Added
@@ -0,0 +1,118 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Wim Taymans */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_LAYOUT_TYPES_H +#define SPA_AUDIO_LAYOUT_TYPES_H + +#include <spa/utils/type.h> +#include <spa/utils/string.h> +#include <spa/param/audio/layout.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#ifndef SPA_API_AUDIO_LAYOUT_TYPES + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_LAYOUT_TYPES SPA_API_IMPL + #else + #define SPA_API_AUDIO_LAYOUT_TYPES static inline + #endif +#endif + +static const struct spa_type_audio_layout_info { + const char *name; + struct spa_audio_layout_info layout; +} spa_type_audio_layout_info = { + { "Mono", { SPA_AUDIO_LAYOUT_Mono } }, + { "Stereo", { SPA_AUDIO_LAYOUT_Stereo } }, + { "Quad", { SPA_AUDIO_LAYOUT_Quad } }, + { "Pentagonal", { SPA_AUDIO_LAYOUT_Pentagonal } }, + { "Hexagonal", { SPA_AUDIO_LAYOUT_Hexagonal } }, + { "Octagonal", { SPA_AUDIO_LAYOUT_Octagonal } }, + { "Cube", { SPA_AUDIO_LAYOUT_Cube } }, + { "MPEG-1.0", { SPA_AUDIO_LAYOUT_MPEG_1_0 } }, + { "MPEG-2.0", { SPA_AUDIO_LAYOUT_MPEG_2_0 } }, + { "MPEG-3.0A", { SPA_AUDIO_LAYOUT_MPEG_3_0A } }, + { "MPEG-3.0B", { SPA_AUDIO_LAYOUT_MPEG_3_0B } }, + { "MPEG-4.0A", { SPA_AUDIO_LAYOUT_MPEG_4_0A } }, + { "MPEG-4.0B", { SPA_AUDIO_LAYOUT_MPEG_4_0B } }, + { "MPEG-5.0A", { SPA_AUDIO_LAYOUT_MPEG_5_0A } }, + { "MPEG-5.0B", { SPA_AUDIO_LAYOUT_MPEG_5_0B } }, + { "MPEG-5.0C", { SPA_AUDIO_LAYOUT_MPEG_5_0C } }, + { "MPEG-5.0D", { SPA_AUDIO_LAYOUT_MPEG_5_0D } }, + { "MPEG-5.1A", { SPA_AUDIO_LAYOUT_MPEG_5_1A } }, + { "MPEG-5.1B", { SPA_AUDIO_LAYOUT_MPEG_5_1B } }, + { "MPEG-5.1C", { SPA_AUDIO_LAYOUT_MPEG_5_1C } }, + { "MPEG-5.1D", { SPA_AUDIO_LAYOUT_MPEG_5_1D } }, + { "MPEG-6.1A", { SPA_AUDIO_LAYOUT_MPEG_6_1A } }, + { "MPEG-7.1A", { SPA_AUDIO_LAYOUT_MPEG_7_1A } }, + { "MPEG-7.1B", { SPA_AUDIO_LAYOUT_MPEG_7_1B } }, + { "MPEG-7.1C", { SPA_AUDIO_LAYOUT_MPEG_7_1C } }, + { "2.1", { SPA_AUDIO_LAYOUT_2_1 } }, + { "2RC", { SPA_AUDIO_LAYOUT_2RC } }, + { "2FC", { SPA_AUDIO_LAYOUT_2FC } }, + { "3.1", { SPA_AUDIO_LAYOUT_3_1 } }, + { "4.0", { SPA_AUDIO_LAYOUT_4_0 } }, + { "2.2", { SPA_AUDIO_LAYOUT_2_2 } }, + { "4.1", { SPA_AUDIO_LAYOUT_4_1 } }, + { "5.0", { SPA_AUDIO_LAYOUT_5_0 } }, + { "5.0R", { SPA_AUDIO_LAYOUT_5_0R } }, + { "5.1", { SPA_AUDIO_LAYOUT_5_1 } }, + { "5.1R", { SPA_AUDIO_LAYOUT_5_1R } }, + { "6.0", { SPA_AUDIO_LAYOUT_6_0 } }, + { "6.0F", { SPA_AUDIO_LAYOUT_6_0F } }, + { "6.1", { SPA_AUDIO_LAYOUT_6_1 } }, + { "6.1F", { SPA_AUDIO_LAYOUT_6_1F } }, + { "7.0", { SPA_AUDIO_LAYOUT_7_0 } }, + { "7.0F", { SPA_AUDIO_LAYOUT_7_0F } }, + { "7.1", { SPA_AUDIO_LAYOUT_7_1 } }, + { "7.1W", { SPA_AUDIO_LAYOUT_7_1W } }, + { "7.1WR", { SPA_AUDIO_LAYOUT_7_1WR } }, + { NULL, }, +}; + +SPA_API_AUDIO_LAYOUT_TYPES int +spa_audio_layout_info_parse_name(struct spa_audio_layout_info *layout, size_t size, + const char *name) +{ + uint32_t max_position = SPA_AUDIO_LAYOUT_INFO_MAX_POSITION(size); + if (spa_strstartswith(name, "AUX")) { + uint32_t i, n_pos; + if (spa_atou32(name+3, &n_pos, 10)) { + if (n_pos > max_position) + return -ECHRNG; + for (i = 0; i < 0x1000 && i < n_pos; i++) + layout->positioni = SPA_AUDIO_CHANNEL_AUX0 + i; + for (; i < n_pos; i++) + layout->positioni = SPA_AUDIO_CHANNEL_UNKNOWN; + layout->n_channels = n_pos; + return n_pos; + } + } + SPA_FOR_EACH_ELEMENT_VAR(spa_type_audio_layout_info, i) { + if (spa_streq(name, i->name)) { + if (i->layout.n_channels > max_position) + return -ECHRNG; + *layout = i->layout; + return i->layout.n_channels; + } + } + return -ENOTSUP; +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_LAYOUT_TYPES_H */
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/layout.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/layout.h
Changed
@@ -21,8 +21,11 @@ struct spa_audio_layout_info { uint32_t n_channels; uint32_t positionSPA_AUDIO_MAX_CHANNELS; + /* padding may follow to allow more channels */ }; +#define SPA_AUDIO_LAYOUT_INFO_MAX_POSITION(size) (((size)-offsetof(struct spa_audio_layout_info,position))/sizeof(uint32_t)) + #define SPA_AUDIO_LAYOUT_Mono 1, { SPA_AUDIO_CHANNEL_MONO, } #define SPA_AUDIO_LAYOUT_Stereo 2, { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, } #define SPA_AUDIO_LAYOUT_Quad 4, { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, \ @@ -37,7 +40,7 @@ SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, \ SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_RC, \ SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR, } -#define SPA_AUDIO_LAYOUT_Cube 8, { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR }, \ +#define SPA_AUDIO_LAYOUT_Cube 8, { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, \ SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, \ SPA_AUDIO_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFR, \ SPA_AUDIO_CHANNEL_TRL, SPA_AUDIO_CHANNEL_TRR, }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/raw-json.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/raw-json.h
Changed
@@ -9,6 +9,7 @@ #include <spa/utils/json.h> #include <spa/param/audio/raw.h> #include <spa/param/audio/raw-types.h> +#include <spa/param/audio/layout-types.h> #ifdef __cplusplus extern "C" { @@ -28,8 +29,8 @@ #endif SPA_API_AUDIO_RAW_JSON int -spa_audio_parse_position(const char *str, size_t len, - uint32_t *position, uint32_t *n_channels) +spa_audio_parse_position_n(const char *str, size_t len, + uint32_t *position, uint32_t max_position, uint32_t *n_channels) { struct spa_json iter; char v256; @@ -38,18 +39,46 @@ if (spa_json_begin_array_relax(&iter, str, len) <= 0) return 0; - while (spa_json_get_string(&iter, v, sizeof(v)) > 0 && - channels < SPA_AUDIO_MAX_CHANNELS) { - positionchannels++ = spa_type_audio_channel_from_short_name(v); + while (spa_json_get_string(&iter, v, sizeof(v)) > 0) { + if (channels < max_position) + positionchannels = spa_type_audio_channel_from_short_name(v); + channels++; } *n_channels = channels; return channels; } SPA_API_AUDIO_RAW_JSON int -spa_audio_info_raw_update(struct spa_audio_info_raw *info, const char *key, const char *val, bool force) +spa_audio_parse_position(const char *str, size_t len, + uint32_t *position, uint32_t *n_channels) +{ + return spa_audio_parse_position_n(str, len, position, SPA_AUDIO_MAX_CHANNELS, n_channels); +} + +SPA_API_AUDIO_RAW_JSON int +spa_audio_parse_layout(const char *str, uint32_t *position, uint32_t max_position, + uint32_t *n_channels) +{ + struct spa_audio_layout_info l; + uint32_t i; + if (spa_audio_layout_info_parse_name(&l, sizeof(l), str) <= 0) + return 0; + for (i = 0; i < l.n_channels && i < max_position; i++) + positioni = l.positioni; + *n_channels = l.n_channels; + return l.n_channels; +} + +SPA_API_AUDIO_RAW_JSON int +spa_audio_info_raw_ext_update(struct spa_audio_info_raw *info, size_t size, + const char *key, const char *val, bool force) { uint32_t v; + uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size); + + if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size)) + return -EINVAL; + if (spa_streq(key, SPA_KEY_AUDIO_FORMAT)) { if (force || info->format == 0) info->format = (enum spa_audio_format)spa_type_audio_format_from_short_name(val); @@ -57,43 +86,99 @@ if (spa_atou32(val, &v, 0) && (force || info->rate == 0)) info->rate = v; } else if (spa_streq(key, SPA_KEY_AUDIO_CHANNELS)) { - if (spa_atou32(val, &v, 0) && (force || info->channels == 0)) - info->channels = SPA_MIN(v, SPA_AUDIO_MAX_CHANNELS); + if (spa_atou32(val, &v, 0) && (force || info->channels == 0)) { + if (v > max_position) + return -ECHRNG; + info->channels = v; + } + } else if (spa_streq(key, SPA_KEY_AUDIO_LAYOUT)) { + if (force || info->channels == 0) { + if (spa_audio_parse_layout(val, info->position, max_position, &v) > 0) { + if (v > max_position) + return -ECHRNG; + info->channels = v; + SPA_FLAG_CLEAR(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); + } + } } else if (spa_streq(key, SPA_KEY_AUDIO_POSITION)) { if (force || info->channels == 0) { - if (spa_audio_parse_position(val, strlen(val), info->position, &info->channels) > 0) + if (spa_audio_parse_position_n(val, strlen(val), info->position, + max_position, &v) > 0) { + if (v > max_position) + return -ECHRNG; + info->channels = v; SPA_FLAG_CLEAR(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); + } } } return 0; } -SPA_API_AUDIO_RAW_JSON int SPA_SENTINEL -spa_audio_info_raw_init_dict_keys(struct spa_audio_info_raw *info, +SPA_API_AUDIO_RAW_JSON int +spa_audio_info_raw_update(struct spa_audio_info_raw *info, + const char *key, const char *val, bool force) +{ + return spa_audio_info_raw_ext_update(info, sizeof(*info), key, val, force); +} + +SPA_API_AUDIO_RAW_JSON int +spa_audio_info_raw_ext_init_dict_keys_va(struct spa_audio_info_raw *info, size_t size, const struct spa_dict *defaults, - const struct spa_dict *dict, ...) + const struct spa_dict *dict, va_list args) { - spa_zero(*info); + int res; + + if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size)) + return -EINVAL; + + memset(info, 0, size); SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); if (dict) { const char *val, *key; - va_list args; - va_start(args, dict); while ((key = va_arg(args, const char *))) { if ((val = spa_dict_lookup(dict, key)) == NULL) continue; - spa_audio_info_raw_update(info, key, val, true); + if ((res = spa_audio_info_raw_ext_update(info, size, + key, val, true)) < 0) + return res; } - va_end(args); } if (defaults) { const struct spa_dict_item *it; spa_dict_for_each(it, defaults) - spa_audio_info_raw_update(info, it->key, it->value, false); + if ((res = spa_audio_info_raw_ext_update(info, size, + it->key, it->value, false)) < 0) + return res; } return 0; } +SPA_API_AUDIO_RAW_JSON int SPA_SENTINEL +spa_audio_info_raw_ext_init_dict_keys(struct spa_audio_info_raw *info, size_t size, + const struct spa_dict *defaults, + const struct spa_dict *dict, ...) +{ + va_list args; + int res; + va_start(args, dict); + res = spa_audio_info_raw_ext_init_dict_keys_va(info, size, defaults, dict, args); + va_end(args); + return res; +} + +SPA_API_AUDIO_RAW_JSON int SPA_SENTINEL +spa_audio_info_raw_init_dict_keys(struct spa_audio_info_raw *info, + const struct spa_dict *defaults, + const struct spa_dict *dict, ...) +{ + va_list args; + int res; + va_start(args, dict); + res = spa_audio_info_raw_ext_init_dict_keys_va(info, sizeof(*info), defaults, dict, args); + va_end(args); + return res; +} + /** * \} */
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/raw-types.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/raw-types.h
Changed
@@ -267,12 +267,34 @@ SPA_API_AUDIO_RAW_TYPES uint32_t spa_type_audio_channel_from_short_name(const char *name) { - return spa_type_from_short_name(name, spa_type_audio_channel, SPA_AUDIO_CHANNEL_UNKNOWN); + uint32_t res; + if (spa_strstartswith(name, "AUX")) { + if (spa_atou32(name+3, &res, 10) && res < 0x1000) + res = SPA_AUDIO_CHANNEL_AUX0 + res; + else + res = SPA_AUDIO_CHANNEL_UNKNOWN; + } else { + res = spa_type_from_short_name(name, spa_type_audio_channel, SPA_AUDIO_CHANNEL_UNKNOWN); + } + return res; } SPA_API_AUDIO_RAW_TYPES const char * spa_type_audio_channel_to_short_name(uint32_t type) { return spa_type_to_short_name(type, spa_type_audio_channel, "UNK"); } +SPA_API_AUDIO_RAW_TYPES const char * spa_type_audio_channel_make_short_name(uint32_t type, + char *buf, size_t size, const char *unknown) +{ + if (SPA_AUDIO_CHANNEL_IS_AUX(type)) { + snprintf(buf, size, "AUX%u", type - SPA_AUDIO_CHANNEL_AUX0); + } else { + const char *str = spa_type_to_short_name(type, spa_type_audio_channel, NULL); + if (str == NULL) + return unknown; + snprintf(buf, size, "%.7s", str); + } + return buf; +} #define SPA_TYPE_INFO_AudioVolumeRampScale SPA_TYPE_INFO_ENUM_BASE "AudioVolumeRampScale" #define SPA_TYPE_INFO_AUDIO_VOLUME_RAMP_SCALE_BASE SPA_TYPE_INFO_AudioVolumeRampScale ":" @@ -292,4 +314,4 @@ } /* extern "C" */ #endif -#endif /* SPA_AUDIO_RAW_RAW_TYPES_H */ +#endif /* SPA_AUDIO_RAW_TYPES_H */
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/raw-utils.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/raw-utils.h
Changed
@@ -29,10 +29,15 @@ #endif SPA_API_AUDIO_RAW_UTILS int -spa_format_audio_raw_parse(const struct spa_pod *format, struct spa_audio_info_raw *info) +spa_format_audio_raw_ext_parse(const struct spa_pod *format, struct spa_audio_info_raw *info, size_t size) { struct spa_pod *position = NULL; int res; + uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size); + + if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size)) + return -EINVAL; + info->flags = 0; res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, @@ -40,18 +45,33 @@ SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); + if (info->channels > max_position) + return -ECHRNG; if (position == NULL || - !spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS)) + spa_pod_copy_array(position, SPA_TYPE_Id, info->position, max_position) != info->channels) SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED); return res; } +SPA_API_AUDIO_RAW_UTILS int +spa_format_audio_raw_parse(const struct spa_pod *format, struct spa_audio_info_raw *info) +{ + return spa_format_audio_raw_ext_parse(format, info, sizeof(*info)); +} + SPA_API_AUDIO_RAW_UTILS struct spa_pod * -spa_format_audio_raw_build(struct spa_pod_builder *builder, uint32_t id, - const struct spa_audio_info_raw *info) +spa_format_audio_raw_ext_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_raw *info, size_t size) { struct spa_pod_frame f; + uint32_t max_position = SPA_AUDIO_INFO_RAW_MAX_POSITION(size); + + if (!SPA_AUDIO_INFO_RAW_VALID_SIZE(size)) { + errno = EINVAL; + return NULL; + } + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); spa_pod_builder_add(builder, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), @@ -66,7 +86,10 @@ if (info->channels != 0) { spa_pod_builder_add(builder, SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); - if (!SPA_FLAG_IS_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED)) { + /* we drop the positions here when we can't read all of them. This is + * really a malformed spa_audio_info structure. */ + if (!SPA_FLAG_IS_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED) && + info->channels <= max_position) { spa_pod_builder_add(builder, SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, info->channels, info->position), 0); @@ -75,6 +98,13 @@ return (struct spa_pod*)spa_pod_builder_pop(builder, &f); } +SPA_API_AUDIO_RAW_UTILS struct spa_pod * +spa_format_audio_raw_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_raw *info) +{ + return spa_format_audio_raw_ext_build(builder, id, info, sizeof(*info)); +} + /** * \} */
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/raw.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/raw.h
Changed
@@ -18,7 +18,11 @@ * \{ */ -#define SPA_AUDIO_MAX_CHANNELS 128u +/* This is the max number of channels, changing this will change the + * size of some helper structures. This value should be at least 64 */ +#ifndef SPA_AUDIO_MAX_CHANNELS +#define SPA_AUDIO_MAX_CHANNELS 64u +#endif enum spa_audio_format { SPA_AUDIO_FORMAT_UNKNOWN, @@ -259,6 +263,8 @@ SPA_AUDIO_CHANNEL_START_Custom = 0x10000, }; +#define SPA_AUDIO_CHANNEL_IS_AUX(ch) ((ch)>=SPA_AUDIO_CHANNEL_START_Aux && (ch)<=SPA_AUDIO_CHANNEL_LAST_Aux) + enum spa_audio_volume_ramp_scale { SPA_AUDIO_VOLUME_RAMP_INVALID, SPA_AUDIO_VOLUME_RAMP_LINEAR, @@ -269,23 +275,34 @@ #define SPA_AUDIO_FLAG_NONE (0) /*< no valid flag */ #define SPA_AUDIO_FLAG_UNPOSITIONED (1 << 0) /*< the position array explicitly * contains unpositioned channels. */ -/** Audio information description */ +/** Audio information description. You can assume when you receive this structure + * that there is enought padding to accomodate all channel positions in case the + * channel count is more than SPA_AUDIO_MAX_CHANNELS. */ struct spa_audio_info_raw { enum spa_audio_format format; /*< format, one of enum spa_audio_format */ uint32_t flags; /*< extra flags */ uint32_t rate; /*< sample rate */ - uint32_t channels; /*< number of channels */ + uint32_t channels; /*< number of channels. This can be more than SPA_AUDIO_MAX_CHANNELS + * and you may assume there is enough padding for the extra + * channel positions. */ uint32_t positionSPA_AUDIO_MAX_CHANNELS; /*< channel position from enum spa_audio_channel */ + /* padding follows here when channels > SPA_AUDIO_MAX_CHANNELS */ }; #define SPA_AUDIO_INFO_RAW_INIT(...) ((struct spa_audio_info_raw) { __VA_ARGS__ }) +#define SPA_AUDIO_INFO_RAW_MAX_POSITION(size) (((size)-offsetof(struct spa_audio_info_raw,position))/sizeof(uint32_t)) + +#define SPA_AUDIO_INFO_RAW_VALID_SIZE(size) ((size) >= offsetof(struct spa_audio_info_raw, position)) + + #define SPA_KEY_AUDIO_FORMAT "audio.format" /**< an audio format as string, * Ex. "S16LE" */ #define SPA_KEY_AUDIO_CHANNEL "audio.channel" /**< an audio channel as string, * Ex. "FL" */ #define SPA_KEY_AUDIO_CHANNELS "audio.channels" /**< an audio channel count as int */ #define SPA_KEY_AUDIO_RATE "audio.rate" /**< an audio sample rate as int */ +#define SPA_KEY_AUDIO_LAYOUT "audio.layout" /**< channel positions as predefined layout */ #define SPA_KEY_AUDIO_POSITION "audio.position" /**< channel positions as comma separated list * of channels ex. "FL,FR" */ #define SPA_KEY_AUDIO_ALLOWED_RATES "audio.allowed-rates" /**< a list of allowed samplerates
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/audio/type-info.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/audio/type-info.h
Changed
@@ -6,6 +6,7 @@ #define SPA_AUDIO_TYPES_H #include <spa/param/audio/raw-types.h> +#include <spa/param/audio/layout-types.h> #include <spa/param/audio/iec958-types.h> #include <spa/param/audio/mp3-types.h> #include <spa/param/audio/aac-types.h>
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/props-types.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/props-types.h
Changed
@@ -40,6 +40,9 @@ { SPA_PROP_quality, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "quality", NULL }, { SPA_PROP_bluetoothAudioCodec, SPA_TYPE_Id, SPA_TYPE_INFO_PROPS_BASE "bluetoothAudioCodec", spa_type_bluetooth_audio_codec }, { SPA_PROP_bluetoothOffloadActive, SPA_TYPE_Bool, SPA_TYPE_INFO_PROPS_BASE "bluetoothOffloadActive", NULL }, + { SPA_PROP_clockId, SPA_TYPE_String, SPA_TYPE_INFO_PROPS_BASE "clockId", NULL }, + { SPA_PROP_clockDevice, SPA_TYPE_String, SPA_TYPE_INFO_PROPS_BASE "clockDevice", NULL }, + { SPA_PROP_clockInterface, SPA_TYPE_String, SPA_TYPE_INFO_PROPS_BASE "clockInterface", NULL }, { SPA_PROP_waveType, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "waveType", NULL }, { SPA_PROP_frequency, SPA_TYPE_Int, SPA_TYPE_INFO_PROPS_BASE "frequency", NULL },
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/param/props.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/param/props.h
Changed
@@ -55,6 +55,9 @@ SPA_PROP_quality, SPA_PROP_bluetoothAudioCodec, SPA_PROP_bluetoothOffloadActive, + SPA_PROP_clockId, + SPA_PROP_clockDevice, + SPA_PROP_clockInterface, SPA_PROP_START_Audio = 0x10000, /**< audio related properties */ SPA_PROP_waveType,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/pod/body.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/pod/body.h
Changed
@@ -78,6 +78,36 @@ return 0; } +SPA_API_POD_BODY int spa_pod_choice_n_values(uint32_t choice_type, uint32_t *min, uint32_t *max) +{ + switch (choice_type) { + case SPA_CHOICE_Enum: + *min = 2; + *max = UINT32_MAX; + break; + case SPA_CHOICE_Range: + *min = *max = 3; + break; + case SPA_CHOICE_Step: + *min = *max = 4; + break; + case SPA_CHOICE_None: + case SPA_CHOICE_Flags: + *min = *max = 1; + break; + default: + /* + * This must always return at least 1, because callers + * assume that n_vals >= spa_pod_choice_n_values() + * mean that n_vals is at least 1. + */ + *min = 1; + *max = UINT32_MAX; + return 0; + } + return 1; +} + SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size, struct spa_pod *pod, const void **body) { @@ -243,9 +273,9 @@ SPA_API_POD_BODY int spa_pod_body_get_pointer(const struct spa_pod *pod, const void *body, uint32_t *type, const void **value) { + struct spa_pod_pointer_body b; if (!spa_pod_is_pointer(pod)) return -EINVAL; - struct spa_pod_pointer_body b; SPA_POD_BODY_LOAD_FIELD_ONCE(&b, body, type); SPA_POD_BODY_LOAD_FIELD_ONCE(&b, body, value); *type = b.type; @@ -333,6 +363,8 @@ *n_values = child_size ? (arr->pod.size - sizeof(arr->body)) / child_size : 0; *val_size = child_size; *val_type = arr->body.child.type; + if (*val_size < spa_pod_type_size(*val_type)) + *n_values = 0; return body; } @@ -366,13 +398,16 @@ const void *body, uint32_t *n_values, uint32_t *choice, uint32_t *val_size, uint32_t *val_type) { - uint32_t child_size = pod->body.child.size; + uint32_t child_size = pod->body.child.size, min, max; *val_size = child_size; *val_type = pod->body.child.type; *n_values = child_size ? (pod->pod.size - sizeof(pod->body)) / child_size : 0; *choice = pod->body.type; - if (*choice == SPA_CHOICE_None) - *n_values = SPA_MIN(1u, *n_values); + spa_pod_choice_n_values(*choice, &min, &max); + if (*n_values < min || *val_size < spa_pod_type_size(*val_type)) + *n_values = 0; + else if (*n_values > max) + *n_values = max; return body; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/pod/filter.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/pod/filter.h
Changed
@@ -82,7 +82,7 @@ v1 = spa_pod_get_values(&p1->value, &nalt1, &p1c); v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c); - /* empty choices */ + /* empty/invalid choices */ if (nalt1 < 1 || nalt2 < 1) return -EINVAL; @@ -95,8 +95,6 @@ /* incompatible property types */ if (type != v2->type || size != v2->size || p1->key != p2->key) return -EINVAL; - if (size < spa_pod_type_size(type)) - return -EINVAL; /* start with copying the property */ spa_pod_builder_prop(b, p1->key, p1->flags & p2->flags); @@ -406,7 +404,7 @@ struct spa_pod *v = spa_pod_get_values(&res->value, &nvals, &choice); const void *vals = SPA_POD_BODY(v); - if (v->size < spa_pod_type_size(v->type)) + if (nvals < 1) continue; if (spa_pod_compare_is_valid_choice(v->type, v->size,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/pod/iter.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/pod/iter.h
Changed
@@ -228,7 +228,7 @@ spa_pod_choice_body_get_values(p, SPA_POD_BODY_CONST(p), n_vals, choice, &size, &type); return (struct spa_pod*)&p->body.child; } else { - *n_vals = 1; + *n_vals = pod->size < spa_pod_type_size(pod->type) ? 0 : 1; *choice = SPA_CHOICE_None; return (struct spa_pod*)pod; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/pod/parser.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/pod/parser.h
Changed
@@ -90,13 +90,14 @@ /* Cast to uint64_t to avoid wraparound. */ const uint64_t long_offset = (uint64_t)offset + header_size; if (long_offset <= size && (offset & 7) == 0) { + struct spa_pod *pod; /* a barrier around the memcpy to make sure it is not moved around or - * duplicated after the size check below. We need to to work on shared - * memory while there could be updates happening while we read. */ + * duplicated after the size check below. We need to work on shared + * memory and so there could be updates happening while we read. */ SPA_BARRIER; memcpy(header, SPA_PTROFF(parser->data, offset, void), header_size); SPA_BARRIER; - struct spa_pod *pod = SPA_PTROFF(header, pod_offset, struct spa_pod); + pod = SPA_PTROFF(header, pod_offset, struct spa_pod); /* Check that the size (rounded to the next multiple of 8) is in bounds. */ if (long_offset + SPA_ROUND_UP_N((uint64_t)pod->size, SPA_POD_ALIGN) <= size) { *body = SPA_PTROFF(parser->data, long_offset, void);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/pod/vararg.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/pod/vararg.h
Changed
@@ -28,7 +28,7 @@ #define SPA_CHOICE_RANGE(def,min,max) 3,(def),(min),(max) #define SPA_CHOICE_STEP(def,min,max,step) 4,(def),(min),(max),(step) -#define SPA_CHOICE_ENUM(n_vals,...) (n_vals),##__VA_ARGS__ +#define SPA_CHOICE_ENUM(n_vals,def,alt1,...) (n_vals),(def),(alt1),##__VA_ARGS__ #define SPA_CHOICE_FLAGS(flags) 1, (flags) #define SPA_CHOICE_FEATURES(features) 1, (features) #define SPA_CHOICE_BOOL(def) 3,(def),(def),!(def)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/support/thread.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/support/thread.h
Changed
@@ -117,6 +117,8 @@ #define SPA_KEY_THREAD_STACK_SIZE "thread.stack-size" /* the stack size of the thread */ #define SPA_KEY_THREAD_AFFINITY "thread.affinity" /* array of CPUs for this thread */ #define SPA_KEY_THREAD_CREATOR "thread.creator" /* platform specific thread creator function */ +#define SPA_KEY_THREAD_RESET_ON_FORK "thread.reset-on-fork" /* reset priority and policy for real-time threads + on fork. Default true */ /** * \}
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/utils/cleanup.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/utils/cleanup.h
Changed
@@ -46,9 +46,13 @@ /* ========================================================================== */ -#if defined(__has_attribute) && __has_attribute(__cleanup__) - +#ifdef __has_attribute +#if __has_attribute(__cleanup__) #define spa_cleanup(func) __attribute__((__cleanup__(func))) +#endif +#endif + +#ifdef spa_cleanup #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/utils/json-core.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/utils/json-core.h
Changed
@@ -54,6 +54,15 @@ { *iter = SPA_JSON_INIT(data, size); } + +#define SPA_JSON_INIT_RELAX(type,data,size) \ + ((struct spa_json) { (data), (data)+(size), NULL, (uint32_t)((type) == '' ? 0x10 : 0x0), 0 }) + +SPA_API_JSON void spa_json_init_relax(struct spa_json * iter, char type, const char *data, size_t size) +{ + *iter = SPA_JSON_INIT_RELAX(type, data, size); +} + #define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 }) SPA_API_JSON void spa_json_enter(struct spa_json * iter, struct spa_json * sub)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/utils/json.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/utils/json.h
Changed
@@ -105,7 +105,7 @@ spa_json_init(iter, data, size); res = spa_json_enter_container(iter, iter, type); if (res == -EPROTO && relax) - spa_json_init(iter, data, size); + spa_json_init_relax(iter, type, data, size); else if (res <= 0) return res; return 1;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/include/spa/utils/string.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/include/spa/utils/string.h
Changed
@@ -10,6 +10,7 @@ #include <errno.h> #include <stdlib.h> #include <locale.h> +#include <sys/types.h> #include <spa/utils/defs.h>
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/lib/lib.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/lib/lib.c
Changed
@@ -1,4 +1,6 @@ +#undef SPA_AUDIO_MAX_CHANNELS + #define SPA_API_IMPL SPA_EXPORT #include <spa/utils/defs.h> #include <spa/buffer/alloc.h> @@ -61,6 +63,7 @@ #include <spa/param/audio/iec958-types.h> #include <spa/param/audio/iec958-utils.h> #include <spa/param/audio/layout.h> +#include <spa/param/audio/layout-types.h> #include <spa/param/audio/mp3.h> #include <spa/param/audio/mp3-types.h> #include <spa/param/audio/mp3-utils.h> @@ -165,9 +168,3 @@ #include <spa/utils/string.h> #include <spa/utils/type.h> #include <spa/utils/type-info.h> - - - - - -
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/alsa/acp/acp.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/alsa/acp/acp.c
Changed
@@ -245,7 +245,7 @@ pa_proplist_update(dev->proplist, PA_UPDATE_REPLACE, m->input_proplist); } if (m->split) { - char pos2048; + char posPA_CHANNELS_MAX*8; struct spa_strbuf b; int i; @@ -1142,8 +1142,9 @@ pa_proplist_unset(p->proplist, ACP_KEY_AUDIO_POSITION_DETECTED); } else { uint32_t positionseld.lpcm_channels; - char position64; - int i = 0, pos = 0; + char positioneld.lpcm_channels * 8; + struct spa_strbuf b; + int i = 0; if (eld.speakers & 0x01) { positionsi++ = ACP_CHANNEL_FL; @@ -1172,16 +1173,14 @@ if (eld.speakers & 0x10) { positionsi++ = ACP_CHANNEL_RC; } - while (i < eld.lpcm_channels) positionsi++ = ACP_CHANNEL_UNKNOWN; - for (i = 0, pos = 0; i < eld.lpcm_channels; i++) { - pos += snprintf(&positionpos, sizeof(position) - pos, "%s,", channel_namespositionsi); - } - - /* Overwrite trailing , */ - positionpos - 1 = 0; + spa_strbuf_init(&b, position, sizeof(position)); + spa_strbuf_append(&b, ""); + for (i = 0; i < eld.lpcm_channels; i++) + spa_strbuf_append(&b, "%s%s", i ? "," : "", channel_namespositionsi); + spa_strbuf_append(&b, ""); changed |= (old_position == NULL) || (!spa_streq(old_position, position)); pa_proplist_sets(p->proplist, ACP_KEY_AUDIO_POSITION_DETECTED, position);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/alsa/acp/channelmap.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/alsa/acp/channelmap.h
Changed
@@ -27,7 +27,11 @@ extern "C" { #endif +#ifdef SPA_AUDIO_MAX_CHANNELS +#define PA_CHANNELS_MAX ((int)SPA_AUDIO_MAX_CHANNELS) +#else #define PA_CHANNELS_MAX 64 +#endif #define PA_CHANNEL_MAP_SNPRINT_MAX (PA_CHANNELS_MAX * 32) @@ -451,7 +455,6 @@ static inline char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { unsigned channel; - bool first = true; char *e; if (!pa_channel_map_valid(map)) { pa_snprintf(s, l, "%s", _("(invalid)")); @@ -460,12 +463,10 @@ *(e = s) = 0; for (channel = 0; channel < map->channels && l > 1; channel++) { l -= pa_snprintf(e, l, "%s%s", - first ? "" : ",", + channel == 0 ? "" : ",", pa_channel_position_to_string(map->mapchannel)); e = strchr(e, 0); - first = false; } - return s; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/alsa/alsa-acp-device.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/alsa/alsa-acp-device.c
Changed
@@ -38,6 +38,7 @@ extern struct spa_i18n *acp_i18n; #define MAX_POLL 16 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define DEFAULT_DEVICE "hw:0" #define DEFAULT_AUTO_PROFILE true @@ -155,12 +156,13 @@ const struct acp_dict_item *it; uint32_t n_items, i; char device_name128, path210, channels16, ch12, routes16; - char card_index16, card_name64, *p; - char positionsSPA_AUDIO_MAX_CHANNELS * 12; + char card_index16, card_name64; + char positionsMAX_CHANNELS * 12; char codecs512; struct spa_device_object_info info; struct acp_card *card = this->card; const char *stream, *card_id, *bus; + struct spa_strbuf b; info = SPA_DEVICE_OBJECT_INFO_INIT(); info.type = SPA_TYPE_INTERFACE_Node; @@ -199,11 +201,13 @@ snprintf(channels, sizeof(channels), "%d", dev->format.channels); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_CHANNELS, channels); - p = positions; + spa_strbuf_init(&b, positions, sizeof(positions)); + spa_strbuf_append(&b, ""); for (i = 0; i < dev->format.channels; i++) { - p += snprintf(p, 12, "%s%s", i == 0 ? "" : ",", + spa_strbuf_append(&b, "%s%s", i == 0 ? " " : ", ", acp_channel_str(ch, sizeof(ch), dev->format.mapi)); } + spa_strbuf_append(&b, " "); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_POSITION, positions); if (dev->n_codecs > 0) { @@ -673,8 +677,8 @@ struct spa_pod_prop *prop; struct spa_pod_object *obj = (struct spa_pod_object *) props; int changed = 0; - float volumesSPA_AUDIO_MAX_CHANNELS; - uint32_t channelsSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; + uint32_t channelsMAX_CHANNELS; uint32_t n_volumes = 0; if (!spa_pod_is_object_type(props, SPA_TYPE_OBJECT_Props)) @@ -696,13 +700,13 @@ break; case SPA_PROP_channelVolumes: if ((n_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - volumes, SPA_AUDIO_MAX_CHANNELS)) > 0) { + volumes, SPA_N_ELEMENTS(volumes))) > 0) { changed++; } break; case SPA_PROP_channelMap: if (spa_pod_copy_array(&prop->value, SPA_TYPE_Id, - channels, SPA_AUDIO_MAX_CHANNELS) > 0) { + channels, SPA_N_ELEMENTS(channels)) > 0) { changed++; } break;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -163,10 +163,10 @@ int fmt_change = 0; if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) { state->default_channels = atoi(s); - if (state->default_channels > SPA_AUDIO_MAX_CHANNELS) { + if (state->default_channels > MAX_CHANNELS) { spa_log_warn(state->log, "%p: %s: %s > %d, clamping", - state, k, s, SPA_AUDIO_MAX_CHANNELS); - state->default_channels = SPA_AUDIO_MAX_CHANNELS; + state, k, s, MAX_CHANNELS); + state->default_channels = MAX_CHANNELS; } fmt_change++; } else if (spa_streq(k, SPA_KEY_AUDIO_RATE)) { @@ -240,35 +240,33 @@ static int position_to_string(struct channel_map *map, char *val, size_t len) { - uint32_t i, o = 0; - int r; - o += snprintf(val, len, " "); - for (i = 0; i < map->channels; i++) { - r = snprintf(val+o, len-o, "%s%s", i == 0 ? "" : ", ", - spa_debug_type_find_short_name(spa_type_audio_channel, - map->posi)); - if (r < 0 || o + r >= len) - return -ENOSPC; - o += r; + uint32_t i; + char pos8; + struct spa_strbuf b; + + spa_strbuf_init(&b, val, len); + spa_strbuf_append(&b, ""); + for (i = 0; i < map->n_pos; i++) { + spa_strbuf_append(&b, "%s%s", i == 0 ? " " : ", ", + spa_type_audio_channel_make_short_name(map->posi, + pos, sizeof(pos), "UNK")); } - if (len > o) - o += snprintf(val+o, len-o, " "); + if (spa_strbuf_append(&b, " ") < 2) + return -ENOSPC; return 0; } static int uint32_array_to_string(uint32_t *vals, uint32_t n_vals, char *val, size_t len) { - uint32_t i, o = 0; - int r; - o += snprintf(val, len, " "); - for (i = 0; i < n_vals; i++) { - r = snprintf(val+o, len-o, "%s%d", i == 0 ? "" : ", ", valsi); - if (r < 0 || o + r >= len) - return -ENOSPC; - o += r; - } - if (len > o) - o += snprintf(val+o, len-o, " "); + uint32_t i; + struct spa_strbuf b; + + spa_strbuf_init(&b, val, len); + spa_strbuf_append(&b, ""); + for (i = 0; i < n_vals; i++) + spa_strbuf_append(&b, "%s%d", i == 0 ? " " : ", ", valsi); + if (spa_strbuf_append(&b, " ") < 2) + return -ENOSPC; return 0; } @@ -775,7 +773,7 @@ snd_ctl_elem_id_alloca(&bound_id); snd_ctl_elem_value_alloca(&old_value); - while ((err = snd_ctl_read(state->ctl, ev) > 0)) { + while ((err = snd_ctl_read(state->ctl, ev)) > 0) { bool changed = false; if (snd_ctl_event_get_type(ev) != SND_CTL_EVENT_ELEM) @@ -1584,8 +1582,8 @@ spa_log_debug(state->log, "channels (%d %d) default:%d all:%d", min, max, state->default_channels, all); - min = SPA_MIN(min, SPA_AUDIO_MAX_CHANNELS); - max = SPA_MIN(max, SPA_AUDIO_MAX_CHANNELS); + min = SPA_MIN(min, MAX_CHANNELS); + max = SPA_MIN(max, MAX_CHANNELS); if (state->default_channels != 0 && !all) { if (min > state->default_channels || @@ -1645,7 +1643,7 @@ } else { const struct channel_map *map = NULL; spa_pod_builder_int(b, min); - if (state->default_pos.channels == min) { + if (state->default_pos.n_pos == min) { map = &state->default_pos; spa_log_debug(state->log, "%p: using provided default", state); } else if (min <= 8) { @@ -1655,7 +1653,7 @@ if (map) { spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_position, 0); spa_pod_builder_push_array(b, &f0); - for (i = 0; i < map->channels; i++) { + for (i = 0; i < map->n_pos; i++) { spa_log_debug(state->log, "%p: position %zd %d", state, i, map->posi); spa_pod_builder_id(b, map->posi); }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/alsa/alsa-pcm.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/alsa/alsa-pcm.h
Changed
@@ -36,6 +36,7 @@ #endif #define MAX_RATES 16 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define DEFAULT_PERIOD 1024u #define DEFAULT_RATE 48000u @@ -71,8 +72,8 @@ #define BW_PERIOD (3 * SPA_NSEC_PER_SEC) struct channel_map { - uint32_t channels; - uint32_t posSPA_AUDIO_MAX_CHANNELS; + uint32_t n_pos; + uint32_t posMAX_CHANNELS; }; struct card { @@ -314,7 +315,7 @@ static inline void spa_alsa_parse_position(struct channel_map *map, const char *val, size_t len) { - spa_audio_parse_position(val, len, map->pos, &map->channels); + spa_audio_parse_position_n(val, len, map->pos, SPA_N_ELEMENTS(map->pos), &map->n_pos); } static inline uint32_t spa_alsa_parse_rates(uint32_t *rates, uint32_t max, const char *val, size_t len)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/audioadapter.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -808,6 +808,7 @@ if (spa_format_audio_parse(param, &info) < 0) { spa_log_error(this->log, "%p: cannot set Format param: " "parsing the POD failed", this); + spa_debug_log_pod(this->log, SPA_LOG_LEVEL_ERROR, 0, NULL, param); return -EINVAL; } if (info.media_subtype != SPA_MEDIA_SUBTYPE_raw) { @@ -841,6 +842,7 @@ SPA_PARAM_PORT_CONFIG_format, SPA_POD_OPT_Pod(&format)) < 0) { spa_log_error(this->log, "%p: cannot set PortConfig param: " "parsing the POD failed", this); + spa_debug_log_pod(this->log, SPA_LOG_LEVEL_ERROR, 0, NULL, param); return -EINVAL; } @@ -848,8 +850,12 @@ struct spa_audio_info info; spa_zero(info); - if ((res = spa_format_audio_parse(format, &info)) < 0) + if ((res = spa_format_audio_parse(format, &info)) < 0) { + spa_log_error(this->log, "%p: cannot set PortConfig param: " + "parsing format failed: %s", this, spa_strerror(res)); + spa_debug_log_pod(this->log, SPA_LOG_LEVEL_ERROR, 0, NULL, format); return res; + } if (info.media_subtype == SPA_MEDIA_SUBTYPE_raw) { info.info.raw.rate = 0; @@ -1213,6 +1219,9 @@ case SPA_PARAM_Tag: idx = IDX_Tag; break; + case SPA_PARAM_EnumFormat: + idx = IDX_EnumFormat; + break; default: continue; } @@ -1240,6 +1249,11 @@ spa_log_debug(this->log, "tag: %d (%s)", res, spa_strerror(res)); } + if (idx == IDX_EnumFormat) { + spa_log_info(this->log, "new EnumFormat from converter"); + /* we will renegotiate when restarting */ + this->recheck_format = true; + } spa_log_debug(this->log, "param %d changed", info->paramsi.id); } } @@ -1438,7 +1452,7 @@ spa_strerror(res)); } if (idx == IDX_EnumFormat) { - spa_log_debug(this->log, "new formats"); + spa_log_debug(this->log, "new EnumFormat from follower"); /* we will renegotiate when restarting */ this->recheck_format = true; } @@ -2046,11 +2060,12 @@ return -ENOENT; if (format.media_subtype == SPA_MEDIA_SUBTYPE_raw) { + uint32_t n_pos = SPA_MIN(SPA_N_ELEMENTS(format.info.raw.position), format.info.raw.channels); if (position == POSITION_AUX) { - for (i = 0; i < format.info.raw.channels; i++) + for (i = 0; i < n_pos; i++) format.info.raw.positioni = SPA_AUDIO_CHANNEL_START_Aux + i; } else if (position == POSITION_UNKNOWN) { - for (i = 0; i < format.info.raw.channels; i++) + for (i = 0; i < n_pos; i++) format.info.raw.positioni = SPA_AUDIO_CHANNEL_UNKNOWN; } }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -47,10 +47,11 @@ #define DEFAULT_RATE 48000 #define DEFAULT_CHANNELS 2 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define MAX_ALIGN FMT_OPS_MAX_ALIGN #define MAX_BUFFERS 32 -#define MAX_DATAS SPA_AUDIO_MAX_CHANNELS -#define MAX_PORTS (SPA_AUDIO_MAX_CHANNELS+1) +#define MAX_DATAS MAX_CHANNELS +#define MAX_PORTS (MAX_CHANNELS+1) #define MAX_STAGES 64 #define MAX_GRAPH 9 /* 8 active + 1 replacement slot */ @@ -62,7 +63,7 @@ struct volumes { bool mute; uint32_t n_volumes; - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; }; static void init_volumes(struct volumes *vol) @@ -70,7 +71,7 @@ uint32_t i; vol->mute = DEFAULT_MUTE; vol->n_volumes = 0; - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) vol->volumesi = DEFAULT_VOLUME; } @@ -91,7 +92,7 @@ float max_volume; float prev_volume; uint32_t n_channels; - uint32_t channel_mapSPA_AUDIO_MAX_CHANNELS; + uint32_t channel_mapMAX_CHANNELS; struct volumes channel; struct volumes soft; struct volumes monitor; @@ -112,7 +113,7 @@ props->min_volume = DEFAULT_MIN_VOLUME; props->max_volume = DEFAULT_MAX_VOLUME; props->n_channels = 0; - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) props->channel_mapi = SPA_AUDIO_CHANNEL_UNKNOWN; init_volumes(&props->channel); init_volumes(&props->soft); @@ -241,9 +242,9 @@ struct spa_filter_graph *graph; struct spa_hook listener; uint32_t n_inputs; - uint32_t inputs_positionSPA_AUDIO_MAX_CHANNELS; + uint32_t inputs_positionMAX_CHANNELS; uint32_t n_outputs; - uint32_t outputs_positionSPA_AUDIO_MAX_CHANNELS; + uint32_t outputs_positionMAX_CHANNELS; uint32_t latency; bool removing; bool setup; @@ -281,6 +282,7 @@ struct props props; + struct spa_io_clock *io_clock; struct spa_io_position *io_position; struct spa_io_rate_match *io_rate_match; @@ -423,7 +425,6 @@ uint32_t position, bool is_dsp, bool is_monitor, bool is_control) { struct port *port = GET_PORT(this, direction, port_id); - const char *name; spa_assert(port_id < MAX_PORTS); @@ -438,8 +439,7 @@ port->latencySPA_DIRECTION_INPUT = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); port->latencySPA_DIRECTION_OUTPUT = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT); - name = spa_debug_type_find_short_name(spa_type_audio_channel, position); - snprintf(port->position, sizeof(port->position), "%s", name ? name : "UNK"); + spa_type_audio_channel_make_short_name(position, port->position, sizeof(port->position), "UNK"); port->info = SPA_PORT_INFO_INIT(); port->info.change_mask = port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | @@ -1006,12 +1006,43 @@ spa_log_debug(this->log, "%p: io %d %p/%zd", this, id, data, size); switch (id) { + case SPA_IO_Clock: + this->io_clock = data; + break; case SPA_IO_Position: + { + struct port *p; + uint32_t i; + this->io_position = data; + + if (this->io_position && this->io_clock && + this->io_position->clock.target_rate.denom != this->io_clock->target_rate.denom && + !this->props.resample_disabled) { + spa_log_warn(this->log, "driver %d changed rate:%u -> %u", this->io_position->clock.id, + this->io_clock->target_rate.denom, + this->io_position->clock.target_rate.denom); + + this->io_clock->target_rate = this->io_position->clock.target_rate; + for (i = 0; i < this->dirSPA_DIRECTION_INPUT.n_ports; i++) { + if ((p = GET_IN_PORT(this, i)) && p->valid && !p->is_dsp && !p->is_control) { + p->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; + p->paramsIDX_EnumFormat.user++; + } + } + for (i = 0; i < this->dirSPA_DIRECTION_OUTPUT.n_ports; i++) { + if ((p = GET_OUT_PORT(this, i)) && p->valid && !p->is_dsp && !p->is_control) { + p->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; + p->paramsIDX_EnumFormat.user++; + } + } + } break; + } default: return -ENOENT; } + emit_info(this, false); return 0; } @@ -1103,11 +1134,11 @@ else if (spa_streq(k, "n_outputs")) spa_atou32(s, &g->n_outputs, 0); else if (spa_streq(k, "inputs.audio.position")) - spa_audio_parse_position(s, strlen(s), - g->inputs_position, &g->n_inputs); + spa_audio_parse_position_n(s, strlen(s), g->inputs_position, + SPA_N_ELEMENTS(g->inputs_position), &g->n_inputs); else if (spa_streq(k, "outputs.audio.position")) - spa_audio_parse_position(s, strlen(s), - g->outputs_position, &g->n_outputs); + spa_audio_parse_position_n(s, strlen(s), g->outputs_position, + SPA_N_ELEMENTS(g->outputs_position), &g->n_outputs); else if (spa_streq(k, "latency")) { double latency; if (spa_atod(s, &latency)) @@ -1539,8 +1570,6 @@ samples = (vrp->volume_ramp_time * vrp->rate) / 1000; spa_log_info(this->log, "volume ramp samples calculated from time is %d", samples); } - if (!samples) - samples = -1; return samples; } @@ -1551,12 +1580,10 @@ if (vrp->volume_ramp_step_samples) samples = vrp->volume_ramp_step_samples; else if (vrp->volume_ramp_step_time) { - /* convert the step time which is in nano seconds to seconds */ - samples = (vrp->volume_ramp_step_time/1000) * (vrp->rate/1000); + /* convert the step time which is in nano seconds to seconds, round up */ + samples = SPA_MAX(1u, vrp->volume_ramp_step_time/1000) * (vrp->rate/1000); spa_log_debug(this->log, "volume ramp step samples calculated from time is %d", samples); } - if (!samples) - samples = -1; return samples; } @@ -1569,76 +1596,52 @@ return 0.0; } -static struct spa_pod *generate_ramp_up_seq(struct impl *this, struct volume_ramp_params *vrp, +static struct spa_pod *generate_ramp_seq(struct impl *this, struct volume_ramp_params *vrp, void *buffer, size_t size) { struct spa_pod_dynamic_builder b; struct spa_pod_frame f1; - float start = vrp->start, end = vrp->end, volume_accum = start; - int ramp_samples = get_ramp_samples(this, vrp); - int ramp_step_samples = get_ramp_step_samples(this, vrp); - float volume_step = ((end - start) / (ramp_samples / ramp_step_samples)); - uint32_t volume_offs = 0; + float start = vrp->start, end = vrp->end; + int samples = get_ramp_samples(this, vrp); + int step = get_ramp_step_samples(this, vrp); + int offs = 0; + + if (samples < 0 || step < 0 || (samples > 0 && step == 0)) + return NULL; spa_pod_dynamic_builder_init(&b, buffer, size, 4096); spa_pod_builder_push_sequence(&b.b, &f0, 0); - spa_log_info(this->log, "generating ramp up sequence from %f to %f with a" - " step value %f at scale %d", start, end, volume_step, vrp->scale);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/channelmix-ops.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/channelmix-ops.c
Changed
@@ -142,29 +142,29 @@ } static void distribute_mix(struct channelmix *mix, - float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS, + float matrixMAX_CHANNELSMAX_CHANNELS, uint64_t mask) { uint32_t i, ch = mask_to_ch(mix, mask); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixich= 1.0f; } static void average_mix(struct channelmix *mix, - float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS, + float matrixMAX_CHANNELSMAX_CHANNELS, uint64_t mask) { uint32_t i, ch = mask_to_ch(mix, mask); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixchi= 1.0f; } -static void pair_mix(float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS) +static void pair_mix(float matrixMAX_CHANNELSMAX_CHANNELS) { uint32_t i; - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixii= 1.0f; } static bool match_mix(struct channelmix *mix, - float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS, + float matrixMAX_CHANNELSMAX_CHANNELS, uint64_t src_mask, uint64_t dst_mask) { bool matched = false; @@ -181,7 +181,7 @@ static int make_matrix(struct channelmix *mix) { - float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS = {{ 0.0f }}; + float matrixMAX_CHANNELSMAX_CHANNELS = {{ 0.0f }}; uint64_t src_mask = mix->src_mask, src_paired; uint64_t dst_mask = mix->dst_mask, dst_paired; uint32_t src_chan = mix->src_chan; @@ -293,7 +293,7 @@ keep &= ~STEREO; } else if (dst_mask & _MASK(MONO)){ spa_log_info(mix->log, "assign FC to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixi_CH(FC)= 1.0f; normalize = true; } else { @@ -313,7 +313,7 @@ keep &= ~FRONT; } else if ((dst_mask & _MASK(MONO))){ spa_log_info(mix->log, "assign STEREO to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { + for (i = 0; i < MAX_CHANNELS; i++) { matrixi_CH(FL)= 1.0f; matrixi_CH(FR)= 1.0f; } @@ -352,7 +352,7 @@ _MATRIX(FC,RC) += slev * SQRT1_2; } else if (dst_mask & _MASK(MONO)){ spa_log_info(mix->log, "assign RC to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixi_CH(RC)= 1.0f; normalize = true; } else { @@ -398,7 +398,7 @@ _MATRIX(FC,RR)+= slev * SQRT1_2; } else if (dst_mask & _MASK(MONO)){ spa_log_info(mix->log, "assign RL+RR to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { + for (i = 0; i < MAX_CHANNELS; i++) { matrixi_CH(RL)= 1.0f; matrixi_CH(RR)= 1.0f; } @@ -450,7 +450,7 @@ _MATRIX(FC,SR) += slev * SQRT1_2; } else if (dst_mask & _MASK(MONO)){ spa_log_info(mix->log, "assign SL+SR to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { + for (i = 0; i < MAX_CHANNELS; i++) { matrixi_CH(SL)= 1.0f; matrixi_CH(SR)= 1.0f; } @@ -471,7 +471,7 @@ _MATRIX(FC,FRC)+= SQRT1_2; } else if (dst_mask & _MASK(MONO)){ spa_log_info(mix->log, "assign FLC+FRC to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { + for (i = 0; i < MAX_CHANNELS; i++) { matrixi_CH(FLC)= 1.0f; matrixi_CH(FRC)= 1.0f; } @@ -492,7 +492,7 @@ _MATRIX(FR,LFE) += llev * SQRT1_2; } else if ((dst_mask & _MASK(MONO))){ spa_log_info(mix->log, "assign LFE to MONO (%f)", 1.0f); - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) + for (i = 0; i < MAX_CHANNELS; i++) matrixi_CH(LFE)= 1.0f; normalize = true; } else { @@ -690,7 +690,7 @@ static void impl_channelmix_set_volume(struct channelmix *mix, float volume, bool mute, uint32_t n_channel_volumes, float *channel_volumes) { - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; float vol = mute ? 0.0f : volume, t; uint32_t i, j; uint32_t src_chan = mix->src_chan; @@ -760,8 +760,8 @@ { const struct channelmix_info *info; - if (mix->src_chan > SPA_AUDIO_MAX_CHANNELS || - mix->dst_chan > SPA_AUDIO_MAX_CHANNELS) + if (mix->src_chan > MAX_CHANNELS || + mix->dst_chan > MAX_CHANNELS) return -EINVAL; info = find_channelmix_info(mix->src_chan, mix->src_mask, mix->dst_chan, mix->dst_mask,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/channelmix-ops.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/channelmix-ops.h
Changed
@@ -24,6 +24,7 @@ #define BUFFER_SIZE 4096 #define MAX_TAPS 255u +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define CHANNELMIX_OPS_MAX_ALIGN 16 @@ -50,8 +51,8 @@ #define CHANNELMIX_FLAG_EQUAL (1<<2) /**< all values are equal */ #define CHANNELMIX_FLAG_COPY (1<<3) /**< 1 on diagonal, can be nxm */ uint32_t flags; - float matrix_origSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS; - float matrixSPA_AUDIO_MAX_CHANNELSSPA_AUDIO_MAX_CHANNELS; + float matrix_origMAX_CHANNELSMAX_CHANNELS; + float matrixMAX_CHANNELSMAX_CHANNELS; float freq; /* sample frequency */ float lfe_cutoff; /* in Hz, 0 is disabled */ @@ -59,7 +60,7 @@ float rear_delay; /* in ms, 0 is disabled */ float widen; /* stereo widen. 0 is disabled */ uint32_t hilbert_taps; /* to phase shift, 0 disabled */ - struct lr4 lr4SPA_AUDIO_MAX_CHANNELS; + struct lr4 lr4MAX_CHANNELS; float buffer_mem2 * BUFFER_SIZE*2 + CHANNELMIX_OPS_MAX_ALIGN/4; float *buffer2;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/fmt-ops.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/fmt-ops.c
Changed
@@ -551,7 +551,7 @@ const struct dither_info *dinfo; const struct noise_info *ninfo; const struct clear_info *cinfo; - uint32_t i, conv_flags, data_size3; + uint32_t i, conv_flags, data_size4; /* we generate int32 bits of random values. With this scale * factor, we bring this in the -1.0, 1.0 range */ @@ -615,15 +615,17 @@ data_size0 = SPA_ROUND_UP(conv->noise_size * sizeof(float), FMT_OPS_MAX_ALIGN); data_size1 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(uint32_t), FMT_OPS_MAX_ALIGN); data_size2 = SPA_ROUND_UP(RANDOM_SIZE * sizeof(int32_t), FMT_OPS_MAX_ALIGN); + data_size3 = SPA_ROUND_UP(conv->n_channels * sizeof(struct shaper), FMT_OPS_MAX_ALIGN); conv->data = calloc(FMT_OPS_MAX_ALIGN + - data_size0 + data_size1 + data_size2, 1); + data_size0 + data_size1 + data_size2 + data_size3, 1); if (conv->data == NULL) return -errno; conv->noise = SPA_PTR_ALIGN(conv->data, FMT_OPS_MAX_ALIGN, float); conv->random = SPA_PTROFF(conv->noise, data_size0, uint32_t); conv->prev = SPA_PTROFF(conv->random, data_size1, int32_t); + conv->shaper = SPA_PTROFF(conv->prev, data_size2, struct shaper); for (i = 0; i < RANDOM_SIZE; i++) conv->randomi = random();
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/fmt-ops.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/fmt-ops.h
Changed
@@ -236,7 +236,7 @@ uint32_t noise_size; const float *ns; uint32_t n_ns; - struct shaper shaper64; + struct shaper *shaper; void (*update_noise) (struct convert *conv, float *noise, uint32_t n_samples); void (*process) (struct convert *conv, void * SPA_RESTRICT dst, const void * SPA_RESTRICT src,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/meson.build -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/meson.build
Changed
@@ -125,7 +125,7 @@ sparesampledumpcoeffs = executable( 'spa-resample-dump-coeffs', sparesampledumpcoeffs_sources, - c_args : cc_flags_native, '-DRESAMPLE_DISABLE_PRECOMP' , + c_args : '-DRESAMPLE_DISABLE_PRECOMP' , dependencies : spa_dep, mathlib_native , install : false, native : true,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/audioconvert/test-audioconvert.c
Changed
@@ -25,7 +25,8 @@ extern const struct spa_handle_factory test_source_factory; -#define MAX_PORTS (SPA_AUDIO_MAX_CHANNELS+1) +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS +#define MAX_PORTS (MAX_CHANNELS+1) struct context { struct spa_handle *convert_handle;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/avb/avb-pcm.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/avb/avb-pcm.c
Changed
@@ -40,7 +40,13 @@ state->default_format = spa_type_audio_format_from_short_name(s); fmt_change++; } else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { - spa_audio_parse_position(s, strlen(s), state->default_pos.pos, + spa_audio_parse_position_n(s, strlen(s), state->default_pos.pos, + SPA_N_ELEMENTS(state->default_pos.pos), + &state->default_pos.channels); + fmt_change++; + } else if (spa_streq(k, SPA_KEY_AUDIO_LAYOUT)) { + spa_audio_parse_layout(s, state->default_pos.pos, + SPA_N_ELEMENTS(state->default_pos.pos), &state->default_pos.channels); fmt_change++; } else if (spa_streq(k, SPA_KEY_AUDIO_ALLOWED_RATES)) { @@ -85,11 +91,12 @@ { uint32_t i, o = 0; int r; + char pos8; o += snprintf(val, len, " "); for (i = 0; i < map->channels; i++) { r = snprintf(val+o, len-o, "%s%s", i == 0 ? "" : ", ", - spa_debug_type_find_short_name(spa_type_audio_channel, - map->posi)); + spa_type_audio_channel_make_short_name(map->posi, + pos, sizeof(pos), "UNK")); if (r < 0 || o + r >= len) return -ENOSPC; o += r;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/avb/avb-pcm.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/avb/avb-pcm.h
Changed
@@ -109,6 +109,7 @@ return str; } +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define MAX_BUFFERS 32 struct buffer { @@ -127,7 +128,7 @@ struct channel_map { uint32_t channels; - uint32_t posSPA_AUDIO_MAX_CHANNELS; + uint32_t posMAX_CHANNELS; }; struct port {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-aac.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-aac.c
Changed
@@ -200,7 +200,7 @@ a2dp_aac_t conf; struct spa_pod_frame f2; struct spa_pod_choice *choice; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; uint32_t i = 0; if (caps_size < sizeof(conf))
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-aptx.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-aptx.c
Changed
@@ -205,7 +205,7 @@ a2dp_aptx_t conf; struct spa_pod_frame f2; struct spa_pod_choice *choice; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; uint32_t i = 0; if (caps_size < sizeof(conf))
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-faststream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-faststream.c
Changed
@@ -114,7 +114,7 @@ a2dp_faststream_t conf; struct spa_pod_frame f2; struct spa_pod_choice *choice; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; uint32_t i = 0; if (caps_size < sizeof(conf))
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-lc3plus.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-lc3plus.c
Changed
@@ -175,7 +175,7 @@ a2dp_lc3plus_hr_t conf; struct spa_pod_frame f2; struct spa_pod_choice *choice; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; uint32_t i = 0; if (caps_size < sizeof(conf))
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-ldac.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-ldac.c
Changed
@@ -158,7 +158,7 @@ struct spa_pod_frame f2; struct spa_pod_choice *choice; uint32_t i = 0; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; if (caps_size < sizeof(conf)) return -EINVAL;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-opus-g.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-opus-g.c
Changed
@@ -164,7 +164,7 @@ { a2dp_opus_g_t conf; struct spa_pod_frame f1; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; int channels; if (caps_size < sizeof(conf))
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-opus.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-opus.c
Changed
@@ -58,6 +58,8 @@ #define BITRATE_DUPLEX_BIDI 160000 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + #define OPUS_05_MAX_BYTES (15 * 1024) struct props { @@ -251,14 +253,8 @@ static uint32_t bt_channel_from_name(const char *name) { size_t i; - enum spa_audio_channel position = SPA_AUDIO_CHANNEL_UNKNOWN; + enum spa_audio_channel position = spa_type_audio_channel_from_short_name(name); - for (i = 0; spa_type_audio_channeli.name; i++) { - if (spa_streq(name, spa_debug_type_short_name(spa_type_audio_channeli.name))) { - position = spa_type_audio_channeli.type; - break; - } - } for (i = 0; i < SPA_N_ELEMENTS(audio_locations); i++) { if (position == audio_locationsi.position) return audio_locationsi.mask; @@ -313,14 +309,14 @@ return; if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.channels"), &v, 0)) - props->channels = SPA_CLAMP(v, 1u, SPA_AUDIO_MAX_CHANNELS); + props->channels = SPA_CLAMP(v, 1u, MAX_CHANNELS); if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.max-bitrate"), &v, 0)) props->max_bitrate = SPA_MAX(v, (uint32_t)BITRATE_MIN); if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.coupled-streams"), &v, 0)) props->coupled_streams = SPA_CLAMP(v, 0u, props->channels / 2); if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.bidi.channels"), &v, 0)) - props->bidi_channels = SPA_CLAMP(v, 0u, SPA_AUDIO_MAX_CHANNELS); + props->bidi_channels = SPA_CLAMP(v, 0u, MAX_CHANNELS); if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.bidi.max-bitrate"), &v, 0)) props->bidi_max_bitrate = SPA_MAX(v, (uint32_t)BITRATE_MIN); if (spa_atou32(spa_dict_lookup(settings, "bluez5.a2dp.opus.pro.bidi.coupled-streams"), &v, 0)) @@ -503,7 +499,7 @@ const uint8_t *permutation = NULL; size_t i, j; - if (channels > SPA_AUDIO_MAX_CHANNELS) + if (channels > MAX_CHANNELS) return -EINVAL; if (2 * coupled_streams > channels) return -EINVAL; @@ -542,10 +538,9 @@ const struct audio_location loc = audio_locationsi; if (location & loc.mask) { - if (permutation) - positionspermutationj++ = loc.position; - else - positionsj++ = loc.position; + uint32_t idx = permutation ? permutationj : j; + positionsidx = loc.position; + j++; } } for (i = SPA_AUDIO_CHANNEL_START_Aux; j < channels; ++i, ++j) @@ -561,7 +556,7 @@ a2dp_opus_05_t a2dp_opus_05 = { .info = codec->vendor, .main = { - .channels = SPA_MIN(255u, SPA_AUDIO_MAX_CHANNELS), + .channels = SPA_MIN(255u, MAX_CHANNELS), .frame_duration = (OPUS_05_FRAME_DURATION_25 | OPUS_05_FRAME_DURATION_50 | OPUS_05_FRAME_DURATION_100 | @@ -571,7 +566,7 @@ OPUS_05_INIT_BITRATE(0) }, .bidi = { - .channels = SPA_MIN(255u, SPA_AUDIO_MAX_CHANNELS), + .channels = SPA_MIN(255u, MAX_CHANNELS), .frame_duration = (OPUS_05_FRAME_DURATION_25 | OPUS_05_FRAME_DURATION_50 | OPUS_05_FRAME_DURATION_100 | @@ -771,7 +766,7 @@ a2dp_opus_05_t conf; a2dp_opus_05_direction_t *dir; struct spa_pod_frame f1; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t positionMAX_CHANNELS; if (caps_size < sizeof(conf)) return -EINVAL; @@ -835,7 +830,8 @@ } info->info.raw.channels = dir1->channels; - if (get_mapping(codec, dir1, surround_encoder, NULL, NULL, NULL, info->info.raw.position) < 0) + if (get_mapping(codec, dir1, surround_encoder, NULL, NULL, NULL, + info->info.raw.position) < 0) return -EINVAL; if (get_mapping(codec, dir2, surround_encoder, NULL, NULL, NULL, NULL) < 0) return -EINVAL;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/a2dp-codec-sbc.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/a2dp-codec-sbc.c
Changed
@@ -346,7 +346,7 @@ struct spa_pod_frame f2; struct spa_pod_choice *choice; uint32_t i = 0; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t position2; if (caps_size < sizeof(conf)) return -EINVAL;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/bap-codec-lc3.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/bap-codec-lc3.c
Changed
@@ -901,12 +901,12 @@ return conf_cmp(&conf1, res1, &conf2, res2); } -static uint8_t channels_to_positions(uint32_t channels, uint32_t *position) +static uint8_t channels_to_positions(uint32_t channels, uint32_t *position, uint32_t max_position) { uint32_t n_channels = get_channel_count(channels); uint8_t n_positions = 0; - spa_assert(n_channels <= SPA_AUDIO_MAX_CHANNELS); + spa_assert(n_channels <= max_position); if (channels == 0) { position0 = SPA_AUDIO_CHANNEL_MONO; @@ -932,7 +932,7 @@ bap_lc3_t conf; struct spa_pod_frame f2; struct spa_pod_choice *choice; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t positionLC3_MAX_CHANNELS; uint32_t i = 0; uint8_t res; @@ -990,7 +990,7 @@ if (i == 0) return -EINVAL; - res = channels_to_positions(conf.channels, position); + res = channels_to_positions(conf.channels, position, SPA_N_ELEMENTS(position)); if (res == 0) return -EINVAL; spa_pod_builder_add(b, @@ -1044,7 +1044,8 @@ return -EINVAL; } - res = channels_to_positions(conf.channels, info->info.raw.position); + res = channels_to_positions(conf.channels, info->info.raw.position, + SPA_N_ELEMENTS(info->info.raw.position)); if (res == 0) return -EINVAL; info->info.raw.channels = res;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/bluez5-dbus.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/bluez5-dbus.c
Changed
@@ -35,6 +35,7 @@ #include <spa/utils/string.h> #include <spa/utils/json.h> #include <spa-private/dbus-helpers.h> +#include <spa/param/audio/raw-utils.h> #include <spa/param/audio/raw-json.h> #include "codec-loader.h" @@ -5037,6 +5038,10 @@ spa_log_error(monitor->log, "invalid transport configuration"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } + if (info.info.raw.channels > MAX_CHANNELS) { + spa_log_error(monitor->log, "too many channels in transport"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } transport->n_channels = info.info.raw.channels; memcpy(transport->channels, info.info.raw.position, transport->n_channels * sizeof(uint32_t)); @@ -6850,7 +6855,7 @@ const char *key, uint32_t *value) { const char *str; - uint32_t positionSPA_AUDIO_MAX_CHANNELS; + uint32_t positionMAX_CHANNELS; uint32_t n_channels; uint32_t locations; unsigned int i, j; @@ -6861,7 +6866,8 @@ if (spa_atou32(str, value, 0)) return; - if (!spa_audio_parse_position(str, strlen(str), position, &n_channels)) { + if (!spa_audio_parse_position_n(str, strlen(str), position, + SPA_N_ELEMENTS(position), &n_channels)) { spa_log_error(this->log, "property %s '%s' is not valid position array", key, str); return; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/bluez5-device.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/bluez5-device.c
Changed
@@ -26,6 +26,7 @@ #include <spa/pod/parser.h> #include <spa/param/param.h> #include <spa/param/audio/raw.h> +#include <spa/param/audio/raw-utils.h> #include <spa/param/bluetooth/audio.h> #include <spa/param/bluetooth/type-info.h> #include <spa/debug/pod.h> @@ -38,7 +39,7 @@ #undef SPA_LOG_TOPIC_DEFAULT #define SPA_LOG_TOPIC_DEFAULT &log_topic -#define MAX_NODES (2*SPA_AUDIO_MAX_CHANNELS) +#define MAX_NODES (2*MAX_CHANNELS) #define DEVICE_ID_SOURCE 0 #define DEVICE_ID_SINK 1 @@ -99,9 +100,9 @@ unsigned int offload_acquired:1; uint32_t n_channels; int64_t latency_offset; - uint32_t channelsSPA_AUDIO_MAX_CHANNELS; - float volumesSPA_AUDIO_MAX_CHANNELS; - float soft_volumesSPA_AUDIO_MAX_CHANNELS; + uint32_t channelsMAX_CHANNELS; + float volumesMAX_CHANNELS; + float soft_volumesMAX_CHANNELS; }; struct dynamic_node @@ -129,8 +130,8 @@ bool leader; uint32_t sinks; uint32_t sources; - struct device_set_member sinkSPA_AUDIO_MAX_CHANNELS; - struct device_set_member sourceSPA_AUDIO_MAX_CHANNELS; + struct device_set_member sinkMAX_CHANNELS; + struct device_set_member sourceMAX_CHANNELS; }; struct impl { @@ -182,7 +183,7 @@ spa_zero(*node); node->id = id; - for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) { + for (i = 0; i < MAX_CHANNELS; i++) { node->volumesi = 1.0f; node->soft_volumesi = 1.0f; } @@ -476,6 +477,7 @@ *n_channels = info.info.raw.channels; memcpy(channels, info.info.raw.position, info.info.raw.channels * sizeof(uint32_t)); + } static const char *get_channel_name(uint32_t channel) @@ -546,7 +548,7 @@ if (node->channelsk == t->channelsj) break; } - if (k == node->n_channels && node->n_channels < SPA_AUDIO_MAX_CHANNELS) + if (k == node->n_channels && node->n_channels < MAX_CHANNELS) node->channelsnode->n_channels++ = t->channelsj; } } @@ -2413,7 +2415,7 @@ default: name_prefix = "bluetooth"; description = _("Bluetooth"); - hfp_description = _("Bluetooth (HFP)"); + hfp_description = _("Bluetooth Handsfree"); port_type = "bluetooth"; break; } @@ -2946,8 +2948,8 @@ struct spa_pod_prop *prop; struct spa_pod_object *obj = (struct spa_pod_object *) props; int changed = 0; - float volumesSPA_AUDIO_MAX_CHANNELS; - uint32_t channelsSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; + uint32_t channelsMAX_CHANNELS; uint32_t n_volumes = 0, SPA_UNUSED n_channels = 0; int64_t latency_offset = 0; @@ -2972,11 +2974,11 @@ break; case SPA_PROP_channelVolumes: n_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - volumes, SPA_AUDIO_MAX_CHANNELS); + volumes, SPA_N_ELEMENTS(volumes)); break; case SPA_PROP_channelMap: n_channels = spa_pod_copy_array(&prop->value, SPA_TYPE_Id, - channels, SPA_AUDIO_MAX_CHANNELS); + channels, SPA_N_ELEMENTS(channels)); break; case SPA_PROP_latencyOffsetNsec: if (spa_pod_get_long(&prop->value, &latency_offset) == 0) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/defs.h -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/defs.h
Changed
@@ -157,6 +157,8 @@ #define SPA_BT_NO_BATTERY ((uint8_t)255) +#define MAX_CHANNELS (SPA_AUDIO_MAX_CHANNELS) + enum spa_bt_media_direction { SPA_BT_MEDIA_SOURCE, SPA_BT_MEDIA_SINK, @@ -678,7 +680,7 @@ struct spa_list bap_transport_linked; uint32_t n_channels; - uint32_t channelsSPA_AUDIO_MAX_CHANNELS; + uint32_t channelsMAX_CHANNELS; struct spa_bt_transport_volume volumesSPA_BT_VOLUME_ID_TERM;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/hfp-codec-cvsd.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/hfp-codec-cvsd.c
Changed
@@ -34,7 +34,7 @@ struct spa_pod_builder *b, struct spa_pod **param) { struct spa_pod_frame f1; - const uint32_t positionSPA_AUDIO_MAX_CHANNELS = { SPA_AUDIO_CHANNEL_MONO }; + const uint32_t position1 = { SPA_AUDIO_CHANNEL_MONO }; const int channels = 1; spa_assert(caps == NULL && caps_size == 0); @@ -47,7 +47,7 @@ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16_LE), - SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_ENUM_Int(1, 8000), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(8000), SPA_FORMAT_AUDIO_channels, SPA_POD_Int(channels), SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, channels, position),
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/hfp-codec-lc3-a127.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/hfp-codec-lc3-a127.c
Changed
@@ -39,7 +39,7 @@ struct spa_pod_builder *b, struct spa_pod **param) { struct spa_pod_frame f1; - const uint32_t positionSPA_AUDIO_MAX_CHANNELS = { SPA_AUDIO_CHANNEL_MONO }; + const uint32_t position1 = { SPA_AUDIO_CHANNEL_MONO }; const int channels = 1; spa_assert(caps == NULL && caps_size == 0); @@ -52,7 +52,7 @@ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_ENUM_Int(1, 24000), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(24000), SPA_FORMAT_AUDIO_channels, SPA_POD_Int(channels), SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, channels, position),
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/hfp-codec-lc3-swb.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/hfp-codec-lc3-swb.c
Changed
@@ -42,7 +42,7 @@ struct spa_pod_builder *b, struct spa_pod **param) { struct spa_pod_frame f1; - const uint32_t positionSPA_AUDIO_MAX_CHANNELS = { SPA_AUDIO_CHANNEL_MONO }; + const uint32_t position1 = { SPA_AUDIO_CHANNEL_MONO }; const int channels = 1; spa_assert(caps == NULL && caps_size == 0); @@ -55,7 +55,7 @@ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32), - SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_ENUM_Int(1, 32000), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(32000), SPA_FORMAT_AUDIO_channels, SPA_POD_Int(channels), SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, channels, position),
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/hfp-codec-msbc.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/hfp-codec-msbc.c
Changed
@@ -49,7 +49,7 @@ struct spa_pod_builder *b, struct spa_pod **param) { struct spa_pod_frame f1; - const uint32_t positionSPA_AUDIO_MAX_CHANNELS = { SPA_AUDIO_CHANNEL_MONO }; + const uint32_t position1 = { SPA_AUDIO_CHANNEL_MONO }; const int channels = 1; spa_assert(caps == NULL && caps_size == 0); @@ -62,7 +62,7 @@ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16), - SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_ENUM_Int(1, 16000), + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(16000), SPA_FORMAT_AUDIO_channels, SPA_POD_Int(channels), SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, channels, position),
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/media-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/media-sink.c
Changed
@@ -2139,7 +2139,7 @@ if (info.info.raw.rate == 0 || info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + info.info.raw.channels > MAX_CHANNELS) return -EINVAL; if (this->transport && this->transport->iso_io) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/bluez5/media-source.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/bluez5/media-source.c
Changed
@@ -1439,7 +1439,7 @@ if (info.info.raw.rate == 0 || info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + info.info.raw.channels > MAX_CHANNELS) return -EINVAL; port->frame_size = info.info.raw.channels;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/filter-graph/filter-graph.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/filter-graph/filter-graph.c
Changed
@@ -39,6 +39,7 @@ SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.filter-graph"); #define MAX_HNDL 64 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define DEFAULT_RATE 48000 @@ -154,15 +155,15 @@ struct volume { bool mute; uint32_t n_volumes; - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; uint32_t n_ports; - struct port *portsSPA_AUDIO_MAX_CHANNELS; - float minSPA_AUDIO_MAX_CHANNELS; - float maxSPA_AUDIO_MAX_CHANNELS; + struct port *portsMAX_CHANNELS; + float minMAX_CHANNELS; + float maxMAX_CHANNELS; #define SCALE_LINEAR 0 #define SCALE_CUBIC 1 - int scaleSPA_AUDIO_MAX_CHANNELS; + int scaleMAX_CHANNELS; }; struct graph { @@ -194,9 +195,9 @@ uint32_t n_inputs; uint32_t n_outputs; - uint32_t inputs_positionSPA_AUDIO_MAX_CHANNELS; + uint32_t inputs_positionMAX_CHANNELS; uint32_t n_inputs_position; - uint32_t outputs_positionSPA_AUDIO_MAX_CHANNELS; + uint32_t outputs_positionMAX_CHANNELS; uint32_t n_outputs_position; float min_latency; @@ -231,16 +232,18 @@ float *discard_data; }; -static inline void print_channels(char *buffer, size_t max_size, uint32_t n_channels, uint32_t *positions) +static inline void print_channels(char *buffer, size_t max_size, uint32_t n_positions, uint32_t *positions) { uint32_t i; struct spa_strbuf buf; + char pos8; spa_strbuf_init(&buf, buffer, max_size); spa_strbuf_append(&buf, ""); - for (i = 0; i < n_channels; i++) { + for (i = 0; i < n_positions; i++) { spa_strbuf_append(&buf, "%s%s", i ? "," : "", - spa_type_audio_channel_to_short_name(positionsi)); + spa_type_audio_channel_make_short_name(positionsi, + pos, sizeof(pos), "UNK")); } spa_strbuf_append(&buf, ""); } @@ -256,8 +259,8 @@ char n_inputs64, n_outputs64, latency64; struct spa_dict_item items6; struct spa_dict dict = SPA_DICT(items, 0); - char in_posSPA_AUDIO_MAX_CHANNELS * 8; - char out_posSPA_AUDIO_MAX_CHANNELS * 8; + char in_posMAX_CHANNELS * 8; + char out_posMAX_CHANNELS * 8; snprintf(n_inputs, sizeof(n_inputs), "%d", impl->graph.n_inputs); snprintf(n_outputs, sizeof(n_outputs), "%d", impl->graph.n_outputs); @@ -745,10 +748,10 @@ case SPA_PROP_channelVolumes: { uint32_t i, n_vols; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n_vols = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, vols, - SPA_AUDIO_MAX_CHANNELS)) > 0) { + SPA_N_ELEMENTS(vols))) > 0) { if (vol->n_volumes != n_vols) do_volume = true; vol->n_volumes = n_vols; @@ -772,7 +775,7 @@ } } if (do_volume && vol->n_ports != 0) { - float soft_volsSPA_AUDIO_MAX_CHANNELS; + float soft_volsMAX_CHANNELS; uint32_t i; for (i = 0; i < vol->n_volumes; i++) @@ -1264,7 +1267,7 @@ spa_log_error(impl->log, "unknown control port %s", control); return -ENOENT; } - if (vol->n_ports >= SPA_AUDIO_MAX_CHANNELS) { + if (vol->n_ports >= MAX_CHANNELS) { spa_log_error(impl->log, "too many volume controls"); return -ENOSPC; } @@ -2118,8 +2121,9 @@ spa_log_error(impl->log, "%s expects an array", key); return -EINVAL; } - spa_audio_parse_position(val, len, graph->inputs_position, - &graph->n_inputs_position); + spa_audio_parse_position_n(val, len, graph->inputs_position, + SPA_N_ELEMENTS(graph->inputs_position), + &graph->n_inputs_position); impl->info.n_inputs = graph->n_inputs_position; } else if (spa_streq("outputs.audio.position", key)) { @@ -2128,8 +2132,9 @@ spa_log_error(impl->log, "%s expects an array", key); return -EINVAL; } - spa_audio_parse_position(val, len, graph->outputs_position, - &graph->n_outputs_position); + spa_audio_parse_position_n(val, len, graph->outputs_position, + SPA_N_ELEMENTS(graph->outputs_position), + &graph->n_outputs_position); impl->info.n_outputs = graph->n_outputs_position; } else if (spa_streq("nodes", key)) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/support/node-driver.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/support/node-driver.c
Changed
@@ -26,6 +26,8 @@ #include <spa/node/io.h> #include <spa/node/utils.h> #include <spa/param/param.h> +#include <spa/pod/filter.h> +#include <spa/pod/parser.h> SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.driver"); @@ -48,12 +50,16 @@ #define BW_PERIOD (3 * SPA_NSEC_PER_SEC) #define MAX_ERROR_MS 1 +#define CLOCK_NAME_MAX 64 + struct props { bool freewheel; - char clock_name64; + char clock_nameCLOCK_NAME_MAX; clockid_t clock_id; uint32_t freewheel_wait; float resync_ms; + char clock_deviceCLOCK_NAME_MAX; + char clock_interfaceCLOCK_NAME_MAX; }; struct clock_offset { @@ -73,7 +79,10 @@ uint64_t info_all; struct spa_node_info info; - struct spa_param_info params1; +#define NODE_PropInfo 0 +#define NODE_Props 1 +#define N_NODE_PARAMS 2 + struct spa_param_info paramsN_NODE_PARAMS; struct spa_hook_list hooks; struct spa_callbacks callbacks; @@ -99,13 +108,20 @@ struct clock_offset nsec_offset; }; +static void reset_props_strings(struct props *props) +{ + spa_zero(props->clock_name); + spa_zero(props->clock_device); + spa_zero(props->clock_interface); +} + static void reset_props(struct props *props) { props->freewheel = DEFAULT_FREEWHEEL; - spa_zero(props->clock_name); props->clock_id = CLOCK_MONOTONIC; props->freewheel_wait = DEFAULT_FREEWHEEL_WAIT; props->resync_ms = DEFAULT_RESYNC_MS; + reset_props_strings(props); } static const struct clock_info { @@ -598,10 +614,280 @@ return SPA_STATUS_HAVE_DATA | SPA_STATUS_NEED_DATA; } +static int impl_node_enum_params(void *object, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) +{ + struct impl *this = object; + struct spa_pod *param; + struct spa_pod_builder b = { 0 }; + uint8_t buffer4096; + struct spa_result_node_params result; + uint32_t count = 0; + + spa_return_val_if_fail(this != NULL, -EINVAL); + spa_return_val_if_fail(num != 0, -EINVAL); + + result.id = id; + result.next = start; +next: + result.index = result.next++; + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + + switch (id) { + case SPA_PARAM_PropInfo: + { + struct props *p = &this->props; + + switch (result.index) { + case 0: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_PropInfo, id, + SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_clockId), + SPA_PROP_INFO_description, SPA_POD_String("The clock id (monotonic, realtime, etc.)"), + SPA_PROP_INFO_type, SPA_POD_String(clock_id_to_name(p->clock_id))); + break; + case 1: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_PropInfo, id, + SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_clockDevice), + SPA_PROP_INFO_description, SPA_POD_String("The clock device (eg. /dev/ptp0)"), + SPA_PROP_INFO_type, SPA_POD_Stringn(p->clock_device, sizeof(p->clock_device))); + break; + case 2: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_PropInfo, id, + SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_clockInterface), + SPA_PROP_INFO_description, SPA_POD_String("The clock network interface (eg. eth0)"), + SPA_PROP_INFO_type, SPA_POD_Stringn(p->clock_interface, sizeof(p->clock_interface))); + break; + default: + return 0; + } + + break; + } + + case SPA_PARAM_Props: + { + struct props *p = &this->props; + + switch (result.index) { + case 0: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Props, id, + SPA_PROP_clockId, SPA_POD_String(clock_id_to_name(p->clock_id)) + ); + break; + case 1: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Props, id, + SPA_PROP_clockDevice, SPA_POD_Stringn(p->clock_device, sizeof(p->clock_device)) + ); + break; + case 2: + param = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Props, id, + SPA_PROP_clockInterface, SPA_POD_Stringn(p->clock_interface, sizeof(p->clock_interface)) + ); + break; + default: + return 0; + } + + break; + } + + default: + return -ENOENT; + } + + if (spa_pod_filter(&b, &result.param, param, filter) < 0) + goto next; + + spa_node_emit_result(&this->hooks, seq, 0, SPA_RESULT_TYPE_NODE_PARAMS, &result); + + if (++count != num) + goto next; + + return 0; +} + +static int get_phc_index(struct spa_system *s, const char *name) { +#ifdef ETHTOOL_GET_TS_INFO + struct ethtool_ts_info info = {0}; + struct ifreq ifr = {0}; + int fd, err; + + info.cmd = ETHTOOL_GET_TS_INFO; + strncpy(ifr.ifr_name, name, IFNAMSIZ - 1); + ifr.ifr_data = (char *) &info; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + return -errno; + + err = spa_system_ioctl(s, fd, SIOCETHTOOL, &ifr); + close(fd); + if (err < 0) + return -errno; + + return info.phc_index; +#else + return -ENOTSUP; +#endif +} + +static bool parse_clock_id(struct impl *this, const char *s) +{ + int id = clock_name_to_id(s); + if (id == -1) { + spa_log_info(this->log, "unknown clock id '%s'", s); + return false; + } + this->props.clock_id = id; + if (this->clock_fd >= 0) { + close(this->clock_fd);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/support/null-audio-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/support/null-audio-sink.c
Changed
@@ -35,12 +35,13 @@ SPA_LOG_TOPIC_DEFINE_STATIC(log_topic, "spa.null-audio-sink"); #define DEFAULT_CLOCK_NAME "clock.system.monotonic" +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS struct props { uint32_t format; uint32_t channels; uint32_t rate; - uint32_t posSPA_AUDIO_MAX_CHANNELS; + uint32_t posMAX_CHANNELS; char clock_name64; unsigned int debug:1; unsigned int driver:1; @@ -636,7 +637,7 @@ if (info.info.raw.rate == 0 || info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + info.info.raw.channels > MAX_CHANNELS) return -EINVAL; if (this->props.format != 0) { @@ -949,7 +950,11 @@ } else if (spa_streq(k, SPA_KEY_NODE_DRIVER)) { this->props.driver = spa_atob(s); } else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { - spa_audio_parse_position(s, strlen(s), this->props.pos, &this->props.channels); + spa_audio_parse_position_n(s, strlen(s), this->props.pos, + SPA_N_ELEMENTS(this->props.pos), &this->props.channels); + } else if (spa_streq(k, SPA_KEY_AUDIO_LAYOUT)) { + spa_audio_parse_layout(s, this->props.pos, + SPA_N_ELEMENTS(this->props.pos), &this->props.channels); } else if (spa_streq(k, "clock.name")) { spa_scnprintf(this->props.clock_name, sizeof(this->props.clock_name),
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/v4l2/v4l2-utils.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
@@ -1486,7 +1486,7 @@ spa_pod_builder_push_object(&b.b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); spa_pod_builder_add(&b.b, SPA_PROP_INFO_id, SPA_POD_Id(prop_id), - SPA_PROP_INFO_type, SPA_POD_CHOICE_ENUM_Int(1, (int32_t)queryctrl.default_value), + SPA_PROP_INFO_type, SPA_POD_Int((int32_t)queryctrl.default_value), SPA_PROP_INFO_description, SPA_POD_String(queryctrl.name), 0);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/videoconvert/videoadapter.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/videoconvert/videoadapter.c
Changed
@@ -900,6 +900,7 @@ switch (id) { case SPA_IO_Position: this->io_position = data; + this->recheck_format = true; break; default: break;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/spa/plugins/volume/volume.c -> _service:download_files:pipewire-1.5.83.tar.bz2/spa/plugins/volume/volume.c
Changed
@@ -454,8 +454,7 @@ return -EINVAL; if (info.info.raw.format != SPA_AUDIO_FORMAT_S16 || - info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + info.info.raw.channels == 0) return -EINVAL; this->bpf = 2 * info.info.raw.channels;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/daemon/pipewire-pulse.conf.in -> _service:download_files:pipewire-1.5.83.tar.bz2/src/daemon/pipewire-pulse.conf.in
Changed
@@ -109,12 +109,12 @@ #server.dbus-name = "org.pulseaudio.Server" #pulse.allow-module-loading = true - #pulse.min.req = 128/48000 # 2.7ms + #pulse.min.req = 256/48000 # 5.3ms #pulse.default.req = 960/48000 # 20 milliseconds - #pulse.min.frag = 128/48000 # 2.7ms + #pulse.min.frag = 256/48000 # 5.3ms #pulse.default.frag = 96000/48000 # 2 seconds #pulse.default.tlength = 96000/48000 # 2 seconds - #pulse.min.quantum = 128/48000 # 2.7ms + #pulse.min.quantum = 256/48000 # 5.3ms #pulse.idle.timeout = 0 # don't pause after underruns #pulse.default.format = F32 #pulse.default.position = FL FR
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/examples/export-source.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/examples/export-source.c
Changed
@@ -268,8 +268,7 @@ d->format.format != SPA_AUDIO_FORMAT_F32) return -EINVAL; if (d->format.rate == 0 || - d->format.channels == 0 || - d->format.channels > SPA_AUDIO_MAX_CHANNELS) + d->format.channels == 0) return -EINVAL; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/gst/gstpipewireclock.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/gst/gstpipewireclock.c
Changed
@@ -45,7 +45,7 @@ t.rate.denom == 0) return pclock->last_time; - result = gst_util_uint64_scale_int (t.ticks, GST_SECOND * t.rate.num, t.rate.denom); + result = gst_util_uint64_scale (t.ticks, GST_SECOND * t.rate.num, t.rate.denom); result += now - t.now; result += pclock->time_offset;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/gst/gstpipewireformat.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/gst/gstpipewireformat.c
Changed
@@ -649,7 +649,7 @@ static void set_default_channels (struct spa_pod_builder *b, uint32_t channels) { - uint32_t positionSPA_AUDIO_MAX_CHANNELS = {0}; + uint32_t position8 = {0}; gboolean ok = TRUE; switch (channels) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/gst/gstpipewiresrc.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/gst/gstpipewiresrc.c
Changed
@@ -769,7 +769,7 @@ GST_BUFFER_DTS (buf) = b->time - pwsrc->delay; } - if (pwsrc->is_video) { + if (pwsrc->media_type == SPA_MEDIA_TYPE_video) { if (pwsrc->video_info.fps_n) { GST_BUFFER_DURATION (buf) = gst_util_uint64_scale (GST_SECOND, pwsrc->video_info.fps_d, pwsrc->video_info.fps_n); @@ -912,7 +912,7 @@ * must handle the clock lost message in it's bus handler by pausing * the pipeline and then setting it back to playing. */ - if (current_state == GST_STATE_PLAYING && !pwsrc->is_video) + if (current_state == GST_STATE_PLAYING && pwsrc->media_type == SPA_MEDIA_TYPE_audio) gst_element_post_message (GST_ELEMENT_CAST (pwsrc), gst_message_new_clock_lost (GST_OBJECT_CAST (pwsrc), GST_CLOCK_CAST (pwsrc->stream->clock))); @@ -1265,7 +1265,7 @@ if (param == NULL) { GST_DEBUG_OBJECT (pwsrc, "clear format"); pwsrc->negotiated = FALSE; - pwsrc->is_video = FALSE; + pwsrc->media_type = SPA_MEDIA_TYPE_unknown; return; } @@ -1303,7 +1303,7 @@ structure = gst_caps_get_structure (pwsrc->caps, 0); if (g_str_has_prefix (gst_structure_get_name (structure), "video/") || g_str_has_prefix (gst_structure_get_name (structure), "image/")) { - pwsrc->is_video = TRUE; + pwsrc->media_type = SPA_MEDIA_TYPE_video; #ifdef HAVE_GSTREAMER_DMA_DRM if (gst_video_is_dma_drm_caps (pwsrc->caps)) { @@ -1342,10 +1342,12 @@ * application/user */ if (pwsrc->use_bufferpool != USE_BUFFERPOOL_YES) pwsrc->use_bufferpool = USE_BUFFERPOOL_NO; + + pwsrc->media_type = SPA_MEDIA_TYPE_audio; } } else { pwsrc->negotiated = FALSE; - pwsrc->is_video = FALSE; + pwsrc->media_type = SPA_MEDIA_TYPE_unknown; pwsrc->is_rawvideo = FALSE; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/gst/gstpipewiresrc.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/gst/gstpipewiresrc.h
Changed
@@ -15,6 +15,7 @@ #include <gst/video/video.h> #include <pipewire/pipewire.h> +#include <spa/param/format.h> #include <gst/gstpipewirepool.h> #include <gst/gstpipewirecore.h> @@ -63,7 +64,7 @@ GstCaps *caps; GstCaps *possible_caps; - gboolean is_video; + enum spa_media_type media_type; gboolean is_rawvideo; GstVideoInfo video_info; #ifdef HAVE_GSTREAMER_DMA_DRM
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-avb/stream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-avb/stream.c
Changed
@@ -484,7 +484,7 @@ pw_log_warn("short packet received (%d < %d)", len, (int)sizeof(struct avb_packet_header)); } else { - struct avb_frame_header *h = (void*)buffer; + struct avb_ethernet_header *h = (void*)buffer; struct avb_packet_iec61883 *p = SPA_PTROFF(h, sizeof(*h), void); if (memcmp(h->dest, stream->addr, 6) != 0 ||
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-combine-stream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-combine-stream.c
Changed
@@ -64,6 +64,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -76,9 +77,10 @@ * ## Stream options * * - `audio.position`: Set the stream channel map. By default this is the same channel - * map as the combine stream. + * map as the combine stream. You can also use audio.layout * - `combine.audio.position`: map the combine audio positions to the stream positions. * combine input channels are mapped one-by-one to stream output channels. + * You can also use combine.audio.layout. * * ## Example configuration * @@ -231,9 +233,9 @@ "( stream.props=<properties> ) " \ "( stream.rules=<properties> ) " +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define DELAYBUF_MAX_SIZE (20 * sizeof(float) * 96000) - static const struct spa_dict_item module_props = { { PW_KEY_MODULE_AUTHOR, "Wim Taymans <wim.taymans@gmail.com>" }, { PW_KEY_MODULE_DESCRIPTION, "Combine multiple streams into a single stream" }, @@ -312,10 +314,10 @@ struct spa_latency_info latency; struct spa_audio_info_raw info; - uint32_t remapSPA_AUDIO_MAX_CHANNELS; + uint32_t remapMAX_CHANNELS; void *delaybuf; - struct ringbuffer delaySPA_AUDIO_MAX_CHANNELS; + struct ringbuffer delayMAX_CHANNELS; int64_t delay_samples; /* for main loop */ int64_t data_delay_samples; /* for data loop */ @@ -326,14 +328,15 @@ unsigned int have_latency:1; }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P"), SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -509,7 +512,7 @@ struct replace_delay_info { struct stream *stream; void *buf; - struct ringbuffer delaySPA_AUDIO_MAX_CHANNELS; + struct ringbuffer delayMAX_CHANNELS; }; static int do_replace_delay(struct spa_loop *loop, bool async, uint32_t seq, @@ -866,13 +869,21 @@ s->info = impl->info; if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) - spa_audio_parse_position(str, strlen(str), s->info.position, &s->info.channels); + spa_audio_parse_position_n(str, strlen(str), s->info.position, + SPA_N_ELEMENTS(s->info.position), &s->info.channels); + if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) + spa_audio_parse_layout(str, s->info.position, + SPA_N_ELEMENTS(s->info.position), &s->info.channels); if (s->info.channels == 0) s->info = impl->info; spa_zero(remap_info); if ((str = pw_properties_get(info->stream_props, "combine.audio.position")) != NULL) - spa_audio_parse_position(str, strlen(str), remap_info.position, &remap_info.channels); + spa_audio_parse_position_n(str, strlen(str), remap_info.position, + SPA_N_ELEMENTS(remap_info.position), &remap_info.channels); + if ((str = pw_properties_get(info->stream_props, "combine.audio.layout")) != NULL) + spa_audio_parse_layout(str, remap_info.position, + SPA_N_ELEMENTS(remap_info.position), &remap_info.channels); if (remap_info.channels == 0) remap_info = s->info; @@ -880,7 +891,10 @@ for (i = 0; i < remap_info.channels; i++) { s->remapi = i; for (j = 0; j < tmp_info.channels; j++) { - if (tmp_info.positionj == remap_info.positioni) { + uint32_t pj, pi; + pj = tmp_info.positionj; + pi = remap_info.positioni; + if (pj == pi) { s->remapi = j; break; } @@ -1228,7 +1242,7 @@ struct pw_buffer *in, *out; struct stream *s; bool delay_changed = false; - bool mixSPA_AUDIO_MAX_CHANNELS; + bool mixMAX_CHANNELS; if ((out = pw_stream_dequeue_buffer(impl->combine)) == NULL) { pw_log_debug("%p: out of output buffers: %m", impl); @@ -1622,6 +1636,7 @@ copy_props(props, impl->combine_props, PW_KEY_NODE_LOOP_NAME); copy_props(props, impl->combine_props, PW_KEY_AUDIO_CHANNELS); + copy_props(props, impl->combine_props, SPA_KEY_AUDIO_LAYOUT); copy_props(props, impl->combine_props, SPA_KEY_AUDIO_POSITION); copy_props(props, impl->combine_props, PW_KEY_NODE_NAME); copy_props(props, impl->combine_props, PW_KEY_NODE_DESCRIPTION); @@ -1633,7 +1648,10 @@ copy_props(props, impl->combine_props, "resample.prefill"); copy_props(props, impl->combine_props, "resample.disable"); - parse_audio_info(impl->combine_props, &impl->info); + if ((res = parse_audio_info(impl->combine_props, &impl->info)) < 0) { + pw_log_error( "can't create format: %s", spa_strerror(res)); + goto error; + } copy_props(props, impl->stream_props, PW_KEY_NODE_LOOP_NAME); copy_props(props, impl->stream_props, PW_KEY_NODE_GROUP);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-echo-cancel.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-echo-cancel.c
Changed
@@ -105,6 +105,7 @@ * * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_CLASS * - \ref PW_KEY_NODE_LATENCY @@ -154,6 +155,7 @@ #define DEFAULT_RATE 48000 #define DEFAULT_POSITION " FL FR " +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS /* Hopefully this is enough for any combination of AEC engine and resampler * input requirement for rate matching */ @@ -203,7 +205,7 @@ struct spa_hook source_listener; struct spa_audio_info_raw source_info; - void *rec_bufferSPA_AUDIO_MAX_CHANNELS; + void *rec_bufferMAX_CHANNELS; uint32_t rec_ringsize; struct spa_ringbuffer rec_ring; @@ -215,21 +217,23 @@ struct pw_properties *sink_props; struct pw_stream *sink; struct spa_hook sink_listener; - void *play_bufferSPA_AUDIO_MAX_CHANNELS; + void *play_bufferMAX_CHANNELS; uint32_t play_ringsize; struct spa_ringbuffer play_ring; struct spa_ringbuffer play_delayed_ring; struct spa_audio_info_raw sink_info; - void *out_bufferSPA_AUDIO_MAX_CHANNELS; + void *out_bufferMAX_CHANNELS; uint32_t out_ringsize; struct spa_ringbuffer out_ring; struct spa_audio_aec *aec; uint32_t aec_blocksize; - unsigned int capture_ready:1; - unsigned int sink_ready:1; + struct spa_io_position *capture_position; + struct spa_io_position *sink_position; + uint32_t capture_cycle; + uint32_t sink_cycle; unsigned int do_disconnect:1; @@ -306,13 +310,24 @@ const float *play_delayedimpl->play_info.channels; float *outimpl->out_info.channels; struct spa_data *dd; - uint32_t i, size; - uint32_t rindex, pindex, oindex, pdindex, avail; + uint32_t i; + uint32_t rindex, pindex, oindex, pdindex, size; + int32_t avail, pavail, pdavail; size = impl->aec_blocksize; - /* First read a block from the playback and capture ring buffers */ - spa_ringbuffer_get_read_index(&impl->rec_ring, &rindex); + /* First read a block from the capture ring buffer */ + avail = spa_ringbuffer_get_read_index(&impl->rec_ring, &rindex); + while (avail >= (int32_t)size * 2) { + /* drop samples that are not needed this or next cycle. Note + * that samples are kept in the ringbuffer until next cycle if + * size is not equal to or divisible by quantum, to avoid + * discontinuity */ + pw_log_debug("avail %d", avail); + spa_ringbuffer_read_update(&impl->rec_ring, rindex + size); + avail = spa_ringbuffer_get_read_index(&impl->rec_ring, &rindex); + pw_log_debug("new avail %d, size %u", avail, size); + } for (i = 0; i < impl->rec_info.channels; i++) { /* captured samples, with echo from sink */ @@ -330,19 +345,34 @@ outi = &out_bufi0; } - spa_ringbuffer_get_read_index(&impl->play_ring, &pindex); - spa_ringbuffer_get_read_index(&impl->play_delayed_ring, &pdindex); + pavail = spa_ringbuffer_get_read_index(&impl->play_ring, &pindex); + pdavail = spa_ringbuffer_get_read_index(&impl->play_delayed_ring, &pdindex); if (impl->playback != NULL && (pout = pw_stream_dequeue_buffer(impl->playback)) == NULL) { pw_log_debug("out of playback buffers: %m"); /* playback stream may not yet be in streaming state, drop play * data to avoid introducing additional playback latency */ - spa_ringbuffer_read_update(&impl->play_ring, pindex + size); - spa_ringbuffer_read_update(&impl->play_delayed_ring, pdindex + size); + spa_ringbuffer_read_update(&impl->play_ring, pindex + pavail); + spa_ringbuffer_read_update(&impl->play_delayed_ring, pdindex + pdavail); goto done; } + if (pavail > avail) { + /* drop too old samples from previous graph cycles */ + pw_log_debug("pavail %d, dropping %d", pavail, pavail - avail); + spa_ringbuffer_read_update(&impl->play_ring, pindex + pavail - avail); + pavail = spa_ringbuffer_get_read_index(&impl->play_ring, &pindex); + pw_log_debug("new pavail %d, avail %d", pavail, avail); + } + if (pdavail > avail) { + /* drop too old samples from previous graph cycles */ + pw_log_debug("pdavail %d, dropping %d", pdavail, pdavail - avail); + spa_ringbuffer_read_update(&impl->play_delayed_ring, pdindex + pdavail - avail); + pdavail = spa_ringbuffer_get_read_index(&impl->play_delayed_ring, &pdindex); + pw_log_debug("new pdavail %d, avail %d", pdavail, avail); + } + for (i = 0; i < impl->play_info.channels; i++) { /* echo from sink */ playi = &play_bufi0; @@ -430,32 +460,31 @@ * available on the source */ avail = spa_ringbuffer_get_read_index(&impl->out_ring, &oindex); - while (avail >= size) { - if ((cout = pw_stream_dequeue_buffer(impl->source)) == NULL) { + while (avail >= (int32_t)size) { + if ((cout = pw_stream_dequeue_buffer(impl->source)) != NULL) { + for (i = 0; i < impl->out_info.channels; i++) { + dd = &cout->buffer->datasi; + spa_ringbuffer_read_data(&impl->out_ring, impl->out_bufferi, + impl->out_ringsize, oindex % impl->out_ringsize, + (void *)dd->data, size); + dd->chunk->offset = 0; + dd->chunk->size = size; + dd->chunk->stride = sizeof(float); + } + pw_stream_queue_buffer(impl->source, cout); + } else { + /* drop data as to not cause delay */ pw_log_debug("out of source buffers: %m"); - break; - } - - for (i = 0; i < impl->out_info.channels; i++) { - dd = &cout->buffer->datasi; - spa_ringbuffer_read_data(&impl->out_ring, impl->out_bufferi, - impl->out_ringsize, oindex % impl->out_ringsize, - (void *)dd->data, size); - dd->chunk->offset = 0; - dd->chunk->size = size; - dd->chunk->stride = sizeof(float); } - pw_stream_queue_buffer(impl->source, cout); - oindex += size; spa_ringbuffer_read_update(&impl->out_ring, oindex); avail -= size; } done: - impl->sink_ready = false; - impl->capture_ready = false; + impl->capture_cycle = 0; + impl->sink_cycle = 0; } static void reset_buffers(struct impl *impl) @@ -479,8 +508,8 @@ spa_ringbuffer_get_read_index(&impl->play_ring, &index); spa_ringbuffer_read_update(&impl->play_ring, index + (sizeof(float) * (impl->buffer_delay))); - impl->sink_ready = false; - impl->capture_ready = false; + impl->capture_cycle = 0; + impl->sink_cycle = 0; } static void capture_destroy(void *d) @@ -546,8 +575,11 @@ spa_ringbuffer_write_update(&impl->rec_ring, index + size); if (avail + size >= impl->aec_blocksize) { - impl->capture_ready = true; - if (impl->sink_ready) + if (impl->capture_position) + impl->capture_cycle = impl->capture_position->clock.cycle; + else + pw_log_warn("no capture position"); + if (impl->capture_cycle == impl->sink_cycle) process(impl); } @@ -740,12 +772,26 @@ } } +static void capture_io_changed(void *data, uint32_t id, void *area, uint32_t size)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-example-filter.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-example-filter.c
Changed
@@ -46,6 +46,7 @@ * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -298,8 +299,7 @@ if (spa_format_audio_raw_parse(param, &info) < 0) return; if (info.rate == 0 || - info.channels == 0 || - info.channels > SPA_AUDIO_MAX_CHANNELS) + info.channels == 0) return; break; } @@ -468,15 +468,16 @@ .destroy = module_destroy, }; -static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P"), SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -549,6 +550,7 @@ copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); @@ -574,8 +576,11 @@ if (pw_properties_get(impl->playback_props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(impl->playback_props, PW_KEY_NODE_DESCRIPTION, str); - parse_audio_info(impl->capture_props, &impl->capture_info); - parse_audio_info(impl->playback_props, &impl->playback_info); + if ((res = parse_audio_info(impl->capture_props, &impl->capture_info)) < 0 || + (res = parse_audio_info(impl->playback_props, &impl->playback_info)) < 0) { + pw_log_error( "can't parse formats: %s", spa_strerror(res)); + goto error; + } if (!impl->capture_info.rate && !impl->playback_info.rate) { if (pw_properties_get(impl->playback_props, "resample.disable") == NULL)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-example-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-example-sink.c
Changed
@@ -52,6 +52,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -273,9 +274,9 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -284,6 +285,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -387,6 +389,7 @@ copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); @@ -395,7 +398,10 @@ copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS); - parse_audio_info(impl->stream_props, &impl->info); + if ((res = parse_audio_info(impl->stream_props, &impl->info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } impl->frame_size = calc_frame_size(&impl->info); if (impl->frame_size == 0) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-example-source.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-example-source.c
Changed
@@ -52,6 +52,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -279,9 +280,9 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -290,6 +291,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -393,6 +395,7 @@ copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); @@ -401,7 +404,10 @@ copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_MEDIA_CLASS); - parse_audio_info(impl->stream_props, &impl->info); + if ((res = parse_audio_info(impl->stream_props, &impl->info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } impl->frame_size = calc_frame_size(&impl->info); if (impl->frame_size == 0) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-ffado-driver.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-ffado-driver.c
Changed
@@ -66,6 +66,7 @@ * Options with well-known behavior. * * - \ref PW_KEY_REMOTE_NAME + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -112,6 +113,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define MAX_PORTS 128 #define FFADO_RT_PRIORITY_PACKETIZER_RELATIVE 5 @@ -179,7 +181,7 @@ struct volume { bool mute; uint32_t n_volumes; - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; }; struct stream { @@ -760,7 +762,7 @@ struct port *port = s->portsi; char channel32; - snprintf(channel, sizeof(channel), "AUX%u", n_channels % SPA_AUDIO_MAX_CHANNELS); + snprintf(channel, sizeof(channel), "AUX%u", n_channels); switch (port->stream_type) { case ffado_stream_type_audio: @@ -873,9 +875,9 @@ case SPA_PROP_channelVolumes: { uint32_t n; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { s->volume.n_volumes = n; for (n = 0; n < s->volume.n_volumes; n++) s->volume.volumesn = volsn; @@ -1227,8 +1229,9 @@ impl->source.portsi = port; } if (impl->source.info.channels != n_channels) { - impl->source.info.channels = n_channels; - for (i = 0; i < SPA_MIN(impl->source.info.channels, SPA_AUDIO_MAX_CHANNELS); i++) + uint32_t n_pos = SPA_MIN(n_channels, SPA_N_ELEMENTS(impl->source.info.position)); + impl->source.info.channels = n_pos; + for (i = 0; i < n_pos; i++) impl->source.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } @@ -1253,8 +1256,9 @@ impl->sink.portsi = port; } if (impl->sink.info.channels != n_channels) { - impl->sink.info.channels = n_channels; - for (i = 0; i < SPA_MIN(impl->sink.info.channels, SPA_AUDIO_MAX_CHANNELS); i++) + uint32_t n_pos = SPA_MIN(n_channels, SPA_N_ELEMENTS(impl->sink.info.position)); + impl->sink.info.channels = n_pos; + for (i = 0; i < n_pos; i++) impl->sink.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } @@ -1426,14 +1430,15 @@ } } -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P"), SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1579,8 +1584,11 @@ copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, PW_KEY_NODE_PAUSE_ON_IDLE); - parse_audio_info(impl->source.props, &impl->source.info); - parse_audio_info(impl->sink.props, &impl->sink.info); + if ((res = parse_audio_info(impl->source.props, &impl->source.info)) < 0 || + (res = parse_audio_info(impl->sink.props, &impl->sink.info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } impl->core = pw_context_get_object(impl->context, PW_TYPE_INTERFACE_Core); if (impl->core == NULL) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-filter-chain.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-filter-chain.c
Changed
@@ -995,6 +995,7 @@ * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -1832,14 +1833,15 @@ .destroy = module_destroy, }; -static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1918,6 +1920,7 @@ copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); @@ -1927,8 +1930,11 @@ copy_props(impl, props, PW_KEY_MEDIA_NAME); copy_props(impl, props, "resample.prefill"); - parse_audio_info(impl->capture_props, &impl->capture_info); - parse_audio_info(impl->playback_props, &impl->playback_info); + if ((res = parse_audio_info(impl->capture_props, &impl->capture_info)) < 0 || + (res = parse_audio_info(impl->playback_props, &impl->playback_info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } if (!impl->capture_info.rate && !impl->playback_info.rate) { if (pw_properties_get(impl->playback_props, "resample.disable") == NULL)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-jack-tunnel.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-jack-tunnel.c
Changed
@@ -72,6 +72,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -115,6 +116,7 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define MAX_PORTS 128 #define DEFAULT_CLIENT_NAME "PipeWire" @@ -157,7 +159,7 @@ struct volume { bool mute; uint32_t n_volumes; - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; }; struct stream { @@ -513,6 +515,7 @@ for (i = 0; i < s->n_ports; i++) { struct port *port = s->portsi; char *link_port = NULL; + char pos8; if (port != NULL) { s->portsi = NULL; @@ -522,8 +525,8 @@ } if (i < s->info.channels) { - str = spa_debug_type_find_short_name(spa_type_audio_channel, - s->info.positioni); + str = spa_type_audio_channel_make_short_name( + s->info.positioni, pos, sizeof(pos), NULL); if (str) snprintf(name, sizeof(name), "%s_%s", prefix, str); else @@ -624,9 +627,9 @@ case SPA_PROP_channelVolumes: { uint32_t n; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { s->volume.n_volumes = n; for (n = 0; n < s->volume.n_volumes; n++) s->volume.volumesn = volsn; @@ -1050,14 +1053,15 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P"), SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1167,6 +1171,7 @@ pw_properties_update_string(impl->source.props, str, strlen(str)); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_ALWAYS_PROCESS); copy_props(impl, props, PW_KEY_NODE_GROUP); @@ -1175,8 +1180,11 @@ copy_props(impl, props, "jack.connect-audio"); copy_props(impl, props, "jack.connect-midi"); - parse_audio_info(impl->source.props, &impl->source.info); - parse_audio_info(impl->sink.props, &impl->sink.info); + if ((res = parse_audio_info(impl->source.props, &impl->source.info)) < 0 || + (res = parse_audio_info(impl->sink.props, &impl->sink.info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } impl->source.n_midi = pw_properties_get_uint32(impl->source.props, "midi.ports", DEFAULT_MIDI_PORTS);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-loopback.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-loopback.c
Changed
@@ -51,6 +51,7 @@ * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -538,8 +539,7 @@ spa_zero(info); if (param != NULL) { if (spa_format_audio_raw_parse(param, &info) < 0 || - info.channels == 0 || - info.channels > SPA_AUDIO_MAX_CHANNELS) + info.channels == 0) return; if ((impl->info.format != 0 && impl->info.format != info.format) || @@ -839,14 +839,15 @@ .destroy = module_destroy, }; -static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -928,6 +929,7 @@ copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); @@ -953,9 +955,12 @@ if (pw_properties_get(impl->playback_props, PW_KEY_NODE_DESCRIPTION) == NULL) pw_properties_set(impl->playback_props, PW_KEY_NODE_DESCRIPTION, str); - parse_audio_info(props, &impl->info); - parse_audio_info(impl->capture_props, &impl->capture_info); - parse_audio_info(impl->playback_props, &impl->playback_info); + if ((res = parse_audio_info(props, &impl->info)) < 0 || + (res = parse_audio_info(impl->capture_props, &impl->capture_info)) < 0 || + (res = parse_audio_info(impl->playback_props, &impl->playback_info)) < 0) { + pw_log_error( "can't parse formats: %s", spa_strerror(res)); + goto error; + } if (!impl->capture_info.rate && !impl->playback_info.rate) { if (pw_properties_get(impl->playback_props, "resample.disable") == NULL)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-netjack2-driver.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-netjack2-driver.c
Changed
@@ -99,6 +99,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -441,11 +442,11 @@ } if (i < s->info.channels) { - str = spa_debug_type_find_short_name(spa_type_audio_channel, - s->info.positioni % SPA_AUDIO_MAX_CHANNELS); + str = spa_type_audio_channel_make_short_name( + s->info.positioni, name, sizeof(name), "UNK"); props = pw_properties_new( PW_KEY_FORMAT_DSP, "32 bit float mono audio", - PW_KEY_AUDIO_CHANNEL, str ? str : "UNK", + PW_KEY_AUDIO_CHANNEL, str, PW_KEY_PORT_PHYSICAL, "true", NULL); @@ -512,9 +513,9 @@ case SPA_PROP_channelVolumes: { uint32_t n; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { s->volume.n_volumes = n; for (n = 0; n < s->volume.n_volumes; n++) s->volume.volumesn = volsn; @@ -863,7 +864,7 @@ } impl->sink.info.rate = peer->params.sample_rate; if ((uint32_t)peer->params.send_audio_channels != impl->sink.info.channels) { - impl->sink.info.channels = SPA_MIN(peer->params.send_audio_channels, (int)SPA_AUDIO_MAX_CHANNELS); + impl->sink.info.channels = peer->params.send_audio_channels; for (i = 0; i < impl->sink.info.channels; i++) impl->sink.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } @@ -874,7 +875,7 @@ } impl->source.info.rate = peer->params.sample_rate; if ((uint32_t)peer->params.recv_audio_channels != impl->source.info.channels) { - impl->source.info.channels = SPA_MIN(peer->params.recv_audio_channels, (int)SPA_AUDIO_MAX_CHANNELS); + impl->source.info.channels = peer->params.recv_audio_channels; for (i = 0; i < impl->source.info.channels; i++) impl->source.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } @@ -1218,13 +1219,14 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1329,6 +1331,7 @@ copy_props(impl, props, PW_KEY_NODE_LOOP_NAME); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_ALWAYS_PROCESS); copy_props(impl, props, PW_KEY_NODE_GROUP); @@ -1336,8 +1339,11 @@ copy_props(impl, props, "midi.ports"); copy_props(impl, props, "audio.ports"); - parse_audio_info(impl->source.props, &impl->source.info); - parse_audio_info(impl->sink.props, &impl->sink.info); + if ((res = parse_audio_info(impl->source.props, &impl->source.info)) < 0 || + (res = parse_audio_info(impl->sink.props, &impl->sink.info)) < 0) { + pw_log_error( "can't parse format: %s", spa_strerror(res)); + goto error; + } impl->source.wanted_n_midi = pw_properties_get_int32(impl->source.props, "midi.ports", DEFAULT_MIDI_PORTS);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-netjack2-manager.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-netjack2-manager.c
Changed
@@ -94,6 +94,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -181,7 +182,7 @@ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info); +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info); struct port { enum spa_direction direction; @@ -601,12 +602,11 @@ } if (i < s->info.channels) { - str = spa_debug_type_find_short_name(spa_type_audio_channel, - s->info.positioni); - + str = spa_type_audio_channel_make_short_name( + s->info.positioni, name, sizeof(name), "UNK"); props = pw_properties_new( PW_KEY_FORMAT_DSP, "32 bit float mono audio", - PW_KEY_AUDIO_CHANNEL, str ? str : "UNK", + PW_KEY_AUDIO_CHANNEL, str, PW_KEY_PORT_PHYSICAL, "true", NULL); @@ -677,9 +677,9 @@ case SPA_PROP_channelVolumes: { uint32_t n; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { s->volume.n_volumes = n; for (n = 0; n < s->volume.n_volumes; n++) s->volume.volumesn = volsn; @@ -969,8 +969,11 @@ follower->sink.direction = PW_DIRECTION_INPUT; follower->sink.props = pw_properties_copy(impl->sink_props); - parse_audio_info(follower->source.props, &follower->source.info); - parse_audio_info(follower->sink.props, &follower->sink.info); + if ((res = parse_audio_info(follower->source.props, &follower->source.info)) < 0 || + (res = parse_audio_info(follower->sink.props, &follower->sink.info)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + return res; + } follower->source.n_audio = pw_properties_get_uint32(follower->source.props, "audio.ports", follower->source.info.channels ? @@ -1026,14 +1029,14 @@ follower->source.n_ports = peer->params.recv_audio_channels + peer->params.recv_midi_channels; follower->source.info.rate = peer->params.sample_rate; if ((uint32_t)peer->params.recv_audio_channels != follower->source.info.channels) { - follower->source.info.channels = SPA_MIN(peer->params.recv_audio_channels, (int)SPA_AUDIO_MAX_CHANNELS); + follower->source.info.channels = peer->params.recv_audio_channels; for (i = 0; i < follower->source.info.channels; i++) follower->source.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } follower->sink.n_ports = peer->params.send_audio_channels + peer->params.send_midi_channels; follower->sink.info.rate = peer->params.sample_rate; if ((uint32_t)peer->params.send_audio_channels != follower->sink.info.channels) { - follower->sink.info.channels = SPA_MIN(peer->params.send_audio_channels, (int)SPA_AUDIO_MAX_CHANNELS); + follower->sink.info.channels = peer->params.send_audio_channels; for (i = 0; i < follower->sink.info.channels; i++) follower->sink.info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; } @@ -1290,13 +1293,14 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1415,6 +1419,7 @@ copy_props(impl, props, PW_KEY_NODE_LOCK_QUANTUM); copy_props(impl, props, PW_KEY_NODE_LOCK_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, "audio.ports"); copy_props(impl, props, "midi.ports");
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-netjack2/peer.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-netjack2/peer.c
Changed
@@ -7,10 +7,12 @@ #include <opus/opus_custom.h> #endif +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + struct volume { bool mute; uint32_t n_volumes; - float volumesSPA_AUDIO_MAX_CHANNELS; + float volumesMAX_CHANNELS; }; static inline float bswap_f32(float f)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-parametric-equalizer.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-parametric-equalizer.c
Changed
@@ -70,6 +70,7 @@ * Options with well-known behaviour: * * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_REMOTE_NAME *
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-pipe-tunnel.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-pipe-tunnel.c
Changed
@@ -79,6 +79,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_NAME @@ -745,9 +746,9 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -756,6 +757,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -886,6 +888,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); @@ -896,7 +899,10 @@ copy_props(impl, props, PW_KEY_TARGET_OBJECT); copy_props(impl, props, "pipe.filename"); - parse_audio_info(impl->stream_props, &impl->info); + if ((res = parse_audio_info(impl->stream_props, &impl->info)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + goto error; + } impl->frame_size = calc_frame_size(&impl->info); if (impl->frame_size == 0) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse.c
Changed
@@ -67,12 +67,12 @@ * * #server.dbus-name = "org.pulseaudio.Server" * #pulse.allow-module-loading = true - * #pulse.min.req = 128/48000 # 2.7ms + * #pulse.min.req = 256/48000 # 5.3ms * #pulse.default.req = 960/48000 # 20 milliseconds - * #pulse.min.frag = 128/48000 # 2.7ms + * #pulse.min.frag = 256/48000 # 5.3ms * #pulse.default.frag = 96000/48000 # 2 seconds * #pulse.default.tlength = 96000/48000 # 2 seconds - * #pulse.min.quantum = 128/48000 # 2.7ms + * #pulse.min.quantum = 256/48000 # 5.3ms * #pulse.default.format = F32 * #pulse.default.position = FL FR * #pulse.idle.timeout = 0 @@ -140,7 +140,7 @@ * ### Playback buffering options * *\code{.unparsed} - * pulse.min.req = 128/48000 # 2.7ms + * pulse.min.req = 256/48000 # 5.3ms *\endcode * * The minimum amount of data to request for clients. The client requested @@ -166,7 +166,7 @@ * ### Record buffering options * *\code{.unparsed} - * pulse.min.frag = 128/48000 # 2.7ms + * pulse.min.frag = 256/48000 # 5.3ms *\endcode * * The minimum allowed size of the capture buffer before it is sent to a client. @@ -184,7 +184,7 @@ * ### Scheduling options * *\code{.unparsed} - * pulse.min.quantum = 128/48000 # 2.7ms + * pulse.min.quantum = 256/48000 # 5.3ms *\endcode * * The minimum quantum (buffer size in samples) to use for pulseaudio clients.
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/collect.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/collect.c
Changed
@@ -169,7 +169,7 @@ SPA_PARAM_PROFILE_description, SPA_POD_OPT_String(&pi->description), SPA_PARAM_PROFILE_priority, SPA_POD_OPT_Int(&pi->priority), SPA_PARAM_PROFILE_available, SPA_POD_OPT_Id(&pi->available), - SPA_PARAM_PROFILE_classes, SPA_POD_OPT_Pod(&classes)) < 0) { + SPA_PARAM_PROFILE_classes, SPA_POD_OPT_PodStruct(&classes)) < 0) { continue; } if (pi->description == NULL) @@ -233,6 +233,7 @@ struct device_info *dev_info, bool monitor, struct defs *defs) { struct pw_manager_param *p; + dev_info->active_port_name = NULL; if (card) { spa_list_for_each(p, &card->param_list, link) { @@ -246,7 +247,7 @@ SPA_TYPE_OBJECT_ParamRoute, NULL, SPA_PARAM_ROUTE_index, SPA_POD_Int(&index), SPA_PARAM_ROUTE_device, SPA_POD_Int(&dev), - SPA_PARAM_ROUTE_props, SPA_POD_OPT_Pod(&props)) < 0) + SPA_PARAM_ROUTE_props, SPA_POD_OPT_PodObject(&props)) < 0) continue; if (dev != dev_info->device) continue; @@ -256,6 +257,30 @@ dev_info->have_volume = true; } } + + /* Look up the port name for the active port */ + if (dev_info->active_port != SPA_ID_INVALID) { + spa_list_for_each(p, &card->param_list, link) { + uint32_t index, direction; + const char *name = NULL; + + if (p->id != SPA_PARAM_EnumRoute) + continue; + + if (spa_pod_parse_object(p->param, + SPA_TYPE_OBJECT_ParamRoute, NULL, + SPA_PARAM_ROUTE_index, SPA_POD_Int(&index), + SPA_PARAM_ROUTE_direction, SPA_POD_Id(&direction), + SPA_PARAM_ROUTE_name, SPA_POD_String(&name)) < 0) + continue; + + if (index == dev_info->active_port && + direction == dev_info->direction) { + dev_info->active_port_name = name; + break; + } + } + } } spa_list_for_each(p, &device->param_list, link) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/format.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/format.c
Changed
@@ -12,6 +12,8 @@ #include "format.h" +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + static const struct format audio_formats = { SAMPLE_U8 = { SAMPLE_U8, SPA_AUDIO_FORMAT_U8, "u8", 1 }, SAMPLE_ALAW = { SAMPLE_ALAW, SPA_AUDIO_FORMAT_ALAW, "alaw", 1 }, @@ -296,9 +298,9 @@ return audio_channelschannel.channel; } -const char *channel_id2name(uint32_t channel) +const char *channel_id2name(uint32_t channel, char *buf, size_t size) { - return spa_type_audio_channel_to_short_name(channel); + return spa_type_audio_channel_make_short_name(channel, buf, size, "UNK"); } uint32_t channel_name2id(const char *name) @@ -346,9 +348,9 @@ } -void channel_map_to_positions(const struct channel_map *map, uint32_t *pos) +void channel_map_to_positions(const struct channel_map *map, uint32_t *pos, uint32_t max_pos) { - uint32_t i, channels = SPA_MIN(map->channels, SPA_AUDIO_MAX_CHANNELS); + uint32_t i, channels = SPA_MIN(map->channels, max_pos); for (i = 0; i < channels; i++) posi = map->mapi; } @@ -448,8 +450,9 @@ void channel_map_parse_position(const char *str, struct channel_map *map) { - uint32_t channels = 0, positionSPA_AUDIO_MAX_CHANNELS; - spa_audio_parse_position(str, strlen(str), position, &channels); + uint32_t channels = 0, positionCHANNELS_MAX; + spa_audio_parse_position_n(str, strlen(str), position, + SPA_N_ELEMENTS(position), &channels); positions_to_channel_map(position, channels, map); } @@ -532,8 +535,7 @@ info.info.raw.rate = 48000; if (info.info.raw.format == 0 || info.info.raw.rate == 0 || - info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + info.info.raw.channels == 0) return -ENOTSUP; } break; @@ -631,8 +633,8 @@ SPA_FORMAT_AUDIO_channels, SPA_POD_Int(spec->channels), 0); if (map && map->channels == spec->channels) { - uint32_t positionsSPA_AUDIO_MAX_CHANNELS; - channel_map_to_positions(map, positions); + uint32_t positionsspec->channels; + channel_map_to_positions(map, positions, spec->channels); spa_pod_builder_add(b, SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, spec->channels, positions), 0);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/format.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/format.h
Changed
@@ -190,13 +190,13 @@ struct spa_dict *props); uint32_t channel_pa2id(enum channel_position channel); -const char *channel_id2name(uint32_t channel); +const char *channel_id2name(uint32_t channel, char *buf, size_t size); uint32_t channel_name2id(const char *name); enum channel_position channel_id2pa(uint32_t id, uint32_t *aux); const char *channel_id2paname(uint32_t id, uint32_t *aux); uint32_t channel_paname2id(const char *name, size_t size); -void channel_map_to_positions(const struct channel_map *map, uint32_t *pos); +void channel_map_to_positions(const struct channel_map *map, uint32_t *pos, uint32_t max_pos); void channel_map_parse(const char *str, struct channel_map *map); bool channel_map_valid(const struct channel_map *map); void channel_map_parse_position(const char *str, struct channel_map *map);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/message.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/message.c
Changed
@@ -761,11 +761,13 @@ case TAG_CHANNEL_MAP: { struct channel_map map; + char pos8; if ((res = read_channel_map(m, &map)) < 0) return res; pw_log(level, "%s %u: channelmap: channels:%u", prefix, o, map.channels); for (i = 0; i < map.channels; i++) - pw_log(level, "%s %d: %s", prefix, i, channel_id2name(map.mapi)); + pw_log(level, "%s %d: %s", prefix, i, + channel_id2name(map.mapi, pos, sizeof(pos))); break; } case TAG_CVOLUME:
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/module.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/module.c
Changed
@@ -12,6 +12,7 @@ #include <spa/utils/list.h> #include <spa/utils/hook.h> #include <spa/utils/string.h> +#include <spa/param/audio/raw-utils.h> #include <pipewire/log.h> #include <pipewire/map.h> #include <pipewire/properties.h> @@ -226,14 +227,15 @@ info->channels, map.channels); return -EINVAL; } - channel_map_to_positions(&map, info->position); + channel_map_to_positions(&map, info->position, SPA_N_ELEMENTS(info->position)); pw_properties_set(props, key_channel_map, NULL); } else { if (info->channels == 0) info->channels = impl->defs.sample_spec.channels; if (info->channels == impl->defs.channel_map.channels) { - channel_map_to_positions(&impl->defs.channel_map, info->position); + channel_map_to_positions(&impl->defs.channel_map, + info->position, SPA_N_ELEMENTS(info->position)); } else if (info->channels == 1) { info->position0 = SPA_AUDIO_CHANNEL_MONO; } else if (info->channels == 2) { @@ -281,14 +283,14 @@ if (info->rate) pw_properties_setf(props, SPA_KEY_AUDIO_RATE, "%u", info->rate); if (info->channels) { - char *s, *p; + char *s, *p, pos8; pw_properties_setf(props, SPA_KEY_AUDIO_CHANNELS, "%u", info->channels); p = s = alloca(info->channels * 8); for (i = 0; i < info->channels; i++) p += spa_scnprintf(p, 8, "%s%s", i == 0 ? "" : ", ", - channel_id2name(info->positioni)); + channel_id2name(info->positioni, pos, sizeof(pos))); pw_properties_setf(props, SPA_KEY_AUDIO_POSITION, " %s ", s); } }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/modules/module-stream-restore.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/modules/module-stream-restore.c
Changed
@@ -295,9 +295,11 @@ fprintf(f, " "); } if (map.channels > 0) { + char pos8; fprintf(f, ", \"channels\": "); for (i = 0; i < map.channels; i++) - fprintf(f, "%s\"%s\"", (i == 0 ? " ":", "), channel_id2name(map.mapi)); + fprintf(f, "%s\"%s\"", (i == 0 ? " ":", "), + channel_id2name(map.mapi, pos, sizeof(pos))); fprintf(f, " "); } if (device_name != NULL && device_name0 &&
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/pulse-server.c
Changed
@@ -57,12 +57,12 @@ #include "volume.h" #define DEFAULT_ALLOW_MODULE_LOADING "true" -#define DEFAULT_MIN_REQ "128/48000" +#define DEFAULT_MIN_REQ "256/48000" #define DEFAULT_DEFAULT_REQ "960/48000" -#define DEFAULT_MIN_FRAG "128/48000" +#define DEFAULT_MIN_FRAG "256/48000" #define DEFAULT_DEFAULT_FRAG "96000/48000" #define DEFAULT_DEFAULT_TLENGTH "96000/48000" -#define DEFAULT_MIN_QUANTUM "128/48000" +#define DEFAULT_MIN_QUANTUM "256/48000" #define DEFAULT_FORMAT "F32" #define DEFAULT_POSITION " FL FR " #define DEFAULT_IDLE_TIMEOUT "0"
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-pulse/volume.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-pulse/volume.c
Changed
@@ -53,7 +53,7 @@ if (monitor) continue; info->volume.channels = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - info->volume.values, CHANNELS_MAX); + info->volume.values, SPA_N_ELEMENTS(info->volume.values)); SPA_FLAG_UPDATE(info->flags, VOLUME_HW_VOLUME, prop->flags & SPA_POD_PROP_FLAG_HARDWARE); break; @@ -68,7 +68,7 @@ if (!monitor) continue; info->volume.channels = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - info->volume.values, CHANNELS_MAX); + info->volume.values, SPA_N_ELEMENTS(info->volume.values)); SPA_FLAG_CLEAR(info->flags, VOLUME_HW_VOLUME); break; case SPA_PROP_volumeBase: @@ -84,7 +84,7 @@ } case SPA_PROP_channelMap: info->map.channels = spa_pod_copy_array(&prop->value, SPA_TYPE_Id, - info->map.map, CHANNELS_MAX); + info->map.map, SPA_N_ELEMENTS(info->map.map)); break; default: break;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-protocol-simple.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-protocol-simple.c
Changed
@@ -72,6 +72,7 @@ * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_RATE @@ -815,13 +816,14 @@ case SPA_AUDIO_FORMAT_F64_OE: return res * 8; default: - return 0; + return -ENOTSUP; } } static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + int res; + if ((res = spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -830,7 +832,9 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, - SPA_KEY_AUDIO_POSITION, NULL); + SPA_KEY_AUDIO_LAYOUT, + SPA_KEY_AUDIO_POSITION, NULL)) < 0) + return res; return calc_frame_size(info); } @@ -851,6 +855,7 @@ const char *str; struct spa_json it1; char value512; + int res; pw_properties_fetch_bool(impl->props, "capture", &impl->capture); pw_properties_fetch_bool(impl->props, "playback", &impl->playback); @@ -885,6 +890,7 @@ copy_props(impl, PW_KEY_AUDIO_FORMAT); copy_props(impl, PW_KEY_AUDIO_RATE); copy_props(impl, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, SPA_KEY_AUDIO_POSITION); copy_props(impl, PW_KEY_NODE_RATE); copy_props(impl, PW_KEY_NODE_NAME); @@ -894,19 +900,20 @@ copy_props(impl, PW_KEY_NODE_VIRTUAL); copy_props(impl, PW_KEY_NODE_NETWORK); - impl->capture_frame_size = parse_audio_info(impl->capture_props, &impl->capture_info); - if (impl->capture_frame_size == 0) { + if ((res = parse_audio_info(impl->capture_props, &impl->capture_info)) <= 0) { pw_log_error("unsupported capture audio format:%d channels:%d", impl->capture_info.format, impl->capture_info.channels); return -EINVAL; } + impl->capture_frame_size = res; - impl->playback_frame_size = parse_audio_info(impl->playback_props, &impl->playback_info); - if (impl->playback_frame_size == 0) { + if ((res = parse_audio_info(impl->playback_props, &impl->playback_info)) <= 0) { pw_log_error("unsupported playback audio format:%d channels:%d", impl->playback_info.format, impl->playback_info.channels); return -EINVAL; } + impl->playback_frame_size = res; + if (impl->capture_info.rate != 0 && pw_properties_get(impl->capture_props, PW_KEY_NODE_RATE) == NULL) pw_properties_setf(impl->capture_props, PW_KEY_NODE_RATE,
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-pulse-tunnel.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-pulse-tunnel.c
Changed
@@ -72,6 +72,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_NAME @@ -117,6 +118,8 @@ #define DEFAULT_CHANNELS 2 #define DEFAULT_POSITION " FL FR " +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + #define MODULE_USAGE "( remote.name=<remote> " \ "( node.latency=<latency as fraction> " \ "( node.name=<name of the nodes> " \ @@ -295,10 +298,10 @@ { struct pa_cvolume volume; uint32_t n; - float volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; if ((n = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { volume.channels = SPA_MIN(PA_CHANNELS_MAX, n); for (n = 0; n < volume.channels; n++) volume.valuesn = pa_sw_volume_from_linear(volsn); @@ -752,7 +755,8 @@ map.channels = impl->info.channels; for (i = 0; i < map.channels; i++) - map.mapi = (pa_channel_position_t)channel_id2pa(impl->info.positioni, &aux); + map.mapi = (pa_channel_position_t)channel_id2pa( + impl->info.positioni, &aux); snprintf(stream_name, sizeof(stream_name), _("Tunnel for %s@%s"), pw_get_user_name(), pw_get_host_name()); @@ -832,10 +836,10 @@ struct spa_pod_frame f1; struct spa_pod *param; uint32_t i, channels; - float volsSPA_AUDIO_MAX_CHANNELS; - float soft_volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS; + float soft_volsMAX_CHANNELS; - channels = SPA_MIN(impl->volume.channels, SPA_AUDIO_MAX_CHANNELS); + channels = SPA_MIN(impl->volume.channels, MAX_CHANNELS); for (i = 0; i < channels; i++) { volsi = (float)pa_sw_volume_to_linear(impl->volume.valuesi); soft_volsi = 1.0f; @@ -1045,9 +1049,9 @@ .destroy = module_destroy, }; -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -1056,6 +1060,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1180,6 +1185,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); @@ -1189,7 +1195,10 @@ copy_props(impl, props, PW_KEY_NODE_NETWORK); copy_props(impl, props, PW_KEY_MEDIA_CLASS); - parse_audio_info(impl->stream_props, &impl->info); + if ((res = parse_audio_info(impl->stream_props, &impl->info)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + goto error; + } impl->frame_size = calc_frame_size(&impl->info); if (impl->frame_size == 0) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-raop-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-raop-sink.c
Changed
@@ -82,6 +82,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -158,6 +159,7 @@ #define RAOP_LATENCY_MS 250 #define DEFAULT_LATENCY_MS 1500 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define VOLUME_MAX 0.0 #define VOLUME_MIN -30.0 #define VOLUME_MUTE -144.0 @@ -1612,11 +1614,11 @@ case SPA_PROP_channelVolumes: { uint32_t i, n_vols; - float volsSPA_AUDIO_MAX_CHANNELS, volume; - float soft_volsSPA_AUDIO_MAX_CHANNELS; + float volsMAX_CHANNELS, volume; + float soft_volsMAX_CHANNELS; if ((n_vols = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, - vols, SPA_AUDIO_MAX_CHANNELS)) > 0) { + vols, SPA_N_ELEMENTS(vols))) > 0) { volume = 0.0f; for (i = 0; i < n_vols; i++) { volume += volsi; @@ -1900,6 +1902,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_DEVICE_ICON_NAME); copy_props(impl, props, PW_KEY_NODE_NAME);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-roc-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-roc-sink.c
Changed
@@ -12,6 +12,7 @@ #include <spa/utils/hook.h> #include <spa/utils/result.h> #include <spa/param/audio/format-utils.h> +#include <spa/param/audio/raw-json.h> #include <roc/config.h> #include <roc/log.h> @@ -52,7 +53,10 @@ * * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION - * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_MEDIA_CLASS + * - \ref SPA_KEY_AUDIO_POSITION + * * ## Example configuration *\code{.unparsed} @@ -70,6 +74,7 @@ * sink.props = { * node.name = "roc-sink" * } + * audio.position = FL FR * } * } * @@ -264,18 +269,34 @@ spa_zero(sender_config); sender_config.frame_encoding.rate = data->rate; - sender_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_STEREO; sender_config.frame_encoding.format = ROC_FORMAT_PCM_FLOAT32; - sender_config.packet_encoding = ROC_PACKET_ENCODING_AVP_L16_STEREO; sender_config.fec_encoding = data->fec_code; - info.rate = data->rate; - /* Fixed to be the same as ROC sender config above */ - info.channels = 2; + info.rate = data->rate; info.format = SPA_AUDIO_FORMAT_F32; - info.position0 = SPA_AUDIO_CHANNEL_FL; - info.position1 = SPA_AUDIO_CHANNEL_FR; + + const char* positions = pw_properties_get(data->capture_props, SPA_KEY_AUDIO_POSITION); + int channels = spa_audio_parse_position_n(positions, strlen(positions), info.position, SPA_N_ELEMENTS(info.position), &info.channels); + + if(channels == 2) { + sender_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_STEREO; + sender_config.packet_encoding = ROC_PACKET_ENCODING_AVP_L16_STEREO; + } else { + sender_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_MULTITRACK; + sender_config.frame_encoding.tracks = channels; + + res = roc_context_register_encoding(data->context, PW_ROC_MULTITRACK_ENCODING_ID, &sender_config.frame_encoding); + if(res) { + pw_log_error("failed to register encoding: %d", res); + return -EINVAL; + } + sender_config.packet_encoding = PW_ROC_MULTITRACK_ENCODING_ID; + + // As of v0.4.0, roc generates packets bigger than it can handle if many channels are used + // (see github.com/roc-streaming/roc-toolkit/issues/821) + sender_config.packet_length = PW_ROC_DEFAULT_PACKET_LENGTH * 2 / channels; + } pw_properties_setf(data->capture_props, PW_KEY_NODE_RATE, "1/%d", info.rate); @@ -360,6 +381,7 @@ "( remote.source.port=<remote receiver port for source packets> ) " "( remote.repair.port=<remote receiver port for repair packets> ) " "( remote.control.port=<remote receiver port for control packets> ) " + "( audio.position=<channel map, default:"PW_ROC_STEREO_POSITIONS"> ) " "( sink.props= { key=val ... } ) " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; @@ -418,6 +440,12 @@ if ((str = pw_properties_get(capture_props, PW_KEY_MEDIA_CLASS)) == NULL) pw_properties_set(capture_props, PW_KEY_MEDIA_CLASS, "Audio/Sink"); + if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) { + pw_properties_set(capture_props, SPA_KEY_AUDIO_POSITION, str); + } else { + pw_properties_set(capture_props, SPA_KEY_AUDIO_POSITION, PW_ROC_STEREO_POSITIONS); + } + data->rate = pw_properties_get_uint32(capture_props, PW_KEY_AUDIO_RATE, 0); if (data->rate == 0) data->rate = PW_ROC_DEFAULT_RATE;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-roc-source.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-roc-source.c
Changed
@@ -12,6 +12,7 @@ #include <spa/utils/hook.h> #include <spa/utils/result.h> #include <spa/param/audio/format-utils.h> +#include <spa/param/audio/raw-json.h> #include <roc/config.h> #include <roc/log.h> @@ -62,7 +63,9 @@ * * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION - * - \ref PW_KEY_MEDIA_NAME + * - \ref PW_KEY_NODE_VIRTUAL + * - \ref PW_KEY_MEDIA_CLASS + * - \ref SPA_KEY_AUDIO_POSITION * * ## Example configuration *\code{.unparsed} @@ -85,6 +88,7 @@ * source.props = { * node.name = "roc-source" * } + * audio.position = FL FR * } * } * @@ -285,20 +289,33 @@ spa_zero(receiver_config); receiver_config.frame_encoding.rate = data->rate; - receiver_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_STEREO; receiver_config.frame_encoding.format = ROC_FORMAT_PCM_FLOAT32; receiver_config.resampler_profile = data->resampler_profile; receiver_config.resampler_backend = data->resampler_backend; receiver_config.latency_tuner_backend = data->latency_tuner_backend; receiver_config.latency_tuner_profile = data->latency_tuner_profile; - info.rate = data->rate; /* Fixed to be the same as ROC receiver config above */ - info.channels = 2; + info.rate = data->rate; info.format = SPA_AUDIO_FORMAT_F32; - info.position0 = SPA_AUDIO_CHANNEL_FL; - info.position1 = SPA_AUDIO_CHANNEL_FR; + + const char* positions = pw_properties_get(data->playback_props, SPA_KEY_AUDIO_POSITION); + int channels = spa_audio_parse_position_n(positions, strlen(positions), info.position, SPA_N_ELEMENTS(info.position), &info.channels); + + if(channels == 2) { + receiver_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_STEREO; + } else { + receiver_config.frame_encoding.channels = ROC_CHANNEL_LAYOUT_MULTITRACK; + receiver_config.frame_encoding.tracks = channels; + + res = roc_context_register_encoding(data->context, PW_ROC_MULTITRACK_ENCODING_ID, &receiver_config.frame_encoding); + if(res) { + pw_log_error("failed to register encoding: %d", res); + return -EINVAL; + } + } + data->stride = info.channels * sizeof(float); pw_properties_setf(data->playback_props, PW_KEY_NODE_RATE, "1/%d", info.rate); @@ -403,6 +420,7 @@ "( local.source.port=<local receiver port for source packets> ) " "( local.repair.port=<local receiver port for repair packets> ) " "( local.control.port=<local receiver port for control packets> ) " + "( audio.position=<channel map, default:"PW_ROC_STEREO_POSITIONS"> ) " "( source.props= { key=value ... } ) " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; @@ -459,6 +477,12 @@ if (pw_properties_get(playback_props, PW_KEY_NODE_NETWORK) == NULL) pw_properties_set(playback_props, PW_KEY_NODE_NETWORK, "true"); + if ((str = pw_properties_get(props, SPA_KEY_AUDIO_POSITION)) != NULL) { + pw_properties_set(playback_props, SPA_KEY_AUDIO_POSITION, str); + } else { + pw_properties_set(playback_props, SPA_KEY_AUDIO_POSITION, PW_ROC_STEREO_POSITIONS); + } + data->rate = pw_properties_get_uint32(playback_props, PW_KEY_AUDIO_RATE, 0); if (data->rate == 0) data->rate = PW_ROC_DEFAULT_RATE;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-roc/common.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-roc/common.h
Changed
@@ -13,6 +13,10 @@ #define PW_ROC_DEFAULT_SESS_LATENCY 200 #define PW_ROC_DEFAULT_RATE 44100 #define PW_ROC_DEFAULT_CONTROL_PROTO ROC_PROTO_RTCP +#define PW_ROC_DEFAULT_PACKET_LENGTH 5000000 // 5ms in ns + +#define PW_ROC_MULTITRACK_ENCODING_ID 100 +#define PW_ROC_STEREO_POSITIONS " FL FR " static inline int pw_roc_parse_fec_encoding(roc_fec_encoding *out, const char *str) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rt.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rt.c
Changed
@@ -650,8 +650,8 @@ static int acquire_rt_sched(struct spa_thread *thread, int priority) { - int err, min, max; - struct sched_param sp; + int err, min, max, new_policy, old_policy; + struct sched_param new_sched_params, old_sched_params; pthread_t pt = (pthread_t)thread; min = max = 0; @@ -663,10 +663,18 @@ priority, min, max, REALTIME_POLICY); priority = SPA_CLAMP(priority, min, max); } + if ((err = pthread_getschedparam(pt, &old_policy, &old_sched_params)) != 0) { + pw_log_warn("Failed to get scheduling params: %s", strerror(err)); + old_policy = SCHED_RESET_ON_FORK; + } - spa_zero(sp); - sp.sched_priority = priority; - if ((err = pthread_setschedparam(pt, REALTIME_POLICY | SCHED_RESET_ON_FORK, &sp)) != 0) { + spa_zero(new_sched_params); + new_sched_params.sched_priority = priority; + new_policy = REALTIME_POLICY; + if ((old_policy & SCHED_RESET_ON_FORK) != 0) + new_policy |= SCHED_RESET_ON_FORK; + + if ((err = pthread_setschedparam(pt, new_policy, &new_sched_params)) != 0) { pw_log_warn("could not make thread %p realtime: %s", thread, strerror(err)); return -err; } @@ -677,12 +685,21 @@ static int impl_drop_rt_generic(void *object, struct spa_thread *thread) { - struct sched_param sp; + struct sched_param new_sched_params, old_sched_params; pthread_t pt = (pthread_t)thread; - int err; + int err, new_policy, old_policy; + + if ((err = pthread_getschedparam(pt, &old_policy, &old_sched_params)) != 0) { + pw_log_warn("Failed to get scheduling params: %s", strerror(err)); + old_policy = SCHED_RESET_ON_FORK; + } + + spa_zero(new_sched_params); + new_policy = SCHED_OTHER; + if (SPA_FLAG_IS_SET(old_policy, SCHED_RESET_ON_FORK)) + new_policy |= SCHED_RESET_ON_FORK; - spa_zero(sp); - if ((err = pthread_setschedparam(pt, SCHED_OTHER | SCHED_RESET_ON_FORK, &sp)) != 0) { + if ((err = pthread_setschedparam(pt, new_policy, &new_sched_params)) != 0) { pw_log_debug("thread %p: SCHED_OTHER|SCHED_RESET_ON_FORK failed: %s", thread, strerror(err)); return -err;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp-sap.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp-sap.c
Changed
@@ -156,6 +156,7 @@ #define DEFAULT_LOOP false #define MAX_SDP 2048 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS #define USAGE "( local.ifname=<local interface name to use> ) " \ "( sap.ip=<SAP IP address to send announce, default:"DEFAULT_SAP_IP"> ) " \ @@ -247,6 +248,16 @@ struct session *session; }; +struct igmp_recovery { + struct pw_timer timer; + int socket_fd; + struct sockaddr_storage mcast_addr; + socklen_t mcast_len; + uint32_t if_index; + bool is_ipv6; + uint32_t deadline; +}; + struct impl { struct pw_properties *props; @@ -264,7 +275,11 @@ struct pw_registry *registry; struct spa_hook registry_listener; - struct pw_timer timer; + struct pw_timer sap_send_timer; + + /* This timer is used when the first start_sap() call fails because + * of an ENODEV error (see the start_sap() code for details) */ + struct pw_timer start_sap_retry_timer; char *ifname; uint32_t ttl; @@ -280,6 +295,10 @@ struct spa_source *sap_source; uint32_t cleanup_interval; + /* IGMP recovery (triggers when no SAP packets are + * received after the recovery deadline is reached) */ + struct igmp_recovery igmp_recovery; + uint32_t max_sessions; uint32_t n_sessions; struct spa_list sessions; @@ -287,7 +306,7 @@ char *extra_attrs_preamble; char *extra_attrs_end; - char *ptp_mgmt_socket; + char *ptp_mgmt_socket_path; int ptp_fd; uint32_t ptp_seq; uint8_t clock_id8; @@ -321,6 +340,7 @@ return NULL; } +static int start_sap(struct impl *impl); static int send_sap(struct impl *impl, struct session *sess, bool bye); @@ -382,7 +402,7 @@ return false; } -static int make_unix_socket(const char *path) { +static int make_unix_ptp_mgmt_socket(const char *path) { struct sockaddr_un addr; spa_autoclose int fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); @@ -418,7 +438,7 @@ af = src->ss_family; if ((fd = socket(af, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) { - pw_log_error("socket failed: %m"); + pw_log_error("socket() failed: %m"); return -errno; } if (bind(fd, (struct sockaddr*)src, src_len) < 0) { @@ -450,6 +470,9 @@ pw_log_warn("setsockopt(IPV6_MULTICAST_HOPS) failed: %m"); } } + + pw_log_info("sender socket up and running"); + return fd; error: close(fd); @@ -457,7 +480,7 @@ } static int make_recv_socket(struct sockaddr_storage *sa, socklen_t salen, - char *ifname) + char *ifname, struct igmp_recovery *igmp_recovery) { int af, fd, val, res; struct ifreq req; @@ -467,13 +490,13 @@ af = sa->ss_family; if ((fd = socket(af, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) { - pw_log_error("socket failed: %m"); + pw_log_error("socket() failed: %m"); return -errno; } val = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { res = -errno; - pw_log_error("setsockopt failed: %m"); + pw_log_error("setsockopt() failed: %m"); goto error; } spa_zero(req); @@ -527,6 +550,16 @@ goto error; } + /* Store multicast info for recovery */ + igmp_recovery->socket_fd = fd; + igmp_recovery->mcast_addr = ba; + igmp_recovery->mcast_len = salen; + igmp_recovery->if_index = req.ifr_ifindex; + igmp_recovery->is_ipv6 = (af == AF_INET6); + pw_log_debug("stored %s multicast info: socket_fd=%d, " + "if_index=%d", igmp_recovery->is_ipv6 ? + "IPv6" : "IPv4", fd, req.ifr_ifindex); + if (bind(fd, (struct sockaddr*)&ba, salen) < 0) { res = -errno; pw_log_error("bind() failed: %m"); @@ -539,6 +572,9 @@ goto error; } } + + pw_log_info("receiver socket up and running"); + return fd; error: close(fd); @@ -547,8 +583,13 @@ static bool update_ts_refclk(struct impl *impl) { - if (!impl->ptp_mgmt_socket || impl->ptp_fd < 0) + if (!impl->ptp_mgmt_socket_path) return false; + if (impl->ptp_fd < 0) { + impl->ptp_fd = make_unix_ptp_mgmt_socket(impl->ptp_mgmt_socket_path); + if (impl->ptp_fd < 0) + return false; + } // Read if something is left in the socket int avail; @@ -580,6 +621,12 @@ if (write(impl->ptp_fd, &req, sizeof(req)) == -1) { pw_log_warn("Failed to send PTP management request: %m"); + if (errno != ENOTCONN) + return false; + close(impl->ptp_fd); + impl->ptp_fd = make_unix_ptp_mgmt_socket(impl->ptp_mgmt_socket_path); + if (impl->ptp_fd > -1) + pw_log_info("Reopened PTP management socket"); return false; } @@ -921,7 +968,98 @@ return res; } -static void on_timer_event(void *data) +static void on_igmp_recovery_timer_event(void *data) +{ + struct impl *impl = data; + char addr128; + int res = 0; + + /* Only attempt recovery if we have a valid socket and multicast address */ + if (impl->igmp_recovery.socket_fd < 0) { + pw_log_debug("no socket, skipping IGMP recovery"); + goto finish; + } + + pw_net_get_ip(&impl->igmp_recovery.mcast_addr, addr, sizeof(addr), NULL, NULL); + pw_log_info("IGMP recovery triggered for %s", addr); + + /* Force IGMP membership refresh by leaving the group first, then rejoin */ + if (impl->igmp_recovery.is_ipv6) { + struct ipv6_mreq mr6; + memset(&mr6, 0, sizeof(mr6)); + mr6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&impl->igmp_recovery.mcast_addr)->sin6_addr; + mr6.ipv6mr_interface = impl->igmp_recovery.if_index;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp-session.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp-session.c
Changed
@@ -82,6 +82,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -148,6 +149,7 @@ "( audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> ) " \ "( audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> ) "\ "( audio.position=<channel map, default:"DEFAULT_POSITION"> ) " \ + "( audio.layout=<layout name, default:"DEFAULT_LAYOUT"> ) " \ "( stream.props= { key=value ... } ) " static const struct spa_dict_item module_info = { @@ -1043,8 +1045,11 @@ if (sess == NULL) goto unknown_ssrc; - if (sess->data_ready && sess->receiving) - rtp_stream_receive_packet(sess->recv, buffer, len); + if (sess->data_ready && sess->receiving) { + uint64_t current_time = rtp_stream_get_nsec(sess->recv); + rtp_stream_receive_packet(sess->recv, buffer, len, + current_time); + } } } return; @@ -1326,6 +1331,12 @@ } else if (spa_streq(key, "channels")) { k = PW_KEY_AUDIO_CHANNELS; mask |= 1<<3; + } else if (spa_streq(key, "position")) { + pw_properties_set(props, + SPA_KEY_AUDIO_POSITION, value); + } else if (spa_streq(key, "layout")) { + pw_properties_set(props, + SPA_KEY_AUDIO_LAYOUT, value); } else if (spa_streq(key, "channelnames")) { pw_properties_set(props, PW_KEY_NODE_CHANNELNAMES, value); @@ -1584,6 +1595,8 @@ txt = avahi_string_list_add_pair(txt, "channels", str); if ((str = pw_properties_get(impl->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) txt = avahi_string_list_add_pair(txt, "position", str); + if ((str = pw_properties_get(impl->stream_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) + txt = avahi_string_list_add_pair(txt, "layout", str); if ((str = pw_properties_get(impl->stream_props, PW_KEY_NODE_CHANNELNAMES)) != NULL) txt = avahi_string_list_add_pair(txt, "channelnames", str); if (impl->ts_refclk != NULL) { @@ -1699,6 +1712,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp-sink.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp-sink.c
Changed
@@ -77,6 +77,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -150,6 +151,7 @@ "( audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> ) " \ "( audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> ) " \ "( audio.position=<channel map, default:"DEFAULT_POSITION"> ) " \ + "( audio.layout=<channel layout, default:"DEFAULT_LAYOUT"> ) " \ "( aes67.driver-group=<driver driving the PTP send> ) " \ "( stream.props= { key=value ... } ) " @@ -578,6 +580,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp-source.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp-source.c
Changed
@@ -15,6 +15,7 @@ #include <net/if.h> #include <ctype.h> +#include <spa/utils/atomic.h> #include <spa/utils/hook.h> #include <spa/utils/result.h> #include <spa/utils/ringbuffer.h> @@ -71,6 +72,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_MEDIA_CLASS @@ -156,6 +158,9 @@ PW_LOG_TOPIC(mod_topic, "mod." NAME); #define PW_LOG_TOPIC_DEFAULT mod_topic +#define DEFAULT_IGMP_CHECK_INTERVAL_SEC 5 +#define DEFAULT_IGMP_DEADLINE_SEC 30 + #define DEFAULT_CLEANUP_SEC 60 #define DEFAULT_SOURCE_IP "224.0.0.56" @@ -171,6 +176,7 @@ "( audio.rate=<sample rate, default:"SPA_STRINGIFY(DEFAULT_RATE)"> ) " \ "( audio.channels=<number of channels, default:"SPA_STRINGIFY(DEFAULT_CHANNELS)"> ) " \ "( audio.position=<channel map, default:"DEFAULT_POSITION"> ) " \ + "( audio.layout=<channel layout, default:"DEFAULT_LAYOUT"> ) " \ "( stream.props= { key=value ... } ) " static const struct spa_dict_item module_info = { @@ -180,6 +186,23 @@ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; +struct igmp_recovery { + struct pw_timer timer; + int socket_fd; + struct sockaddr_storage mcast_addr; + socklen_t mcast_len; + uint32_t if_index; + bool is_ipv6; + /* This is the interval the recovery timer runs at. The timer + * checks at each interval if recovery is required. This value + * is defined by the igmp.check.interval.sec property. */ + uint32_t check_interval; + /* This is the deadline for packets to arrive. If the deadline + * is exceeded, an IGMP recovery is attempted. This value is + * defined by the igmp.deadline.sec property. */ + uint32_t deadline; +}; + struct impl { struct pw_impl_module *module; struct spa_hook module_listener; @@ -201,6 +224,15 @@ bool always_process; uint32_t cleanup_interval; + /* IGMP recovery (triggers when no RTP packets are + * received after the recovery deadline is reached) */ + struct igmp_recovery igmp_recovery; + + /* Monotonic timestamp of the last time a packet was + * received. This is accessed with atomic accessors + * to avoid race conditions. */ + uint64_t last_packet_time; + struct pw_timer standby_timer; /* This timer is used when the first stream_start() call fails because * of an ENODEV error (see the stream_start() code for details) */ @@ -227,13 +259,6 @@ bool waiting; }; -static inline uint64_t get_time_ns(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return SPA_TIMESPEC_TO_NSEC(&ts); -} - static int do_start(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) { @@ -261,6 +286,9 @@ struct impl *impl = data; ssize_t len; int suppressed; + uint64_t current_time; + + current_time = rtp_stream_get_nsec(impl->stream); if (mask & SPA_IO_IN) { if ((len = recv(fd, impl->buffer, impl->buffer_size, 0)) < 0) @@ -270,10 +298,17 @@ goto short_packet; if (SPA_LIKELY(impl->stream)) { - if (rtp_stream_receive_packet(impl->stream, impl->buffer, len) < 0) + if (rtp_stream_receive_packet(impl->stream, impl->buffer, len, + current_time) < 0) goto receive_error; } + /* Update last packet timestamp for IGMP recovery. + * The recovery timer will check this to see if recovery + * is necessary. Do this _before_ invoking do_start() + * in case the stream is waking up from standby. */ + SPA_ATOMIC_STORE(impl->last_packet_time, current_time); + if (SPA_ATOMIC_LOAD(impl->state) != STATE_RECEIVING) { if (!SPA_ATOMIC_CAS(impl->state, STATE_PROBE, STATE_RECEIVING)) { if (SPA_ATOMIC_CAS(impl->state, STATE_IDLE, STATE_RECEIVING)) @@ -284,17 +319,148 @@ return; receive_error: - if ((suppressed = spa_ratelimit_test(&impl->rate_limit, get_time_ns())) >= 0) + if ((suppressed = spa_ratelimit_test(&impl->rate_limit, current_time)) >= 0) pw_log_warn("(%d suppressed) recv() error: %m", suppressed); return; short_packet: - if ((suppressed = spa_ratelimit_test(&impl->rate_limit, get_time_ns())) >= 0) + if ((suppressed = spa_ratelimit_test(&impl->rate_limit, current_time)) >= 0) pw_log_warn("(%d suppressed) short packet of len %zd received", suppressed, len); return; } -static int make_socket(const struct sockaddr* sa, socklen_t salen, char *ifname) +static int rejoin_igmp_group(struct spa_loop *loop, bool async, uint32_t seq, + const void *data, size_t size, void *user_data) +{ + /* IMPORTANT: This must be run from within the data loop. */ + + int res; + struct impl *impl = user_data; + uint64_t current_time; + + /* Force IGMP membership refresh by leaving the group first, then rejoin */ + if (impl->igmp_recovery.is_ipv6) { + struct ipv6_mreq mr6; + memset(&mr6, 0, sizeof(mr6)); + mr6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&impl->igmp_recovery.mcast_addr)->sin6_addr; + mr6.ipv6mr_interface = impl->igmp_recovery.if_index; + + /* Leave the group first */ + res = setsockopt(impl->igmp_recovery.socket_fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, + &mr6, sizeof(mr6)); + if (SPA_LIKELY(res == 0)) { + pw_log_info("left IPv6 multicast group"); + } else { + if (errno == EADDRNOTAVAIL) { + pw_log_info("attempted to leave IPv6 multicast group, but " + "membership was already silently dropped"); + } else { + pw_log_warn("failed to leave IPv6 multicast group: %m"); + } + } + + res = setsockopt(impl->igmp_recovery.socket_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &mr6, sizeof(mr6)); + if (res < 0) { + pw_log_warn("failed to re-join IPv6 multicast group: %m"); + } else { + pw_log_info("re-joined IPv6 multicast group successfully"); + } + } else { + struct ip_mreqn mr4; + memset(&mr4, 0, sizeof(mr4)); + mr4.imr_multiaddr = ((struct sockaddr_in*)&impl->igmp_recovery.mcast_addr)->sin_addr; + mr4.imr_ifindex = impl->igmp_recovery.if_index; + + /* Leave the group first */ + res = setsockopt(impl->igmp_recovery.socket_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, + &mr4, sizeof(mr4)); + if (SPA_LIKELY(res == 0)) { + pw_log_info("left IPv4 multicast group"); + } else { + if (errno == EADDRNOTAVAIL) { + pw_log_info("attempted to leave IPv4 multicast group, but " + "membership was already silently dropped"); + } else { + pw_log_warn("failed to leave IPv4 multicast group: %m"); + } + } + + res = setsockopt(impl->igmp_recovery.socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &mr4, sizeof(mr4)); + if (res < 0) { + pw_log_warn("failed to re-join IPv4 multicast group: %m"); + } else { + pw_log_info("re-joined IPv4 multicast group successfully"); + } + } +
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp/audio.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp/audio.c
Changed
@@ -233,7 +233,8 @@ pw_stream_queue_buffer(impl->stream, buf); } -static int rtp_audio_receive(struct impl *impl, uint8_t *buffer, ssize_t len) +static int rtp_audio_receive(struct impl *impl, uint8_t *buffer, ssize_t len, + uint64_t current_time) { struct rtp_header *hdr; ssize_t hlen, plen; @@ -273,7 +274,7 @@ timestamp = ntohl(hdr->timestamp) - impl->ts_offset; impl->receiving = true; - impl->last_recv_timestamp = pw_stream_get_nsec(impl->stream); + impl->last_recv_timestamp = current_time; plen = len - hlen; samples = plen / stride;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp/midi.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp/midi.c
Changed
@@ -318,7 +318,8 @@ return 0; } -static int rtp_midi_receive(struct impl *impl, uint8_t *buffer, ssize_t len) +static int rtp_midi_receive(struct impl *impl, uint8_t *buffer, ssize_t len, + uint64_t current_time) { struct rtp_header *hdr; ssize_t hlen;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp/opus.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp/opus.c
Changed
@@ -99,7 +99,8 @@ pw_stream_queue_buffer(impl->stream, buf); } -static int rtp_opus_receive(struct impl *impl, uint8_t *buffer, ssize_t len) +static int rtp_opus_receive(struct impl *impl, uint8_t *buffer, ssize_t len, + uint64_t current_time) { struct rtp_header *hdr; ssize_t hlen, plen; @@ -334,9 +335,12 @@ static int rtp_opus_init(struct impl *impl, enum spa_direction direction) { int err; - unsigned char mappingSPA_AUDIO_MAX_CHANNELS; + unsigned char mapping255; uint32_t i; + if (impl->info.info.opus.channels > 255) + return -EINVAL; + if (impl->psamples >= 2880) impl->psamples = 2880; else if (impl->psamples >= 1920)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp/stream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp/stream.c
Changed
@@ -151,7 +151,8 @@ * access below for the reason why. */ uint8_t timer_running; - int (*receive_rtp)(struct impl *impl, uint8_t *buffer, ssize_t len); + int (*receive_rtp)(struct impl *impl, uint8_t *buffer, ssize_t len, + uint64_t current_time); /* Used for resetting the ring buffer before the stream starts, to prevent * reading from uninitialized memory. This can otherwise happen in direct * timestamp mode when the read index is set to an uninitialized location. @@ -569,9 +570,9 @@ return NULL; } -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -580,6 +581,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -675,7 +677,10 @@ switch (impl->info.media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - parse_audio_info(props, &impl->info.info.raw); + if ((res = parse_audio_info(props, &impl->info.info.raw)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + goto out; + } impl->stream_info = impl->info; impl->format_info = find_audio_format_info(&impl->info); if (impl->format_info == NULL) { @@ -704,7 +709,10 @@ case SPA_MEDIA_SUBTYPE_opus: impl->stream_info.media_type = SPA_MEDIA_TYPE_audio; impl->stream_info.media_subtype = SPA_MEDIA_SUBTYPE_raw; - parse_audio_info(props, &impl->stream_info.info.raw); + if ((res = parse_audio_info(props, &impl->stream_info.info.raw)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + goto out; + } impl->stream_info.info.raw.format = SPA_AUDIO_FORMAT_F32; impl->info.info.opus.rate = impl->stream_info.info.raw.rate; impl->info.info.opus.channels = impl->stream_info.info.raw.channels; @@ -1030,10 +1038,17 @@ return pw_stream_update_properties(impl->stream, dict); } -int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len) +int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len, + uint64_t current_time) +{ + struct impl *impl = (struct impl*)s; + return impl->receive_rtp(impl, buffer, len, current_time); +} + +uint64_t rtp_stream_get_nsec(struct rtp_stream *s) { struct impl *impl = (struct impl*)s; - return impl->receive_rtp(impl, buffer, len); + return pw_stream_get_nsec(impl->stream); } uint64_t rtp_stream_get_time(struct rtp_stream *s, uint32_t *rate)
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-rtp/stream.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-rtp/stream.h
Changed
@@ -15,6 +15,7 @@ #define DEFAULT_RATE 48000 #define DEFAULT_CHANNELS 2 #define DEFAULT_POSITION " FL FR " +#define DEFAULT_LAYOUT "Stereo" #define ERROR_MSEC 2.0f #define DEFAULT_SESS_LATENCY 100.0f @@ -62,7 +63,10 @@ int rtp_stream_update_properties(struct rtp_stream *s, const struct spa_dict *dict); -int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len); +int rtp_stream_receive_packet(struct rtp_stream *s, uint8_t *buffer, size_t len, + uint64_t current_time); + +uint64_t rtp_stream_get_nsec(struct rtp_stream *s); uint64_t rtp_stream_get_time(struct rtp_stream *s, uint32_t *rate);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-snapcast-discover.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-snapcast-discover.c
Changed
@@ -503,9 +503,11 @@ return -ENOENT; } -static void parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + int res; + + if ((res = spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -514,12 +516,15 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, - SPA_KEY_AUDIO_POSITION, NULL); + SPA_KEY_AUDIO_LAYOUT, + SPA_KEY_AUDIO_POSITION, NULL)) < 0) + return res; pw_properties_set(props, PW_KEY_AUDIO_FORMAT, spa_type_audio_format_to_short_name(info->format)); pw_properties_setf(props, PW_KEY_AUDIO_RATE, "%d", info->rate); pw_properties_setf(props, PW_KEY_AUDIO_CHANNELS, "%d", info->channels); + return res; } static int create_stream(struct impl *impl, struct pw_properties *props, @@ -545,7 +550,10 @@ if ((str = pw_properties_get(props, "capture.props")) == NULL) pw_properties_set(props, "capture.props", "{ media.class = Audio/Sink }"); - parse_audio_info(props, &t->audio_info); + if ((res = parse_audio_info(props, &t->audio_info)) < 0) { + pw_log_error("Can't parse format: %s", spa_strerror(res)); + goto done; + } if ((f = open_memstream(&args, &size)) == NULL) { res = -errno;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-vban-recv.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-vban-recv.c
Changed
@@ -75,6 +75,7 @@ * Options with well-known behavior: * * - \ref PW_KEY_REMOTE_NAME + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_MEDIA_CLASS @@ -694,6 +695,7 @@ pw_properties_update_string(stream_props, str, strlen(str)); copy_props(impl, props, PW_KEY_NODE_LOOP_NAME); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-vban-send.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-vban-send.c
Changed
@@ -68,6 +68,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -417,6 +418,7 @@ copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-vban/stream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-vban/stream.c
Changed
@@ -185,9 +185,9 @@ return NULL; } -static void parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) +static int parse_audio_info(const struct pw_properties *props, struct spa_audio_info_raw *info) { - spa_audio_info_raw_init_dict_keys(info, + return spa_audio_info_raw_init_dict_keys(info, &SPA_DICT_ITEMS( SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, DEFAULT_FORMAT), SPA_DICT_ITEM(SPA_KEY_AUDIO_RATE, SPA_STRINGIFY(DEFAULT_RATE)), @@ -196,6 +196,7 @@ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -274,9 +275,14 @@ switch (impl->info.media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - parse_audio_info(props, &impl->info.info.raw); - if (SPA_FLAG_IS_SET(impl->info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED)) + if ((res = parse_audio_info(props, &impl->info.info.raw)) < 0) { + pw_log_error("can't parse format: %s", spa_strerror(res)); + goto out; + } + if (SPA_FLAG_IS_SET(impl->info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED)) { default_layout(impl->info.info.raw.channels, impl->info.info.raw.position); + SPA_FLAG_CLEAR(impl->info.info.raw.flags, SPA_AUDIO_FLAG_UNPOSITIONED); + } impl->stream_info = impl->info; impl->format_info = find_audio_format_info(&impl->info); if (impl->format_info == NULL) {
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/modules/module-zeroconf-discover.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/modules/module-zeroconf-discover.c
Changed
@@ -188,17 +188,17 @@ else if (spa_streq(key, "channel_map")) { struct channel_map channel_map; uint32_t i, posCHANNELS_MAX; - char *p, *s; + char *p, *s, buf8; spa_zero(channel_map); channel_map_parse(value, &channel_map); - channel_map_to_positions(&channel_map, pos); + channel_map_to_positions(&channel_map, pos, CHANNELS_MAX); p = s = alloca(4 + channel_map.channels * 8); p += spa_scnprintf(p, 2, ""); for (i = 0; i < channel_map.channels; i++) p += spa_scnprintf(p, 8, "%s%s", i == 0 ? "" : ",", - channel_id2name(posi)); + channel_id2name(posi, buf, sizeof(buf))); p += spa_scnprintf(p, 2, ""); pw_properties_set(props, SPA_KEY_AUDIO_POSITION, s); }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/data-loop.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/data-loop.c
Changed
@@ -110,6 +110,7 @@ } this->loop = loop; this->rt_prio = -1; + this->reset_on_fork = true; if (props != NULL) { if ((str = spa_dict_lookup(props, PW_KEY_LOOP_CANCEL)) != NULL) @@ -122,6 +123,8 @@ name = str; if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_AFFINITY)) != NULL) this->affinity = strdup(str); + if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_RESET_ON_FORK)) != NULL) + this->reset_on_fork = spa_atob(str); } if (class == NULL) class = this->rt_prio != 0 ? "data.rt" : "data"; @@ -236,7 +239,7 @@ if (!loop->running) { struct spa_thread_utils *utils; struct spa_thread *thr; - struct spa_dict_item items2; + struct spa_dict_item items3; uint32_t n_items = 0; loop->running = true; @@ -248,6 +251,8 @@ if (loop->affinity) itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_AFFINITY, loop->affinity); + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_THREAD_RESET_ON_FORK, + loop->reset_on_fork ? "true" : "false"); thr = spa_thread_utils_create(utils, &SPA_DICT_INIT(items, n_items), do_loop, loop); loop->thread = (pthread_t)thr;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/impl-port.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/impl-port.c
Changed
@@ -1874,11 +1874,10 @@ tag = other->tagother->direction; if (tag) { void *state = NULL; - while (spa_tag_parse(tag, &info, &state) == 1) { + while (spa_tag_parse(tag, &info, &state) == 1) spa_tag_build_add_info(&b.b, info.info); - count++; - } } + count++; } } else { spa_list_for_each(l, &port->links, input_link) { @@ -1886,11 +1885,10 @@ tag = other->tagother->direction; if (tag) { void *state = NULL; - while (spa_tag_parse(tag, &info, &state) == 1) { + while (spa_tag_parse(tag, &info, &state) == 1) spa_tag_build_add_info(&b.b, info.info); - count++; - } } + count++; } } param = count == 0 ? NULL : spa_tag_build_end(&b.b, &f);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/private.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/private.h
Changed
@@ -431,6 +431,7 @@ char *class; char **classes; int rt_prio; + bool reset_on_fork; struct spa_hook_list listener_list; struct spa_thread_utils *thread_utils;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/properties.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/properties.c
Changed
@@ -252,7 +252,8 @@ continue; } /* item changed or added, apply changes later */ - if ((errno = -add_item(&changes, key, false, val, true) < 0)) { + if ((res = add_item(&changes, key, false, val, true)) < 0) { + errno = -res; it0.state = SPA_JSON_ERROR_FLAG; break; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/settings.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/settings.c
Changed
@@ -245,24 +245,21 @@ static void expose_settings(struct pw_context *context, struct pw_impl_metadata *metadata) { struct settings *s = &context->settings; - uint32_t i, o; - char ratesMAX_RATES*16 = ""; + uint32_t i; + char ratesMAX_RATES*16; + struct spa_strbuf b; pw_impl_metadata_set_propertyf(metadata, PW_ID_CORE, "log.level", "", "%d", s->log_level); pw_impl_metadata_set_propertyf(metadata, PW_ID_CORE, "clock.rate", "", "%d", s->clock_rate); - for (i = 0, o = 0; i < s->n_clock_rates; i++) { - int r = snprintf(rates+o, sizeof(rates)-o, "%s%d", i == 0 ? "" : ", ", + + spa_strbuf_init(&b, rates, sizeof(rates)); + for (i = 0; i < s->n_clock_rates; i++) + spa_strbuf_append(&b, "%s%d", i == 0 ? "" : ", ", s->clock_ratesi); - if (r < 0 || o + r >= (int)sizeof(rates)) { - snprintf(rates, sizeof(rates), "%d", s->clock_rate); - break; - } - o += r; - } if (s->n_clock_rates == 0) - snprintf(rates, sizeof(rates), "%d", s->clock_rate); + spa_strbuf_append(&b, "%d", s->clock_rate); pw_impl_metadata_set_propertyf(metadata, PW_ID_CORE, "clock.allowed-rates", "", " %s ", rates);
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/stream.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/stream.c
Changed
@@ -1270,6 +1270,9 @@ return 0; c = calloc(1, sizeof(*c) + SPA_POD_SIZE(param)); + if (c == NULL) + return -errno; + c->info = SPA_PTROFF(c, sizeof(*c), struct spa_pod); memcpy(c->info, param, SPA_POD_SIZE(param)); c->control.n_values = 0; @@ -1286,7 +1289,7 @@ } pod = spa_pod_get_values(type, &n_vals, &choice); - if (n_vals == 0) { + if (n_vals < 1) { free(c); return -EINVAL; } @@ -1318,19 +1321,12 @@ switch (choice) { case SPA_CHOICE_None: - if (n_vals < 1) { - free(c); - return -EINVAL; - } c->control.n_values = 1; c->control.max_values = 1; c->control.values0 = c->control.def = c->control.min = c->control.max = vals0; break; case SPA_CHOICE_Range: - if (n_vals < 3) { - free(c); - return -EINVAL; - } + case SPA_CHOICE_Step: c->control.n_values = 1; c->control.max_values = 1; c->control.values0 = vals0;
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/thread.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/thread.c
Changed
@@ -92,8 +92,10 @@ pthread_t pt; pthread_attr_t *attr = NULL, attributes; const char *str; - int err; + int err, old_policy, new_policy; int (*create_func)(pthread_t *, const pthread_attr_t *attr, void *(*start)(void*), void *) = NULL; + struct sched_param sp; + bool reset_on_fork = true; attr = pw_thread_fill_attr(props, &attributes); @@ -118,7 +120,16 @@ if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_AFFINITY)) != NULL && (err = thread_setaffinity(pt, str)) != 0) pw_log_warn("pthread_setaffinity error: %s", strerror(-err)); + if ((str = spa_dict_lookup(props, SPA_KEY_THREAD_RESET_ON_FORK)) != NULL) + reset_on_fork = spa_atob(str); } + + pthread_getschedparam(pt, &old_policy, &sp); + new_policy = old_policy; + SPA_FLAG_UPDATE(new_policy, SCHED_RESET_ON_FORK, reset_on_fork); + if (old_policy != new_policy) + pthread_setschedparam(pt, new_policy, &sp); + return (struct spa_thread*)pt; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/pipewire/utils.h -> _service:download_files:pipewire-1.5.83.tar.bz2/src/pipewire/utils.h
Changed
@@ -12,6 +12,7 @@ # include <sys/mount.h> #endif #include <errno.h> +#include <sys/types.h> #include <spa/utils/cleanup.h> #include <spa/utils/defs.h>
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/tools/pw-cat.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/tools/pw-cat.c
Changed
@@ -70,6 +70,8 @@ #define DEFAULT_VOLUME 1.0 #define DEFAULT_QUALITY 4 +#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS + enum mode { mode_none, mode_playback, @@ -91,7 +93,7 @@ struct channelmap { uint32_t n_channels; - uint32_t channelsSPA_AUDIO_MAX_CHANNELS; + uint32_t channelsMAX_CHANNELS; }; struct data { @@ -702,7 +704,8 @@ } } - spa_audio_parse_position(channel_map, strlen(channel_map), map->channels, &map->n_channels); + spa_audio_parse_position_n(channel_map, strlen(channel_map), + map->channels, SPA_N_ELEMENTS(map->channels), &map->n_channels); return 0; } @@ -744,10 +747,11 @@ static void channelmap_print(struct channelmap *map) { uint32_t i; - + char pos8; for (i = 0; i < map->n_channels; i++) { - const char *name = spa_type_audio_channel_to_short_name(map->channelsi); - fprintf(stderr, "%s%s", name, i + 1 < map->n_channels ? "," : ""); + fprintf(stderr, "%s%s", i ? "," : "", + spa_type_audio_channel_make_short_name(map->channelsi, + pos, sizeof(pos), "UNK")); } } @@ -2344,9 +2348,23 @@ .rate = data.rate, .channels = data.channels); - if (data.channelmap.n_channels) - memcpy(info.position, data.channelmap.channels, data.channels * sizeof(int)); - + if (data.channels > MAX_CHANNELS) { + fprintf(stderr, "error: too many channels %d > %d\n", + data.channels, MAX_CHANNELS); + goto error_bad_file; + } + if (data.channelmap.n_channels) { + if (data.channels > MAX_CHANNELS) { + fprintf(stderr, "error: too many channels in channelmap %d > %d\n", + data.channelmap.n_channels, MAX_CHANNELS); + goto error_bad_file; + } + uint32_t i; + for (i = 0; i < data.channelmap.n_channels; i++) + info.positioni = data.channelmap.channelsi; + for (; i < data.channels; i++) + info.positioni = SPA_AUDIO_CHANNEL_AUX0 + i; + } paramsn_params++ = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info); break; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/src/tools/pw-link.c -> _service:download_files:pipewire-1.5.83.tar.bz2/src/tools/pw-link.c
Changed
@@ -871,6 +871,7 @@ " -o, --output List output ports\n" " -i, --input List input ports\n" " -l, --links List links\n" + " -t, --latency List port latencies\n" " -m, --monitor Monitor links and ports\n" " -I, --id List IDs\n" " -v, --verbose Verbose port properties\n"
View file
_service:download_files:pipewire-1.5.81.tar.bz2/test/meson.build -> _service:download_files:pipewire-1.5.83.tar.bz2/test/meson.build
Changed
@@ -112,6 +112,7 @@ executable('test-spa', 'test-spa-buffer.c', 'test-spa-control.c', + 'test-spa-format.c', 'test-spa-json.c', 'test-spa-utils.c', 'test-spa-log.c',
View file
_service:download_files:pipewire-1.5.83.tar.bz2/test/test-spa-format.c
Added
@@ -0,0 +1,129 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Pauli Virtanen */ +/* SPDX-License-Identifier: MIT */ + +#include <spa/param/audio/format-utils.h> +#include <spa/param/audio/format.h> + +#include "pwtest.h" + +PWTEST(audio_format_sizes) +{ + union { + uint8_t buf1024; + struct spa_audio_info align; + } data; + struct spa_audio_info info; + size_t i; + + memset(&info, 0xf3, sizeof(info)); + info.media_type = SPA_MEDIA_TYPE_audio; + info.media_subtype = SPA_MEDIA_SUBTYPE_raw; + info.info.raw.channels = 5; + info.info.raw.format = SPA_AUDIO_FORMAT_F32P; + info.info.raw.rate = 12345; + info.info.raw.flags = 0; + info.info.raw.position0 = 1; + info.info.raw.position1 = 2; + info.info.raw.position2 = 3; + info.info.raw.position3 = 4; + info.info.raw.position4 = 5; + + for (i = 0; i < sizeof(data.buf); ++i) { + struct spa_pod *pod; + uint8_t buf4096; + struct spa_pod_builder b; + + spa_pod_builder_init(&b, buf, sizeof(buf)); + memcpy(data.buf, &info, sizeof(info)); + + pod = spa_format_audio_ext_build(&b, 123, (void *)data.buf, i); + if (i < offsetof(struct spa_audio_info, info.raw) + + offsetof(struct spa_audio_info_raw, position)) + pwtest_bool_true(!pod); + else + pwtest_bool_true(pod); + } + + for (i = 0; i < sizeof(data.buf); ++i) { + struct spa_pod *pod; + uint8_t buf4096; + struct spa_pod_builder b; + int ret; + + spa_pod_builder_init(&b, buf, sizeof(buf)); + pod = spa_format_audio_ext_build(&b, 123, &info, sizeof(info)); + pwtest_bool_true(pod); + + memset(data.buf, 0xf3, sizeof(data.buf)); + + ret = spa_format_audio_ext_parse(pod, (void *)data.buf, i); + if (i < offsetof(struct spa_audio_info, info.raw) + + offsetof(struct spa_audio_info_raw, position) + + info.info.raw.channels*sizeof(uint32_t)) { + for (size_t j = i; j < sizeof(data.buf); ++j) + pwtest_int_eq(data.bufj, 0xf3); + pwtest_int_lt(ret, 0); + } else { + pwtest_int_ge(ret, 0); + pwtest_bool_true(memcmp(data.buf, &info, SPA_MIN(i, sizeof(info))) == 0); + } + } + + memset(&info, 0xf3, sizeof(info)); + info.media_type = SPA_MEDIA_TYPE_audio; + info.media_subtype = SPA_MEDIA_SUBTYPE_aac; + info.info.aac.rate = 12345; + info.info.aac.channels = 6; + info.info.aac.bitrate = 54321; + info.info.aac.stream_format = SPA_AUDIO_AAC_STREAM_FORMAT_MP4LATM; + + for (i = 0; i < sizeof(data.buf); ++i) { + struct spa_pod *pod; + uint8_t buf4096; + struct spa_pod_builder b; + + spa_pod_builder_init(&b, buf, sizeof(buf)); + memcpy(data.buf, &info, sizeof(info)); + + pod = spa_format_audio_ext_build(&b, 123, (void *)data.buf, i); + if (i < offsetof(struct spa_audio_info, info.raw) + + sizeof(struct spa_audio_info_aac)) + pwtest_bool_true(!pod); + else + pwtest_bool_true(pod); + } + + for (i = 0; i < sizeof(data.buf); ++i) { + struct spa_pod *pod; + uint8_t buf4096; + struct spa_pod_builder b; + int ret; + + spa_pod_builder_init(&b, buf, sizeof(buf)); + pod = spa_format_audio_ext_build(&b, 123, &info, sizeof(info)); + pwtest_bool_true(pod); + + memset(data.buf, 0xf3, sizeof(data.buf)); + + ret = spa_format_audio_ext_parse(pod, (void *)data.buf, i); + if (i < offsetof(struct spa_audio_info, info.raw) + + sizeof(struct spa_audio_info_aac)) { + for (size_t j = i; j < sizeof(data.buf); ++j) + pwtest_int_eq(data.bufj, 0xf3); + pwtest_int_lt(ret, 0); + } else { + pwtest_int_ge(ret, 0); + pwtest_bool_true(memcmp(data.buf, &info, SPA_MIN(i, sizeof(info))) == 0); + } + } + + return PWTEST_PASS; +} + +PWTEST_SUITE(spa_format) +{ + pwtest_add(audio_format_sizes, PWTEST_NOARG); + + return PWTEST_PASS; +}
View file
_service:download_files:pipewire-1.5.81.tar.bz2/test/test-spa-json.c -> _service:download_files:pipewire-1.5.83.tar.bz2/test/test-spa-json.c
Changed
@@ -609,7 +609,7 @@ spa_json_init(&it0, str, strlen(str)); if (spa_json_enter_array(&it0, &it1) <= 0) - spa_json_init(&it1, str, strlen(str)); + spa_json_init_relax(&it1, '', str, strlen(str)); for (i = 0; valsi; i++) { pwtest_int_gt(spa_json_get_string(&it1, val, sizeof(val)), 0); pwtest_str_eq(val, valsi); @@ -624,6 +624,7 @@ test_array("FL FR", (const char *){ "FL", "FR", NULL }); test_array("FL FR", (const char *){ "FL", "FR", NULL }); test_array(" FL FR ", (const char *){ "FL", "FR", NULL }); + test_array("FL FR FC", (const char *){ "FL", "FR", "FC", NULL }); return PWTEST_PASS; }
View file
_service:download_files:pipewire-1.5.81.tar.bz2/test/test-spa-pod.c -> _service:download_files:pipewire-1.5.83.tar.bz2/test/test-spa-pod.c
Changed
@@ -1612,7 +1612,7 @@ spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); spa_pod_builder_add(&b, SPA_PROP_INFO_id, SPA_POD_Id(32567359), - SPA_PROP_INFO_type, SPA_POD_CHOICE_ENUM_Int(1, 0), + SPA_PROP_INFO_type, SPA_POD_Int(0), SPA_PROP_INFO_description, SPA_POD_String("DV Timings"), 0); @@ -1669,7 +1669,7 @@ spa_pod_builder_push_object(&b, &f0, SPA_TYPE_OBJECT_PropInfo, SPA_PARAM_PropInfo); spa_pod_builder_add(&b, SPA_PROP_INFO_id, SPA_POD_Id(32567359), - SPA_PROP_INFO_type, SPA_POD_CHOICE_ENUM_Int(1, 0), + SPA_PROP_INFO_type, SPA_POD_Int(0), SPA_PROP_INFO_description, SPA_POD_String("DV Timings"), 0);
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
.