diff --git a/Cargo.lock b/Cargo.lock index 57bbbef..57d9f64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,7 +113,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.119", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -135,7 +135,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -152,9 +152,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ "aws-lc-sys", "zeroize", @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.44.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" dependencies = [ "cc", "cmake", @@ -209,7 +209,7 @@ version = "0.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "cexpr", "clang-sys", "lazy_static", @@ -234,9 +234,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.1" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "block-buffer" @@ -291,7 +291,7 @@ checksum = "46d07918caa9eeaaf06b7873925c53a61daac173539b4f7715090745e44e4e69" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -329,9 +329,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.4.3" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" dependencies = [ "find-msvc-tools", "jobserver", @@ -362,9 +362,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cfg_aliases" @@ -385,12 +385,12 @@ dependencies = [ [[package]] name = "chacha20" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures 0.3.1", "rand_core 0.10.1", ] @@ -458,18 +458,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstyle", "clap_lex", @@ -477,9 +477,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] name = "cmake" @@ -498,9 +498,9 @@ checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "combine" -version = "4.6.7" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ "bytes", "memchr", @@ -534,6 +534,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -545,9 +551,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -569,9 +575,9 @@ checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" dependencies = [ "cfg-if", ] @@ -613,9 +619,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -623,18 +629,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -754,9 +760,6 @@ name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] [[package]] name = "digest" @@ -790,7 +793,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -857,9 +860,9 @@ dependencies = [ [[package]] name = "either" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" @@ -884,11 +887,17 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.35" +version = "0.8.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "7b5ef0006ac9ab233c38522f5ae99cae3625151de8f706cacee1cba4b8e2832a" dependencies = [ "cfg-if", + "core_detect", + "multiversion", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", ] [[package]] @@ -941,9 +950,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" [[package]] name = "fixedbitset" @@ -953,12 +962,13 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" dependencies = [ "crc32fast", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -1044,7 +1054,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -1140,7 +1150,7 @@ dependencies = [ "futures-util", "hmac 0.13.0", "openh264", - "opusic-sys", + "opus", "prost", "prost-build", "prost-types", @@ -1189,9 +1199,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.16" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -1273,11 +1283,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1321,18 +1331,18 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hybrid-array" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" dependencies = [ "typenum", ] [[package]] name = "hyper" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ "atomic-waker", "bytes", @@ -1351,9 +1361,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.9" +version = "0.27.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" dependencies = [ "http", "hyper", @@ -1389,12 +1399,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1402,9 +1413,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -1415,9 +1426,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1429,16 +1440,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -1449,15 +1461,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -1481,9 +1493,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1491,9 +1503,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown 0.17.1", @@ -1532,9 +1544,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.1" +version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" [[package]] name = "itertools" @@ -1621,9 +1633,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.104" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", "futures-util", @@ -1687,9 +1699,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "logos" @@ -1759,9 +1771,9 @@ dependencies = [ [[package]] name = "lru-slab" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" [[package]] name = "matchers" @@ -1833,9 +1845,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.9" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" dependencies = [ "adler2", "simd-adler32", @@ -1843,9 +1855,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" dependencies = [ "libc", "wasi", @@ -1858,6 +1870,33 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +[[package]] +name = "multiversion" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca4bea16ffc3f443cf7d866912118196bfef4c6a1556ca00f9f9b00bb43f7c" +dependencies = [ + "multiversion-macros", +] + +[[package]] +name = "multiversion-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d416831a7317ef4b08bee00b69cbbb9c8763da7959a7026244d6266869f9c83" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 3.0.6", +] + +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + [[package]] name = "munge" version = "0.4.7" @@ -2007,6 +2046,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +[[package]] +name = "opus" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33718946cc77d4032911d4efe03a66dbcbfbd2bb16c3da06aaeadcc637c32216" +dependencies = [ + "opusic-sys", +] + [[package]] name = "opusic-sys" version = "0.7.5" @@ -2359,14 +2407,14 @@ checksum = "1c8d9ca532f185d5d4db7a7c9d51420b452168ea1c2b913953281bd6fe1fcbd0" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] name = "quinn" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" dependencies = [ "bytes", "cfg_aliases", @@ -2384,15 +2432,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.16" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" +checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc" dependencies = [ "aws-lc-rs", "bytes", "getrandom 0.4.3", "lru-slab", - "rand 0.10.2", + "rand 0.10.3", "rand_pcg", "ring", "rustc-hash 2.1.3", @@ -2461,11 +2509,11 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ - "chacha20 0.10.1", + "chacha20 0.10.2", "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2553,7 +2601,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", ] [[package]] @@ -2596,11 +2644,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "encoding_rs", "futures-core", @@ -2688,7 +2736,7 @@ checksum = "1c25ef604ac7dd839d44d64648952ea23c97866f124ff671b0ed2cf3ad9bb06e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -2753,7 +2801,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys 0.4.15", @@ -2762,11 +2810,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys 0.12.1", @@ -2775,9 +2823,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.43" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "aws-lc-rs", "once_cell", @@ -2839,9 +2887,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.14" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", @@ -2920,7 +2968,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "core-foundation", "core-foundation-sys", "libc", @@ -2970,7 +3018,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -3004,7 +3052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures 0.3.1", "digest 0.11.3", ] @@ -3026,7 +3074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures 0.3.1", "digest 0.11.3", ] @@ -3101,9 +3149,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" [[package]] name = "smol_str" @@ -3197,9 +3245,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -3226,6 +3274,17 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -3234,7 +3293,7 @@ checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "once_cell", - "rustix 1.1.4", + "rustix 1.1.5", "windows-sys 0.61.2", ] @@ -3275,7 +3334,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] @@ -3289,12 +3348,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -3304,15 +3362,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -3340,18 +3398,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" [[package]] name = "tokio" @@ -3378,14 +3427,14 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" dependencies = [ "rustls", "tokio", @@ -3442,7 +3491,7 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.13.1", + "bitflags 2.13.2", "bytes", "futures-util", "http", @@ -3544,7 +3593,7 @@ dependencies = [ "http", "httparse", "log", - "rand 0.10.2", + "rand 0.10.3", "rustls", "rustls-pki-types", "sha1 0.11.0", @@ -3586,9 +3635,9 @@ checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unicode-width" @@ -3632,9 +3681,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.24.0" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -3689,18 +3738,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.127" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -3711,9 +3760,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.77" +version = "0.4.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" +checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" dependencies = [ "js-sys", "wasm-bindgen", @@ -3721,9 +3770,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.127" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3731,22 +3780,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.127" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.127" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -3766,9 +3815,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.104" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" +checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" dependencies = [ "js-sys", "wasm-bindgen", @@ -4132,9 +4181,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" @@ -4194,30 +4243,30 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", - "synstructure", + "syn 3.0.6", + "synstructure 0.14.0", ] [[package]] name = "zerocopy" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", @@ -4235,14 +4284,14 @@ dependencies = [ [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", - "synstructure", + "syn 3.0.6", + "synstructure 0.14.0", ] [[package]] @@ -4278,9 +4327,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b5c6b5976d66c1d703c4fd17d3f5e43c8cedaacf604961b171adc7130896d8" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -4289,15 +4338,21 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47402523226a02bfe5230160dc3ccc089aa6f6f19e7fcbb4e6f824bbb1b4aa62" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.6", ] +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 5e94174..165cbec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ homepage = "https://getstream.io/video/" documentation = "https://docs.rs/getstream" keywords = ["video", "webrtc", "sfu", "stream", "rtc"] categories = ["api-bindings", "multimedia::video", "network-programming"] + # A published crate's own `.cargo/config.toml` is never read by Cargo (config is # discovered from the *consumer's* directory tree), so it is deliberately absent # from this list — see the note above `[dependencies]`. @@ -44,15 +45,13 @@ rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] # system dependency (libvpx) and the vendored-opus build tools. [dependencies] -# Opus encode/decode for the audio media path. `opusic-sys` is a maintained -# libopus binding (tracks libopus 1.6.1) that bundles + static-links a *vendored* -# libopus, so the SDK build needs no system libopus at link or runtime. It -# replaces the unmaintained `audiopus_sys` (RUSTSEC-2026-0150); see -# `src/rtc/opus.rs` for the thin safe wrapper. The bundled CMake build needs -# `cmake` and a C compiler on PATH and nothing else: its `CMakeLists.txt` -# declares `cmake_minimum_required(VERSION 3.16)`, which satisfies CMake 4's +# Opus encode/decode for the audio media path. A safe wrapper over `opusic-sys`, +# which bundles + static-links a *vendored* libopus, so the SDK build needs no +# system libopus at link or runtime. The bundled CMake build needs `cmake` and a +# C compiler on PATH and nothing else: its `CMakeLists.txt` declares +# `cmake_minimum_required(VERSION 3.16)`, which satisfies CMake 4's # minimum-policy floor without any build-time environment override. -opusic-sys = "0.7.4" +opus = "0.4" base64 = "0.23.1" bytes = "1.12.1" futures-util = "0.3.34" @@ -86,9 +85,6 @@ flate2 = "1.1.9" openh264 = "=0.8.1" [dev-dependencies] -# Example-only convenience for the two executable demos. OpenAI-specific bridge -# orchestration stays in `examples/gpt_realtime_bot.rs`; `tokio` here adds the -# runtime and signal features used only by the examples. anyhow = "1.0.86" criterion = "0.8.2" dotenvy = "0.15.7" diff --git a/benches/media_baseline.rs b/benches/media_baseline.rs index b35ed07..0a69426 100644 --- a/benches/media_baseline.rs +++ b/benches/media_baseline.rs @@ -93,7 +93,8 @@ fn bench_resampling(criterion: &mut Criterion) { fn bench_opus(criterion: &mut Criterion) { let pcm = tone(48_000, 1, 20).samples; - let mut encoder = rtc::opus::Encoder::new_voip_mono().expect("create Opus encoder"); + let mut encoder = opus::Encoder::new(48_000, opus::Channels::Mono, opus::Application::Voip) + .expect("create Opus encoder"); let mut encoded = vec![0u8; 1_500]; let mut group = criterion.benchmark_group("opus"); @@ -111,7 +112,8 @@ fn bench_opus(criterion: &mut Criterion) { .encode(&pcm, &mut encoded) .expect("encode Opus decode fixture"); encoded.truncate(encoded_length); - let mut decoder = rtc::opus::Decoder::new_mono().expect("create Opus decoder"); + let mut decoder = + opus::Decoder::new(48_000, opus::Channels::Mono).expect("create Opus decoder"); let mut decoded = vec![0i16; 5_760]; group.throughput(Throughput::Bytes(encoded.len() as u64)); group.bench_function("decode_48k_mono_20ms", |bencher| { @@ -274,8 +276,11 @@ fn bench_multitrack_load(criterion: &mut Criterion) { const VIDEO_H: u32 = 360; let pcm = tone(48_000, 1, 20).samples; - let mut audio_encoders: Vec = (0..AUDIO_TRACKS) - .map(|_| rtc::opus::Encoder::new_voip_mono().expect("create multitrack Opus encoder")) + let mut audio_encoders: Vec = (0..AUDIO_TRACKS) + .map(|_| { + opus::Encoder::new(48_000, opus::Channels::Mono, opus::Application::Voip) + .expect("create multitrack Opus encoder") + }) .collect(); let mut audio_scratch = vec![0u8; 1_500]; diff --git a/benches/support/rtc_sources.rs b/benches/support/rtc_sources.rs index e8ccfd0..421d612 100644 --- a/benches/support/rtc_sources.rs +++ b/benches/support/rtc_sources.rs @@ -12,8 +12,6 @@ pub(crate) mod error { #[path = "../../src/rtc/h264.rs"] pub(crate) mod h264; -#[path = "../../src/rtc/opus.rs"] -pub(crate) mod opus; #[path = "../../src/rtc/rtp_h264.rs"] pub(crate) mod rtp_h264; #[path = "../../src/rtc/rtp_vpx.rs"] diff --git a/benches/timer_drift.rs b/benches/timer_drift.rs index 07e84e9..f6cd7e3 100644 --- a/benches/timer_drift.rs +++ b/benches/timer_drift.rs @@ -2,10 +2,6 @@ use std::time::Duration; -#[allow(dead_code)] -#[path = "../src/rtc/opus.rs"] -mod opus; - const PERIOD: Duration = Duration::from_millis(20); const TICKS: usize = 500; @@ -26,7 +22,9 @@ async fn measure_timer_drift() { (12_000.0 * (std::f64::consts::TAU * 440.0 * time).sin()) as i16 }) .collect(); - let mut encoder = opus::Encoder::new_voip_mono().expect("create Opus encoder"); + let mut encoder = + opus::Encoder::new(sample_rate, opus::Channels::Mono, opus::Application::Voip) + .expect("create Opus encoder"); let mut encoded = vec![0u8; 1_500]; let mut interval = tokio::time::interval(PERIOD); diff --git a/deny.toml b/deny.toml index 9b17f86..08977ec 100644 --- a/deny.toml +++ b/deny.toml @@ -6,9 +6,7 @@ # from software licenses. [advisories] -# Fail on all security advisories. There are no ignores: the previously -# unmaintained Opus binding (`audiopus_sys`, RUSTSEC-2026-0150) was replaced by -# the maintained `opusic-sys`, so no advisory needs suppressing. +# Fail on all security advisories. There are no ignores. [licenses] # Dependency-license policy. If a new dependency introduces an unreviewed diff --git a/src/rtc/local_track.rs b/src/rtc/local_track.rs index ed316ff..a6f709f 100644 --- a/src/rtc/local_track.rs +++ b/src/rtc/local_track.rs @@ -321,7 +321,7 @@ struct AudioInner { /// Resampled 48 kHz mono PCM awaiting the 20 ms pacer. pcm: StdMutex>, resampler: StdMutex, - encoder: StdMutex, + encoder: StdMutex, pacer: StdMutex>>, pacer_started: AtomicBool, pcm_pacing: AtomicBool, @@ -350,7 +350,12 @@ impl LocalAudioTrack { }; let track_id = format!("audio-{}", uuid::Uuid::new_v4().simple()); let core = TrackCore::new(codec, track_id, "stream-rust-audio".to_owned())?; - let encoder = super::opus::Encoder::new_voip_mono().map_err(RtcError::Media)?; + let encoder = opus::Encoder::new( + OPUS_SAMPLE_RATE, + opus::Channels::Mono, + opus::Application::Voip, + ) + .map_err(|error| RtcError::Media(error.to_string()))?; Ok(Self { inner: Arc::new(AudioInner { core, @@ -601,12 +606,10 @@ fn push_bounded_pcm(queue: &mut VecDeque, samples: Vec) -> usize { overflow } -fn encode_opus_into( - encoder: &mut super::opus::Encoder, - pcm: &[i16], - output: &mut [u8], -) -> Result { - encoder.encode(pcm, output).map_err(RtcError::Media) +fn encode_opus_into(encoder: &mut opus::Encoder, pcm: &[i16], output: &mut [u8]) -> Result { + encoder + .encode(pcm, output) + .map_err(|error| RtcError::Media(error.to_string())) } // Video @@ -1915,6 +1918,42 @@ impl LocalTrack { mod tests { use super::*; + #[test] + fn encode_opus_into_produces_a_packet_for_a_20ms_mono_frame() { + let mut encoder = opus::Encoder::new( + OPUS_SAMPLE_RATE, + opus::Channels::Mono, + opus::Application::Voip, + ) + .expect("encoder"); + let pcm = vec![1_000i16; FRAME_SAMPLES_20MS]; + let mut output = vec![0u8; 1_500]; + + let length = encode_opus_into(&mut encoder, &pcm, &mut output).expect("encode"); + + assert!( + length > 0 && length <= output.len(), + "packet length {length}" + ); + } + + #[test] + fn encode_opus_into_rejects_a_bogus_frame_size() { + let mut encoder = opus::Encoder::new( + OPUS_SAMPLE_RATE, + opus::Channels::Mono, + opus::Application::Voip, + ) + .expect("encoder"); + let mut output = vec![0u8; 1_500]; + + // 137 samples is not a valid 48 kHz Opus frame size. + let error = encode_opus_into(&mut encoder, &vec![0i16; 137], &mut output) + .expect_err("bogus frame size must be rejected"); + + assert!(matches!(error, RtcError::Media(_)), "error was: {error}"); + } + #[tokio::test] async fn opus_track_builds_and_writes_sample() { let track = LocalAudioTrack::opus().expect("opus track"); diff --git a/src/rtc/mod.rs b/src/rtc/mod.rs index a0c0fcb..e5d2807 100644 --- a/src/rtc/mod.rs +++ b/src/rtc/mod.rs @@ -29,7 +29,6 @@ pub mod identity; pub mod join; mod layers; pub mod local_track; -mod opus; pub mod pcm; pub mod peer; pub mod proto; diff --git a/src/rtc/opus.rs b/src/rtc/opus.rs deleted file mode 100644 index cb8d08f..0000000 --- a/src/rtc/opus.rs +++ /dev/null @@ -1,233 +0,0 @@ -//! Thin, safe wrapper over the maintained [`opusic-sys`] libopus binding. -//! -//! The SDK only needs a narrow slice of libopus: a mono 48 kHz VoIP encoder for -//! the publish path and a mono 48 kHz decoder for the subscribe path. This module -//! owns the raw `OpusEncoder`/`OpusDecoder` handles behind RAII guards so the C -//! resources are always released, and turns libopus's negative status codes into -//! descriptive errors. It replaces the unmaintained `audiopus_sys` -//! (RUSTSEC-2026-0150) with a binding that tracks upstream libopus. -//! -//! [`opusic-sys`]: https://crates.io/crates/opusic-sys - -use core::ffi::{CStr, c_int}; - -use opusic_sys as sys; - -/// The single sample rate the SDK's Opus path uses (matches the SFU codec and -/// [`super::pcm::OPUS_SAMPLE_RATE`]). Kept local so this wrapper is self-contained -/// and can be compiled standalone by the benches. -const OPUS_SAMPLE_RATE_HZ: sys::opus_int32 = 48_000; - -/// Render a libopus status code as a human-readable string. -fn opus_strerror(code: c_int) -> String { - // SAFETY: `opus_strerror` returns a pointer to a static, NUL-terminated C - // string for any input, so the pointer is valid and lives for the program. - let ptr = unsafe { sys::opus_strerror(code) }; - if ptr.is_null() { - return format!("opus error {code}"); - } - // SAFETY: `ptr` is non-null and points at a static NUL-terminated string. - unsafe { CStr::from_ptr(ptr) } - .to_string_lossy() - .into_owned() -} - -fn frame_size_arg(samples: usize, what: &str) -> Result { - c_int::try_from(samples).map_err(|_| format!("opus {what} frame too large: {samples} samples")) -} - -fn max_bytes_arg(bytes: usize) -> Result { - i32::try_from(bytes).map_err(|_| format!("opus output buffer too large: {bytes} bytes")) -} - -/// A mono 48 kHz Opus encoder configured for interactive voice. -/// -/// libopus mutates encoder state on every `encode`, so the methods take `&mut -/// self`; callers serialize access (the media path holds it in a mutex). -pub struct Encoder { - raw: *mut sys::OpusEncoder, -} - -// SAFETY: `OpusEncoder` is a self-contained heap allocation with no thread -// affinity; libopus permits moving an instance between threads. It is *not* -// `Sync` (concurrent `opus_encode` on one instance is UB), so we deliberately do -// not implement `Sync` — callers guard shared access with a mutex. -unsafe impl Send for Encoder {} - -impl Encoder { - /// Create a mono 48 kHz encoder tuned for VoIP (matches the SFU Opus codec). - /// - /// # Errors - /// - /// Returns the libopus status string if the encoder cannot be created. - pub fn new_voip_mono() -> Result { - let mut error: c_int = sys::OPUS_OK; - // SAFETY: all scalar args are valid libopus inputs; `error` is a valid - // out-pointer. On success the returned pointer owns a fresh encoder that - // we free in `Drop`. - let raw = unsafe { - sys::opus_encoder_create( - OPUS_SAMPLE_RATE_HZ, - 1, - sys::OPUS_APPLICATION_VOIP, - &raw mut error, - ) - }; - if error != sys::OPUS_OK || raw.is_null() { - return Err(format!("opus encoder init: {}", opus_strerror(error))); - } - Ok(Self { raw }) - } - - /// Encode one mono frame of 16-bit PCM into `output`, returning the byte - /// length of the Opus packet. - /// - /// `pcm.len()` must be a valid Opus frame size for 48 kHz (e.g. 960 for the - /// 20 ms media frame). - /// - /// # Errors - /// - /// Returns the libopus status string if encoding fails or the frame size is - /// not representable. - pub fn encode(&mut self, pcm: &[i16], output: &mut [u8]) -> Result { - let frame_size = frame_size_arg(pcm.len(), "encode")?; - let max_bytes = max_bytes_arg(output.len())?; - // SAFETY: `self.raw` is a live encoder; `pcm`/`output` are valid slices - // whose lengths we pass as the frame size and capacity, so libopus reads - // exactly `frame_size` samples and writes at most `max_bytes`. - let written = unsafe { - sys::opus_encode( - self.raw, - pcm.as_ptr(), - frame_size, - output.as_mut_ptr(), - max_bytes, - ) - }; - if written < 0 { - return Err(format!("opus encode: {}", opus_strerror(written))); - } - Ok(written as usize) - } -} - -impl Drop for Encoder { - fn drop(&mut self) { - // SAFETY: `self.raw` was created by `opus_encoder_create` and is freed - // exactly once here; no other code frees or uses it afterwards. - unsafe { sys::opus_encoder_destroy(self.raw) }; - } -} - -/// A mono 48 kHz Opus decoder. -pub struct Decoder { - raw: *mut sys::OpusDecoder, -} - -// SAFETY: see `Encoder` — an `OpusDecoder` may move between threads but is not -// safe for concurrent use, so it is `Send` but not `Sync`. -unsafe impl Send for Decoder {} - -impl Decoder { - /// Create a mono 48 kHz decoder. - /// - /// # Errors - /// - /// Returns the libopus status string if the decoder cannot be created. - pub fn new_mono() -> Result { - let mut error: c_int = sys::OPUS_OK; - // SAFETY: valid scalar args and a valid `error` out-pointer; a non-null - // result owns a decoder freed in `Drop`. - let raw = unsafe { sys::opus_decoder_create(OPUS_SAMPLE_RATE_HZ, 1, &raw mut error) }; - if error != sys::OPUS_OK || raw.is_null() { - return Err(format!("opus decoder init: {}", opus_strerror(error))); - } - Ok(Self { raw }) - } - - /// Decode one Opus packet into `output`, returning the number of mono samples - /// written. `output.len()` bounds the samples produced. - /// - /// # Errors - /// - /// Returns the libopus status string if decoding fails or the frame size is - /// not representable. - pub fn decode( - &mut self, - packet: &[u8], - output: &mut [i16], - fec: bool, - ) -> Result { - let frame_size = frame_size_arg(output.len(), "decode")?; - let len = max_bytes_arg(packet.len())?; - // SAFETY: `self.raw` is a live decoder; `packet`/`output` are valid - // slices whose lengths bound the read and the write. libopus writes at - // most `frame_size` samples into `output`. - let samples = unsafe { - sys::opus_decode( - self.raw, - packet.as_ptr(), - len, - output.as_mut_ptr(), - frame_size, - c_int::from(fec), - ) - }; - if samples < 0 { - return Err(format!("opus decode: {}", opus_strerror(samples))); - } - Ok(samples as usize) - } -} - -impl Drop for Decoder { - fn drop(&mut self) { - // SAFETY: `self.raw` was created by `opus_decoder_create` and is freed - // exactly once here. - unsafe { sys::opus_decoder_destroy(self.raw) }; - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::f64::consts::PI; - - fn tone_20ms() -> Vec { - let frame = OPUS_SAMPLE_RATE_HZ as usize / 50; - (0..frame) - .map(|i| { - let t = i as f64 / f64::from(OPUS_SAMPLE_RATE_HZ); - (12_000.0 * (2.0 * PI * 440.0 * t).sin()) as i16 - }) - .collect() - } - - #[test] - fn encode_then_decode_round_trips_a_tone() { - let mut encoder = Encoder::new_voip_mono().expect("encoder"); - let mut decoder = Decoder::new_mono().expect("decoder"); - let pcm = tone_20ms(); - let mut packet = vec![0u8; 4_000]; - - let bytes = encoder.encode(&pcm, &mut packet).expect("encode"); - assert!(bytes > 0 && bytes <= packet.len(), "packet length {bytes}"); - - let mut out = vec![0i16; 5_760]; - let samples = decoder - .decode(&packet[..bytes], &mut out, false) - .expect("decode"); - assert_eq!(samples, pcm.len(), "decoded sample count matches the frame"); - } - - #[test] - fn encode_rejects_a_bogus_frame_size() { - let mut encoder = Encoder::new_voip_mono().expect("encoder"); - let mut packet = vec![0u8; 4_000]; - // 137 samples is not a valid 48 kHz Opus frame size. - let err = encoder - .encode(&vec![0i16; 137], &mut packet) - .expect_err("bogus frame size must be rejected"); - assert!(err.contains("opus encode"), "error was: {err}"); - } -} diff --git a/src/rtc/remote_track.rs b/src/rtc/remote_track.rs index 9c6ecba..7f11ade 100644 --- a/src/rtc/remote_track.rs +++ b/src/rtc/remote_track.rs @@ -208,7 +208,7 @@ struct VideoDecode { /// How this track's payload is turned into something the caller can use. enum Decode { /// Opus → 48 kHz mono PCM. - Audio(StdMutex), + Audio(StdMutex), /// VP8/VP9/H264 RTP → packed I420 frames. Shared with the bounded blocking /// decode work; a [`SampleBuilder`] carries a full sequence-number window. Video(Arc>), @@ -602,7 +602,7 @@ fn is_audio(track_type: TrackType) -> bool { /// returning `None` rather than panicking; `read_rtp` keeps working either way. fn build_decoder(track_type: TrackType, codec: &Codec) -> Decode { if is_audio(track_type) { - return match super::opus::Decoder::new_mono() { + return match opus::Decoder::new(OPUS_SAMPLE_RATE, opus::Channels::Mono) { Ok(d) => Decode::Audio(StdMutex::new(d)), Err(e) => { tracing::warn!(error = %e, "stream.rtc.remote.opus_decoder_init_failed"); @@ -656,9 +656,9 @@ fn video_codec_for(mime_type: &str) -> Option { /// Decode a single Opus packet into mono s16 samples (48 kHz). fn decode_opus( - decoder: &mut super::opus::Decoder, + decoder: &mut opus::Decoder, payload: &[u8], -) -> std::result::Result, String> { +) -> std::result::Result, opus::Error> { // Max Opus frame at 48 kHz mono is 120 ms = 5760 samples. let mut out = vec![0i16; 5760]; let n = decoder.decode(payload, &mut out, false)?; @@ -669,6 +669,7 @@ fn decode_opus( #[cfg(test)] mod tests { use super::*; + use crate::rtc::pcm::FRAME_SAMPLES_20MS; #[test] fn supported_video_mime_types_map_to_a_decoder() { @@ -677,6 +678,41 @@ mod tests { assert_eq!(video_codec_for("video/H264"), Some(VideoCodec::H264)); } + #[test] + fn decoded_opus_yields_one_20ms_mono_frame() { + let mut encoder = opus::Encoder::new( + OPUS_SAMPLE_RATE, + opus::Channels::Mono, + opus::Application::Voip, + ) + .expect("encoder"); + let pcm: Vec = (0..FRAME_SAMPLES_20MS) + .map(|index| { + let time = index as f64 / f64::from(OPUS_SAMPLE_RATE); + (12_000.0 * (std::f64::consts::TAU * 440.0 * time).sin()) as i16 + }) + .collect(); + let mut packet = vec![0u8; 1_500]; + let length = encoder.encode(&pcm, &mut packet).expect("encode"); + + let mut decoder = + opus::Decoder::new(OPUS_SAMPLE_RATE, opus::Channels::Mono).expect("decoder"); + let samples = decode_opus(&mut decoder, &packet[..length]).expect("decode"); + + assert_eq!(samples.len(), FRAME_SAMPLES_20MS); + assert!( + samples.iter().any(|sample| sample.abs() > 1_000), + "decoded frame is silent" + ); + } + + #[test] + fn decoding_a_corrupt_payload_is_an_error() { + let mut decoder = + opus::Decoder::new(OPUS_SAMPLE_RATE, opus::Channels::Mono).expect("decoder"); + assert!(decode_opus(&mut decoder, &[0xff; 4]).is_err()); + } + #[test] fn undecodable_video_codecs_have_no_decoder() { assert_eq!(video_codec_for("video/AV1"), None);