From cb4cb6ee38d6bc893ffa6860bddf24f345d1563e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Fri, 31 May 2024 03:09:56 +0200 Subject: [PATCH 1/5] Update .gitignore --- webrtc-sys/libwebrtc/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webrtc-sys/libwebrtc/.gitignore b/webrtc-sys/libwebrtc/.gitignore index 382124058..e9b7b8276 100644 --- a/webrtc-sys/libwebrtc/.gitignore +++ b/webrtc-sys/libwebrtc/.gitignore @@ -4,6 +4,8 @@ src depot_tools ninja +!src/livekit_rtc/**/* + # builds win-* mac-* From 9535b9f8ccfe2a1aa63cbf2cb709b258c7dec292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Fri, 31 May 2024 03:18:06 +0200 Subject: [PATCH 2/5] Create .gitignore --- webrtc-sys/libwebrtc/.gitignore | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/webrtc-sys/libwebrtc/.gitignore b/webrtc-sys/libwebrtc/.gitignore index e9b7b8276..98019b583 100644 --- a/webrtc-sys/libwebrtc/.gitignore +++ b/webrtc-sys/libwebrtc/.gitignore @@ -1,14 +1,16 @@ .cipd -src .gclient_* depot_tools ninja -!src/livekit_rtc/**/* - # builds win-* mac-* linux-* android-* ios-* + +src/* +!src/livekit_rtc/* + + From 00d428043e28dfd7cf848d96be8a699b8331f753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Sun, 2 Jun 2024 12:37:47 +0200 Subject: [PATCH 3/5] wip C bindings --- Cargo.lock | 783 +++--------------- Cargo.toml | 4 +- livekit-api/src/services/ingress.rs | 6 + livekit-api/src/services/sip.rs | 49 +- livekit-ffi/Cargo.toml | 4 +- livekit-protocol/protocol | 2 +- livekit-protocol/src/livekit.rs | 104 ++- livekit-protocol/src/livekit.serde.rs | 486 ++++++++++- webrtc-sys/Cargo.toml | 10 +- webrtc-sys/README.md | 16 - webrtc-sys/build.rs | 246 +----- webrtc-sys/build/Cargo.toml | 15 - webrtc-sys/build/src/lib.rs | 284 ------- webrtc-sys/compile_flags.txt | 21 - webrtc-sys/generate_bindgen.sh | 5 + webrtc-sys/generate_jni_symbols.sh | 13 + webrtc-sys/include/livekit/android.h | 37 - webrtc-sys/include/livekit/audio_device.h | 129 --- webrtc-sys/include/livekit/audio_resampler.h | 47 -- webrtc-sys/include/livekit/audio_track.h | 142 ---- webrtc-sys/include/livekit/candidate.h | 43 - webrtc-sys/include/livekit/data_channel.h | 78 -- webrtc-sys/include/livekit/frame_cryptor.h | 202 ----- webrtc-sys/include/livekit/helper.h | 57 -- webrtc-sys/include/livekit/jsep.h | 151 ---- webrtc-sys/include/livekit/media_stream.h | 57 -- .../include/livekit/media_stream_track.h | 60 -- .../include/livekit/objc_video_factory.h | 29 - webrtc-sys/include/livekit/peer_connection.h | 208 ----- .../include/livekit/peer_connection_factory.h | 71 -- webrtc-sys/include/livekit/rtc_error.h | 34 - webrtc-sys/include/livekit/rtp_parameters.h | 61 -- webrtc-sys/include/livekit/rtp_receiver.h | 79 -- webrtc-sys/include/livekit/rtp_sender.h | 81 -- webrtc-sys/include/livekit/rtp_transceiver.h | 93 --- webrtc-sys/include/livekit/video_frame.h | 71 -- .../include/livekit/video_frame_buffer.h | 232 ------ webrtc-sys/include/livekit/video_track.h | 140 ---- webrtc-sys/include/livekit/webrtc.h | 116 --- webrtc-sys/include/livekit/yuv_helper.h | 364 -------- webrtc-sys/libwebrtc/.gitignore | 5 +- webrtc-sys/libwebrtc/build-utils/Cargo.toml | 13 + .../build-utils/generate_jni_symbols.sh | 13 + .../libwebrtc/build-utils/jni_symbols.txt | 215 +++++ webrtc-sys/libwebrtc/build-utils/src/lib.rs | 287 +++++++ webrtc-sys/libwebrtc/build_macos.sh | 23 +- webrtc-sys/libwebrtc/compile_flags.txt | 14 + webrtc-sys/libwebrtc/src/livekit_rtc/BUILD.gn | 84 ++ .../src/livekit_rtc/livekit/android.h | 18 + .../src/livekit_rtc/livekit/audio_device.h | 155 ++++ .../src/livekit_rtc/livekit/audio_track.h | 13 + .../libwebrtc/src/livekit_rtc/livekit/capi.h | 218 +++++ .../src/livekit_rtc/livekit/data_channel.h | 64 ++ .../livekit_rtc/livekit/objc_video_factory.h | 16 + .../libwebrtc/src/livekit_rtc/livekit/peer.h | 104 +++ .../src/livekit_rtc/livekit/transceiver.h | 38 + .../libwebrtc/src/livekit_rtc/livekit/utils.h | 17 + .../src/livekit_rtc/livekit/video_decoder.h} | 21 +- .../src/livekit_rtc/livekit/video_encoder.h} | 21 +- .../src/livekit_rtc/src/android.cc} | 18 +- .../src/livekit_rtc/src/audio_device.cc | 53 ++ .../libwebrtc/src/livekit_rtc/src/capi.cc | 149 ++++ .../src/livekit_rtc/src/data_channel.cc | 62 ++ .../src/livekit_rtc/src/objc_video_factory.mm | 22 + .../libwebrtc/src/livekit_rtc/src/peer.cc | 392 +++++++++ .../src/livekit_rtc/src/transceiver.cc | 24 + .../libwebrtc/src/livekit_rtc/src/utils.cc | 21 + .../src/livekit_rtc/src/video_decoder.cc} | 22 +- .../src/livekit_rtc/src/video_encoder.cc} | 2 +- webrtc-sys/src/android.rs | 24 - webrtc-sys/src/audio_device.cpp | 335 -------- webrtc-sys/src/audio_resampler.cpp | 47 -- webrtc-sys/src/audio_resampler.rs | 40 - webrtc-sys/src/audio_track.cpp | 176 ---- webrtc-sys/src/audio_track.rs | 94 --- webrtc-sys/src/candidate.cpp | 22 - webrtc-sys/src/candidate.rs | 24 - webrtc-sys/src/data_channel.cpp | 117 --- webrtc-sys/src/data_channel.rs | 117 --- webrtc-sys/src/frame_cryptor.cpp | 187 ----- webrtc-sys/src/frame_cryptor.rs | 166 ---- webrtc-sys/src/helper.rs | 67 -- webrtc-sys/src/jsep.cpp | 151 ---- webrtc-sys/src/jsep.rs | 132 --- webrtc-sys/src/lib.rs | 45 +- webrtc-sys/src/media_stream.cpp | 101 --- webrtc-sys/src/media_stream.rs | 49 -- webrtc-sys/src/media_stream_track.cpp | 58 -- webrtc-sys/src/media_stream_track.rs | 40 - webrtc-sys/src/objc_video_factory.mm | 35 - webrtc-sys/src/peer_connection.cpp | 478 ----------- webrtc-sys/src/peer_connection.rs | 236 +----- webrtc-sys/src/peer_connection_factory.cpp | 145 ---- webrtc-sys/src/peer_connection_factory.rs | 307 ------- webrtc-sys/src/rtc_error.cpp | 68 -- webrtc-sys/src/rtc_error.rs | 136 --- webrtc-sys/src/rtp_parameters.cpp | 414 --------- webrtc-sys/src/rtp_parameters.rs | 198 ----- webrtc-sys/src/rtp_receiver.cpp | 81 -- webrtc-sys/src/rtp_receiver.rs | 63 -- webrtc-sys/src/rtp_sender.cpp | 93 --- webrtc-sys/src/rtp_sender.rs | 65 -- webrtc-sys/src/rtp_transceiver.cpp | 154 ---- webrtc-sys/src/rtp_transceiver.rs | 79 -- webrtc-sys/src/sys/ffi.rs | 651 +++++++++++++++ webrtc-sys/src/sys/mod.rs | 118 +++ webrtc-sys/src/video_frame.cpp | 86 -- webrtc-sys/src/video_frame.rs | 62 -- webrtc-sys/src/video_frame_buffer.cpp | 272 ------ webrtc-sys/src/video_frame_buffer.rs | 156 ---- webrtc-sys/src/video_track.cpp | 202 ----- webrtc-sys/src/video_track.rs | 118 --- webrtc-sys/src/webrtc.cpp | 176 ---- webrtc-sys/src/webrtc.rs | 67 -- webrtc-sys/src/yuv_helper.rs | 297 ------- 115 files changed, 3542 insertions(+), 9941 deletions(-) delete mode 100644 webrtc-sys/README.md delete mode 100644 webrtc-sys/build/Cargo.toml delete mode 100644 webrtc-sys/build/src/lib.rs delete mode 100644 webrtc-sys/compile_flags.txt create mode 100755 webrtc-sys/generate_bindgen.sh create mode 100755 webrtc-sys/generate_jni_symbols.sh delete mode 100644 webrtc-sys/include/livekit/android.h delete mode 100644 webrtc-sys/include/livekit/audio_device.h delete mode 100644 webrtc-sys/include/livekit/audio_resampler.h delete mode 100644 webrtc-sys/include/livekit/audio_track.h delete mode 100644 webrtc-sys/include/livekit/candidate.h delete mode 100644 webrtc-sys/include/livekit/data_channel.h delete mode 100644 webrtc-sys/include/livekit/frame_cryptor.h delete mode 100644 webrtc-sys/include/livekit/helper.h delete mode 100644 webrtc-sys/include/livekit/jsep.h delete mode 100644 webrtc-sys/include/livekit/media_stream.h delete mode 100644 webrtc-sys/include/livekit/media_stream_track.h delete mode 100644 webrtc-sys/include/livekit/objc_video_factory.h delete mode 100644 webrtc-sys/include/livekit/peer_connection.h delete mode 100644 webrtc-sys/include/livekit/peer_connection_factory.h delete mode 100644 webrtc-sys/include/livekit/rtc_error.h delete mode 100644 webrtc-sys/include/livekit/rtp_parameters.h delete mode 100644 webrtc-sys/include/livekit/rtp_receiver.h delete mode 100644 webrtc-sys/include/livekit/rtp_sender.h delete mode 100644 webrtc-sys/include/livekit/rtp_transceiver.h delete mode 100644 webrtc-sys/include/livekit/video_frame.h delete mode 100644 webrtc-sys/include/livekit/video_frame_buffer.h delete mode 100644 webrtc-sys/include/livekit/video_track.h delete mode 100644 webrtc-sys/include/livekit/webrtc.h delete mode 100644 webrtc-sys/include/livekit/yuv_helper.h create mode 100644 webrtc-sys/libwebrtc/build-utils/Cargo.toml create mode 100755 webrtc-sys/libwebrtc/build-utils/generate_jni_symbols.sh create mode 100644 webrtc-sys/libwebrtc/build-utils/jni_symbols.txt create mode 100644 webrtc-sys/libwebrtc/build-utils/src/lib.rs create mode 100644 webrtc-sys/libwebrtc/compile_flags.txt create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/BUILD.gn create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/android.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_device.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_track.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/capi.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/data_channel.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/objc_video_factory.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/peer.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/transceiver.h create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/livekit/utils.h rename webrtc-sys/{include/livekit/video_decoder_factory.h => libwebrtc/src/livekit_rtc/livekit/video_decoder.h} (52%) rename webrtc-sys/{include/livekit/video_encoder_factory.h => libwebrtc/src/livekit_rtc/livekit/video_encoder.h} (66%) rename webrtc-sys/{src/android.cpp => libwebrtc/src/livekit_rtc/src/android.cc} (71%) create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/audio_device.cc create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/capi.cc create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/data_channel.cc create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/objc_video_factory.mm create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/peer.cc create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/transceiver.cc create mode 100644 webrtc-sys/libwebrtc/src/livekit_rtc/src/utils.cc rename webrtc-sys/{src/video_decoder_factory.cpp => libwebrtc/src/livekit_rtc/src/video_decoder.cc} (82%) rename webrtc-sys/{src/video_encoder_factory.cpp => libwebrtc/src/livekit_rtc/src/video_encoder.cc} (99%) delete mode 100644 webrtc-sys/src/android.rs delete mode 100644 webrtc-sys/src/audio_device.cpp delete mode 100644 webrtc-sys/src/audio_resampler.cpp delete mode 100644 webrtc-sys/src/audio_resampler.rs delete mode 100644 webrtc-sys/src/audio_track.cpp delete mode 100644 webrtc-sys/src/audio_track.rs delete mode 100644 webrtc-sys/src/candidate.cpp delete mode 100644 webrtc-sys/src/candidate.rs delete mode 100644 webrtc-sys/src/data_channel.cpp delete mode 100644 webrtc-sys/src/data_channel.rs delete mode 100644 webrtc-sys/src/frame_cryptor.cpp delete mode 100644 webrtc-sys/src/frame_cryptor.rs delete mode 100644 webrtc-sys/src/helper.rs delete mode 100644 webrtc-sys/src/jsep.cpp delete mode 100644 webrtc-sys/src/jsep.rs delete mode 100644 webrtc-sys/src/media_stream.cpp delete mode 100644 webrtc-sys/src/media_stream.rs delete mode 100644 webrtc-sys/src/media_stream_track.cpp delete mode 100644 webrtc-sys/src/media_stream_track.rs delete mode 100644 webrtc-sys/src/objc_video_factory.mm delete mode 100644 webrtc-sys/src/peer_connection.cpp delete mode 100644 webrtc-sys/src/peer_connection_factory.cpp delete mode 100644 webrtc-sys/src/peer_connection_factory.rs delete mode 100644 webrtc-sys/src/rtc_error.cpp delete mode 100644 webrtc-sys/src/rtc_error.rs delete mode 100644 webrtc-sys/src/rtp_parameters.cpp delete mode 100644 webrtc-sys/src/rtp_parameters.rs delete mode 100644 webrtc-sys/src/rtp_receiver.cpp delete mode 100644 webrtc-sys/src/rtp_receiver.rs delete mode 100644 webrtc-sys/src/rtp_sender.cpp delete mode 100644 webrtc-sys/src/rtp_sender.rs delete mode 100644 webrtc-sys/src/rtp_transceiver.cpp delete mode 100644 webrtc-sys/src/rtp_transceiver.rs create mode 100644 webrtc-sys/src/sys/ffi.rs create mode 100644 webrtc-sys/src/sys/mod.rs delete mode 100644 webrtc-sys/src/video_frame.cpp delete mode 100644 webrtc-sys/src/video_frame.rs delete mode 100644 webrtc-sys/src/video_frame_buffer.cpp delete mode 100644 webrtc-sys/src/video_frame_buffer.rs delete mode 100644 webrtc-sys/src/video_track.cpp delete mode 100644 webrtc-sys/src/video_track.rs delete mode 100644 webrtc-sys/src/webrtc.cpp delete mode 100644 webrtc-sys/src/webrtc.rs delete mode 100644 webrtc-sys/src/yuv_helper.rs diff --git a/Cargo.lock b/Cargo.lock index 7fc730b65..32fe723c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,17 +199,6 @@ version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" -[[package]] -name = "async-trait" -version = "0.1.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.50", -] - [[package]] name = "async-tungstenite" version = "0.25.0" @@ -237,51 +226,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http 0.2.11", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 0.2.11", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - [[package]] name = "backtrace" version = "0.3.69" @@ -304,33 +248,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] -name = "base64ct" -version = "1.6.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "bindgen" -version = "0.69.2" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" -dependencies = [ - "bitflags 2.4.1", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.50", - "which", -] +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -430,15 +357,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -464,27 +382,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clang-sys" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "combine" version = "4.6.6" @@ -504,43 +401,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console-api" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tonic", - "tracing-core", -] - -[[package]] -name = "console-subscriber" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" -dependencies = [ - "console-api", - "crossbeam-channel", - "crossbeam-utils", - "futures", - "hdrhistogram", - "humantime", - "parking_lot", - "prost-types 0.11.9", - "serde", - "serde_json", - "thread_local", - "tokio", - "tokio-stream", - "tonic", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -581,35 +441,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -668,21 +499,6 @@ dependencies = [ "link-cplusplus", ] -[[package]] -name = "cxx-build" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bc81d2664db24cf1d35405f66e18a85cffd4d49ab930c71a5c6342a410f38c" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.50", -] - [[package]] name = "cxxbridge-flags" version = "1.0.111" @@ -697,20 +513,7 @@ checksum = "5c6888cd161769d65134846d4d4981d5a6654307cc46ec83fb917e530aea5f84" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.3", - "lock_api", - "once_cell", - "parking_lot_core", + "syn", ] [[package]] @@ -739,12 +542,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "either" version = "1.9.0" @@ -992,7 +789,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -1054,12 +851,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "gloo-timers" version = "0.2.6" @@ -1084,38 +875,19 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.11", - "indexmap 2.1.0", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -[[package]] -name = "hdrhistogram" -version = "7.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" -dependencies = [ - "base64", - "byteorder", - "flate2", - "nom", - "num-traits", -] - [[package]] name = "heck" version = "0.4.1" @@ -1230,23 +1002,11 @@ dependencies = [ "futures-util", "http 0.2.11", "hyper", - "rustls", + "rustls 0.21.10", "tokio", "tokio-rustls", ] -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - [[package]] name = "hyper-tls" version = "0.5.0" @@ -1270,25 +1030,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "imgproc" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce22149028888b582c91e56e1d53add9cd42f98d22046618478ef2aadbc9091" -dependencies = [ - "yuv-sys", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.1.0" @@ -1296,7 +1037,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -1374,15 +1115,6 @@ dependencies = [ "waker-fn", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.11.0" @@ -1444,7 +1176,7 @@ version = "9.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" dependencies = [ - "base64", + "base64 0.21.5", "js-sys", "ring", "serde", @@ -1466,28 +1198,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "libwebrtc" version = "0.3.2" @@ -1512,6 +1228,16 @@ dependencies = [ "webrtc-sys", ] +[[package]] +name = "libwebrtc-build" +version = "0.3.2" +dependencies = [ + "fs2", + "scratch", + "ureq", + "zip", +] + [[package]] name = "libz-sys" version = "1.1.15" @@ -1557,7 +1283,7 @@ dependencies = [ "livekit-runtime", "log", "parking_lot", - "prost 0.12.3", + "prost", "serde", "serde_json", "thiserror", @@ -1569,7 +1295,7 @@ name = "livekit-api" version = "0.3.2" dependencies = [ "async-tungstenite", - "base64", + "base64 0.21.5", "futures-util", "http 0.2.11", "isahc", @@ -1578,7 +1304,7 @@ dependencies = [ "livekit-runtime", "log", "parking_lot", - "prost 0.12.3", + "prost", "reqwest", "scopeguard", "serde", @@ -1590,30 +1316,6 @@ dependencies = [ "url", ] -[[package]] -name = "livekit-ffi" -version = "0.5.0" -dependencies = [ - "console-subscriber", - "dashmap", - "downcast-rs", - "env_logger", - "futures-util", - "imgproc", - "jni", - "lazy_static", - "livekit", - "livekit-api", - "livekit-protocol", - "log", - "parking_lot", - "prost 0.12.3", - "prost-types 0.12.3", - "thiserror", - "tokio", - "webrtc-sys-build", -] - [[package]] name = "livekit-protocol" version = "0.3.2" @@ -1623,8 +1325,8 @@ dependencies = [ "parking_lot", "pbjson", "pbjson-types", - "prost 0.12.3", - "prost-types 0.12.3", + "prost", + "prost-types", "serde", "thiserror", "tokio", @@ -1660,21 +1362,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "memchr" version = "2.6.4" @@ -1687,12 +1374,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1737,16 +1418,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-traits" version = "0.2.17" @@ -1804,7 +1475,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -1857,13 +1528,10 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ - "backtrace", "cfg-if", "libc", - "petgraph", "redox_syscall", "smallvec", - "thread-id", "windows-targets 0.48.5", ] @@ -1884,7 +1552,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1030c719b0ec2a2d25a5df729d6cff1acf3cc230bf766f4f97833591f7577b90" dependencies = [ - "base64", + "base64 0.21.5", "serde", ] @@ -1895,9 +1563,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" dependencies = [ "heck", - "itertools 0.11.0", - "prost 0.12.3", - "prost-types 0.12.3", + "itertools", + "prost", + "prost-types", ] [[package]] @@ -1910,7 +1578,7 @@ dependencies = [ "chrono", "pbjson", "pbjson-build", - "prost 0.12.3", + "prost", "prost-build", "serde", ] @@ -1927,12 +1595,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1946,7 +1608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap", ] [[package]] @@ -1966,7 +1628,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -2047,7 +1709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.50", + "syn", ] [[package]] @@ -2059,16 +1721,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - [[package]] name = "prost" version = "0.12.3" @@ -2076,7 +1728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive", ] [[package]] @@ -2087,33 +1739,20 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck", - "itertools 0.11.0", + "itertools", "log", "multimap", "once_cell", "petgraph", "prettyplease", - "prost 0.12.3", - "prost-types 0.12.3", + "prost", + "prost-types", "regex", - "syn 2.0.50", + "syn", "tempfile", "which", ] -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "prost-derive" version = "0.12.3" @@ -2121,19 +1760,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools", "proc-macro2", "quote", - "syn 2.0.50", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", + "syn", ] [[package]] @@ -2142,7 +1772,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ - "prost 0.12.3", + "prost", ] [[package]] @@ -2184,26 +1814,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rayon" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2221,17 +1831,8 @@ checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -2242,15 +1843,9 @@ checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -2263,7 +1858,7 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -2282,7 +1877,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.21.10", "rustls-native-certs", "rustls-pemfile", "serde", @@ -2297,7 +1892,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.3", "winreg", ] @@ -2321,12 +1916,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" version = "0.37.27" @@ -2362,10 +1951,24 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -2384,9 +1987,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.5", ] +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -2398,10 +2007,15 @@ dependencies = [ ] [[package]] -name = "rustversion" -version = "1.0.14" +name = "rustls-webpki" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] [[package]] name = "ryu" @@ -2472,12 +2086,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" - [[package]] name = "serde" version = "1.0.197" @@ -2495,7 +2103,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -2543,30 +2151,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "slab" version = "0.4.9" @@ -2625,17 +2209,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.50" @@ -2647,12 +2220,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "system-configuration" version = "0.5.1" @@ -2713,27 +2280,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", -] - -[[package]] -name = "thread-id" -version = "4.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", + "syn", ] [[package]] @@ -2780,25 +2327,12 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "tracing", "windows-sys 0.48.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.2.0" @@ -2807,7 +2341,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -2826,7 +2360,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.10", "tokio", ] @@ -2850,13 +2384,13 @@ dependencies = [ "futures-util", "log", "native-tls", - "rustls", + "rustls 0.21.10", "rustls-native-certs", "tokio", "tokio-native-tls", "tokio-rustls", "tungstenite 0.20.1", - "webpki-roots", + "webpki-roots 0.25.3", ] [[package]] @@ -2873,60 +2407,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64", - "bytes", - "futures-core", - "futures-util", - "h2", - "http 0.2.11", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - [[package]] name = "tower-service" version = "0.3.2" @@ -2953,7 +2433,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -2963,7 +2443,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", - "valuable", ] [[package]] @@ -2976,22 +2455,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "once_cell", - "parking_lot", - "regex", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -3012,7 +2475,7 @@ dependencies = [ "log", "native-tls", "rand", - "rustls", + "rustls 0.21.10", "sha1", "thiserror", "url", @@ -3066,18 +2529,29 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64 0.22.1", + "flate2", + "log", + "once_cell", + "rustls 0.22.4", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "url", + "webpki-roots 0.26.1", +] + [[package]] name = "url" version = "2.5.0" @@ -3095,12 +2569,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "value-bag" version = "1.7.0" @@ -3171,7 +2639,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn", "wasm-bindgen-shared", ] @@ -3205,7 +2673,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3233,28 +2701,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] -name = "webrtc-sys" -version = "0.3.2" +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" dependencies = [ - "cc", - "cxx", - "cxx-build", - "env_logger", - "glob", - "log", - "webrtc-sys-build", + "rustls-pki-types", ] [[package]] -name = "webrtc-sys-build" +name = "webrtc-sys" version = "0.3.2" dependencies = [ - "fs2", - "regex", - "reqwest", - "scratch", - "semver", - "zip", + "env_logger", + "libwebrtc-build", + "log", ] [[package]] @@ -3509,16 +2970,10 @@ dependencies = [ ] [[package]] -name = "yuv-sys" -version = "0.3.6" +name = "zeroize" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a3f589776c945135cd8dee6e1e0d6006748f2808e439200cc242f639b07150" -dependencies = [ - "bindgen", - "cc", - "rayon", - "regex", -] +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" diff --git a/Cargo.toml b/Cargo.toml index 507af2249..0d3b4e71f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = [ "livekit", "livekit-api", "livekit-protocol", - "livekit-ffi", + #"livekit-ffi", "libwebrtc", "webrtc-sys", - "webrtc-sys/build", + "webrtc-sys/libwebrtc/build-utils", ] diff --git a/livekit-api/src/services/ingress.rs b/livekit-api/src/services/ingress.rs index 4cc91f97e..88b16cd97 100644 --- a/livekit-api/src/services/ingress.rs +++ b/livekit-api/src/services/ingress.rs @@ -26,7 +26,9 @@ pub struct CreateIngressOptions { pub participant_name: String, pub audio: proto::IngressAudioOptions, pub video: proto::IngressVideoOptions, + #[deprecated(note = "use enable_transcoding instead")] pub bypass_transcoding: bool, + pub enable_transcoding: bool, pub url: String, } @@ -39,7 +41,9 @@ pub struct UpdateIngressOptions { pub participant_name: String, pub audio: proto::IngressAudioOptions, pub video: proto::IngressVideoOptions, + #[deprecated(note = "use enable_transcoding instead")] pub bypass_transcoding: Option, + pub enable_transcoding: Option, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -89,6 +93,7 @@ impl IngressClient { audio: Some(options.audio), video: Some(options.video), bypass_transcoding: options.bypass_transcoding, + enable_transcoding: Some(options.enable_transcoding), url: options.url, }, self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, @@ -116,6 +121,7 @@ impl IngressClient { audio: Some(options.audio), video: Some(options.video), bypass_transcoding: options.bypass_transcoding, + enable_transcoding: options.enable_transcoding, }, self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, ) diff --git a/livekit-api/src/services/sip.rs b/livekit-api/src/services/sip.rs index d722b03ea..790c0a7a5 100644 --- a/livekit-api/src/services/sip.rs +++ b/livekit-api/src/services/sip.rs @@ -13,11 +13,9 @@ // limitations under the License. use livekit_protocol as proto; -use std::ptr::null; use crate::access_token::VideoGrants; use crate::get_env_keys; -use crate::services::ingress::{CreateIngressOptions, IngressListFilter}; use crate::services::twirp_client::TwirpClient; use crate::services::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; @@ -31,6 +29,8 @@ pub struct SIPClient { #[derive(Default, Clone, Debug)] pub struct CreateSIPTrunkOptions { + pub name: String, + pub metadata: String, /// CIDR or IPs that traffic is accepted from /// An empty list means all inbound traffic is accepted. pub inbound_addresses: Vec, @@ -58,9 +58,12 @@ pub enum ListSIPTrunkFilter { #[derive(Default, Clone, Debug)] pub struct CreateSIPDispatchRuleOptions { + pub name: String, + pub metadata: String, /// What trunks are accepted for this dispatch rule /// If empty all trunks will match this dispatch rule pub trunk_ids: Vec, + pub inbound_numbers: Vec, pub hide_phone_number: bool, } @@ -73,8 +76,10 @@ pub enum ListSIPDispatchRuleFilter { pub struct CreateSIPParticipantOptions { /// Optional identity of the participant in LiveKit room pub participant_identity: String, - // Optionally set the name of the participant in a LiveKit room + /// Optionally set the name of the participant in a LiveKit room pub participant_name: String, + /// Optionally send metadata to the participant in LiveKit room + pub participant_metadata: String, /// Optionally send following DTMF digits (extension codes) when making a call. /// Character 'w' can be used to add a 0.5 sec delay. pub dtmf: String, @@ -105,16 +110,18 @@ impl SIPClient { SVC, "CreateSIPTrunk", proto::CreateSipTrunkRequest { - outbound_number: number.to_owned(), - outbound_address: options.outbound_address.to_owned(), - outbound_username: options.outbound_username.to_owned(), - outbound_password: options.outbound_password.to_owned(), - - inbound_numbers: options.inbound_numbers.to_owned(), + name: options.name, + metadata: options.metadata, + outbound_number: number, + outbound_address: options.outbound_address, + outbound_username: options.outbound_username, + outbound_password: options.outbound_password, + + inbound_numbers: options.inbound_numbers, inbound_numbers_regex: Vec::new(), - inbound_addresses: options.inbound_addresses.to_owned(), - inbound_username: options.inbound_username.to_owned(), - inbound_password: options.inbound_password.to_owned(), + inbound_addresses: options.inbound_addresses, + inbound_username: options.inbound_username, + inbound_password: options.inbound_password, }, self.base.auth_header(VideoGrants { ..Default::default() })?, ) @@ -161,7 +168,10 @@ impl SIPClient { SVC, "CreateSIPDispatchRule", proto::CreateSipDispatchRuleRequest { - trunk_ids: options.trunk_ids.to_owned(), + name: options.name, + metadata: options.metadata, + trunk_ids: options.trunk_ids, + inbound_numbers: options.inbound_numbers, hide_phone_number: options.hide_phone_number, rule: Some(proto::SipDispatchRule { rule: Some(rule.to_owned()) }), }, @@ -217,12 +227,13 @@ impl SIPClient { SVC, "CreateSIPParticipant", proto::CreateSipParticipantRequest { - sip_trunk_id: sip_trunk_id.to_owned(), - sip_call_to: call_to.to_owned(), - room_name: room_name.to_owned(), - participant_identity: options.participant_identity.to_owned(), - participant_name: options.participant_name.to_owned(), - dtmf: options.dtmf.to_owned(), + sip_trunk_id, + sip_call_to: call_to, + room_name, + participant_identity: options.participant_identity, + participant_metadata: options.participant_metadata, + participant_name: options.participant_name, + dtmf: options.dtmf, play_ringtone: options.play_ringtone, }, self.base.auth_header(VideoGrants { ..Default::default() })?, diff --git a/livekit-ffi/Cargo.toml b/livekit-ffi/Cargo.toml index 5343413f3..a0f745c4a 100644 --- a/livekit-ffi/Cargo.toml +++ b/livekit-ffi/Cargo.toml @@ -37,8 +37,8 @@ imgproc = "0.3.11" [target.'cfg(target_os = "android")'.dependencies] jni = "0.21.1" -[build-dependencies] -webrtc-sys-build = { path = "../webrtc-sys/build", version = "0.3.2" } +#[build-dependencies] +#webrtc-sys-build = { path = "../webrtc-sys/build", version = "0.3.2" } [dev-dependencies] livekit-api = { path = "../livekit-api", version = "0.3.2" } diff --git a/livekit-protocol/protocol b/livekit-protocol/protocol index bad3fc968..ec704e0cf 160000 --- a/livekit-protocol/protocol +++ b/livekit-protocol/protocol @@ -1 +1 @@ -Subproject commit bad3fc9684c3fccb68b12d7ef3cbeeadf0cf5df9 +Subproject commit ec704e0cf263bd29557470806c17f03861d5079f diff --git a/livekit-protocol/src/livekit.rs b/livekit-protocol/src/livekit.rs index 60a06b3b7..b09e85afc 100644 --- a/livekit-protocol/src/livekit.rs +++ b/livekit-protocol/src/livekit.rs @@ -1,5 +1,4 @@ // @generated -// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Room { @@ -281,6 +280,8 @@ pub struct TrackInfo { pub stream: ::prost::alloc::string::String, #[prost(message, optional, tag="18")] pub version: ::core::option::Option, + #[prost(enumeration="AudioTrackFeature", repeated, tag="19")] + pub audio_features: ::prost::alloc::vec::Vec, } /// provide information about available spatial layers #[allow(clippy::derive_partial_eq_without_eq)] @@ -418,14 +419,13 @@ pub struct SipDtmf { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Transcription { + /// Participant that got its speech transcribed #[prost(string, tag="2")] - pub participant_identity: ::prost::alloc::string::String, + pub transcribed_participant_identity: ::prost::alloc::string::String, #[prost(string, tag="3")] pub track_id: ::prost::alloc::string::String, #[prost(message, repeated, tag="4")] pub segments: ::prost::alloc::vec::Vec, - #[prost(string, tag="5")] - pub language: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -440,6 +440,8 @@ pub struct TranscriptionSegment { pub end_time: u64, #[prost(bool, tag="5")] pub r#final: bool, + #[prost(string, tag="6")] + pub language: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -1683,6 +1685,8 @@ pub struct EgressInfo { pub details: ::prost::alloc::string::String, #[prost(string, tag="9")] pub error: ::prost::alloc::string::String, + #[prost(int32, tag="22")] + pub error_code: i32, #[prost(message, repeated, tag="15")] pub stream_results: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag="16")] @@ -1859,7 +1863,7 @@ pub struct AutoTrackEgress { /// disables upload of json manifest file (default false) #[prost(bool, tag="5")] pub disable_manifest: bool, - #[prost(oneof="auto_track_egress::Output", tags="2, 3, 4")] + #[prost(oneof="auto_track_egress::Output", tags="2, 3, 4, 6")] pub output: ::core::option::Option, } /// Nested message and enum types in `AutoTrackEgress`. @@ -1873,6 +1877,8 @@ pub mod auto_track_egress { Gcp(super::GcpUpload), #[prost(message, tag="4")] Azure(super::AzureBlobUpload), + #[prost(message, tag="6")] + AliOss(super::AliOssUpload), } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] @@ -2648,7 +2654,7 @@ pub struct DataChannelInfo { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SimulateScenario { - #[prost(oneof="simulate_scenario::Scenario", tags="1, 2, 3, 4, 5, 6, 7, 8")] + #[prost(oneof="simulate_scenario::Scenario", tags="1, 2, 3, 4, 5, 6, 7, 8, 9")] pub scenario: ::core::option::Option, } /// Nested message and enum types in `SimulateScenario`. @@ -2681,6 +2687,9 @@ pub mod simulate_scenario { /// disconnect signal on resume before sending any messages from server #[prost(bool, tag="8")] DisconnectSignalOnResumeNoMessages(bool), + /// full reconnect leave request + #[prost(bool, tag="9")] + LeaveRequestFullReconnect(bool), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -3017,9 +3026,13 @@ pub struct CreateIngressRequest { /// metadata associated with the publishing participant #[prost(string, tag="10")] pub participant_metadata: ::prost::alloc::string::String, - /// whether to pass through the incoming media without transcoding, only compatible with some input types + /// \[depreacted \] whether to pass through the incoming media without transcoding, only compatible with some input types. Use `enable_transcoding` instead. + #[deprecated] #[prost(bool, tag="8")] pub bypass_transcoding: bool, + /// Whether to transcode the ingested media. Only WHIP supports disabling transcoding currently. WHIP will default to transcoding disabled. Replaces `bypass_transcoding. + #[prost(bool, optional, tag="11")] + pub enable_transcoding: ::core::option::Option, #[prost(message, optional, tag="6")] pub audio: ::core::option::Option, #[prost(message, optional, tag="7")] @@ -3109,8 +3122,11 @@ pub struct IngressInfo { /// for SRT input, it'll be a srt:// URL #[prost(enumeration="IngressInput", tag="5")] pub input_type: i32, + #[deprecated] #[prost(bool, tag="13")] pub bypass_transcoding: bool, + #[prost(bool, optional, tag="15")] + pub enable_transcoding: ::core::option::Option, #[prost(message, optional, tag="6")] pub audio: ::core::option::Option, #[prost(message, optional, tag="7")] @@ -3234,8 +3250,11 @@ pub struct UpdateIngressRequest { pub participant_name: ::prost::alloc::string::String, #[prost(string, tag="9")] pub participant_metadata: ::prost::alloc::string::String, + #[deprecated] #[prost(bool, optional, tag="8")] pub bypass_transcoding: ::core::option::Option, + #[prost(bool, optional, tag="10")] + pub enable_transcoding: ::core::option::Option, #[prost(message, optional, tag="6")] pub audio: ::core::option::Option, #[prost(message, optional, tag="7")] @@ -3445,6 +3464,12 @@ pub struct CreateSipTrunkRequest { pub outbound_username: ::prost::alloc::string::String, #[prost(string, tag="8")] pub outbound_password: ::prost::alloc::string::String, + /// Optional human-readable name for the Trunk. + #[prost(string, tag="10")] + pub name: ::prost::alloc::string::String, + /// Optional user-defined metadata for the Trunk. + #[prost(string, tag="11")] + pub metadata: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3461,6 +3486,9 @@ pub struct SipTrunkInfo { /// Number used to make outbound calls #[prost(string, tag="4")] pub outbound_number: ::prost::alloc::string::String, + /// Transport used for inbound and outbound calls. + #[prost(enumeration="SipTransport", tag="13")] + pub transport: i32, #[deprecated] #[prost(string, repeated, tag="5")] pub inbound_numbers_regex: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, @@ -3479,6 +3507,12 @@ pub struct SipTrunkInfo { pub outbound_username: ::prost::alloc::string::String, #[prost(string, tag="9")] pub outbound_password: ::prost::alloc::string::String, + /// Human-readable name for the Trunk. + #[prost(string, tag="11")] + pub name: ::prost::alloc::string::String, + /// User-defined metadata for the Trunk. + #[prost(string, tag="12")] + pub metadata: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3550,6 +3584,15 @@ pub struct CreateSipDispatchRuleRequest { /// If true a random value will be used instead #[prost(bool, tag="3")] pub hide_phone_number: bool, + /// Dispatch Rule will only accept a call made to these numbers (if set). + #[prost(string, repeated, tag="6")] + pub inbound_numbers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Optional human-readable name for the Dispatch Rule. + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + /// Optional user-defined metadata for the Dispatch Rule. + #[prost(string, tag="5")] + pub metadata: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3562,6 +3605,16 @@ pub struct SipDispatchRuleInfo { pub trunk_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, #[prost(bool, tag="4")] pub hide_phone_number: bool, + /// Dispatch Rule will only accept a call made to these numbers (if set). + #[prost(string, repeated, tag="7")] + pub inbound_numbers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Human-readable name for the Dispatch Rule. + #[prost(string, tag="5")] + pub name: ::prost::alloc::string::String, + /// User-defined metadata for the Dispatch Rule. + /// Participants created by this rule will inherit this metadata. + #[prost(string, tag="6")] + pub metadata: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3599,6 +3652,9 @@ pub struct CreateSipParticipantRequest { /// Optional name of the participant in LiveKit room #[prost(string, tag="7")] pub participant_name: ::prost::alloc::string::String, + /// Optional user-defined metadata. Will be attached to a created Participant in the room. + #[prost(string, tag="8")] + pub participant_metadata: ::prost::alloc::string::String, /// Optionally send following DTMF digits (extension codes) when making a call. /// Character 'w' can be used to add a 0.5 sec delay. #[prost(string, tag="5")] @@ -3616,6 +3672,40 @@ pub struct SipParticipantInfo { pub participant_identity: ::prost::alloc::string::String, #[prost(string, tag="3")] pub room_name: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub sip_call_id: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SipTransport { + Auto = 0, + Udp = 1, + Tcp = 2, + Tls = 3, +} +impl SipTransport { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + SipTransport::Auto => "SIP_TRANSPORT_AUTO", + SipTransport::Udp => "SIP_TRANSPORT_UDP", + SipTransport::Tcp => "SIP_TRANSPORT_TCP", + SipTransport::Tls => "SIP_TRANSPORT_TLS", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SIP_TRANSPORT_AUTO" => Some(Self::Auto), + "SIP_TRANSPORT_UDP" => Some(Self::Udp), + "SIP_TRANSPORT_TCP" => Some(Self::Tcp), + "SIP_TRANSPORT_TLS" => Some(Self::Tls), + _ => None, + } + } } include!("livekit.serde.rs"); // @@protoc_insertion_point(module) diff --git a/livekit-protocol/src/livekit.serde.rs b/livekit-protocol/src/livekit.serde.rs index 00efe0ab8..931bcb6d0 100644 --- a/livekit-protocol/src/livekit.serde.rs +++ b/livekit-protocol/src/livekit.serde.rs @@ -946,6 +946,9 @@ impl serde::Serialize for AutoTrackEgress { auto_track_egress::Output::Azure(v) => { struct_ser.serialize_field("azure", v)?; } + auto_track_egress::Output::AliOss(v) => { + struct_ser.serialize_field("aliOSS", v)?; + } } } struct_ser.end() @@ -964,6 +967,7 @@ impl<'de> serde::Deserialize<'de> for AutoTrackEgress { "s3", "gcp", "azure", + "aliOSS", ]; #[allow(clippy::enum_variant_names)] @@ -973,6 +977,7 @@ impl<'de> serde::Deserialize<'de> for AutoTrackEgress { S3, Gcp, Azure, + AliOss, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -1000,6 +1005,7 @@ impl<'de> serde::Deserialize<'de> for AutoTrackEgress { "s3" => Ok(GeneratedField::S3), "gcp" => Ok(GeneratedField::Gcp), "azure" => Ok(GeneratedField::Azure), + "aliOSS" => Ok(GeneratedField::AliOss), _ => Ok(GeneratedField::__SkipField__), } } @@ -1055,6 +1061,13 @@ impl<'de> serde::Deserialize<'de> for AutoTrackEgress { return Err(serde::de::Error::duplicate_field("azure")); } output__ = map_.next_value::<::std::option::Option<_>>()?.map(auto_track_egress::Output::Azure) +; + } + GeneratedField::AliOss => { + if output__.is_some() { + return Err(serde::de::Error::duplicate_field("aliOSS")); + } + output__ = map_.next_value::<::std::option::Option<_>>()?.map(auto_track_egress::Output::AliOss) ; } GeneratedField::__SkipField__ => { @@ -2326,6 +2339,9 @@ impl serde::Serialize for CreateIngressRequest { if self.bypass_transcoding { len += 1; } + if self.enable_transcoding.is_some() { + len += 1; + } if self.audio.is_some() { len += 1; } @@ -2359,6 +2375,9 @@ impl serde::Serialize for CreateIngressRequest { if self.bypass_transcoding { struct_ser.serialize_field("bypassTranscoding", &self.bypass_transcoding)?; } + if let Some(v) = self.enable_transcoding.as_ref() { + struct_ser.serialize_field("enableTranscoding", v)?; + } if let Some(v) = self.audio.as_ref() { struct_ser.serialize_field("audio", v)?; } @@ -2389,6 +2408,8 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { "participantMetadata", "bypass_transcoding", "bypassTranscoding", + "enable_transcoding", + "enableTranscoding", "audio", "video", ]; @@ -2403,6 +2424,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { ParticipantName, ParticipantMetadata, BypassTranscoding, + EnableTranscoding, Audio, Video, __SkipField__, @@ -2435,6 +2457,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { "participantName" | "participant_name" => Ok(GeneratedField::ParticipantName), "participantMetadata" | "participant_metadata" => Ok(GeneratedField::ParticipantMetadata), "bypassTranscoding" | "bypass_transcoding" => Ok(GeneratedField::BypassTranscoding), + "enableTranscoding" | "enable_transcoding" => Ok(GeneratedField::EnableTranscoding), "audio" => Ok(GeneratedField::Audio), "video" => Ok(GeneratedField::Video), _ => Ok(GeneratedField::__SkipField__), @@ -2464,6 +2487,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { let mut participant_name__ = None; let mut participant_metadata__ = None; let mut bypass_transcoding__ = None; + let mut enable_transcoding__ = None; let mut audio__ = None; let mut video__ = None; while let Some(k) = map_.next_key()? { @@ -2516,6 +2540,12 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { } bypass_transcoding__ = Some(map_.next_value()?); } + GeneratedField::EnableTranscoding => { + if enable_transcoding__.is_some() { + return Err(serde::de::Error::duplicate_field("enableTranscoding")); + } + enable_transcoding__ = map_.next_value()?; + } GeneratedField::Audio => { if audio__.is_some() { return Err(serde::de::Error::duplicate_field("audio")); @@ -2542,6 +2572,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { participant_name: participant_name__.unwrap_or_default(), participant_metadata: participant_metadata__.unwrap_or_default(), bypass_transcoding: bypass_transcoding__.unwrap_or_default(), + enable_transcoding: enable_transcoding__, audio: audio__, video: video__, }) @@ -2832,6 +2863,15 @@ impl serde::Serialize for CreateSipDispatchRuleRequest { if self.hide_phone_number { len += 1; } + if !self.inbound_numbers.is_empty() { + len += 1; + } + if !self.name.is_empty() { + len += 1; + } + if !self.metadata.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateSIPDispatchRuleRequest", len)?; if let Some(v) = self.rule.as_ref() { struct_ser.serialize_field("rule", v)?; @@ -2842,6 +2882,15 @@ impl serde::Serialize for CreateSipDispatchRuleRequest { if self.hide_phone_number { struct_ser.serialize_field("hidePhoneNumber", &self.hide_phone_number)?; } + if !self.inbound_numbers.is_empty() { + struct_ser.serialize_field("inboundNumbers", &self.inbound_numbers)?; + } + if !self.name.is_empty() { + struct_ser.serialize_field("name", &self.name)?; + } + if !self.metadata.is_empty() { + struct_ser.serialize_field("metadata", &self.metadata)?; + } struct_ser.end() } } @@ -2857,6 +2906,10 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { "trunkIds", "hide_phone_number", "hidePhoneNumber", + "inbound_numbers", + "inboundNumbers", + "name", + "metadata", ]; #[allow(clippy::enum_variant_names)] @@ -2864,6 +2917,9 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { Rule, TrunkIds, HidePhoneNumber, + InboundNumbers, + Name, + Metadata, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -2889,6 +2945,9 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { "rule" => Ok(GeneratedField::Rule), "trunkIds" | "trunk_ids" => Ok(GeneratedField::TrunkIds), "hidePhoneNumber" | "hide_phone_number" => Ok(GeneratedField::HidePhoneNumber), + "inboundNumbers" | "inbound_numbers" => Ok(GeneratedField::InboundNumbers), + "name" => Ok(GeneratedField::Name), + "metadata" => Ok(GeneratedField::Metadata), _ => Ok(GeneratedField::__SkipField__), } } @@ -2911,6 +2970,9 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { let mut rule__ = None; let mut trunk_ids__ = None; let mut hide_phone_number__ = None; + let mut inbound_numbers__ = None; + let mut name__ = None; + let mut metadata__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Rule => { @@ -2931,6 +2993,24 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { } hide_phone_number__ = Some(map_.next_value()?); } + GeneratedField::InboundNumbers => { + if inbound_numbers__.is_some() { + return Err(serde::de::Error::duplicate_field("inboundNumbers")); + } + inbound_numbers__ = Some(map_.next_value()?); + } + GeneratedField::Name => { + if name__.is_some() { + return Err(serde::de::Error::duplicate_field("name")); + } + name__ = Some(map_.next_value()?); + } + GeneratedField::Metadata => { + if metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("metadata")); + } + metadata__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -2940,6 +3020,9 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { rule: rule__, trunk_ids: trunk_ids__.unwrap_or_default(), hide_phone_number: hide_phone_number__.unwrap_or_default(), + inbound_numbers: inbound_numbers__.unwrap_or_default(), + name: name__.unwrap_or_default(), + metadata: metadata__.unwrap_or_default(), }) } } @@ -2969,6 +3052,9 @@ impl serde::Serialize for CreateSipParticipantRequest { if !self.participant_name.is_empty() { len += 1; } + if !self.participant_metadata.is_empty() { + len += 1; + } if !self.dtmf.is_empty() { len += 1; } @@ -2991,6 +3077,9 @@ impl serde::Serialize for CreateSipParticipantRequest { if !self.participant_name.is_empty() { struct_ser.serialize_field("participantName", &self.participant_name)?; } + if !self.participant_metadata.is_empty() { + struct_ser.serialize_field("participantMetadata", &self.participant_metadata)?; + } if !self.dtmf.is_empty() { struct_ser.serialize_field("dtmf", &self.dtmf)?; } @@ -3017,6 +3106,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "participantIdentity", "participant_name", "participantName", + "participant_metadata", + "participantMetadata", "dtmf", "play_ringtone", "playRingtone", @@ -3029,6 +3120,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { RoomName, ParticipantIdentity, ParticipantName, + ParticipantMetadata, Dtmf, PlayRingtone, __SkipField__, @@ -3058,6 +3150,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "roomName" | "room_name" => Ok(GeneratedField::RoomName), "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), "participantName" | "participant_name" => Ok(GeneratedField::ParticipantName), + "participantMetadata" | "participant_metadata" => Ok(GeneratedField::ParticipantMetadata), "dtmf" => Ok(GeneratedField::Dtmf), "playRingtone" | "play_ringtone" => Ok(GeneratedField::PlayRingtone), _ => Ok(GeneratedField::__SkipField__), @@ -3084,6 +3177,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { let mut room_name__ = None; let mut participant_identity__ = None; let mut participant_name__ = None; + let mut participant_metadata__ = None; let mut dtmf__ = None; let mut play_ringtone__ = None; while let Some(k) = map_.next_key()? { @@ -3118,6 +3212,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { } participant_name__ = Some(map_.next_value()?); } + GeneratedField::ParticipantMetadata => { + if participant_metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("participantMetadata")); + } + participant_metadata__ = Some(map_.next_value()?); + } GeneratedField::Dtmf => { if dtmf__.is_some() { return Err(serde::de::Error::duplicate_field("dtmf")); @@ -3141,6 +3241,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { room_name: room_name__.unwrap_or_default(), participant_identity: participant_identity__.unwrap_or_default(), participant_name: participant_name__.unwrap_or_default(), + participant_metadata: participant_metadata__.unwrap_or_default(), dtmf: dtmf__.unwrap_or_default(), play_ringtone: play_ringtone__.unwrap_or_default(), }) @@ -3184,6 +3285,12 @@ impl serde::Serialize for CreateSipTrunkRequest { if !self.outbound_password.is_empty() { len += 1; } + if !self.name.is_empty() { + len += 1; + } + if !self.metadata.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateSIPTrunkRequest", len)?; if !self.inbound_addresses.is_empty() { struct_ser.serialize_field("inboundAddresses", &self.inbound_addresses)?; @@ -3212,6 +3319,12 @@ impl serde::Serialize for CreateSipTrunkRequest { if !self.outbound_password.is_empty() { struct_ser.serialize_field("outboundPassword", &self.outbound_password)?; } + if !self.name.is_empty() { + struct_ser.serialize_field("name", &self.name)?; + } + if !self.metadata.is_empty() { + struct_ser.serialize_field("metadata", &self.metadata)?; + } struct_ser.end() } } @@ -3240,6 +3353,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { "outboundUsername", "outbound_password", "outboundPassword", + "name", + "metadata", ]; #[allow(clippy::enum_variant_names)] @@ -3253,6 +3368,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { InboundPassword, OutboundUsername, OutboundPassword, + Name, + Metadata, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -3284,6 +3401,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { "inboundPassword" | "inbound_password" => Ok(GeneratedField::InboundPassword), "outboundUsername" | "outbound_username" => Ok(GeneratedField::OutboundUsername), "outboundPassword" | "outbound_password" => Ok(GeneratedField::OutboundPassword), + "name" => Ok(GeneratedField::Name), + "metadata" => Ok(GeneratedField::Metadata), _ => Ok(GeneratedField::__SkipField__), } } @@ -3312,6 +3431,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { let mut inbound_password__ = None; let mut outbound_username__ = None; let mut outbound_password__ = None; + let mut name__ = None; + let mut metadata__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::InboundAddresses => { @@ -3368,6 +3489,18 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { } outbound_password__ = Some(map_.next_value()?); } + GeneratedField::Name => { + if name__.is_some() { + return Err(serde::de::Error::duplicate_field("name")); + } + name__ = Some(map_.next_value()?); + } + GeneratedField::Metadata => { + if metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("metadata")); + } + metadata__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -3383,6 +3516,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipTrunkRequest { inbound_password: inbound_password__.unwrap_or_default(), outbound_username: outbound_username__.unwrap_or_default(), outbound_password: outbound_password__.unwrap_or_default(), + name: name__.unwrap_or_default(), + metadata: metadata__.unwrap_or_default(), }) } } @@ -4659,6 +4794,9 @@ impl serde::Serialize for EgressInfo { if !self.error.is_empty() { len += 1; } + if self.error_code != 0 { + len += 1; + } if !self.stream_results.is_empty() { len += 1; } @@ -4710,6 +4848,9 @@ impl serde::Serialize for EgressInfo { if !self.error.is_empty() { struct_ser.serialize_field("error", &self.error)?; } + if self.error_code != 0 { + struct_ser.serialize_field("errorCode", &self.error_code)?; + } if !self.stream_results.is_empty() { struct_ser.serialize_field("streamResults", &self.stream_results)?; } @@ -4779,6 +4920,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "updatedAt", "details", "error", + "error_code", + "errorCode", "stream_results", "streamResults", "file_results", @@ -4810,6 +4953,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { UpdatedAt, Details, Error, + ErrorCode, StreamResults, FileResults, SegmentResults, @@ -4853,6 +4997,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "updatedAt" | "updated_at" => Ok(GeneratedField::UpdatedAt), "details" => Ok(GeneratedField::Details), "error" => Ok(GeneratedField::Error), + "errorCode" | "error_code" => Ok(GeneratedField::ErrorCode), "streamResults" | "stream_results" => Ok(GeneratedField::StreamResults), "fileResults" | "file_results" => Ok(GeneratedField::FileResults), "segmentResults" | "segment_results" => Ok(GeneratedField::SegmentResults), @@ -4893,6 +5038,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { let mut updated_at__ = None; let mut details__ = None; let mut error__ = None; + let mut error_code__ = None; let mut stream_results__ = None; let mut file_results__ = None; let mut segment_results__ = None; @@ -4961,6 +5107,14 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { } error__ = Some(map_.next_value()?); } + GeneratedField::ErrorCode => { + if error_code__.is_some() { + return Err(serde::de::Error::duplicate_field("errorCode")); + } + error_code__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } GeneratedField::StreamResults => { if stream_results__.is_some() { return Err(serde::de::Error::duplicate_field("streamResults")); @@ -5056,6 +5210,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { updated_at: updated_at__.unwrap_or_default(), details: details__.unwrap_or_default(), error: error__.unwrap_or_default(), + error_code: error_code__.unwrap_or_default(), stream_results: stream_results__.unwrap_or_default(), file_results: file_results__.unwrap_or_default(), segment_results: segment_results__.unwrap_or_default(), @@ -7380,6 +7535,9 @@ impl serde::Serialize for IngressInfo { if self.bypass_transcoding { len += 1; } + if self.enable_transcoding.is_some() { + len += 1; + } if self.audio.is_some() { len += 1; } @@ -7425,6 +7583,9 @@ impl serde::Serialize for IngressInfo { if self.bypass_transcoding { struct_ser.serialize_field("bypassTranscoding", &self.bypass_transcoding)?; } + if let Some(v) = self.enable_transcoding.as_ref() { + struct_ser.serialize_field("enableTranscoding", v)?; + } if let Some(v) = self.audio.as_ref() { struct_ser.serialize_field("audio", v)?; } @@ -7469,6 +7630,8 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { "inputType", "bypass_transcoding", "bypassTranscoding", + "enable_transcoding", + "enableTranscoding", "audio", "video", "room_name", @@ -7491,6 +7654,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { Url, InputType, BypassTranscoding, + EnableTranscoding, Audio, Video, RoomName, @@ -7527,6 +7691,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { "url" => Ok(GeneratedField::Url), "inputType" | "input_type" => Ok(GeneratedField::InputType), "bypassTranscoding" | "bypass_transcoding" => Ok(GeneratedField::BypassTranscoding), + "enableTranscoding" | "enable_transcoding" => Ok(GeneratedField::EnableTranscoding), "audio" => Ok(GeneratedField::Audio), "video" => Ok(GeneratedField::Video), "roomName" | "room_name" => Ok(GeneratedField::RoomName), @@ -7560,6 +7725,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { let mut url__ = None; let mut input_type__ = None; let mut bypass_transcoding__ = None; + let mut enable_transcoding__ = None; let mut audio__ = None; let mut video__ = None; let mut room_name__ = None; @@ -7606,6 +7772,12 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { } bypass_transcoding__ = Some(map_.next_value()?); } + GeneratedField::EnableTranscoding => { + if enable_transcoding__.is_some() { + return Err(serde::de::Error::duplicate_field("enableTranscoding")); + } + enable_transcoding__ = map_.next_value()?; + } GeneratedField::Audio => { if audio__.is_some() { return Err(serde::de::Error::duplicate_field("audio")); @@ -7666,6 +7838,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { url: url__.unwrap_or_default(), input_type: input_type__.unwrap_or_default(), bypass_transcoding: bypass_transcoding__.unwrap_or_default(), + enable_transcoding: enable_transcoding__, audio: audio__, video: video__, room_name: room_name__.unwrap_or_default(), @@ -15754,6 +15927,15 @@ impl serde::Serialize for SipDispatchRuleInfo { if self.hide_phone_number { len += 1; } + if !self.inbound_numbers.is_empty() { + len += 1; + } + if !self.name.is_empty() { + len += 1; + } + if !self.metadata.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPDispatchRuleInfo", len)?; if !self.sip_dispatch_rule_id.is_empty() { struct_ser.serialize_field("sipDispatchRuleId", &self.sip_dispatch_rule_id)?; @@ -15767,6 +15949,15 @@ impl serde::Serialize for SipDispatchRuleInfo { if self.hide_phone_number { struct_ser.serialize_field("hidePhoneNumber", &self.hide_phone_number)?; } + if !self.inbound_numbers.is_empty() { + struct_ser.serialize_field("inboundNumbers", &self.inbound_numbers)?; + } + if !self.name.is_empty() { + struct_ser.serialize_field("name", &self.name)?; + } + if !self.metadata.is_empty() { + struct_ser.serialize_field("metadata", &self.metadata)?; + } struct_ser.end() } } @@ -15784,6 +15975,10 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { "trunkIds", "hide_phone_number", "hidePhoneNumber", + "inbound_numbers", + "inboundNumbers", + "name", + "metadata", ]; #[allow(clippy::enum_variant_names)] @@ -15792,6 +15987,9 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { Rule, TrunkIds, HidePhoneNumber, + InboundNumbers, + Name, + Metadata, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -15818,6 +16016,9 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { "rule" => Ok(GeneratedField::Rule), "trunkIds" | "trunk_ids" => Ok(GeneratedField::TrunkIds), "hidePhoneNumber" | "hide_phone_number" => Ok(GeneratedField::HidePhoneNumber), + "inboundNumbers" | "inbound_numbers" => Ok(GeneratedField::InboundNumbers), + "name" => Ok(GeneratedField::Name), + "metadata" => Ok(GeneratedField::Metadata), _ => Ok(GeneratedField::__SkipField__), } } @@ -15841,6 +16042,9 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { let mut rule__ = None; let mut trunk_ids__ = None; let mut hide_phone_number__ = None; + let mut inbound_numbers__ = None; + let mut name__ = None; + let mut metadata__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipDispatchRuleId => { @@ -15867,6 +16071,24 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { } hide_phone_number__ = Some(map_.next_value()?); } + GeneratedField::InboundNumbers => { + if inbound_numbers__.is_some() { + return Err(serde::de::Error::duplicate_field("inboundNumbers")); + } + inbound_numbers__ = Some(map_.next_value()?); + } + GeneratedField::Name => { + if name__.is_some() { + return Err(serde::de::Error::duplicate_field("name")); + } + name__ = Some(map_.next_value()?); + } + GeneratedField::Metadata => { + if metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("metadata")); + } + metadata__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -15877,6 +16099,9 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { rule: rule__, trunk_ids: trunk_ids__.unwrap_or_default(), hide_phone_number: hide_phone_number__.unwrap_or_default(), + inbound_numbers: inbound_numbers__.unwrap_or_default(), + name: name__.unwrap_or_default(), + metadata: metadata__.unwrap_or_default(), }) } } @@ -15900,6 +16125,9 @@ impl serde::Serialize for SipParticipantInfo { if !self.room_name.is_empty() { len += 1; } + if !self.sip_call_id.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPParticipantInfo", len)?; if !self.participant_id.is_empty() { struct_ser.serialize_field("participantId", &self.participant_id)?; @@ -15910,6 +16138,9 @@ impl serde::Serialize for SipParticipantInfo { if !self.room_name.is_empty() { struct_ser.serialize_field("roomName", &self.room_name)?; } + if !self.sip_call_id.is_empty() { + struct_ser.serialize_field("sipCallId", &self.sip_call_id)?; + } struct_ser.end() } } @@ -15926,6 +16157,8 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { "participantIdentity", "room_name", "roomName", + "sip_call_id", + "sipCallId", ]; #[allow(clippy::enum_variant_names)] @@ -15933,6 +16166,7 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { ParticipantId, ParticipantIdentity, RoomName, + SipCallId, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -15958,6 +16192,7 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { "participantId" | "participant_id" => Ok(GeneratedField::ParticipantId), "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), "roomName" | "room_name" => Ok(GeneratedField::RoomName), + "sipCallId" | "sip_call_id" => Ok(GeneratedField::SipCallId), _ => Ok(GeneratedField::__SkipField__), } } @@ -15980,6 +16215,7 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { let mut participant_id__ = None; let mut participant_identity__ = None; let mut room_name__ = None; + let mut sip_call_id__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::ParticipantId => { @@ -16000,6 +16236,12 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { } room_name__ = Some(map_.next_value()?); } + GeneratedField::SipCallId => { + if sip_call_id__.is_some() { + return Err(serde::de::Error::duplicate_field("sipCallId")); + } + sip_call_id__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -16009,12 +16251,90 @@ impl<'de> serde::Deserialize<'de> for SipParticipantInfo { participant_id: participant_id__.unwrap_or_default(), participant_identity: participant_identity__.unwrap_or_default(), room_name: room_name__.unwrap_or_default(), + sip_call_id: sip_call_id__.unwrap_or_default(), }) } } deserializer.deserialize_struct("livekit.SIPParticipantInfo", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for SipTransport { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::Auto => "SIP_TRANSPORT_AUTO", + Self::Udp => "SIP_TRANSPORT_UDP", + Self::Tcp => "SIP_TRANSPORT_TCP", + Self::Tls => "SIP_TRANSPORT_TLS", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipTransport { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "SIP_TRANSPORT_AUTO", + "SIP_TRANSPORT_UDP", + "SIP_TRANSPORT_TCP", + "SIP_TRANSPORT_TLS", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipTransport; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self) + }) + } + + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "SIP_TRANSPORT_AUTO" => Ok(SipTransport::Auto), + "SIP_TRANSPORT_UDP" => Ok(SipTransport::Udp), + "SIP_TRANSPORT_TCP" => Ok(SipTransport::Tcp), + "SIP_TRANSPORT_TLS" => Ok(SipTransport::Tls), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} impl serde::Serialize for SipTrunkInfo { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -16035,6 +16355,9 @@ impl serde::Serialize for SipTrunkInfo { if !self.outbound_number.is_empty() { len += 1; } + if self.transport != 0 { + len += 1; + } if !self.inbound_numbers_regex.is_empty() { len += 1; } @@ -16053,6 +16376,12 @@ impl serde::Serialize for SipTrunkInfo { if !self.outbound_password.is_empty() { len += 1; } + if !self.name.is_empty() { + len += 1; + } + if !self.metadata.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPTrunkInfo", len)?; if !self.sip_trunk_id.is_empty() { struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; @@ -16066,6 +16395,11 @@ impl serde::Serialize for SipTrunkInfo { if !self.outbound_number.is_empty() { struct_ser.serialize_field("outboundNumber", &self.outbound_number)?; } + if self.transport != 0 { + let v = SipTransport::try_from(self.transport) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.transport)))?; + struct_ser.serialize_field("transport", &v)?; + } if !self.inbound_numbers_regex.is_empty() { struct_ser.serialize_field("inboundNumbersRegex", &self.inbound_numbers_regex)?; } @@ -16084,6 +16418,12 @@ impl serde::Serialize for SipTrunkInfo { if !self.outbound_password.is_empty() { struct_ser.serialize_field("outboundPassword", &self.outbound_password)?; } + if !self.name.is_empty() { + struct_ser.serialize_field("name", &self.name)?; + } + if !self.metadata.is_empty() { + struct_ser.serialize_field("metadata", &self.metadata)?; + } struct_ser.end() } } @@ -16102,6 +16442,7 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { "outboundAddress", "outbound_number", "outboundNumber", + "transport", "inbound_numbers_regex", "inboundNumbersRegex", "inbound_numbers", @@ -16114,6 +16455,8 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { "outboundUsername", "outbound_password", "outboundPassword", + "name", + "metadata", ]; #[allow(clippy::enum_variant_names)] @@ -16122,12 +16465,15 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { InboundAddresses, OutboundAddress, OutboundNumber, + Transport, InboundNumbersRegex, InboundNumbers, InboundUsername, InboundPassword, OutboundUsername, OutboundPassword, + Name, + Metadata, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -16154,12 +16500,15 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { "inboundAddresses" | "inbound_addresses" => Ok(GeneratedField::InboundAddresses), "outboundAddress" | "outbound_address" => Ok(GeneratedField::OutboundAddress), "outboundNumber" | "outbound_number" => Ok(GeneratedField::OutboundNumber), + "transport" => Ok(GeneratedField::Transport), "inboundNumbersRegex" | "inbound_numbers_regex" => Ok(GeneratedField::InboundNumbersRegex), "inboundNumbers" | "inbound_numbers" => Ok(GeneratedField::InboundNumbers), "inboundUsername" | "inbound_username" => Ok(GeneratedField::InboundUsername), "inboundPassword" | "inbound_password" => Ok(GeneratedField::InboundPassword), "outboundUsername" | "outbound_username" => Ok(GeneratedField::OutboundUsername), "outboundPassword" | "outbound_password" => Ok(GeneratedField::OutboundPassword), + "name" => Ok(GeneratedField::Name), + "metadata" => Ok(GeneratedField::Metadata), _ => Ok(GeneratedField::__SkipField__), } } @@ -16183,12 +16532,15 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { let mut inbound_addresses__ = None; let mut outbound_address__ = None; let mut outbound_number__ = None; + let mut transport__ = None; let mut inbound_numbers_regex__ = None; let mut inbound_numbers__ = None; let mut inbound_username__ = None; let mut inbound_password__ = None; let mut outbound_username__ = None; let mut outbound_password__ = None; + let mut name__ = None; + let mut metadata__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -16215,6 +16567,12 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { } outbound_number__ = Some(map_.next_value()?); } + GeneratedField::Transport => { + if transport__.is_some() { + return Err(serde::de::Error::duplicate_field("transport")); + } + transport__ = Some(map_.next_value::()? as i32); + } GeneratedField::InboundNumbersRegex => { if inbound_numbers_regex__.is_some() { return Err(serde::de::Error::duplicate_field("inboundNumbersRegex")); @@ -16251,6 +16609,18 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { } outbound_password__ = Some(map_.next_value()?); } + GeneratedField::Name => { + if name__.is_some() { + return Err(serde::de::Error::duplicate_field("name")); + } + name__ = Some(map_.next_value()?); + } + GeneratedField::Metadata => { + if metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("metadata")); + } + metadata__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -16261,12 +16631,15 @@ impl<'de> serde::Deserialize<'de> for SipTrunkInfo { inbound_addresses: inbound_addresses__.unwrap_or_default(), outbound_address: outbound_address__.unwrap_or_default(), outbound_number: outbound_number__.unwrap_or_default(), + transport: transport__.unwrap_or_default(), inbound_numbers_regex: inbound_numbers_regex__.unwrap_or_default(), inbound_numbers: inbound_numbers__.unwrap_or_default(), inbound_username: inbound_username__.unwrap_or_default(), inbound_password: inbound_password__.unwrap_or_default(), outbound_username: outbound_username__.unwrap_or_default(), outbound_password: outbound_password__.unwrap_or_default(), + name: name__.unwrap_or_default(), + metadata: metadata__.unwrap_or_default(), }) } } @@ -18372,6 +18745,9 @@ impl serde::Serialize for SimulateScenario { simulate_scenario::Scenario::DisconnectSignalOnResumeNoMessages(v) => { struct_ser.serialize_field("disconnectSignalOnResumeNoMessages", v)?; } + simulate_scenario::Scenario::LeaveRequestFullReconnect(v) => { + struct_ser.serialize_field("leaveRequestFullReconnect", v)?; + } } } struct_ser.end() @@ -18399,6 +18775,8 @@ impl<'de> serde::Deserialize<'de> for SimulateScenario { "disconnectSignalOnResume", "disconnect_signal_on_resume_no_messages", "disconnectSignalOnResumeNoMessages", + "leave_request_full_reconnect", + "leaveRequestFullReconnect", ]; #[allow(clippy::enum_variant_names)] @@ -18411,6 +18789,7 @@ impl<'de> serde::Deserialize<'de> for SimulateScenario { SubscriberBandwidth, DisconnectSignalOnResume, DisconnectSignalOnResumeNoMessages, + LeaveRequestFullReconnect, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -18441,6 +18820,7 @@ impl<'de> serde::Deserialize<'de> for SimulateScenario { "subscriberBandwidth" | "subscriber_bandwidth" => Ok(GeneratedField::SubscriberBandwidth), "disconnectSignalOnResume" | "disconnect_signal_on_resume" => Ok(GeneratedField::DisconnectSignalOnResume), "disconnectSignalOnResumeNoMessages" | "disconnect_signal_on_resume_no_messages" => Ok(GeneratedField::DisconnectSignalOnResumeNoMessages), + "leaveRequestFullReconnect" | "leave_request_full_reconnect" => Ok(GeneratedField::LeaveRequestFullReconnect), _ => Ok(GeneratedField::__SkipField__), } } @@ -18511,6 +18891,12 @@ impl<'de> serde::Deserialize<'de> for SimulateScenario { } scenario__ = map_.next_value::<::std::option::Option<_>>()?.map(simulate_scenario::Scenario::DisconnectSignalOnResumeNoMessages); } + GeneratedField::LeaveRequestFullReconnect => { + if scenario__.is_some() { + return Err(serde::de::Error::duplicate_field("leaveRequestFullReconnect")); + } + scenario__ = map_.next_value::<::std::option::Option<_>>()?.map(simulate_scenario::Scenario::LeaveRequestFullReconnect); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -21658,6 +22044,9 @@ impl serde::Serialize for TrackInfo { if self.version.is_some() { len += 1; } + if !self.audio_features.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.TrackInfo", len)?; if !self.sid.is_empty() { struct_ser.serialize_field("sid", &self.sid)?; @@ -21719,6 +22108,13 @@ impl serde::Serialize for TrackInfo { if let Some(v) = self.version.as_ref() { struct_ser.serialize_field("version", v)?; } + if !self.audio_features.is_empty() { + let v = self.audio_features.iter().cloned().map(|v| { + AudioTrackFeature::try_from(v) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", v))) + }).collect::, _>>()?; + struct_ser.serialize_field("audioFeatures", &v)?; + } struct_ser.end() } } @@ -21750,6 +22146,8 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { "encryption", "stream", "version", + "audio_features", + "audioFeatures", ]; #[allow(clippy::enum_variant_names)] @@ -21772,6 +22170,7 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { Encryption, Stream, Version, + AudioFeatures, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -21812,6 +22211,7 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { "encryption" => Ok(GeneratedField::Encryption), "stream" => Ok(GeneratedField::Stream), "version" => Ok(GeneratedField::Version), + "audioFeatures" | "audio_features" => Ok(GeneratedField::AudioFeatures), _ => Ok(GeneratedField::__SkipField__), } } @@ -21849,6 +22249,7 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { let mut encryption__ = None; let mut stream__ = None; let mut version__ = None; + let mut audio_features__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Sid => { @@ -21963,6 +22364,12 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { } version__ = map_.next_value()?; } + GeneratedField::AudioFeatures => { + if audio_features__.is_some() { + return Err(serde::de::Error::duplicate_field("audioFeatures")); + } + audio_features__ = Some(map_.next_value::>()?.into_iter().map(|x| x as i32).collect()); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -21987,6 +22394,7 @@ impl<'de> serde::Deserialize<'de> for TrackInfo { encryption: encryption__.unwrap_or_default(), stream: stream__.unwrap_or_default(), version: version__, + audio_features: audio_features__.unwrap_or_default(), }) } } @@ -22513,7 +22921,7 @@ impl serde::Serialize for Transcription { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.participant_identity.is_empty() { + if !self.transcribed_participant_identity.is_empty() { len += 1; } if !self.track_id.is_empty() { @@ -22522,12 +22930,9 @@ impl serde::Serialize for Transcription { if !self.segments.is_empty() { len += 1; } - if !self.language.is_empty() { - len += 1; - } let mut struct_ser = serializer.serialize_struct("livekit.Transcription", len)?; - if !self.participant_identity.is_empty() { - struct_ser.serialize_field("participantIdentity", &self.participant_identity)?; + if !self.transcribed_participant_identity.is_empty() { + struct_ser.serialize_field("transcribedParticipantIdentity", &self.transcribed_participant_identity)?; } if !self.track_id.is_empty() { struct_ser.serialize_field("trackId", &self.track_id)?; @@ -22535,9 +22940,6 @@ impl serde::Serialize for Transcription { if !self.segments.is_empty() { struct_ser.serialize_field("segments", &self.segments)?; } - if !self.language.is_empty() { - struct_ser.serialize_field("language", &self.language)?; - } struct_ser.end() } } @@ -22548,20 +22950,18 @@ impl<'de> serde::Deserialize<'de> for Transcription { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "participant_identity", - "participantIdentity", + "transcribed_participant_identity", + "transcribedParticipantIdentity", "track_id", "trackId", "segments", - "language", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - ParticipantIdentity, + TranscribedParticipantIdentity, TrackId, Segments, - Language, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -22584,10 +22984,9 @@ impl<'de> serde::Deserialize<'de> for Transcription { E: serde::de::Error, { match value { - "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), + "transcribedParticipantIdentity" | "transcribed_participant_identity" => Ok(GeneratedField::TranscribedParticipantIdentity), "trackId" | "track_id" => Ok(GeneratedField::TrackId), "segments" => Ok(GeneratedField::Segments), - "language" => Ok(GeneratedField::Language), _ => Ok(GeneratedField::__SkipField__), } } @@ -22607,17 +23006,16 @@ impl<'de> serde::Deserialize<'de> for Transcription { where V: serde::de::MapAccess<'de>, { - let mut participant_identity__ = None; + let mut transcribed_participant_identity__ = None; let mut track_id__ = None; let mut segments__ = None; - let mut language__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::ParticipantIdentity => { - if participant_identity__.is_some() { - return Err(serde::de::Error::duplicate_field("participantIdentity")); + GeneratedField::TranscribedParticipantIdentity => { + if transcribed_participant_identity__.is_some() { + return Err(serde::de::Error::duplicate_field("transcribedParticipantIdentity")); } - participant_identity__ = Some(map_.next_value()?); + transcribed_participant_identity__ = Some(map_.next_value()?); } GeneratedField::TrackId => { if track_id__.is_some() { @@ -22631,22 +23029,15 @@ impl<'de> serde::Deserialize<'de> for Transcription { } segments__ = Some(map_.next_value()?); } - GeneratedField::Language => { - if language__.is_some() { - return Err(serde::de::Error::duplicate_field("language")); - } - language__ = Some(map_.next_value()?); - } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } Ok(Transcription { - participant_identity: participant_identity__.unwrap_or_default(), + transcribed_participant_identity: transcribed_participant_identity__.unwrap_or_default(), track_id: track_id__.unwrap_or_default(), segments: segments__.unwrap_or_default(), - language: language__.unwrap_or_default(), }) } } @@ -22676,6 +23067,9 @@ impl serde::Serialize for TranscriptionSegment { if self.r#final { len += 1; } + if !self.language.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.TranscriptionSegment", len)?; if !self.id.is_empty() { struct_ser.serialize_field("id", &self.id)?; @@ -22694,6 +23088,9 @@ impl serde::Serialize for TranscriptionSegment { if self.r#final { struct_ser.serialize_field("final", &self.r#final)?; } + if !self.language.is_empty() { + struct_ser.serialize_field("language", &self.language)?; + } struct_ser.end() } } @@ -22711,6 +23108,7 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { "end_time", "endTime", "final", + "language", ]; #[allow(clippy::enum_variant_names)] @@ -22720,6 +23118,7 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { StartTime, EndTime, Final, + Language, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -22747,6 +23146,7 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { "startTime" | "start_time" => Ok(GeneratedField::StartTime), "endTime" | "end_time" => Ok(GeneratedField::EndTime), "final" => Ok(GeneratedField::Final), + "language" => Ok(GeneratedField::Language), _ => Ok(GeneratedField::__SkipField__), } } @@ -22771,6 +23171,7 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { let mut start_time__ = None; let mut end_time__ = None; let mut r#final__ = None; + let mut language__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Id => { @@ -22807,6 +23208,12 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { } r#final__ = Some(map_.next_value()?); } + GeneratedField::Language => { + if language__.is_some() { + return Err(serde::de::Error::duplicate_field("language")); + } + language__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -22818,6 +23225,7 @@ impl<'de> serde::Deserialize<'de> for TranscriptionSegment { start_time: start_time__.unwrap_or_default(), end_time: end_time__.unwrap_or_default(), r#final: r#final__.unwrap_or_default(), + language: language__.unwrap_or_default(), }) } } @@ -22967,6 +23375,9 @@ impl serde::Serialize for UpdateIngressRequest { if self.bypass_transcoding.is_some() { len += 1; } + if self.enable_transcoding.is_some() { + len += 1; + } if self.audio.is_some() { len += 1; } @@ -22995,6 +23406,9 @@ impl serde::Serialize for UpdateIngressRequest { if let Some(v) = self.bypass_transcoding.as_ref() { struct_ser.serialize_field("bypassTranscoding", v)?; } + if let Some(v) = self.enable_transcoding.as_ref() { + struct_ser.serialize_field("enableTranscoding", v)?; + } if let Some(v) = self.audio.as_ref() { struct_ser.serialize_field("audio", v)?; } @@ -23024,6 +23438,8 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { "participantMetadata", "bypass_transcoding", "bypassTranscoding", + "enable_transcoding", + "enableTranscoding", "audio", "video", ]; @@ -23037,6 +23453,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { ParticipantName, ParticipantMetadata, BypassTranscoding, + EnableTranscoding, Audio, Video, __SkipField__, @@ -23068,6 +23485,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { "participantName" | "participant_name" => Ok(GeneratedField::ParticipantName), "participantMetadata" | "participant_metadata" => Ok(GeneratedField::ParticipantMetadata), "bypassTranscoding" | "bypass_transcoding" => Ok(GeneratedField::BypassTranscoding), + "enableTranscoding" | "enable_transcoding" => Ok(GeneratedField::EnableTranscoding), "audio" => Ok(GeneratedField::Audio), "video" => Ok(GeneratedField::Video), _ => Ok(GeneratedField::__SkipField__), @@ -23096,6 +23514,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { let mut participant_name__ = None; let mut participant_metadata__ = None; let mut bypass_transcoding__ = None; + let mut enable_transcoding__ = None; let mut audio__ = None; let mut video__ = None; while let Some(k) = map_.next_key()? { @@ -23142,6 +23561,12 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { } bypass_transcoding__ = map_.next_value()?; } + GeneratedField::EnableTranscoding => { + if enable_transcoding__.is_some() { + return Err(serde::de::Error::duplicate_field("enableTranscoding")); + } + enable_transcoding__ = map_.next_value()?; + } GeneratedField::Audio => { if audio__.is_some() { return Err(serde::de::Error::duplicate_field("audio")); @@ -23167,6 +23592,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { participant_name: participant_name__.unwrap_or_default(), participant_metadata: participant_metadata__.unwrap_or_default(), bypass_transcoding: bypass_transcoding__, + enable_transcoding: enable_transcoding__, audio: audio__, video: video__, }) diff --git a/webrtc-sys/Cargo.toml b/webrtc-sys/Cargo.toml index 7ab71c449..7080c651f 100644 --- a/webrtc-sys/Cargo.toml +++ b/webrtc-sys/Cargo.toml @@ -7,15 +7,15 @@ license = "Apache-2.0" description = "Unsafe bindings to libwebrtc" repository = "https://github.com/livekit/client-sdk-rust" +[features] +default = [] +static = [] + [dependencies] -cxx = "1.0" log = "0.4" [build-dependencies] -webrtc-sys-build = { version = "0.3.2", path = "./build" } -cxx-build = "1.0" -glob = "0.3" -cc = "1.0" +libwebrtc-build = { version="0.3.2", path="./libwebrtc/build-utils"} [dev-dependencies] env_logger = "0.10" diff --git a/webrtc-sys/README.md b/webrtc-sys/README.md deleted file mode 100644 index f3c044694..000000000 --- a/webrtc-sys/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# webrtc-sys - -This crate provides wrapper over the WebRTC API for use from Rust. -We use the crate [cxx.rs](https://cxx.rs/) to simplify our bindings. - -## Wrappers - -Most of our wrappers use the cxx.rs types compatible with Rust. -As most of our wrappers are stateless, we allow multiple instances of a specific wrapper to point to the same underlying webrtc pointer. (e.g: multiple livekit::MediaStreamTrack pointing to the same webrtc::MediaStreamTrackInterface). - -Threadsafe methods use the const keyword so we can easily call them from the Rust side without worrying about the mutability of the object. (This is similar on how Cell/UnsafeCell works but implemented on the C++ side: interior mutability). - -## Code - -We also use this C++ code to provide other needed utilities/features on the Rust side (e.g: tiny bindings to libyuv). - diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index 826c528b0..508f6899d 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -1,4 +1,4 @@ -// Copyright 2023 LiveKit, Inc. +// Copyright 2024 LiveKit, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,247 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{env, path, process::Command}; +use std::env; fn main() { if env::var("DOCS_RS").is_ok() { return; } - println!("cargo:rerun-if-env-changed=LK_DEBUG_WEBRTC"); - println!("cargo:rerun-if-env-changed=LK_CUSTOM_WEBRTC"); + let use_debug_lib = libwebrtc_build::rtc_debug_enabled(); + let use_dylib = !cfg!(feature = "static"); + let use_custom_rtc = libwebrtc_build::is_using_custom_webrtc(); - let mut builder = cxx_build::bridges([ - "src/peer_connection.rs", - "src/peer_connection_factory.rs", - "src/media_stream.rs", - "src/media_stream_track.rs", - "src/audio_track.rs", - "src/video_track.rs", - "src/data_channel.rs", - "src/frame_cryptor.rs", - "src/jsep.rs", - "src/candidate.rs", - "src/rtp_parameters.rs", - "src/rtp_sender.rs", - "src/rtp_receiver.rs", - "src/rtp_transceiver.rs", - "src/rtc_error.rs", - "src/webrtc.rs", - "src/video_frame.rs", - "src/video_frame_buffer.rs", - "src/helper.rs", - "src/yuv_helper.rs", - "src/audio_resampler.rs", - "src/android.rs", - ]); - - builder.files(&[ - "src/peer_connection.cpp", - "src/peer_connection_factory.cpp", - "src/media_stream.cpp", - "src/media_stream_track.cpp", - "src/audio_track.cpp", - "src/video_track.cpp", - "src/data_channel.cpp", - "src/jsep.cpp", - "src/candidate.cpp", - "src/rtp_receiver.cpp", - "src/rtp_sender.cpp", - "src/rtp_transceiver.cpp", - "src/rtp_parameters.cpp", - "src/rtc_error.cpp", - "src/webrtc.cpp", - "src/video_frame.cpp", - "src/video_frame_buffer.cpp", - "src/video_encoder_factory.cpp", - "src/video_decoder_factory.cpp", - "src/audio_device.cpp", - "src/audio_resampler.cpp", - "src/frame_cryptor.cpp", - ]); - - let webrtc_dir = webrtc_sys_build::webrtc_dir(); - let webrtc_include = webrtc_dir.join("include"); - let webrtc_lib = webrtc_dir.join("lib"); - - if !webrtc_dir.exists() { - webrtc_sys_build::download_webrtc().unwrap(); + if !use_custom_rtc { + libwebrtc_build::download_webrtc_if_needed(use_debug_lib, use_dylib).unwrap(); } - builder.includes(&[ - path::PathBuf::from("./include"), - webrtc_include.clone(), - webrtc_include.join("third_party/abseil-cpp/"), - webrtc_include.join("third_party/libyuv/include/"), - webrtc_include.join("third_party/libc++/"), - // For mac & ios - webrtc_include.join("sdk/objc"), - webrtc_include.join("sdk/objc/base"), - ]); - - println!("cargo:rustc-link-search=native={}", webrtc_lib.to_str().unwrap()); - - for (key, value) in webrtc_sys_build::webrtc_defines() { - let value = value.as_deref(); - builder.define(key.as_str(), value); + let mut rtc_path = libwebrtc_build::rtc_directory(); + if use_custom_rtc { + rtc_path = libwebrtc_build::custom_rtc_directory().unwrap(); } - // Link webrtc library - println!("cargo:rustc-link-lib=static=webrtc"); - - let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); - match target_os.as_str() { - "windows" => { - println!("cargo:rustc-link-lib=dylib=msdmo"); - println!("cargo:rustc-link-lib=dylib=wmcodecdspuuid"); - println!("cargo:rustc-link-lib=dylib=dmoguids"); - println!("cargo:rustc-link-lib=dylib=crypt32"); - println!("cargo:rustc-link-lib=dylib=iphlpapi"); - println!("cargo:rustc-link-lib=dylib=ole32"); - println!("cargo:rustc-link-lib=dylib=secur32"); - println!("cargo:rustc-link-lib=dylib=winmm"); - println!("cargo:rustc-link-lib=dylib=ws2_32"); - println!("cargo:rustc-link-lib=dylib=strmiids"); - println!("cargo:rustc-link-lib=dylib=d3d11"); - println!("cargo:rustc-link-lib=dylib=gdi32"); - println!("cargo:rustc-link-lib=dylib=dxgi"); - println!("cargo:rustc-link-lib=dylib=dwmapi"); - println!("cargo:rustc-link-lib=dylib=shcore"); - - builder.flag("/std:c++20").flag("/EHsc"); - } - "linux" => { - println!("cargo:rustc-link-lib=dylib=Xext"); - println!("cargo:rustc-link-lib=dylib=X11"); - println!("cargo:rustc-link-lib=dylib=GL"); - println!("cargo:rustc-link-lib=dylib=rt"); - println!("cargo:rustc-link-lib=dylib=dl"); - println!("cargo:rustc-link-lib=dylib=pthread"); - println!("cargo:rustc-link-lib=dylib=m"); - - builder.flag("-std=c++2a"); + if use_dylib { + if let Err(e) = libwebrtc_build::copy_dylib_to_target(&rtc_path) { + println!("cargo:warning=failed to copy livekit_rtc dylib to target: {}", e); } - "macos" => { - println!("cargo:rustc-link-lib=framework=Foundation"); - println!("cargo:rustc-link-lib=framework=AVFoundation"); - println!("cargo:rustc-link-lib=framework=CoreAudio"); - println!("cargo:rustc-link-lib=framework=AudioToolbox"); - println!("cargo:rustc-link-lib=framework=Appkit"); - println!("cargo:rustc-link-lib=framework=CoreMedia"); - println!("cargo:rustc-link-lib=framework=CoreGraphics"); - println!("cargo:rustc-link-lib=framework=VideoToolbox"); - println!("cargo:rustc-link-lib=framework=CoreVideo"); - println!("cargo:rustc-link-lib=framework=OpenGL"); - println!("cargo:rustc-link-lib=framework=Metal"); - println!("cargo:rustc-link-lib=framework=MetalKit"); - println!("cargo:rustc-link-lib=framework=QuartzCore"); - println!("cargo:rustc-link-lib=framework=IOKit"); - println!("cargo:rustc-link-lib=framework=IOSurface"); - - configure_darwin_sysroot(&mut builder); - - builder.file("src/objc_video_factory.mm").flag("-stdlib=libc++").flag("-std=c++20"); - } - "ios" => { - println!("cargo:rustc-link-lib=framework=CoreFoundation"); - println!("cargo:rustc-link-lib=framework=AVFoundation"); - println!("cargo:rustc-link-lib=framework=CoreAudio"); - println!("cargo:rustc-link-lib=framework=UIKit"); - println!("cargo:rustc-link-lib=framework=CoreVideo"); - println!("cargo:rustc-link-lib=framework=CoreGraphics"); - println!("cargo:rustc-link-lib=framework=CoreMedia"); - println!("cargo:rustc-link-lib=framework=VideoToolbox"); - println!("cargo:rustc-link-lib=framework=AudioToolbox"); - println!("cargo:rustc-link-lib=framework=OpenGLES"); - println!("cargo:rustc-link-lib=framework=GLKit"); - println!("cargo:rustc-link-lib=framework=Metal"); - println!("cargo:rustc-link-lib=framework=MetalKit"); - println!("cargo:rustc-link-lib=framework=Network"); - println!("cargo:rustc-link-lib=framework=QuartzCore"); - - configure_darwin_sysroot(&mut builder); - - builder.file("src/objc_video_factory.mm").flag("-std=c++20"); - } - "android" => { - webrtc_sys_build::configure_jni_symbols().unwrap(); - - println!("cargo:rustc-link-lib=EGL"); - println!("cargo:rustc-link-lib=c++abi"); - println!("cargo:rustc-link-lib=OpenSLES"); - - configure_android_sysroot(&mut builder); - - builder.file("src/android.cpp").flag("-std=c++20").cpp_link_stdlib("c++_static"); - } - _ => { - panic!("Unsupported target, {}", target_os); - } - } - // TODO(theomonnom) Only add this define when building tests - builder.define("LIVEKIT_TEST", None); - builder.warnings(false).compile("webrtcsys-cxx"); - - for entry in glob::glob("./src/**/*.cpp").unwrap() { - println!("cargo:rerun-if-changed={}", entry.unwrap().display()); - } - - for entry in glob::glob("./src/**/*.mm").unwrap() { - println!("cargo:rerun-if-changed={}", entry.unwrap().display()); + libwebrtc_build::link_shared_library(&rtc_path); + } else { + libwebrtc_build::link_static_library(&rtc_path); } - - for entry in glob::glob("./include/**/*.h").unwrap() { - println!("cargo:rerun-if-changed={}", entry.unwrap().display()); - } -} - -fn configure_darwin_sysroot(builder: &mut cc::Build) { - let target_os = webrtc_sys_build::target_os(); - - let sdk = match target_os.as_str() { - "mac" => "macosx", - "ios-device" => "iphoneos", - "ios-simulator" => "iphonesimulator", - _ => panic!("Unsupported target_os: {}", target_os), - }; - - let clang_rt = match target_os.as_str() { - "mac" => "clang_rt.osx", - "ios-device" => "clang_rt.ios", - "ios-simulator" => "clang_rt.iossim", - _ => panic!("Unsupported target_os: {}", target_os), - }; - - println!("cargo:rustc-link-lib={}", clang_rt); - println!("cargo:rustc-link-arg=-ObjC"); - - let sysroot = Command::new("xcrun").args(["--sdk", sdk, "--show-sdk-path"]).output().unwrap(); - - let sysroot = String::from_utf8_lossy(&sysroot.stdout); - let sysroot = sysroot.trim(); - - let search_dirs = Command::new("clang").arg("--print-search-dirs").output().unwrap(); - - let search_dirs = String::from_utf8_lossy(&search_dirs.stdout); - for line in search_dirs.lines() { - if line.contains("libraries: =") { - let path = line.split('=').nth(1).unwrap(); - let path = format!("{}/lib/darwin", path); - println!("cargo:rustc-link-search={}", path); - } - } - - builder.flag(format!("-isysroot{}", sysroot).as_str()); -} - -fn configure_android_sysroot(builder: &mut cc::Build) { - let toolchain = webrtc_sys_build::android_ndk_toolchain().unwrap(); - let toolchain_lib = toolchain.join("lib"); - - let sysroot = toolchain.join("sysroot").canonicalize().unwrap(); - println!("cargo:rustc-link-search={}", toolchain_lib.display()); - - builder.flag(format!("-isysroot{}", sysroot.display()).as_str()); } diff --git a/webrtc-sys/build/Cargo.toml b/webrtc-sys/build/Cargo.toml deleted file mode 100644 index 6dc600b9e..000000000 --- a/webrtc-sys/build/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "webrtc-sys-build" -version = "0.3.2" -edition = "2021" -license = "Apache-2.0" -description = "Build utilities when working with libwebrtc" -repository = "https://github.com/livekit/client-sdk-rust" - -[dependencies] -reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-native-roots", "blocking"] } -zip = "0.6" -regex = "1.0" -scratch = "1.0" -fs2 = "0.4" -semver = "1.0" diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs deleted file mode 100644 index c99c2ae56..000000000 --- a/webrtc-sys/build/src/lib.rs +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - env, - error::Error, - fs::{self, File}, - io::{self, BufRead, Write}, - path, - process::Command, -}; - -use fs2::FileExt; -use regex::Regex; -use reqwest::StatusCode; - -pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-b951613-4"; -pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; - -pub fn target_os() -> String { - let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); - let target = env::var("TARGET").unwrap(); - let is_simulator = target.ends_with("-sim"); - - match target_os.as_str() { - "windows" => "win", - "macos" => "mac", - "ios" => { - if is_simulator { - "ios-simulator" - } else { - "ios-device" - } - } - _ => &target_os, - } - .to_string() -} - -pub fn target_arch() -> String { - let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - match target_arch.as_str() { - "aarch64" => "arm64", - "x86_64" => "x64", - _ => &target_arch, - } - .to_owned() -} - -/// The full name of the webrtc library -/// e.g. mac-x64-release (Same name on GH releases) -pub fn webrtc_triple() -> String { - let profile = if use_debug() { "debug" } else { "release" }; - format!("{}-{}-{}", target_os(), target_arch(), profile) -} - -/// Using debug builds of webrtc is still experimental for now -/// On Windows, Rust doesn't link against libcmtd on debug, which is an issue -/// Default to false (even on cargo debug) -pub fn use_debug() -> bool { - let var = env::var("LK_DEBUG_WEBRTC"); - var.is_ok() && var.unwrap() == "true" -} - -/// The location of the custom build is defined by the user -pub fn custom_dir() -> Option { - if let Ok(path) = env::var("LK_CUSTOM_WEBRTC") { - return Some(path::PathBuf::from(path)); - } - None -} - -/// Location of the downloaded webrtc binaries -/// The reason why we don't use OUT_DIR is because we sometimes need to share the same binaries -/// across multiple crates without dependencies constraints -/// This also has the benefit of not re-downloading the binaries for each crate -pub fn prebuilt_dir() -> path::PathBuf { - let target_dir = scratch::path(SCRATH_PATH); - path::Path::new(&target_dir).join(format!( - "livekit/{}-{}/{}", - webrtc_triple(), - WEBRTC_TAG, - webrtc_triple() - )) -} - -pub fn download_url() -> String { - format!( - "https://github.com/livekit/client-sdk-rust/releases/download/{}/{}.zip", - WEBRTC_TAG, - format!("webrtc-{}", webrtc_triple()) - ) -} - -/// Used location of libwebrtc depending on whether it's a custom build or not -pub fn webrtc_dir() -> path::PathBuf { - if let Some(path) = custom_dir() { - return path; - } - - prebuilt_dir() -} - -pub fn webrtc_defines() -> Vec<(String, Option)> { - // read preprocessor definitions from webrtc.ninja - let defines_re = Regex::new(r"-D(\w+)(?:=([^\s]+))?").unwrap(); - let webrtc_gni = fs::File::open(webrtc_dir().join("webrtc.ninja")).unwrap(); - - let mut defines_line = String::default(); - io::BufReader::new(webrtc_gni).read_line(&mut defines_line).unwrap(); - - let mut vec = Vec::default(); - for cap in defines_re.captures_iter(&defines_line) { - let define_name = &cap[1]; - let define_value = cap.get(2).map(|m| m.as_str()); - if IGNORE_DEFINES.contains(&define_name) { - continue; - } - - vec.push((define_name.to_owned(), define_value.map(str::to_string))); - } - - vec -} - -pub fn configure_jni_symbols() -> Result<(), Box> { - download_webrtc()?; - - let toolchain = android_ndk_toolchain()?; - let toolchain_bin = toolchain.join("bin"); - - let webrtc_dir = webrtc_dir(); - let webrtc_lib = webrtc_dir.join("lib"); - - let out_dir = path::PathBuf::from(env::var("OUT_DIR").unwrap()); - - // Find JNI symbols - let readelf_output = Command::new(toolchain_bin.join("llvm-readelf")) - .arg("-Ws") - .arg(webrtc_lib.join("libwebrtc.a")) - .output() - .expect("failed to run llvm-readelf"); - - let jni_regex = Regex::new(r"(Java_org_webrtc.*)").unwrap(); - let content = String::from_utf8_lossy(&readelf_output.stdout); - let jni_symbols: Vec<&str> = - jni_regex.captures_iter(&content).map(|cap| cap.get(1).unwrap().as_str()).collect(); - - if jni_symbols.is_empty() { - return Err("No JNI symbols found".into()); // Shouldn't happen - } - - // Keep JNI symbols - for symbol in &jni_symbols { - println!("cargo:rustc-link-arg=-Wl,--undefined={}", symbol); - } - - // Version script - let vs_path = out_dir.join("webrtc_jni.map"); - let mut vs_file = fs::File::create(&vs_path).unwrap(); - - let jni_symbols = jni_symbols.join("; "); - write!(vs_file, "JNI_WEBRTC {{\n\tglobal: {}; \n}};", jni_symbols).unwrap(); - - println!("cargo:rustc-link-arg=-Wl,--version-script={}", vs_path.display()); - - Ok(()) -} - -pub fn download_webrtc() -> Result<(), Box> { - let dir = scratch::path(SCRATH_PATH); - let flock = File::create(dir.join(".lock"))?; - flock.lock_exclusive()?; - - let webrtc_dir = webrtc_dir(); - if webrtc_dir.exists() { - return Ok(()); - } - - let mut resp = reqwest::blocking::get(download_url())?; - if resp.status() != StatusCode::OK { - return Err(format!("failed to download webrtc: {}", resp.status()).into()); - } - - let tmp_path = env::var("OUT_DIR").unwrap() + "/webrtc.zip"; - let tmp_path = path::Path::new(&tmp_path); - let mut file = fs::File::options().write(true).read(true).create(true).open(tmp_path)?; - resp.copy_to(&mut file)?; - - let mut archive = zip::ZipArchive::new(file)?; - archive.extract(webrtc_dir.parent().unwrap())?; - drop(archive); - - fs::remove_file(tmp_path)?; - Ok(()) -} - -pub fn android_ndk_toolchain() -> Result { - let host_os = host_os(); - - let home = env::var("HOME"); - let local = env::var("LOCALAPPDATA"); - - let home = if host_os == Some("linux") { - path::PathBuf::from(home.unwrap()) - } else if host_os == Some("darwin") { - path::PathBuf::from(home.unwrap()).join("Library") - } else if host_os == Some("windows") { - path::PathBuf::from(local.unwrap()) - } else { - return Err("Unsupported host OS"); - }; - - let ndk_dir = || -> Option { - let ndk_env = env::var("ANDROID_NDK_HOME"); - if let Ok(ndk_env) = ndk_env { - return Some(path::PathBuf::from(ndk_env)); - } - - let ndk_dir = home.join("Android/sdk/ndk"); - if !ndk_dir.exists() { - return None; - } - - // Find the highest version - let versions = fs::read_dir(ndk_dir.clone()); - if versions.is_err() { - return None; - } - - let version = versions - .unwrap() - .filter_map(Result::ok) - .filter_map(|dir| dir.file_name().to_str().map(ToOwned::to_owned)) - .filter_map(|dir| semver::Version::parse(&dir).ok()) - .max_by(semver::Version::cmp); - - version.as_ref()?; - - let version = version.unwrap(); - Some(ndk_dir.join(version.to_string())) - }(); - - if let Some(ndk_dir) = ndk_dir { - let llvm_dir = if host_os == Some("linux") { - "linux-x86_64" - } else if host_os == Some("darwin") { - "darwin-x86_64" - } else if host_os == Some("windows") { - "windows-x86_64" - } else { - return Err("Unsupported host OS"); - }; - - Ok(ndk_dir.join(format!("toolchains/llvm/prebuilt/{}", llvm_dir))) - } else { - Err("Android NDK not found, please set ANDROID_NDK_HOME to your NDK path") - } -} - -fn host_os() -> Option<&'static str> { - let host = env::var("HOST").unwrap(); - if host.contains("darwin") { - Some("darwin") - } else if host.contains("linux") { - Some("linux") - } else if host.contains("windows") { - Some("windows") - } else { - None - } -} diff --git a/webrtc-sys/compile_flags.txt b/webrtc-sys/compile_flags.txt deleted file mode 100644 index 950ea1edc..000000000 --- a/webrtc-sys/compile_flags.txt +++ /dev/null @@ -1,21 +0,0 @@ --xc++ --xobjective-c --xobjective-c++ --std=c++17 --Iinclude --Ilibwebrtc/src --Ilibwebrtc/src/third_party/abseil-cpp --Ilibwebrtc/src/third_party/libc++ --Ilibwebrtc/src/third_party/libyuv/include --Ilibwebrtc/src/sdk/objc/base --Ilibwebrtc/src/sdk/objc --I../target/cxxbridge --DWEBRTC_POSIX --DWEBRTC_ANDROID --DNDEBUG --DWEBRTC_ENABLE_SYMBOL_EXPORT --D__ANDROID_API__=29 --DWEBRTC_LIBRARY_IMPL ---sysroot=/Users/theomonnom/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot ---target=aarch64-none-linux-android ---gcc-toolchain=/Users/theomonnom/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64 diff --git a/webrtc-sys/generate_bindgen.sh b/webrtc-sys/generate_bindgen.sh new file mode 100755 index 000000000..9f1cf6931 --- /dev/null +++ b/webrtc-sys/generate_bindgen.sh @@ -0,0 +1,5 @@ +bindgen libwebrtc/src/livekit_rtc/livekit/capi.h \ + --output src/sys/ffi.rs \ + --allowlist-type "lk.*" \ + --allowlist-function "lk.*" \ + --default-enum-style rust diff --git a/webrtc-sys/generate_jni_symbols.sh b/webrtc-sys/generate_jni_symbols.sh new file mode 100755 index 000000000..ed802042a --- /dev/null +++ b/webrtc-sys/generate_jni_symbols.sh @@ -0,0 +1,13 @@ +# retrieve webrtc JNI symbols from a lib +# Usage: generate_jni_symbols.sh jni_symbols.txt + +lib=$1 + +llvm-readelf -s $lib \ +| grep Java_org_webrtc \ +| awk '{print $8}' \ +| sort \ +| uniq \ +| sed 's/@@JNI_WEBRTC//' \ +> jni_symbols.txt + diff --git a/webrtc-sys/include/livekit/android.h b/webrtc-sys/include/livekit/android.h deleted file mode 100644 index 2826ea33f..000000000 --- a/webrtc-sys/include/livekit/android.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include - -#include "api/video_codecs/video_decoder_factory.h" -#include "api/video_codecs/video_encoder_factory.h" - -namespace livekit { -typedef JavaVM JavaVM; -} // namespace livekit -#include "webrtc-sys/src/android.rs.h" - -namespace livekit { -void init_android(JavaVM* jvm); - -std::unique_ptr CreateAndroidVideoEncoderFactory(); -std::unique_ptr CreateAndroidVideoDecoderFactory(); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/audio_device.h b/webrtc-sys/include/livekit/audio_device.h deleted file mode 100644 index 903e22d6e..000000000 --- a/webrtc-sys/include/livekit/audio_device.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/task_queue/task_queue_factory.h" -#include "modules/audio_device/include/audio_device.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/task_queue.h" -#include "rtc_base/task_utils/repeating_task.h" - -namespace livekit { - -class AudioDevice : public webrtc::AudioDeviceModule { - public: - AudioDevice(webrtc::TaskQueueFactory* task_queue_factory); - ~AudioDevice() override; - - int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override; - int32_t RegisterAudioCallback(webrtc::AudioTransport* transport) override; - - int32_t Init() override; - int32_t Terminate() override; - bool Initialized() const override; - - int16_t PlayoutDevices() override; - int16_t RecordingDevices() override; - int32_t PlayoutDeviceName(uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) override; - - int32_t RecordingDeviceName(uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) override; - - int32_t SetPlayoutDevice(uint16_t index) override; - int32_t SetPlayoutDevice(WindowsDeviceType device) override; - int32_t SetRecordingDevice(uint16_t index) override; - int32_t SetRecordingDevice(WindowsDeviceType device) override; - - int32_t PlayoutIsAvailable(bool* available) override; - int32_t InitPlayout() override; - bool PlayoutIsInitialized() const override; - int32_t RecordingIsAvailable(bool* available) override; - int32_t InitRecording() override; - bool RecordingIsInitialized() const override; - - int32_t StartPlayout() override; - int32_t StopPlayout() override; - bool Playing() const override; - int32_t StartRecording() override; - int32_t StopRecording() override; - bool Recording() const override; - - int32_t InitSpeaker() override; - bool SpeakerIsInitialized() const override; - int32_t InitMicrophone() override; - bool MicrophoneIsInitialized() const override; - - int32_t SpeakerVolumeIsAvailable(bool* available) override; - int32_t SetSpeakerVolume(uint32_t volume) override; - int32_t SpeakerVolume(uint32_t* volume) const override; - int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override; - int32_t MinSpeakerVolume(uint32_t* minVolume) const override; - - int32_t MicrophoneVolumeIsAvailable(bool* available) override; - int32_t SetMicrophoneVolume(uint32_t volume) override; - int32_t MicrophoneVolume(uint32_t* volume) const override; - int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override; - int32_t MinMicrophoneVolume(uint32_t* minVolume) const override; - - int32_t SpeakerMuteIsAvailable(bool* available) override; - int32_t SetSpeakerMute(bool enable) override; - int32_t SpeakerMute(bool* enabled) const override; - - int32_t MicrophoneMuteIsAvailable(bool* available) override; - int32_t SetMicrophoneMute(bool enable) override; - int32_t MicrophoneMute(bool* enabled) const override; - - int32_t StereoPlayoutIsAvailable(bool* available) const override; - int32_t SetStereoPlayout(bool enable) override; - int32_t StereoPlayout(bool* enabled) const override; - int32_t StereoRecordingIsAvailable(bool* available) const override; - int32_t SetStereoRecording(bool enable) override; - int32_t StereoRecording(bool* enabled) const override; - - int32_t PlayoutDelay(uint16_t* delayMS) const override; - - bool BuiltInAECIsAvailable() const override; - bool BuiltInAGCIsAvailable() const override; - bool BuiltInNSIsAvailable() const override; - - int32_t EnableBuiltInAEC(bool enable) override; - int32_t EnableBuiltInAGC(bool enable) override; - int32_t EnableBuiltInNS(bool enable) override; - -#if defined(WEBRTC_IOS) - int GetPlayoutAudioParameters(webrtc::AudioParameters* params) const override; - int GetRecordAudioParameters(webrtc::AudioParameters* params) const override; -#endif // WEBRTC_IOS - - int32_t SetAudioDeviceSink(webrtc::AudioDeviceSink* sink) const override; - - private: - mutable webrtc::Mutex mutex_; - std::vector data_; - std::unique_ptr audio_queue_; - webrtc::RepeatingTaskHandle audio_task_; - webrtc::AudioTransport* audio_transport_; - webrtc::TaskQueueFactory* task_queue_factory_; - bool playing_{false}; - bool initialized_{false}; -}; -} // namespace livekit diff --git a/webrtc-sys/include/livekit/audio_resampler.h b/webrtc-sys/include/livekit/audio_resampler.h deleted file mode 100644 index e0880449e..000000000 --- a/webrtc-sys/include/livekit/audio_resampler.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/audio/audio_frame.h" -#include "api/data_channel_interface.h" -#include "common_audio/resampler/include/push_resampler.h" -#include "livekit/webrtc.h" -#include "rust/cxx.h" - -namespace livekit { - -class AudioResampler { - public: - size_t remix_and_resample(const int16_t* src, - size_t samples_per_channel, - size_t num_channels, - int sample_rate_hz, - size_t dest_num_channels, - int dest_sample_rate_hz); - - const int16_t* data() const; - - private: - webrtc::AudioFrame frame_; - webrtc::PushResampler resampler_; -}; - -std::unique_ptr create_audio_resampler(); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/audio_track.h b/webrtc-sys/include/livekit/audio_track.h deleted file mode 100644 index a67ca8116..000000000 --- a/webrtc-sys/include/livekit/audio_track.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/audio_options.h" -#include "livekit/helper.h" -#include "livekit/media_stream_track.h" -#include "livekit/webrtc.h" -#include "pc/local_audio_source.h" -#include "rtc_base/synchronization/mutex.h" -#include "rust/cxx.h" - -namespace livekit { -class AudioTrack; -class NativeAudioSink; -class AudioTrackSource; -} // namespace livekit -#include "webrtc-sys/src/audio_track.rs.h" - -namespace livekit { - -class AudioTrack : public MediaStreamTrack { - private: - friend RtcRuntime; - AudioTrack(std::shared_ptr rtc_runtime, - rtc::scoped_refptr track); - - public: - ~AudioTrack(); - - void add_sink(const std::shared_ptr& sink) const; - void remove_sink(const std::shared_ptr& sink) const; - - private: - webrtc::AudioTrackInterface* track() const { - return static_cast(track_.get()); - } - - mutable webrtc::Mutex mutex_; - - // Same for VideoTrack: - // Keep a strong reference to the added sinks, so we don't need to - // manage the lifetime safety on the Rust side - mutable std::vector> sinks_; -}; - -class NativeAudioSink : public webrtc::AudioTrackSinkInterface { - public: - explicit NativeAudioSink(rust::Box observer); - void OnData(const void* audio_data, - int bits_per_sample, - int sample_rate, - size_t number_of_channels, - size_t number_of_frames) override; - - private: - rust::Box observer_; -}; - -std::shared_ptr new_native_audio_sink( - rust::Box observer); - -class AudioTrackSource { - class InternalSource : public webrtc::LocalAudioSource { - public: - InternalSource(const cricket::AudioOptions& options); - - SourceState state() const override; - bool remote() const override; - - const cricket::AudioOptions options() const override; - - void AddSink(webrtc::AudioTrackSinkInterface* sink) override; - void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override; - - void set_options(const cricket::AudioOptions& options); - - // AudioFrame should always contain 10 ms worth of data (see index.md of - // acm) - void on_captured_frame(rust::Slice audio_data, - uint32_t sample_rate, - uint32_t number_of_channels, - size_t number_of_frames); - - private: - mutable webrtc::Mutex mutex_; - std::vector sinks_; - cricket::AudioOptions options_{}; - }; - - public: - AudioTrackSource(AudioSourceOptions options); - - AudioSourceOptions audio_options() const; - - void set_audio_options(const AudioSourceOptions& options) const; - - void on_captured_frame(rust::Slice audio_data, - uint32_t sample_rate, - uint32_t number_of_channels, - size_t number_of_frames) const; - - rtc::scoped_refptr get() const; - - private: - rtc::scoped_refptr source_; -}; - -std::shared_ptr new_audio_track_source( - AudioSourceOptions options); - -static std::shared_ptr audio_to_media( - std::shared_ptr track) { - return track; -} - -static std::shared_ptr media_to_audio( - std::shared_ptr track) { - return std::static_pointer_cast(track); -} - -static std::shared_ptr _shared_audio_track() { - return nullptr; // Ignore -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/candidate.h b/webrtc-sys/include/livekit/candidate.h deleted file mode 100644 index 574ededc6..000000000 --- a/webrtc-sys/include/livekit/candidate.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/candidate.h" - -namespace livekit { -class Candidate; -} -#include "webrtc-sys/src/candidate.rs.h" - -// cricket::Candidate -namespace livekit { - -class Candidate { - public: - explicit Candidate(const cricket::Candidate& candidate); - - private: - cricket::Candidate candidate_; -}; - -static std::shared_ptr _shared_candidate() { - return nullptr; -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/data_channel.h b/webrtc-sys/include/livekit/data_channel.h deleted file mode 100644 index f08e93ea1..000000000 --- a/webrtc-sys/include/livekit/data_channel.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "api/data_channel_interface.h" -#include "livekit/webrtc.h" -#include "rtc_base/synchronization/mutex.h" -#include "rust/cxx.h" - -namespace livekit { -class DataChannel; -} // namespace livekit -#include "webrtc-sys/src/data_channel.rs.h" - -namespace livekit { - -class NativeDataChannelObserver; - -webrtc::DataChannelInit to_native_data_channel_init(DataChannelInit init); - -class DataChannel { - public: - explicit DataChannel( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr data_channel); - ~DataChannel(); - - void register_observer(rust::Box observer) const; - void unregister_observer() const; - bool send(const DataBuffer& buffer) const; - int id() const; - rust::String label() const; - DataState state() const; - void close() const; - - private: - mutable webrtc::Mutex mutex_; - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr data_channel_; - mutable std::unique_ptr observer_; -}; - -static std::shared_ptr _shared_data_channel() { - return nullptr; // Ignore -} - -class NativeDataChannelObserver : public webrtc::DataChannelObserver { - public: - NativeDataChannelObserver(rust::Box observer, - const DataChannel* dc); - - void OnStateChange() override; - void OnMessage(const webrtc::DataBuffer& buffer) override; - void OnBufferedAmountChange(uint64_t sent_data_size) override; - - private: - rust::Box observer_; - const DataChannel* dc_; -}; - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/frame_cryptor.h b/webrtc-sys/include/livekit/frame_cryptor.h deleted file mode 100644 index 43102d3cf..000000000 --- a/webrtc-sys/include/livekit/frame_cryptor.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include -#include -#include - -#include "api/crypto/frame_crypto_transformer.h" -#include "api/scoped_refptr.h" -#include "livekit/peer_connection.h" -#include "livekit/peer_connection_factory.h" -#include "livekit/rtp_receiver.h" -#include "livekit/rtp_sender.h" -#include "livekit/webrtc.h" -#include "rtc_base/synchronization/mutex.h" -#include "rust/cxx.h" - -namespace livekit { - -struct KeyProviderOptions; -enum class Algorithm : ::std::int32_t; -class RtcFrameCryptorObserverWrapper; -class NativeFrameCryptorObserver; - -/// Shared secret key for frame encryption. -class KeyProvider { - public: - KeyProvider(KeyProviderOptions options); - ~KeyProvider() {} - - bool set_shared_key(int32_t index, rust::Vec<::std::uint8_t> key) const { - std::vector key_vec; - std::copy(key.begin(), key.end(), std::back_inserter(key_vec)); - return impl_->SetSharedKey(index, key_vec); - } - - rust::Vec<::std::uint8_t> ratchet_shared_key(int32_t key_index) const { - rust::Vec vec; - auto data = impl_->RatchetSharedKey(key_index); - if (data.empty()) { - throw std::runtime_error("ratchet_shared_key failed"); - } - - std::move(data.begin(), data.end(), std::back_inserter(vec)); - return vec; - } - - rust::Vec<::std::uint8_t> get_shared_key(int32_t key_index) const { - rust::Vec vec; - auto data = impl_->ExportSharedKey(key_index); - if (data.empty()) { - throw std::runtime_error("get_shared_key failed"); - } - - std::move(data.begin(), data.end(), std::back_inserter(vec)); - return vec; - } - - /// Set the key at the given index. - bool set_key(const ::rust::String participant_id, - int32_t index, - rust::Vec<::std::uint8_t> key) const { - std::vector key_vec; - std::copy(key.begin(), key.end(), std::back_inserter(key_vec)); - return impl_->SetKey( - std::string(participant_id.data(), participant_id.size()), index, - key_vec); - } - - rust::Vec<::std::uint8_t> ratchet_key(const ::rust::String participant_id, - int32_t key_index) const { - rust::Vec vec; - auto data = impl_->RatchetKey( - std::string(participant_id.data(), participant_id.size()), key_index); - if (data.empty()) { - throw std::runtime_error("ratchet_key failed"); - } - - std::move(data.begin(), data.end(), std::back_inserter(vec)); - return vec; - } - - rust::Vec<::std::uint8_t> get_key(const ::rust::String participant_id, - int32_t key_index) const { - rust::Vec vec; - auto data = impl_->ExportKey( - std::string(participant_id.data(), participant_id.size()), key_index); - if (data.empty()) { - throw std::runtime_error("get_key failed"); - } - - std::move(data.begin(), data.end(), std::back_inserter(vec)); - return vec; - } - - void set_sif_trailer(rust::Vec<::std::uint8_t> trailer) const { - std::vector trailer_vec; - std::copy(trailer.begin(), trailer.end(), std::back_inserter(trailer_vec)); - impl_->SetSifTrailer(trailer_vec); - } - - rtc::scoped_refptr rtc_key_provider() { return impl_; } - - private: - rtc::scoped_refptr impl_; -}; - -class FrameCryptor { - public: - FrameCryptor(std::shared_ptr rtc_runtime, - const std::string participant_id, - webrtc::FrameCryptorTransformer::Algorithm algorithm, - rtc::scoped_refptr key_provider, - rtc::scoped_refptr sender); - - FrameCryptor(std::shared_ptr rtc_runtime, - const std::string participant_id, - webrtc::FrameCryptorTransformer::Algorithm algorithm, - rtc::scoped_refptr key_provider, - rtc::scoped_refptr receiver); - ~FrameCryptor(); - - /// Enable/Disable frame crypto for the sender or receiver. - void set_enabled(bool enabled) const; - - /// Get the enabled state for the sender or receiver. - bool enabled() const; - - /// Set the key index for the sender or receiver. - /// If the key index is not set, the key index will be set to 0. - void set_key_index(int32_t index) const; - - /// Get the key index for the sender or receiver. - int32_t key_index() const; - - rust::String participant_id() const { return participant_id_; } - - void register_observer( - rust::Box observer) const; - - void unregister_observer() const; - - private: - std::shared_ptr rtc_runtime_; - const rust::String participant_id_; - mutable webrtc::Mutex mutex_; - rtc::scoped_refptr e2ee_transformer_; - rtc::scoped_refptr key_provider_; - rtc::scoped_refptr sender_; - rtc::scoped_refptr receiver_; - mutable rtc::scoped_refptr observer_; -}; - -class NativeFrameCryptorObserver - : public webrtc::FrameCryptorTransformerObserver { - public: - NativeFrameCryptorObserver(rust::Box observer, - const FrameCryptor* fc); - ~NativeFrameCryptorObserver(); - - void OnFrameCryptionStateChanged(const std::string participant_id, - webrtc::FrameCryptionState error) override; - - private: - rust::Box observer_; - const FrameCryptor* fc_; -}; - -std::shared_ptr new_frame_cryptor_for_rtp_sender( - std::shared_ptr peer_factory, - const ::rust::String participant_id, - Algorithm algorithm, - std::shared_ptr key_provider, - std::shared_ptr sender); - -std::shared_ptr new_frame_cryptor_for_rtp_receiver( - std::shared_ptr peer_factory, - const ::rust::String participant_id, - Algorithm algorithm, - std::shared_ptr key_provider, - std::shared_ptr receiver); - -std::shared_ptr new_key_provider(KeyProviderOptions options); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/helper.h b/webrtc-sys/include/livekit/helper.h deleted file mode 100644 index 629912605..000000000 --- a/webrtc-sys/include/livekit/helper.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "rust/cxx.h" - -namespace livekit { -class MediaStream; -class AudioTrack; -class VideoTrack; -class Candidate; -class RtpSender; -class RtpReceiver; -class RtpTransceiver; -} // namespace livekit -#include "webrtc-sys/src/helper.rs.h" - -namespace livekit { - -// Impl not needed -static rust::Vec _vec_media_stream_ptr() { - throw; -} -static rust::Vec _vec_candidate_ptr() { - throw; -} -static rust::Vec _vec_audio_track_ptr() { - throw; -} -static rust::Vec _vec_video_track_ptr() { - throw; -} -static rust::Vec _vec_rtp_sender_ptr() { - throw; -} -static rust::Vec _vec_rtp_receiver_ptr() { - throw; -} -static rust::Vec _vec_rtp_transceiver_ptr() { - throw; -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/jsep.h b/webrtc-sys/include/livekit/jsep.h deleted file mode 100644 index 6f100f43e..000000000 --- a/webrtc-sys/include/livekit/jsep.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/jsep.h" -#include "api/ref_counted_base.h" -#include "api/set_local_description_observer_interface.h" -#include "api/set_remote_description_observer_interface.h" -#include "api/stats/rtc_stats_collector_callback.h" -#include "livekit/rtc_error.h" -#include "rtc_base/ref_count.h" -#include "rust/cxx.h" - -namespace livekit { -class IceCandidate; -class SessionDescription; -}; // namespace livekit -#include "webrtc-sys/src/jsep.rs.h" - -namespace livekit { - -class PeerContext; - -class IceCandidate { - public: - explicit IceCandidate( - std::unique_ptr ice_candidate); - - rust::String sdp_mid() const; - int sdp_mline_index() const; - rust::String candidate() const; // TODO(theomonnom) Return livekit::Candidate - // instead of rust::String - - rust::String stringify() const; - std::unique_ptr release(); - - private: - std::unique_ptr ice_candidate_; -}; - -std::shared_ptr create_ice_candidate(rust::String sdp_mid, - int sdp_mline_index, - rust::String sdp); - -static std::shared_ptr _shared_ice_candidate() { - return nullptr; // Ignore -} - -class SessionDescription { - public: - explicit SessionDescription( - std::unique_ptr session_description); - - SdpType sdp_type() const; - rust::String stringify() const; - std::unique_ptr clone() const; - std::unique_ptr release(); - - private: - std::unique_ptr session_description_; -}; - -std::unique_ptr create_session_description( - SdpType type, - rust::String sdp); - -static std::unique_ptr _unique_session_description() { - return nullptr; // Ignore -} - -class NativeCreateSdpObserver - : public webrtc::CreateSessionDescriptionObserver { - public: - NativeCreateSdpObserver( - rust::Box ctx, - rust::Fn ctx, - std::unique_ptr)> on_success, - rust::Fn ctx, RtcError)> on_error); - - void OnSuccess(webrtc::SessionDescriptionInterface* desc) override; - void OnFailure(webrtc::RTCError error) override; - - private: - rust::Box ctx_; - rust::Fn, std::unique_ptr)> - on_success_; - rust::Fn, RtcError)> on_error_; -}; - -class NativeSetLocalSdpObserver - : public webrtc::SetLocalDescriptionObserverInterface { - public: - NativeSetLocalSdpObserver( - rust::Box ctx, - rust::Fn, RtcError)> on_complete); - - void OnSetLocalDescriptionComplete(webrtc::RTCError error) override; - - private: - rust::Box ctx_; - rust::Fn, RtcError)> on_complete_; -}; - -class NativeSetRemoteSdpObserver - : public webrtc::SetRemoteDescriptionObserverInterface { - public: - NativeSetRemoteSdpObserver( - rust::Box ctx, - rust::Fn, RtcError)> on_complete); - - void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override; - - private: - rust::Box ctx_; - rust::Fn, RtcError)> on_complete_; -}; - -template // Context type -class NativeRtcStatsCollector : public webrtc::RTCStatsCollectorCallback { - public: - NativeRtcStatsCollector(rust::Box ctx, - rust::Fn, rust::String)> on_stats) - : ctx_(std::move(ctx)), on_stats_(on_stats) {} - - void OnStatsDelivered( - const rtc::scoped_refptr& report) override { - on_stats_(std::move(ctx_), report->ToJson()); - } - - private: - rust::Box ctx_; - rust::Fn, rust::String)> on_stats_; -}; - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/media_stream.h b/webrtc-sys/include/livekit/media_stream.h deleted file mode 100644 index fe64dbe6a..000000000 --- a/webrtc-sys/include/livekit/media_stream.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/media_stream_interface.h" -#include "livekit/helper.h" -#include "livekit/webrtc.h" -#include "rust/cxx.h" - -namespace livekit { -class MediaStream; -} // namespace livekit -#include "webrtc-sys/src/media_stream.rs.h" - -namespace livekit { - -class MediaStream { - public: - MediaStream(std::shared_ptr rtc_runtime, - rtc::scoped_refptr stream); - - rust::String id() const; - rust::Vec get_video_tracks() const; - rust::Vec get_audio_tracks() const; - - std::shared_ptr find_audio_track(rust::String track_id) const; - std::shared_ptr find_video_track(rust::String track_id) const; - - bool add_track(std::shared_ptr track) const; - bool remove_track(std::shared_ptr track) const; - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr media_stream_; -}; - -static std::shared_ptr _shared_media_stream() { - return nullptr; // Ignore -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/media_stream_track.h b/webrtc-sys/include/livekit/media_stream_track.h deleted file mode 100644 index 6be69047a..000000000 --- a/webrtc-sys/include/livekit/media_stream_track.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/media_stream_interface.h" -#include "livekit/helper.h" -#include "livekit/webrtc.h" -#include "rust/cxx.h" - -namespace livekit { -class MediaStreamTrack; -} // namespace livekit -#include "webrtc-sys/src/media_stream_track.rs.h" - -namespace livekit { - -class MediaStreamTrack { - protected: - MediaStreamTrack(std::shared_ptr, - rtc::scoped_refptr track); - - public: - rust::String kind() const; - rust::String id() const; - - bool enabled() const; - bool set_enabled(bool enable) const; - - TrackState state() const; - - rtc::scoped_refptr rtc_track() const { - return track_; - } - - protected: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr track_; -}; - -static std::shared_ptr _shared_media_stream_track() { - return nullptr; // Ignore -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/objc_video_factory.h b/webrtc-sys/include/livekit/objc_video_factory.h deleted file mode 100644 index cbc2a0d95..000000000 --- a/webrtc-sys/include/livekit/objc_video_factory.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/video_codecs/video_decoder_factory.h" -#include "api/video_codecs/video_encoder_factory.h" - -namespace livekit { - -std::unique_ptr CreateObjCVideoEncoderFactory(); -std::unique_ptr CreateObjCVideoDecoderFactory(); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/peer_connection.h b/webrtc-sys/include/livekit/peer_connection.h deleted file mode 100644 index 32496ca00..000000000 --- a/webrtc-sys/include/livekit/peer_connection.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/peer_connection_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/data_channel.h" -#include "livekit/helper.h" -#include "livekit/jsep.h" -#include "livekit/media_stream.h" -#include "livekit/rtc_error.h" -#include "livekit/rtp_receiver.h" -#include "livekit/rtp_sender.h" -#include "livekit/rtp_transceiver.h" -#include "livekit/webrtc.h" -#include "rust/cxx.h" -#include "webrtc-sys/src/data_channel.rs.h" - -namespace livekit { -class PeerConnection; -} // namespace livekit -#include "webrtc-sys/src/peer_connection.rs.h" - -namespace livekit { - -webrtc::PeerConnectionInterface::RTCConfiguration to_native_rtc_configuration( - RtcConfiguration config); - -class PeerConnectionObserverWrapper; - -class PeerConnection : webrtc::PeerConnectionObserver { - public: - PeerConnection( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr pc_factory, - rust::Box observer); - - ~PeerConnection(); - - bool Initialize(webrtc::PeerConnectionInterface::RTCConfiguration config); - - void set_configuration(RtcConfiguration config) const; - - void create_offer( - RtcOfferAnswerOptions options, - rust::Box ctx, - rust::Fn, - std::unique_ptr)> on_success, - rust::Fn, RtcError)> on_error) const; - - void create_answer( - RtcOfferAnswerOptions options, - rust::Box ctx, - rust::Fn, - std::unique_ptr)> on_success, - rust::Fn, RtcError)> on_error) const; - - void set_local_description( - std::unique_ptr desc, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const; - - void set_remote_description( - std::unique_ptr desc, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const; - - std::shared_ptr create_data_channel(rust::String label, - DataChannelInit init) const; - - void add_ice_candidate( - std::shared_ptr candidate, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const; - - std::shared_ptr add_track( - std::shared_ptr track, - const rust::Vec& stream_ids) const; - - void remove_track(std::shared_ptr sender) const; - - void get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const; - - void restart_ice() const; - - std::shared_ptr add_transceiver( - std::shared_ptr track, - RtpTransceiverInit init) const; - - std::shared_ptr add_transceiver_for_media( - MediaType media_type, - RtpTransceiverInit init) const; - - rust::Vec get_senders() const; - - rust::Vec get_receivers() const; - - rust::Vec get_transceivers() const; - - std::unique_ptr current_local_description() const; - - std::unique_ptr current_remote_description() const; - - std::unique_ptr pending_local_description() const; - - std::unique_ptr pending_remote_description() const; - - std::unique_ptr local_description() const; - - std::unique_ptr remote_description() const; - - PeerConnectionState connection_state() const; - - SignalingState signaling_state() const; - - IceGatheringState ice_gathering_state() const; - - IceConnectionState ice_connection_state() const; - - void close() const; - - void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) override; - - void OnAddStream( - rtc::scoped_refptr stream) override; - - void OnRemoveStream( - rtc::scoped_refptr stream) override; - - void OnDataChannel( - rtc::scoped_refptr data_channel) override; - - void OnRenegotiationNeeded() override; - - void OnNegotiationNeededEvent(uint32_t event_id) override; - - void OnIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) override; - - void OnStandardizedIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) override; - - void OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; - - void OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) override; - - void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override; - - void OnIceCandidateError(const std::string& address, - int port, - const std::string& url, - int error_code, - const std::string& error_text) override; - - void OnIceCandidatesRemoved( - const std::vector& candidates) override; - - void OnIceConnectionReceivingChange(bool receiving) override; - - void OnIceSelectedCandidatePairChanged( - const cricket::CandidatePairChangeEvent& event) override; - - void OnAddTrack( - rtc::scoped_refptr receiver, - const std::vector>& - streams) override; - - void OnTrack( - rtc::scoped_refptr transceiver) override; - - void OnRemoveTrack( - rtc::scoped_refptr receiver) override; - - void OnInterestingUsage(int usage_pattern) override; - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr pc_factory_; - rust::Box observer_; - rtc::scoped_refptr peer_connection_; -}; - -static std::shared_ptr _shared_peer_connection() { - return nullptr; // Ignore -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/peer_connection_factory.h b/webrtc-sys/include/livekit/peer_connection_factory.h deleted file mode 100644 index 7d22c4e81..000000000 --- a/webrtc-sys/include/livekit/peer_connection_factory.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "api/peer_connection_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/audio_device.h" -#include "media_stream.h" -#include "rtp_parameters.h" -#include "rust/cxx.h" -#include "webrtc.h" - -namespace livekit { -class PeerConnectionFactory; -class PeerConnectionObserverWrapper; -} // namespace livekit -#include "webrtc-sys/src/peer_connection_factory.rs.h" - -namespace livekit { - -class PeerConnection; -struct RtcConfiguration; - -webrtc::PeerConnectionInterface::RTCConfiguration to_native_rtc_configuration( - RtcConfiguration config); - -class PeerConnectionFactory { - public: - explicit PeerConnectionFactory(std::shared_ptr rtc_runtime); - ~PeerConnectionFactory(); - - std::shared_ptr create_peer_connection( - RtcConfiguration config, - rust::Box observer) const; - - std::shared_ptr create_video_track( - rust::String label, - std::shared_ptr source) const; - - std::shared_ptr create_audio_track( - rust::String label, - std::shared_ptr source) const; - - RtpCapabilities rtp_sender_capabilities(MediaType type) const; - - RtpCapabilities rtp_receiver_capabilities(MediaType type) const; - - std::shared_ptr rtc_runtime() const { return rtc_runtime_; } - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr audio_device_; - rtc::scoped_refptr peer_factory_; -}; - -std::shared_ptr create_peer_connection_factory(); -} // namespace livekit diff --git a/webrtc-sys/include/livekit/rtc_error.h b/webrtc-sys/include/livekit/rtc_error.h deleted file mode 100644 index 1240642eb..000000000 --- a/webrtc-sys/include/livekit/rtc_error.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "api/rtc_error.h" -#include "rust/cxx.h" -#include "webrtc-sys/src/rtc_error.rs.h" - -namespace livekit { - -RtcError to_error(const webrtc::RTCError& error); -std::string serialize_error( - const RtcError& error); // to be used inside cxx::Exception msg - -#ifdef LIVEKIT_TEST -rust::String serialize_deserialize(); -void throw_error(); -#endif - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/rtp_parameters.h b/webrtc-sys/include/livekit/rtp_parameters.h deleted file mode 100644 index 40cca4ff1..000000000 --- a/webrtc-sys/include/livekit/rtp_parameters.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/media_types.h" -#include "api/priority.h" -#include "api/rtp_parameters.h" -#include "api/rtp_transceiver_direction.h" -#include "webrtc-sys/src/rtp_parameters.rs.h" - -namespace livekit { - -webrtc::RtcpFeedback to_native_rtcp_feedback(RtcpFeedback feedback); -webrtc::RtpCodecCapability to_native_rtp_codec_capability( - RtpCodecCapability capability); -webrtc::RtpHeaderExtensionCapability to_native_rtp_header_extension_capability( - RtpHeaderExtensionCapability header); -webrtc::RtpExtension to_native_rtp_extension(RtpExtension ext); -webrtc::RtpFecParameters to_rtp_fec_parameters(RtpFecParameters fec); -webrtc::RtpRtxParameters to_rtp_rtx_parameters(RtpRtxParameters rtx); -webrtc::RtpEncodingParameters to_native_rtp_encoding_paramters( - RtpEncodingParameters parameters); -webrtc::RtpCodecParameters to_native_rtp_codec_parameters( - RtpCodecParameters params); -webrtc::RtpCapabilities to_rtp_capabilities(RtpCapabilities capabilities); -webrtc::RtcpParameters to_native_rtcp_paramaters(RtcpParameters params); -webrtc::RtpParameters to_native_rtp_parameters(RtpParameters params); - -RtcpFeedback to_rust_rtcp_feedback(webrtc::RtcpFeedback feedback); -RtpCodecCapability to_rust_rtp_codec_capability( - webrtc::RtpCodecCapability capability); -RtpHeaderExtensionCapability to_rust_rtp_header_extension_capability( - webrtc::RtpHeaderExtensionCapability header); -RtpExtension to_rust_rtp_extension(webrtc::RtpExtension ext); -RtpFecParameters to_rust_rtp_fec_parameters(webrtc::RtpFecParameters fec); -RtpRtxParameters to_rust_rtp_rtx_parameters(webrtc::RtpRtxParameters param); -RtpEncodingParameters to_rust_rtp_encoding_parameters( - webrtc::RtpEncodingParameters params); -RtpCodecParameters to_rust_rtp_codec_parameters( - webrtc::RtpCodecParameters params); -RtpCapabilities to_rust_rtp_capabilities(webrtc::RtpCapabilities capabilities); -RtcpParameters to_rust_rtcp_parameters(webrtc::RtcpParameters params); -RtpParameters to_rust_rtp_parameters(webrtc::RtpParameters params); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/rtp_receiver.h b/webrtc-sys/include/livekit/rtp_receiver.h deleted file mode 100644 index 1bec92b8f..000000000 --- a/webrtc-sys/include/livekit/rtp_receiver.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/peer_connection_interface.h" -#include "api/rtp_receiver_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/helper.h" -#include "livekit/media_stream.h" -#include "livekit/rtp_parameters.h" -#include "livekit/webrtc.h" -#include "rust/cxx.h" - -namespace livekit { -class RtpReceiver; -} -#include "webrtc-sys/src/rtp_receiver.rs.h" -namespace livekit { - -// TODO(theomonnom): Implement RtpReceiverObserverInterface? -// TODO(theomonnom): RtpSource -// TODO(theomonnom): FrameTransformer & FrameDecryptor interface -class RtpReceiver { - public: - RtpReceiver( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr receiver, - rtc::scoped_refptr peer_connection); - - std::shared_ptr track() const; - - void get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const; - - rust::Vec stream_ids() const; - rust::Vec streams() const; - - MediaType media_type() const; - rust::String id() const; - - RtpParameters get_parameters() const; - - // bool set_parameters(RtpParameters parameters) const; // Seems unsupported - - void set_jitter_buffer_minimum_delay(bool is_some, - double delay_seconds) const; - - rtc::scoped_refptr rtc_receiver() const { - return receiver_; - } - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr receiver_; - rtc::scoped_refptr peer_connection_; -}; - -static std::shared_ptr _shared_rtp_receiver() { - return nullptr; -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/rtp_sender.h b/webrtc-sys/include/livekit/rtp_sender.h deleted file mode 100644 index b9ff44e29..000000000 --- a/webrtc-sys/include/livekit/rtp_sender.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/peer_connection_interface.h" -#include "api/rtp_sender_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/media_stream.h" -#include "livekit/rtc_error.h" -#include "livekit/rtp_parameters.h" -#include "rust/cxx.h" - -namespace livekit { -class RtpSender; -} -#include "webrtc-sys/src/rtp_sender.rs.h" - -namespace livekit { - -// TODO(theomonnom): FrameTransformer & FrameEncryptor interface -class RtpSender { - public: - RtpSender( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr sender, - rtc::scoped_refptr peer_connection); - - bool set_track(std::shared_ptr track) const; - - std::shared_ptr track() const; - - uint32_t ssrc() const; - - void get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const; - - MediaType media_type() const; - - rust::String id() const; - - rust::Vec stream_ids() const; - - void set_streams(const rust::Vec& stream_ids) const; - - rust::Vec init_send_encodings() const; - - RtpParameters get_parameters() const; - - void set_parameters(RtpParameters params) const; - - rtc::scoped_refptr rtc_sender() const { - return sender_; - } - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr sender_; - rtc::scoped_refptr peer_connection_; -}; - -static std::shared_ptr _shared_rtp_sender() { - return nullptr; // Ignore -} -} // namespace livekit diff --git a/webrtc-sys/include/livekit/rtp_transceiver.h b/webrtc-sys/include/livekit/rtp_transceiver.h deleted file mode 100644 index 0eba06fb2..000000000 --- a/webrtc-sys/include/livekit/rtp_transceiver.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/peer_connection_interface.h" -#include "api/rtp_parameters.h" -#include "api/rtp_transceiver_direction.h" -#include "api/rtp_transceiver_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/rtc_error.h" -#include "livekit/rtp_parameters.h" -#include "livekit/rtp_receiver.h" -#include "livekit/rtp_sender.h" -#include "rust/cxx.h" - -namespace livekit { -class RtpTransceiver; -} -#include "webrtc-sys/src/rtp_transceiver.rs.h" - -namespace livekit { - -webrtc::RtpTransceiverInit to_native_rtp_transceiver_init( - RtpTransceiverInit init); - -class RtpTransceiver { - public: - RtpTransceiver( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr transceiver, - rtc::scoped_refptr peer_connection); - - MediaType media_type() const; - - rust::String mid() const; - - std::shared_ptr sender() const; - - std::shared_ptr receiver() const; - - bool stopped() const; - - bool stopping() const; - - RtpTransceiverDirection direction() const; - - void set_direction(RtpTransceiverDirection direction) const; - - RtpTransceiverDirection current_direction() const; - - RtpTransceiverDirection fired_direction() const; - - void stop_standard() const; - - void set_codec_preferences(rust::Vec codecs) const; - - rust::Vec codec_preferences() const; - - rust::Vec header_extensions_to_negotiate() - const; - - rust::Vec negotiated_header_extensions() const; - - void set_header_extensions_to_negotiate( - rust::Vec header_extensions_to_offer) const; - - private: - std::shared_ptr rtc_runtime_; - rtc::scoped_refptr transceiver_; - rtc::scoped_refptr peer_connection_; -}; - -static std::shared_ptr _shared_rtp_transceiver() { - return nullptr; -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/video_frame.h b/webrtc-sys/include/livekit/video_frame.h deleted file mode 100644 index 22e4b89eb..000000000 --- a/webrtc-sys/include/livekit/video_frame.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "api/video/video_frame.h" -#include "livekit/video_frame_buffer.h" -#include "rtc_base/checks.h" - -namespace livekit { -class VideoFrame; -class VideoFrameBuilder; -} // namespace livekit -#include "webrtc-sys/src/video_frame.rs.h" - -namespace livekit { - -class VideoFrame { - public: - explicit VideoFrame(const webrtc::VideoFrame& frame); - - unsigned int width() const; - unsigned int height() const; - uint32_t size() const; - uint16_t id() const; - int64_t timestamp_us() const; - int64_t ntp_time_ms() const; - uint32_t timestamp() const; - - VideoRotation rotation() const; - std::unique_ptr video_frame_buffer() const; - - webrtc::VideoFrame get() const; - - private: - webrtc::VideoFrame frame_; -}; - -// Allow to create VideoFrames from Rust, -// the builder pattern will be redone in Rust -class VideoFrameBuilder { - public: - VideoFrameBuilder() = default; - - // TODO(theomonnom): other setters? - void set_video_frame_buffer(const VideoFrameBuffer& buffer); - void set_timestamp_us(int64_t timestamp_us); - void set_rotation(VideoRotation rotation); - void set_id(uint16_t id); - std::unique_ptr build(); - - private: - webrtc::VideoFrame::Builder builder_; -}; - -std::unique_ptr new_video_frame_builder(); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/video_frame_buffer.h b/webrtc-sys/include/livekit/video_frame_buffer.h deleted file mode 100644 index 544ecb056..000000000 --- a/webrtc-sys/include/livekit/video_frame_buffer.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/video/i420_buffer.h" -#include "api/video/i422_buffer.h" -#include "api/video/i444_buffer.h" -#include "api/video/i010_buffer.h" -#include "api/video/nv12_buffer.h" -#include "api/video/video_frame_buffer.h" - -namespace livekit { -class VideoFrameBuffer; -class PlanarYuvBuffer; -class PlanarYuv8Buffer; -class PlanarYuv16BBuffer; -class BiplanarYuvBuffer; -class BiplanarYuv8Buffer; -class I420Buffer; -class I420ABuffer; -class I422Buffer; -class I444Buffer; -class I010Buffer; -class NV12Buffer; -} // namespace livekit -#include "webrtc-sys/src/video_frame_buffer.rs.h" - -namespace livekit { - -class VideoFrameBuffer { - public: - explicit VideoFrameBuffer( - rtc::scoped_refptr buffer); - - VideoFrameBufferType buffer_type() const; - - unsigned int width() const; - unsigned int height() const; - - std::unique_ptr to_i420() const; - - // Requires ownership - std::unique_ptr get_i420(); - std::unique_ptr get_i420a(); - std::unique_ptr get_i422(); - std::unique_ptr get_i444(); - std::unique_ptr get_i010(); - std::unique_ptr get_nv12(); - rtc::scoped_refptr get() const; - - protected: - rtc::scoped_refptr buffer_; -}; - -class PlanarYuvBuffer : public VideoFrameBuffer { - public: - explicit PlanarYuvBuffer(rtc::scoped_refptr buffer); - - unsigned int chroma_width() const; - unsigned int chroma_height() const; - - unsigned int stride_y() const; - unsigned int stride_u() const; - unsigned int stride_v() const; - - private: - webrtc::PlanarYuvBuffer* buffer() const; -}; - -class PlanarYuv8Buffer : public PlanarYuvBuffer { - public: - explicit PlanarYuv8Buffer( - rtc::scoped_refptr buffer); - - const uint8_t* data_y() const; - const uint8_t* data_u() const; - const uint8_t* data_v() const; - - private: - webrtc::PlanarYuv8Buffer* buffer() const; -}; - -class PlanarYuv16BBuffer : public PlanarYuvBuffer { - public: - explicit PlanarYuv16BBuffer( - rtc::scoped_refptr buffer); - - const uint16_t* data_y() const; - const uint16_t* data_u() const; - const uint16_t* data_v() const; - - private: - webrtc::PlanarYuv16BBuffer* buffer() const; -}; - -class BiplanarYuvBuffer : public VideoFrameBuffer { - public: - explicit BiplanarYuvBuffer( - rtc::scoped_refptr buffer); - - unsigned int chroma_width() const; - unsigned int chroma_height() const; - - unsigned int stride_y() const; - unsigned int stride_uv() const; - - private: - webrtc::BiplanarYuvBuffer* buffer() const; -}; - -class BiplanarYuv8Buffer : public BiplanarYuvBuffer { - public: - explicit BiplanarYuv8Buffer( - rtc::scoped_refptr buffer); - - const uint8_t* data_y() const; - const uint8_t* data_uv() const; - - private: - webrtc::BiplanarYuv8Buffer* buffer() const; -}; - -class I420Buffer : public PlanarYuv8Buffer { - public: - explicit I420Buffer(rtc::scoped_refptr buffer); -}; - -class I420ABuffer : public I420Buffer { - public: - explicit I420ABuffer(rtc::scoped_refptr buffer); - - unsigned int stride_a() const; - const uint8_t* data_a() const; - - private: - webrtc::I420ABufferInterface* buffer() const; -}; - -class I422Buffer : public PlanarYuv8Buffer { - public: - explicit I422Buffer(rtc::scoped_refptr buffer); -}; - -class I444Buffer : public PlanarYuv8Buffer { - public: - explicit I444Buffer(rtc::scoped_refptr buffer); -}; - -class I010Buffer : public PlanarYuv16BBuffer { - public: - explicit I010Buffer(rtc::scoped_refptr buffer); -}; - -class NV12Buffer : public BiplanarYuv8Buffer { - public: - explicit NV12Buffer(rtc::scoped_refptr buffer); -}; - -std::unique_ptr copy_i420_buffer( - const std::unique_ptr& i420); -std::unique_ptr new_i420_buffer(int width, int height, int stride_y, int stride_u, int stride_v); -std::unique_ptr new_i422_buffer(int width, int height, int stride_y, int stride_u, int stride_v); -std::unique_ptr new_i444_buffer(int width, int height, int stride_y, int stride_u, int stride_v); -std::unique_ptr new_i010_buffer(int width, int height, int stride_y, int stride_u, int stride_v); -std::unique_ptr new_nv12_buffer(int width, int height, int stride_y, int stride_uv); - -static const VideoFrameBuffer* yuv_to_vfb(const PlanarYuvBuffer* yuv) { - return yuv; -} - -static const VideoFrameBuffer* biyuv_to_vfb(const BiplanarYuvBuffer* biyuv) { - return biyuv; -} - -static const PlanarYuvBuffer* yuv8_to_yuv(const PlanarYuv8Buffer* yuv8) { - return yuv8; -} - -static const PlanarYuvBuffer* yuv16b_to_yuv(const PlanarYuv16BBuffer* yuv16) { - return yuv16; -} - -static const BiplanarYuvBuffer* biyuv8_to_biyuv( - const BiplanarYuv8Buffer* biyuv8) { - return biyuv8; -} - -static const PlanarYuv8Buffer* i420_to_yuv8(const I420Buffer* i420) { - return i420; -} - -static const PlanarYuv8Buffer* i420a_to_yuv8(const I420ABuffer* i420a) { - return i420a; -} - -static const PlanarYuv8Buffer* i422_to_yuv8(const I422Buffer* i422) { - return i422; -} - -static const PlanarYuv8Buffer* i444_to_yuv8(const I444Buffer* i444) { - return i444; -} - -static const PlanarYuv16BBuffer* i010_to_yuv16b(const I010Buffer* i010) { - return i010; -} - -static const BiplanarYuv8Buffer* nv12_to_biyuv8(const NV12Buffer* nv12) { - return nv12; -} - -static std::unique_ptr _unique_video_frame_buffer() { - return nullptr; -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/video_track.h b/webrtc-sys/include/livekit/video_track.h deleted file mode 100644 index f60c3dd91..000000000 --- a/webrtc-sys/include/livekit/video_track.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/media_stream_interface.h" -#include "api/video/video_frame.h" -#include "livekit/helper.h" -#include "livekit/media_stream_track.h" -#include "livekit/video_frame.h" -#include "livekit/webrtc.h" -#include "media/base/adapted_video_track_source.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/timestamp_aligner.h" -#include "rust/cxx.h" - -namespace livekit { -class VideoTrack; -class NativeVideoSink; -class VideoTrackSource; -} // namespace livekit -#include "webrtc-sys/src/video_track.rs.h" - -namespace livekit { - -class VideoTrack : public MediaStreamTrack { - private: - friend RtcRuntime; - VideoTrack(std::shared_ptr rtc_runtime, - rtc::scoped_refptr track); - - public: - ~VideoTrack(); - - void add_sink(const std::shared_ptr& sink) const; - void remove_sink(const std::shared_ptr& sink) const; - - void set_should_receive(bool should_receive) const; - bool should_receive() const; - ContentHint content_hint() const; - void set_content_hint(ContentHint hint) const; - - private: - webrtc::VideoTrackInterface* track() const { - return static_cast(track_.get()); - } - - mutable webrtc::Mutex mutex_; - - // Same for AudioTrack: - // Keep a strong reference to the added sinks, so we don't need to - // manage the lifetime safety on the Rust side - mutable std::vector> sinks_; -}; - -class NativeVideoSink : public rtc::VideoSinkInterface { - public: - explicit NativeVideoSink(rust::Box observer); - - void OnFrame(const webrtc::VideoFrame& frame) override; - void OnDiscardedFrame() override; - void OnConstraintsChanged( - const webrtc::VideoTrackSourceConstraints& constraints) override; - - private: - rust::Box observer_; -}; - -std::shared_ptr new_native_video_sink( - rust::Box observer); - -class VideoTrackSource { - class InternalSource : public rtc::AdaptedVideoTrackSource { - public: - InternalSource(const VideoResolution& - resolution); // (0, 0) means no resolution/optional, the - // source will guess the resolution at the - // first captured frame - ~InternalSource() override; - - bool is_screencast() const override; - absl::optional needs_denoising() const override; - SourceState state() const override; - bool remote() const override; - VideoResolution video_resolution() const; - bool on_captured_frame(const webrtc::VideoFrame& frame); - - private: - mutable webrtc::Mutex mutex_; - rtc::TimestampAligner timestamp_aligner_; - VideoResolution resolution_; - }; - - public: - VideoTrackSource(const VideoResolution& resolution); - - VideoResolution video_resolution() const; - - bool on_captured_frame(const std::unique_ptr& frame) - const; // frames pushed from Rust (+interior mutability) - - rtc::scoped_refptr get() const; - - private: - rtc::scoped_refptr source_; -}; - -std::shared_ptr new_video_track_source( - const VideoResolution& resolution); - -static std::shared_ptr video_to_media( - std::shared_ptr track) { - return track; -} - -static std::shared_ptr media_to_video( - std::shared_ptr track) { - return std::static_pointer_cast(track); -} - -static std::shared_ptr _shared_video_track() { - return nullptr; // Ignore -} - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/webrtc.h b/webrtc-sys/include/livekit/webrtc.h deleted file mode 100644 index 88ad1027e..000000000 --- a/webrtc-sys/include/livekit/webrtc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include "api/media_stream_interface.h" -#include "api/rtp_receiver_interface.h" -#include "api/rtp_sender_interface.h" -#include "livekit/helper.h" -#include "rtc_base/logging.h" -#include "rtc_base/physical_socket_server.h" -#include "rtc_base/ssl_adapter.h" -#include "rust/cxx.h" - -#ifdef WEBRTC_WIN -#include "rtc_base/win32_socket_init.h" -#endif - -namespace livekit { -class RtcRuntime; -class LogSink; -} // namespace livekit -#include "webrtc-sys/src/webrtc.rs.h" - -namespace livekit { - -class MediaStreamTrack; -class RtpReceiver; -class RtpSender; - -// Using a shared_ptr in RtcRuntime allows us to keep a strong reference to it -// on resources that depend on it. (e.g: AudioTrack, VideoTrack). -class RtcRuntime : public std::enable_shared_from_this { - public: - [[nodiscard]] static std::shared_ptr create() { - return std::shared_ptr(new RtcRuntime()); - } - - RtcRuntime(const RtcRuntime&) = delete; - RtcRuntime& operator=(const RtcRuntime&) = delete; - ~RtcRuntime(); - - rtc::Thread* network_thread() const; - rtc::Thread* worker_thread() const; - rtc::Thread* signaling_thread() const; - - std::shared_ptr get_or_create_media_stream_track( - rtc::scoped_refptr track); - - std::shared_ptr get_or_create_audio_track( - rtc::scoped_refptr track); - - std::shared_ptr get_or_create_video_track( - rtc::scoped_refptr track); - - private: - RtcRuntime(); - - std::unique_ptr network_thread_; - std::unique_ptr worker_thread_; - std::unique_ptr signaling_thread_; - - // Lists used to make sure we don't create multiple wrappers for one - // underlying webrtc object. (e.g: webrtc::VideoTrackInterface should only - // have one livekit::VideoTrack associated with it). - // The only reason we to do that is to allow to add states inside our - // wrappers (e.g: the sinks_ member inside AudioTrack) - // DataChannel and the PeerConnectionFactory don't need to do this (There's no - // way to retrieve them after creation) - webrtc::Mutex mutex_; - std::vector> media_stream_tracks_; - // We don't have additonal state in RtpReceiver and RtpSender atm.. - // std::vector> rtp_receivers_; - // std::vector> rtp_senders_; - -#ifdef WEBRTC_WIN - // rtc::WinsockInitializer winsock_; - // rtc::PhysicalSocketServer ss_; - // rtc::AutoSocketServerThread main_thread_{&ss_}; -#endif -}; - -class LogSink : public rtc::LogSink { - public: - LogSink(rust::Fn fnc); - ~LogSink(); - - void OnLogMessage(const std::string& message, - rtc::LoggingSeverity severity) override; - void OnLogMessage(const std::string& message) override {} - - private: - rust::Fn fnc_; -}; - -std::unique_ptr new_log_sink( - rust::Fn fnc); - -rust::String create_random_uuid(); - -} // namespace livekit diff --git a/webrtc-sys/include/livekit/yuv_helper.h b/webrtc-sys/include/livekit/yuv_helper.h deleted file mode 100644 index acec26739..000000000 --- a/webrtc-sys/include/livekit/yuv_helper.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -#include "api/video/yuv_helper.h" -#include "webrtc-sys/src/yuv_helper.rs.h" - -namespace livekit { - -#define THROW_ON_ERROR(ret) \ - if (ret != 0) { \ - throw std::runtime_error("libyuv error: " + std::to_string(ret)); \ - } - -static void i420_to_argb(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - THROW_ON_ERROR(webrtc::I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_argb, - dst_stride_argb, width, height)); -} - -static void i420_to_bgra(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height) { - THROW_ON_ERROR(webrtc::I420ToBGRA(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_bgra, - dst_stride_bgra, width, height)); -} - -static void i420_to_abgr(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_abgr, - dst_stride_abgr, width, height)); -} - -static void i420_to_rgba(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - THROW_ON_ERROR(webrtc::I420ToRGBA(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_rgba, - dst_stride_rgba, width, height)); -} - -static void argb_to_i420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::ARGBToI420(src_argb, src_stride_argb, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, width, height)); -} - -static void abgr_to_i420(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::ABGRToI420(src_abgr, src_stride_abgr, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, width, height)); -} - -static void argb_to_rgb24(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - THROW_ON_ERROR(webrtc::ARGBToRGB24(src_argb, src_stride_argb, dst_rgb24, - dst_stride_rgb24, width, height)); -} - -static void i420_to_nv12(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - THROW_ON_ERROR(webrtc::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_y, dst_stride_y, - dst_uv, dst_stride_uv, width, height)); -} - -static void nv12_to_i420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, - dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height)); -} - -static void i444_to_i420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::I444ToI420( - src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); -} - -static void i422_to_i420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::I422ToI420( - src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); -} - -static void i010_to_i420(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - THROW_ON_ERROR(webrtc::I010ToI420( - src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)); -} - -static void nv12_to_argb(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - THROW_ON_ERROR(webrtc::NV12ToARGB(src_y, src_stride_y, src_uv, src_stride_uv, - dst_argb, dst_stride_argb, width, height)); -} - -static void nv12_to_abgr(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::NV12ToABGR(src_y, src_stride_y, src_uv, src_stride_uv, - dst_abgr, dst_stride_abgr, width, height)); -} - -static void i444_to_argb(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::I444ToARGB(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_abgr, - dst_stride_abgr, width, height)); -} - -static void i444_to_abgr(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::I444ToABGR(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_abgr, - dst_stride_abgr, width, height)); -} - -static void i422_to_argb(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - THROW_ON_ERROR(webrtc::I422ToARGB(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_argb, - dst_stride_argb, width, height)); -} - -static void i422_to_abgr(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::I422ToABGR(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_abgr, - dst_stride_abgr, width, height)); -} - -static void i010_to_argb(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - THROW_ON_ERROR(webrtc::I010ToARGB(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_argb, - dst_stride_argb, width, height)); -} - -static void i010_to_abgr(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - THROW_ON_ERROR(webrtc::I010ToABGR(src_y, src_stride_y, src_u, src_stride_u, - src_v, src_stride_v, dst_abgr, - dst_stride_abgr, width, height)); -} - -static void abgr_to_nv12(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - THROW_ON_ERROR(webrtc::ABGRToNV12(src_abgr, src_stride_abgr, dst_y, - dst_stride_y, dst_uv, dst_stride_uv, width, - height)); -} - -static void argb_to_nv12(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - THROW_ON_ERROR(webrtc::ARGBToNV12(src_argb, src_stride_argb, dst_y, - dst_stride_y, dst_uv, dst_stride_uv, width, - height)); -} - -} // namespace livekit diff --git a/webrtc-sys/libwebrtc/.gitignore b/webrtc-sys/libwebrtc/.gitignore index 98019b583..9ba7cbb27 100644 --- a/webrtc-sys/libwebrtc/.gitignore +++ b/webrtc-sys/libwebrtc/.gitignore @@ -1,3 +1,4 @@ +# build cfg .cipd .gclient_* depot_tools @@ -10,7 +11,9 @@ linux-* android-* ios-* +# ignore everything inside the libwebrtc code except livekit_rtc +!src/ src/* -!src/livekit_rtc/* +!src/livekit_rtc diff --git a/webrtc-sys/libwebrtc/build-utils/Cargo.toml b/webrtc-sys/libwebrtc/build-utils/Cargo.toml new file mode 100644 index 000000000..0f0233038 --- /dev/null +++ b/webrtc-sys/libwebrtc/build-utils/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "libwebrtc-build" +version = "0.3.2" +edition = "2021" +license = "Apache-2.0" +description = "Build utilities when working with libwebrtc" +repository = "https://github.com/livekit/rust-sdks" + +[dependencies] +ureq = "2.9" +zip = "0.6" +scratch = "1.0" +fs2 = "0.4" diff --git a/webrtc-sys/libwebrtc/build-utils/generate_jni_symbols.sh b/webrtc-sys/libwebrtc/build-utils/generate_jni_symbols.sh new file mode 100755 index 000000000..ed802042a --- /dev/null +++ b/webrtc-sys/libwebrtc/build-utils/generate_jni_symbols.sh @@ -0,0 +1,13 @@ +# retrieve webrtc JNI symbols from a lib +# Usage: generate_jni_symbols.sh jni_symbols.txt + +lib=$1 + +llvm-readelf -s $lib \ +| grep Java_org_webrtc \ +| awk '{print $8}' \ +| sort \ +| uniq \ +| sed 's/@@JNI_WEBRTC//' \ +> jni_symbols.txt + diff --git a/webrtc-sys/libwebrtc/build-utils/jni_symbols.txt b/webrtc-sys/libwebrtc/build-utils/jni_symbols.txt new file mode 100644 index 000000000..4b874a6f3 --- /dev/null +++ b/webrtc-sys/libwebrtc/build-utils/jni_symbols.txt @@ -0,0 +1,215 @@ +Java_org_webrtc_AudioTrack_nativeAddSink +Java_org_webrtc_AudioTrack_nativeFreeSink +Java_org_webrtc_AudioTrack_nativeRemoveSink +Java_org_webrtc_AudioTrack_nativeSetVolume +Java_org_webrtc_AudioTrack_nativeWrapSink +Java_org_webrtc_BuiltinAudioDecoderFactoryFactory_nativeCreateBuiltinAudioDecoderFactory +Java_org_webrtc_BuiltinAudioEncoderFactoryFactory_nativeCreateBuiltinAudioEncoderFactory +Java_org_webrtc_CallSessionFileRotatingLogSink_nativeAddSink +Java_org_webrtc_CallSessionFileRotatingLogSink_nativeDeleteSink +Java_org_webrtc_CallSessionFileRotatingLogSink_nativeGetLogData +Java_org_webrtc_DataChannel_nativeBufferedAmount +Java_org_webrtc_DataChannel_nativeClose +Java_org_webrtc_DataChannel_nativeId +Java_org_webrtc_DataChannel_nativeLabel +Java_org_webrtc_DataChannel_nativeRegisterObserver +Java_org_webrtc_DataChannel_nativeSend +Java_org_webrtc_DataChannel_nativeState +Java_org_webrtc_DataChannel_nativeUnregisterObserver +Java_org_webrtc_DtmfSender_nativeCanInsertDtmf +Java_org_webrtc_DtmfSender_nativeDuration +Java_org_webrtc_DtmfSender_nativeInsertDtmf +Java_org_webrtc_DtmfSender_nativeInterToneGap +Java_org_webrtc_DtmfSender_nativeTones +Java_org_webrtc_EglBase10Impl_nativeGetCurrentNativeEGLContext +Java_org_webrtc_ExternalAudioProcessingFactory_nativeDestroy +Java_org_webrtc_ExternalAudioProcessingFactory_nativeGetDefaultApm +Java_org_webrtc_ExternalAudioProcessingFactory_nativeSetBypassFlagForCapturePost +Java_org_webrtc_ExternalAudioProcessingFactory_nativeSetBypassFlagForRenderPre +Java_org_webrtc_ExternalAudioProcessingFactory_nativeSetCapturePostProcessing +Java_org_webrtc_ExternalAudioProcessingFactory_nativeSetRenderPreProcessing +Java_org_webrtc_FrameCryptorFactory_nativeCreateFrameCryptorForRtpReceiver +Java_org_webrtc_FrameCryptorFactory_nativeCreateFrameCryptorForRtpSender +Java_org_webrtc_FrameCryptorFactory_nativeCreateFrameCryptorKeyProvider +Java_org_webrtc_FrameCryptorKeyProvider_nativeExportKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeExportSharedKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeRatchetKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeRatchetSharedKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeSetKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeSetSharedKey +Java_org_webrtc_FrameCryptorKeyProvider_nativeSetSifTrailer +Java_org_webrtc_FrameCryptor_nativeGetKeyIndex +Java_org_webrtc_FrameCryptor_nativeIsEnabled +Java_org_webrtc_FrameCryptor_nativeSetEnabled +Java_org_webrtc_FrameCryptor_nativeSetKeyIndex +Java_org_webrtc_FrameCryptor_nativeSetObserver +Java_org_webrtc_FrameCryptor_nativeUnSetObserver +Java_org_webrtc_H264Utils_nativeIsSameH264Profile +Java_org_webrtc_Histogram_nativeAddSample +Java_org_webrtc_Histogram_nativeCreateCounts +Java_org_webrtc_Histogram_nativeCreateEnumeration +Java_org_webrtc_JavaI420Buffer_nativeCropAndScaleI420 +Java_org_webrtc_JniCommon_nativeAddRef +Java_org_webrtc_JniCommon_nativeAllocateByteBuffer +Java_org_webrtc_JniCommon_nativeFreeByteBuffer +Java_org_webrtc_JniCommon_nativeReleaseRef +Java_org_webrtc_LibvpxVp8Decoder_nativeCreateDecoder +Java_org_webrtc_LibvpxVp8Encoder_nativeCreateEncoder +Java_org_webrtc_LibvpxVp9Decoder_nativeCreateDecoder +Java_org_webrtc_LibvpxVp9Decoder_nativeIsSupported +Java_org_webrtc_LibvpxVp9Encoder_nativeCreateEncoder +Java_org_webrtc_LibvpxVp9Encoder_nativeGetSupportedScalabilityModes +Java_org_webrtc_LibvpxVp9Encoder_nativeIsSupported +Java_org_webrtc_Logging_nativeEnableLogThreads +Java_org_webrtc_Logging_nativeEnableLogTimeStamps +Java_org_webrtc_Logging_nativeEnableLogToDebugOutput +Java_org_webrtc_Logging_nativeLog +Java_org_webrtc_MediaSource_nativeGetState +Java_org_webrtc_MediaStreamTrack_nativeGetEnabled +Java_org_webrtc_MediaStreamTrack_nativeGetId +Java_org_webrtc_MediaStreamTrack_nativeGetKind +Java_org_webrtc_MediaStreamTrack_nativeGetState +Java_org_webrtc_MediaStreamTrack_nativeSetEnabled +Java_org_webrtc_MediaStream_nativeAddAudioTrackToNativeStream +Java_org_webrtc_MediaStream_nativeAddVideoTrackToNativeStream +Java_org_webrtc_MediaStream_nativeGetId +Java_org_webrtc_MediaStream_nativeRemoveAudioTrack +Java_org_webrtc_MediaStream_nativeRemoveVideoTrack +Java_org_webrtc_Metrics_nativeEnable +Java_org_webrtc_Metrics_nativeGetAndReset +Java_org_webrtc_NV12Buffer_nativeCropAndScale +Java_org_webrtc_NV21Buffer_nativeCropAndScale +Java_org_webrtc_NativeAndroidVideoTrackSource_nativeAdaptFrame +Java_org_webrtc_NativeAndroidVideoTrackSource_nativeAdaptOutputFormat +Java_org_webrtc_NativeAndroidVideoTrackSource_nativeOnFrameCaptured +Java_org_webrtc_NativeAndroidVideoTrackSource_nativeSetIsScreencast +Java_org_webrtc_NativeAndroidVideoTrackSource_nativeSetState +Java_org_webrtc_NetworkMonitor_nativeNotifyConnectionTypeChanged +Java_org_webrtc_NetworkMonitor_nativeNotifyOfActiveNetworkList +Java_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkConnect +Java_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkDisconnect +Java_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkPreference +Java_org_webrtc_PeerConnectionFactory_nativeCreateAudioSource +Java_org_webrtc_PeerConnectionFactory_nativeCreateAudioTrack +Java_org_webrtc_PeerConnectionFactory_nativeCreateLocalMediaStream +Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnection +Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnectionFactory +Java_org_webrtc_PeerConnectionFactory_nativeCreateVideoSource +Java_org_webrtc_PeerConnectionFactory_nativeCreateVideoTrack +Java_org_webrtc_PeerConnectionFactory_nativeDeleteLoggable +Java_org_webrtc_PeerConnectionFactory_nativeFindFieldTrialsFullName +Java_org_webrtc_PeerConnectionFactory_nativeFreeFactory +Java_org_webrtc_PeerConnectionFactory_nativeGetNativePeerConnectionFactory +Java_org_webrtc_PeerConnectionFactory_nativeGetRtpReceiverCapabilities +Java_org_webrtc_PeerConnectionFactory_nativeGetRtpSenderCapabilities +Java_org_webrtc_PeerConnectionFactory_nativeInitializeAndroidGlobals +Java_org_webrtc_PeerConnectionFactory_nativeInitializeFieldTrials +Java_org_webrtc_PeerConnectionFactory_nativeInitializeInternalTracer +Java_org_webrtc_PeerConnectionFactory_nativeInjectLoggable +Java_org_webrtc_PeerConnectionFactory_nativePrintStackTrace +Java_org_webrtc_PeerConnectionFactory_nativeShutdownInternalTracer +Java_org_webrtc_PeerConnectionFactory_nativeStartAecDump +Java_org_webrtc_PeerConnectionFactory_nativeStartInternalTracingCapture +Java_org_webrtc_PeerConnectionFactory_nativeStopAecDump +Java_org_webrtc_PeerConnectionFactory_nativeStopInternalTracingCapture +Java_org_webrtc_PeerConnection_nativeAddIceCandidate +Java_org_webrtc_PeerConnection_nativeAddIceCandidateWithObserver +Java_org_webrtc_PeerConnection_nativeAddLocalStream +Java_org_webrtc_PeerConnection_nativeAddTrack +Java_org_webrtc_PeerConnection_nativeAddTransceiverOfType +Java_org_webrtc_PeerConnection_nativeAddTransceiverWithTrack +Java_org_webrtc_PeerConnection_nativeClose +Java_org_webrtc_PeerConnection_nativeConnectionState +Java_org_webrtc_PeerConnection_nativeCreateAnswer +Java_org_webrtc_PeerConnection_nativeCreateDataChannel +Java_org_webrtc_PeerConnection_nativeCreateOffer +Java_org_webrtc_PeerConnection_nativeCreatePeerConnectionObserver +Java_org_webrtc_PeerConnection_nativeCreateSender +Java_org_webrtc_PeerConnection_nativeFreeOwnedPeerConnection +Java_org_webrtc_PeerConnection_nativeGetCertificate +Java_org_webrtc_PeerConnection_nativeGetLocalDescription +Java_org_webrtc_PeerConnection_nativeGetNativePeerConnection +Java_org_webrtc_PeerConnection_nativeGetReceivers +Java_org_webrtc_PeerConnection_nativeGetRemoteDescription +Java_org_webrtc_PeerConnection_nativeGetSenders +Java_org_webrtc_PeerConnection_nativeGetTransceivers +Java_org_webrtc_PeerConnection_nativeIceConnectionState +Java_org_webrtc_PeerConnection_nativeIceGatheringState +Java_org_webrtc_PeerConnection_nativeNewGetStats +Java_org_webrtc_PeerConnection_nativeNewGetStatsReceiver +Java_org_webrtc_PeerConnection_nativeNewGetStatsSender +Java_org_webrtc_PeerConnection_nativeOldGetStats +Java_org_webrtc_PeerConnection_nativeRemoveIceCandidates +Java_org_webrtc_PeerConnection_nativeRemoveLocalStream +Java_org_webrtc_PeerConnection_nativeRemoveTrack +Java_org_webrtc_PeerConnection_nativeRestartIce +Java_org_webrtc_PeerConnection_nativeSetAudioPlayout +Java_org_webrtc_PeerConnection_nativeSetAudioRecording +Java_org_webrtc_PeerConnection_nativeSetBitrate +Java_org_webrtc_PeerConnection_nativeSetConfiguration +Java_org_webrtc_PeerConnection_nativeSetLocalDescription +Java_org_webrtc_PeerConnection_nativeSetLocalDescriptionAutomatically +Java_org_webrtc_PeerConnection_nativeSetRemoteDescription +Java_org_webrtc_PeerConnection_nativeSignalingState +Java_org_webrtc_PeerConnection_nativeStartRtcEventLog +Java_org_webrtc_PeerConnection_nativeStopRtcEventLog +Java_org_webrtc_RtcCertificatePem_nativeGenerateCertificate +Java_org_webrtc_RtpReceiver_nativeGetId +Java_org_webrtc_RtpReceiver_nativeGetParameters +Java_org_webrtc_RtpReceiver_nativeGetTrack +Java_org_webrtc_RtpReceiver_nativeSetFrameDecryptor +Java_org_webrtc_RtpReceiver_nativeSetObserver +Java_org_webrtc_RtpReceiver_nativeUnsetObserver +Java_org_webrtc_RtpSender_nativeGetDtmfSender +Java_org_webrtc_RtpSender_nativeGetId +Java_org_webrtc_RtpSender_nativeGetMediaType +Java_org_webrtc_RtpSender_nativeGetParameters +Java_org_webrtc_RtpSender_nativeGetStreams +Java_org_webrtc_RtpSender_nativeGetTrack +Java_org_webrtc_RtpSender_nativeSetFrameEncryptor +Java_org_webrtc_RtpSender_nativeSetParameters +Java_org_webrtc_RtpSender_nativeSetStreams +Java_org_webrtc_RtpSender_nativeSetTrack +Java_org_webrtc_RtpTransceiver_nativeCurrentDirection +Java_org_webrtc_RtpTransceiver_nativeDirection +Java_org_webrtc_RtpTransceiver_nativeGetMediaType +Java_org_webrtc_RtpTransceiver_nativeGetMid +Java_org_webrtc_RtpTransceiver_nativeGetReceiver +Java_org_webrtc_RtpTransceiver_nativeGetSender +Java_org_webrtc_RtpTransceiver_nativeSetCodecPreferences +Java_org_webrtc_RtpTransceiver_nativeSetDirection +Java_org_webrtc_RtpTransceiver_nativeStopInternal +Java_org_webrtc_RtpTransceiver_nativeStopStandard +Java_org_webrtc_RtpTransceiver_nativeStopped +Java_org_webrtc_SimulcastVideoEncoder_nativeCreateEncoder +Java_org_webrtc_SoftwareVideoDecoderFactory_nativeCreateDecoder +Java_org_webrtc_SoftwareVideoDecoderFactory_nativeCreateFactory +Java_org_webrtc_SoftwareVideoDecoderFactory_nativeGetSupportedCodecs +Java_org_webrtc_SoftwareVideoEncoderFactory_nativeCreateEncoder +Java_org_webrtc_SoftwareVideoEncoderFactory_nativeCreateFactory +Java_org_webrtc_SoftwareVideoEncoderFactory_nativeGetSupportedCodecs +Java_org_webrtc_TimestampAligner_nativeCreateTimestampAligner +Java_org_webrtc_TimestampAligner_nativeReleaseTimestampAligner +Java_org_webrtc_TimestampAligner_nativeRtcTimeNanos +Java_org_webrtc_TimestampAligner_nativeTranslateTimestamp +Java_org_webrtc_TurnCustomizer_nativeFreeTurnCustomizer +Java_org_webrtc_VideoDecoderFallback_nativeCreateDecoder +Java_org_webrtc_VideoDecoderWrapper_nativeOnDecodedFrame +Java_org_webrtc_VideoEncoderFallback_nativeCreateEncoder +Java_org_webrtc_VideoEncoderWrapper_nativeOnEncodedFrame +Java_org_webrtc_VideoTrack_nativeAddSink +Java_org_webrtc_VideoTrack_nativeFreeSink +Java_org_webrtc_VideoTrack_nativeGetShouldReceive +Java_org_webrtc_VideoTrack_nativeRemoveSink +Java_org_webrtc_VideoTrack_nativeSetShouldReceive +Java_org_webrtc_VideoTrack_nativeWrapSink +Java_org_webrtc_YuvHelper_nativeABGRToI420 +Java_org_webrtc_YuvHelper_nativeCopyPlane +Java_org_webrtc_YuvHelper_nativeI420Copy +Java_org_webrtc_YuvHelper_nativeI420Rotate +Java_org_webrtc_YuvHelper_nativeI420ToNV12 +Java_org_webrtc_audio_JavaAudioDeviceModule_nativeCreateAudioDeviceModule +Java_org_webrtc_audio_WebRtcAudioRecord_nativeCacheDirectBufferAddress +Java_org_webrtc_audio_WebRtcAudioRecord_nativeDataIsRecorded +Java_org_webrtc_audio_WebRtcAudioTrack_nativeCacheDirectBufferAddress +Java_org_webrtc_audio_WebRtcAudioTrack_nativeGetPlayoutData diff --git a/webrtc-sys/libwebrtc/build-utils/src/lib.rs b/webrtc-sys/libwebrtc/build-utils/src/lib.rs new file mode 100644 index 000000000..6278a3367 --- /dev/null +++ b/webrtc-sys/libwebrtc/build-utils/src/lib.rs @@ -0,0 +1,287 @@ +// Copyright 2024 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use fs2::FileExt; +use std::{env, error::Error, ffi::OsStr, fs, io::Write, path}; + +// env var +pub const LK_WEBRTC_DEBUG: &str = "LK_RTC_DEBUG"; +pub const LK_WEBRTC_PATH: &str = "LK_RTC_PATH"; + +pub const SCRATH_PATH: &str = "livekit_rtc"; +pub const WEBRTC_TAG: &str = "webrtc-b951613-4"; +pub const DOWNLOAD_URL: &str = "https://github.com/livekit/rust-sdks/releases/download/{}/{}.zip"; + +// dir structure of the webrtc build looks like: +// mac-arm64-release +// - include +// - lib +// - LICENSE.md + +pub fn target_os() -> &'static str { + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + let target = env::var("TARGET").unwrap(); + let simulator = target.ends_with("-sim"); + + match target_os.as_str() { + "windows" => "win", + "macos" => "mac", + "android" => "android", + "linux" => "linux", + "ios" => { + if simulator { + "ios-simulator" + } else { + "ios-device" + } + } + _ => panic!("unsupported rtc target_os: {}", target_os), + } +} + +pub fn target_arch() -> &'static str { + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + match target_arch.as_str() { + "aarch64" => "arm64", + "x86_64" => "x64", + _ => panic!("unsupported rtc target_arch: {}", target_arch), + } +} + +pub fn rtc_debug_enabled() -> bool { + let debug_var = env::var(LK_WEBRTC_DEBUG); + debug_var.is_ok() && (debug_var.clone().unwrap() == "1" || debug_var.unwrap() == "true") +} + +pub fn webrtc_triple(target_os: &str, target_arch: &str, debug: bool) -> String { + let profile = if debug { "debug" } else { "release" }; + format!("{}-{}-{}", target_os, target_arch, profile) +} + +pub fn custom_rtc_directory() -> Option { + let custom_path = env::var(LK_WEBRTC_PATH); + if let Ok(custom_path) = custom_path { + return Some(path::Path::new(&custom_path).to_path_buf()); + } + None +} + +pub fn is_using_custom_webrtc() -> bool { + custom_rtc_directory().is_some() +} + +pub fn rtc_directory() -> path::PathBuf { + let target_dir = scratch::path(SCRATH_PATH); + let rtc_triple = webrtc_triple(target_os(), target_arch(), rtc_debug_enabled()); + path::Path::new(&target_dir) + .join(format!("livekit/{}-{}/{}", rtc_triple, WEBRTC_TAG, rtc_triple)) +} + +/// Make sure the JNI symbols of libwebrtc are correctly exported and visible in the final shared library. +/// Calling this function should only be needed when statically linking livekit_rtc. +pub fn export_jni_symbols() -> Result<(), Box> { + let jni_symbols = include_str!("../jni_symbols.txt"); + let jni_symbols = jni_symbols.lines().collect::>(); + + for symbol in &jni_symbols { + println!("cargo:rustc-link-arg=-Wl,--undefined={}", symbol); + } + + let out = env::var("OUT_DIR").unwrap(); + let out_dir = path::Path::new(&out); + + let vs_path = out_dir.join("livekit_rtc_jni.map"); + let mut vs_file = fs::File::create(&vs_path).unwrap(); + + let jni_symbols = jni_symbols.join("; "); + write!(vs_file, "JNI_WEBRTC {{\n\tglobal: {}; \n}};", jni_symbols).unwrap(); + + println!("cargo:rustc-link-arg=-Wl,--version-script={}", vs_path.display()); + Ok(()) +} + +pub fn copy_dylib_to_target(rtc_path: &path::PathBuf) -> Result<(), Box> { + if let Some(target_dir) = find_target_dir() { + let build_mode = env::var("PROFILE").unwrap(); + let source_dylib = rtc_path.join("lib").join("liblivekit_rtc.dylib"); + println!("cargo:rerun-if-changed={}", source_dylib.display()); + let target_dylib = target_dir.join(build_mode).join("liblivekit_rtc.dylib"); + fs::copy(source_dylib, target_dylib)?; + Ok(()) + } else { + Err("could not find target dir".into()) + } +} + +// from https://github.com/dtolnay/cxx/blob/1449ffbc412a5d5039714f398ae589c214335181/gen/build/src/target.rs#L10 +fn find_target_dir() -> Option { + if let Some(target_dir) = env::var_os("CARGO_TARGET_DIR") { + let target_dir = path::PathBuf::from(target_dir); + if target_dir.is_absolute() { + return Some(target_dir); + } else { + return None; + }; + } + + let out_dir = path::PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let mut dir = out_dir.to_owned(); + loop { + if dir.join(".rustc_info.json").exists() + || dir.join("CACHEDIR.TAG").exists() + || dir.file_name() == Some(OsStr::new("target")) + && dir.parent().map_or(false, |parent| parent.join("Cargo.toml").exists()) + { + return Some(dir); + } + + if dir.pop() { + continue; + } + + return None; + } +} + +pub fn link_shared_library(rtc_path: &path::PathBuf) { + let lib_search_path = rtc_path.join("lib"); + + println!("cargo:rerun-if-env-changed={}", LK_WEBRTC_DEBUG); + println!("cargo:rerun-if-env-changed={}", LK_WEBRTC_PATH); + println!("cargo:rustc-link-search=native={}", lib_search_path.display()); + println!("cargo:rustc-link-lib=dylib=livekit_rtc"); +} + +pub fn link_static_library(rtc_path: &path::PathBuf) { + let lib_search_path = rtc_path.join("lib"); + + println!("cargo:rerun-if-env-changed={}", LK_WEBRTC_DEBUG); + println!("cargo:rerun-if-env-changed={}", LK_WEBRTC_PATH); + println!("cargo:rustc-link-search=native={}", lib_search_path.display()); + println!("cargo:rustc-link-lib=static=livekit_rtc"); + + let target_os = target_os(); + // TODO(theomonnom): some of these libraries may not be needed + match target_os { + "windows" => { + println!("cargo:rustc-link-lib=dylib=msdmo"); + println!("cargo:rustc-link-lib=dylib=wmcodecdspuuid"); + println!("cargo:rustc-link-lib=dylib=dmoguids"); + println!("cargo:rustc-link-lib=dylib=crypt32"); + println!("cargo:rustc-link-lib=dylib=iphlpapi"); + println!("cargo:rustc-link-lib=dylib=ole32"); + println!("cargo:rustc-link-lib=dylib=secur32"); + println!("cargo:rustc-link-lib=dylib=winmm"); + println!("cargo:rustc-link-lib=dylib=ws2_32"); + println!("cargo:rustc-link-lib=dylib=strmiids"); + println!("cargo:rustc-link-lib=dylib=d3d11"); + println!("cargo:rustc-link-lib=dylib=gdi32"); + println!("cargo:rustc-link-lib=dylib=dxgi"); + println!("cargo:rustc-link-lib=dylib=dwmapi"); + println!("cargo:rustc-link-lib=dylib=shcore"); + } + "linux" => { + println!("cargo:rustc-link-lib=dylib=Xext"); + println!("cargo:rustc-link-lib=dylib=X11"); + println!("cargo:rustc-link-lib=dylib=GL"); + println!("cargo:rustc-link-lib=dylib=rt"); + println!("cargo:rustc-link-lib=dylib=dl"); + println!("cargo:rustc-link-lib=dylib=pthread"); + println!("cargo:rustc-link-lib=dylib=m"); + } + "macos" => { + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=AVFoundation"); + println!("cargo:rustc-link-lib=framework=CoreAudio"); + println!("cargo:rustc-link-lib=framework=AudioToolbox"); + println!("cargo:rustc-link-lib=framework=Appkit"); + println!("cargo:rustc-link-lib=framework=CoreMedia"); + println!("cargo:rustc-link-lib=framework=CoreGraphics"); + println!("cargo:rustc-link-lib=framework=VideoToolbox"); + println!("cargo:rustc-link-lib=framework=CoreVideo"); + println!("cargo:rustc-link-lib=framework=OpenGL"); + println!("cargo:rustc-link-lib=framework=Metal"); + println!("cargo:rustc-link-lib=framework=MetalKit"); + println!("cargo:rustc-link-lib=framework=QuartzCore"); + println!("cargo:rustc-link-lib=framework=IOKit"); + println!("cargo:rustc-link-lib=framework=IOSurface"); + } + "ios" => { + println!("cargo:rustc-link-lib=framework=CoreFoundation"); + println!("cargo:rustc-link-lib=framework=AVFoundation"); + println!("cargo:rustc-link-lib=framework=CoreAudio"); + println!("cargo:rustc-link-lib=framework=UIKit"); + println!("cargo:rustc-link-lib=framework=CoreVideo"); + println!("cargo:rustc-link-lib=framework=CoreGraphics"); + println!("cargo:rustc-link-lib=framework=CoreMedia"); + println!("cargo:rustc-link-lib=framework=VideoToolbox"); + println!("cargo:rustc-link-lib=framework=AudioToolbox"); + println!("cargo:rustc-link-lib=framework=OpenGLES"); + println!("cargo:rustc-link-lib=framework=GLKit"); + println!("cargo:rustc-link-lib=framework=Metal"); + println!("cargo:rustc-link-lib=framework=MetalKit"); + println!("cargo:rustc-link-lib=framework=Network"); + println!("cargo:rustc-link-lib=framework=QuartzCore"); + } + "android" => { + println!("cargo:rustc-link-lib=EGL"); + println!("cargo:rustc-link-lib=c++abi"); + println!("cargo:rustc-link-lib=OpenSLES"); + } + _ => { + panic!("Unsupported target, {}", target_os); + } + } +} + +/// dylib and static library are on different arifacts (for file size reasons) +fn download_url(debug: bool, dylib: bool) -> String { + let lib_type = if dylib { "dylib" } else { "static" }; + format!( + "https://github.com/livekit/rust-sdks/releases/download/{}/{}-{}.zip", + WEBRTC_TAG, + format!("webrtc-{}", webrtc_triple(target_os(), target_arch(), debug)), + lib_type + ) +} + +pub fn download_webrtc_if_needed(debug: bool, dylib: bool) -> Result<(), Box> { + let dir = scratch::path(SCRATH_PATH); + let flock = fs::File::create(dir.join(".lock"))?; + flock.lock_exclusive()?; + + let rtc_dir = rtc_directory(); + if rtc_dir.exists() { + return Ok(()); + } + + let resp = ureq::get(&download_url(debug, dylib)).call()?; + if resp.status() != 200 { + return Err(format!("failed to download webrtc: {}", resp.status()).into()); + } + + let mut reader = resp.into_reader(); + let tmp_path = env::var("OUT_DIR").unwrap(); + let tmp_path = path::Path::new(&tmp_path).join("webrtc.zip"); + let mut file = + fs::File::options().write(true).read(true).create(true).open(tmp_path.clone())?; + std::io::copy(&mut reader, &mut file)?; + + let mut archive = zip::ZipArchive::new(file)?; + archive.extract(rtc_dir.parent().unwrap())?; + drop(archive); + + fs::remove_file(tmp_path)?; + Ok(()) +} diff --git a/webrtc-sys/libwebrtc/build_macos.sh b/webrtc-sys/libwebrtc/build_macos.sh index 4498b2eb0..f651c2c5e 100755 --- a/webrtc-sys/libwebrtc/build_macos.sh +++ b/webrtc-sys/libwebrtc/build_macos.sh @@ -97,7 +97,7 @@ gn gen "$OUTPUT_DIR" --root="src" \ enable_stripping=true \ rtc_enable_symbol_export=true \ rtc_enable_objc_symbol_export=false \ - rtc_include_dav1d_in_internal_decoder_factory = true \ + rtc_include_dav1d_in_internal_decoder_factory=true \ rtc_use_h264=true \ use_custom_libcxx=false \ clang_use_chrome_plugins=false \ @@ -105,26 +105,19 @@ gn gen "$OUTPUT_DIR" --root="src" \ use_lld=false" # build static library -ninja -C "$OUTPUT_DIR" :default \ - api/audio_codecs:builtin_audio_decoder_factory \ - api/task_queue:default_task_queue_factory \ - sdk:native_api \ - sdk:default_codec_factory_objc \ - pc:peerconnection \ - sdk:videocapture_objc \ - sdk:mac_framework_objc +ninja -C "$OUTPUT_DIR" livekit_rtc # make libwebrtc.a # don't include nasm -ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` +#ar -rc "$ARTIFACTS_DIR/lib/libwebrtc.a" `find "$OUTPUT_DIR/obj" -name '*.o' -not -path "*/third_party/nasm/*"` -python3 "./src/tools_webrtc/libs/generate_licenses.py" \ - --target :webrtc "$OUTPUT_DIR" "$OUTPUT_DIR" +#python3 "./src/tools_webrtc/libs/generate_licenses.py" \ +# --target :webrtc "$OUTPUT_DIR" "$OUTPUT_DIR" cp "$OUTPUT_DIR/obj/webrtc.ninja" "$ARTIFACTS_DIR" cp "$OUTPUT_DIR/args.gn" "$ARTIFACTS_DIR" cp "$OUTPUT_DIR/LICENSE.md" "$ARTIFACTS_DIR" +cp "$OUTPUT_DIR/liblivekit_rtc.dylib" "$ARTIFACTS_DIR/lib" -cd src -find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include" - +#cd src +# find . -name "*.h" -print | cpio -pd "$ARTIFACTS_DIR/include" \ No newline at end of file diff --git a/webrtc-sys/libwebrtc/compile_flags.txt b/webrtc-sys/libwebrtc/compile_flags.txt new file mode 100644 index 000000000..4b7eb2625 --- /dev/null +++ b/webrtc-sys/libwebrtc/compile_flags.txt @@ -0,0 +1,14 @@ +-xc++ +-xobjective-c +-xobjective-c++ +-std=c++17 +-Isrc +-Isrc/livekit_rtc +-Isrc/third_party/abseil-cpp +-Isrc/third_party/libc++ +-Isrc/third_party/libyuv/include +-Isrc/sdk/objc/base +-Isrc/sdk/objc +-DWEBRTC_POSIX +-DWEBRTC_MAC +-DNDEBUG diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/BUILD.gn b/webrtc-sys/libwebrtc/src/livekit_rtc/BUILD.gn new file mode 100644 index 000000000..dcb6f3646 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/BUILD.gn @@ -0,0 +1,84 @@ +import("../webrtc.gni") + +if (is_android) { + import("//build/config/android/config.gni") + import("//build/config/android/rules.gni") +} else if (is_mac) { + import("//build/config/mac/rules.gni") +} else if (is_ios) { + import("//build/config/ios/rules.gni") +} else if (is_linux) { + import("//build/config/linux/pkg_config.gni") +} + + + +lk_sources = [ + "src/peer.cc", + "src/audio_device.cc", + "src/transceiver.cc", + "src/utils.cc", + "src/data_channel.cc", + "src/capi.cc", + "src/video_encoder.cc", + "src/video_decoder.cc", + #"src/android.cc", +] + +if (is_mac) { + lk_sources += [ + "src/objc_video_factory.mm", + ] +} + +config("livekit_config") { + include_dirs = [ "." ] +} + + +rtc_shared_library("livekit_rtc") { + libs = [] + + sources = lk_sources + + defines = [ + "USE_LIBYUV", + "WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE", + ] + + public_configs = [ ":livekit_config" ] + + deps = [ + "../api:create_peerconnection_factory", + "../api:libjingle_peerconnection_api", + "../api/audio_codecs:builtin_audio_decoder_factory", + "../api/audio_codecs:builtin_audio_encoder_factory", + "../api/crypto:frame_crypto_transformer", + "../api/video:video_frame", + "../api/video_codecs:builtin_video_decoder_factory", + "../api/video_codecs:builtin_video_encoder_factory", + "../media:rtc_audio_video", + "../media:rtc_internal_video_codecs", + "../media:rtc_media", + "../media:rtc_media_base", + "../modules/audio_device:audio_device", + "../modules/audio_processing:api", + "../modules/audio_processing:audio_processing", + "../modules/video_capture:video_capture_module", + "../pc:libjingle_peerconnection", + "../rtc_base:threading", + "../sdk:media_constraints", + "//third_party/abseil-cpp/absl/memory", + "//third_party/boringssl:boringssl", + "//third_party/libyuv", + ] + + + if (is_mac) { + + deps += [ + "../sdk:peerconnectionfactory_base_objc", + ] + } + +} diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/android.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/android.h new file mode 100644 index 000000000..63f17127d --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/android.h @@ -0,0 +1,18 @@ +#ifndef LIVEKIT_ANDROID_H +#define LIVEKIT_ANDROID_H + +#include +#include + +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" + +namespace livekit { +void init_android(void* jvm); + +std::unique_ptr CreateAndroidVideoEncoderFactory(); +std::unique_ptr CreateAndroidVideoDecoderFactory(); + +} // namespace livekit + +#endif // LIVEKIT_ANDROID_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_device.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_device.h new file mode 100644 index 000000000..862249054 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_device.h @@ -0,0 +1,155 @@ +#ifndef LIVEKIT_AUDIO_DEVICE_H +#define LIVEKIT_AUDIO_DEVICE_H + +#include "api/task_queue/task_queue_factory.h" +#include "modules/audio_device/include/audio_device.h" +#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/task_queue.h" +#include "rtc_base/task_utils/repeating_task.h" + +namespace livekit { + +class AudioDevice : public webrtc::AudioDeviceModule { + public: + AudioDevice(webrtc::TaskQueueFactory* task_queue_factory) + : task_queue_factory_(task_queue_factory) {} + ~AudioDevice() override { Terminate(); } + + int32_t Init() override; + int32_t Terminate() override; + + int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override { + *audioLayer = AudioDeviceModule::kDummyAudio; + return 0; + } + int32_t RegisterAudioCallback(webrtc::AudioTransport* transport) override { + webrtc::MutexLock lock(&mutex_); + audio_transport_ = transport; + return 0; + } + + bool Initialized() const override { + webrtc::MutexLock lock(&mutex_); + return initialized_; + } + + int16_t PlayoutDevices() override { return 0; } + int16_t RecordingDevices() override { return 0; } + int32_t PlayoutDeviceName(uint16_t index, + char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) override { + return 0; + } + + int32_t RecordingDeviceName(uint16_t index, + char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) override { + return 0; + } + + int32_t SetPlayoutDevice(uint16_t index) override { return 0; } + int32_t SetPlayoutDevice(WindowsDeviceType device) override { return 0; } + int32_t SetRecordingDevice(uint16_t index) override { return 0; } + int32_t SetRecordingDevice(WindowsDeviceType device) override { return 0; } + + int32_t PlayoutIsAvailable(bool* available) override { return 0; } + int32_t InitPlayout() override { return 0; } + bool PlayoutIsInitialized() const override { return false; } + int32_t RecordingIsAvailable(bool* available) override { return 0; } + int32_t InitRecording() override { return 0; } + bool RecordingIsInitialized() const override { return false; } + + int32_t StartPlayout() override { + webrtc::MutexLock lock(&mutex_); + playing_ = true; + return 0; + } + int32_t StopPlayout() override { + webrtc::MutexLock lock(&mutex_); + playing_ = false; + return 0; + } + bool Playing() const override { + webrtc::MutexLock lock(&mutex_); + return playing_; + } + int32_t StartRecording() override { return 0; } + int32_t StopRecording() override { return 0; } + bool Recording() const override { return false; } + + int32_t InitSpeaker() override { return 0; } + bool SpeakerIsInitialized() const override { return false; } + int32_t InitMicrophone() override { return 0; } + bool MicrophoneIsInitialized() const override { return false; } + + int32_t SpeakerVolumeIsAvailable(bool* available) override { return 0; } + int32_t SetSpeakerVolume(uint32_t volume) override { return 0; } + int32_t SpeakerVolume(uint32_t* volume) const override { return 0; } + int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override { return 0; } + int32_t MinSpeakerVolume(uint32_t* minVolume) const override { return 0; } + + int32_t MicrophoneVolumeIsAvailable(bool* available) override { return 0; } + int32_t SetMicrophoneVolume(uint32_t volume) override { return 0; } + int32_t MicrophoneVolume(uint32_t* volume) const override { return 0; } + int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { return 0; } + int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { return 0; } + + int32_t SpeakerMuteIsAvailable(bool* available) override { return 0; } + int32_t SetSpeakerMute(bool enable) override { return 0; } + int32_t SpeakerMute(bool* enabled) const override { return 0; } + + int32_t MicrophoneMuteIsAvailable(bool* available) override { return 0; } + int32_t SetMicrophoneMute(bool enable) override { return 0; } + int32_t MicrophoneMute(bool* enabled) const override { return 0; } + + int32_t StereoPlayoutIsAvailable(bool* available) const override { return 0; } + int32_t SetStereoPlayout(bool enable) override { return 0; } + int32_t StereoPlayout(bool* enabled) const override { return 0; } + int32_t StereoRecordingIsAvailable(bool* available) const override { + *available = true; + return 0; + } + int32_t SetStereoRecording(bool enable) override { return 0; } + int32_t StereoRecording(bool* enabled) const override { + *enabled = true; + return 0; + } + + int32_t PlayoutDelay(uint16_t* delayMS) const override { return 0; } + + bool BuiltInAECIsAvailable() const override { return false; } + bool BuiltInAGCIsAvailable() const override { return false; } + bool BuiltInNSIsAvailable() const override { return false; } + + int32_t EnableBuiltInAEC(bool enable) override { return 0; } + int32_t EnableBuiltInAGC(bool enable) override { return 0; } + int32_t EnableBuiltInNS(bool enable) override { return 0; } + +#if defined(WEBRTC_IOS) + int GetPlayoutAudioParameters( + webrtc::AudioParameters* params) const override { + return 0; + } + int GetRecordAudioParameters(webrtc::AudioParameters* params) const override { + return 0; + } +#endif // WEBRTC_IOS + + int32_t SetAudioDeviceSink(webrtc::AudioDeviceSink* sink) const override { + return 0; + } + + private: + mutable webrtc::Mutex mutex_; + std::vector data_; + std::unique_ptr audio_queue_; + webrtc::RepeatingTaskHandle audio_task_; + webrtc::AudioTransport* audio_transport_; + webrtc::TaskQueueFactory* task_queue_factory_; + bool playing_{false}; + bool initialized_{false}; +}; + +} // namespace livekit + +#endif // LIVEKIT_AUDIO_DEVICE_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_track.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_track.h new file mode 100644 index 000000000..59ab6f17d --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/audio_track.h @@ -0,0 +1,13 @@ +#ifndef LIVEKIT_AUDIO_TRACK_H +#define LIVEKIT_AUDIO_TRACK_H + +namespace livekit { + + class AudioTrack { + + }; + +} + +#endif // LIVEKIT_AUDIO_TRACK_H + diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/capi.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/capi.h new file mode 100644 index 000000000..35c7a1b0a --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/capi.h @@ -0,0 +1,218 @@ +#ifndef LIVEKIT_CAPI_H +#define LIVEKIT_CAPI_H + +#include +#include + +#define LK_EXPORT __attribute__((visibility("default"))) + +#ifdef __cplusplus +extern "C" { +#endif + +// Opaque types, mapping to C++ classes +typedef void lkRefCounted; +typedef void lkPeerFactory; +typedef void lkPeer; +typedef void lkDataChannel; +typedef void lkRtpTransceiver; + +typedef enum { + LK_ICE_TRANSPORT_TYPE_NONE, + LK_ICE_TRANSPORT_TYPE_RELAY, + LK_ICE_TRANSPORT_TYPE_NO_HOST, + LK_ICE_TRANSPORT_TYPE_ALL, +} lkIceTransportType; + +typedef enum { + LK_GATHERING_POLICY_ONCE, + LK_GATHERING_POLICY_CONTINUALLY, +} lkContinualGatheringPolicy; + +typedef enum { + LK_PEER_STATE_NEW, + LK_PEER_STATE_CONNECTING, + LK_PEER_STATE_CONNECTED, + LK_PEER_STATE_DISCONNECTED, + LK_PEER_STATE_FAILED, + LK_PEER_STATE_CLOSED, +} lkPeerState; + +typedef enum { + LK_SIGNALING_STATE_STABLE, + LK_SIGNALING_STATE_HAVE_LOCAL_OFFER, + LK_SIGNALING_STATE_HAVE_LOCAL_PRANSWER, + LK_SIGNALING_STATE_HAVE_REMOTE_OFFER, + LK_SIGNALING_STATE_HAVE_REMOTE_PRANSWER, + LK_SIGNALING_STATE_CLOSED, +} lkSignalingState; + +typedef enum { + LK_ICE_STATE_NEW, + LK_ICE_STATE_CHECKING, + LK_ICE_STATE_CONNECTED, + LK_ICE_STATE_COMPLETED, + LK_ICE_STATE_FAILED, + LK_ICE_STATE_DISCONNECTED, + LK_ICE_STATE_CLOSED, +} lkIceState; + +typedef enum { + LK_SDP_TYPE_OFFER, + LK_SDP_TYPE_PRANSWER, + LK_SDP_TYPE_ANSWER, + LK_SDP_TYPE_ROLLBACK, +} lkSdpType; + +typedef enum { + LK_DC_STATE_CONNECTING, + LK_DC_STATE_OPEN, + LK_DC_STATE_CLOSING, + LK_DC_STATE_CLOSED, +} lkDcState; + +typedef struct { + const char* sdpMid; + int sdpMLineIndex; + const char* sdp; +} lkIceCandidate; + +typedef struct { + void (*onSignalingChange)(lkSignalingState state, void* userdata); + void (*onIceCandidate)(const lkIceCandidate* candidate, void* userdata); + void (*onDataChannel)(const lkDataChannel* dc, void* userdata); + void (*onTrack)(const lkRtpTransceiver* transceiver, void* userdata); + void (*onConnectionChange)(lkPeerState state, void* userdata); + void (*onIceCandidateError)(const char* address, + int port, + const char* url, + int error_code, + const char* error_text, + void* userdata); +} lkPeerObserver; + +typedef struct { + void (*onStateChange)(void* userdata); + void (*onMessage)(const uint8_t* data, + uint64_t size, + bool binary, + void* userdata); + void (*onBufferedAmountChange)(uint64_t sentDataSize, void* userdata); +} lkDataChannelObserver; + +typedef struct { + const char** urls; + int urlsCount; + const char* username; + const char* password; +} lkIceServer; + +typedef struct { + lkIceServer* iceServers; + int iceServersCount; + lkIceTransportType iceTransportType; + lkContinualGatheringPolicy gatheringPolicy; +} lkRtcConfiguration; + +typedef struct { + bool reliable; + bool ordered; + int maxRetransmits; +} lkDataChannelInit; + +typedef struct { + const char* message; +} lkRtcError; + +typedef struct { + void (*onSuccess)(void* userdata); + void (*onFailure)(const lkRtcError* error, void* userdata); +} lkSetSdpObserver; + +typedef struct { + void (*onSuccess)(lkSdpType type, const char* sdp, void* userdata); + void (*onFailure)(const lkRtcError* error, void* userdata); +} lkCreateSdpObserver; + +typedef struct { + bool iceRestart; + bool useRtpMux; +} lkOfferAnswerOptions; + +LK_EXPORT int lkInitialize(); +LK_EXPORT int lkDispose(); + +/* PeerConnection API */ + +LK_EXPORT void lkAddRef(lkRefCounted* rc); + +LK_EXPORT void lkReleaseRef(lkRefCounted* rc); + +LK_EXPORT lkPeerFactory* lkCreatePeerFactory(); +LK_EXPORT lkPeer* lkCreatePeer(lkPeerFactory* factory, + const lkRtcConfiguration* config, + const lkPeerObserver* observer, + void* userdata); + +LK_EXPORT lkDataChannel* lkCreateDataChannel(lkPeer* peer, + const char* label, + const lkDataChannelInit* init); + +LK_EXPORT bool lkAddIceCandidate(lkPeer* peer, + const lkIceCandidate* candidate, + void (*onComplete)(lkRtcError* error, + void* userdata), + void* userdata); + +LK_EXPORT bool lkSetLocalDescription(lkPeer* peer, + lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata); + +LK_EXPORT bool lkSetRemoteDescription(lkPeer* peer, + lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata); + +LK_EXPORT bool lkCreateOffer(lkPeer* peer, + const lkOfferAnswerOptions* options, + const lkCreateSdpObserver* observer, + void* userdata); + +LK_EXPORT bool lkCreateAnswer(lkPeer* peer, + const lkOfferAnswerOptions* options, + const lkCreateSdpObserver* observer, + void* userdata); + +LK_EXPORT bool lkPeerSetConfig(lkPeer* peer, const lkRtcConfiguration* config); + +LK_EXPORT bool lkPeerClose(lkPeer* peer); + +/* DataChannel API */ +LK_EXPORT void lkDcRegisterObserver(lkDataChannel* dc, + const lkDataChannelObserver* observer, + void* userdata); + +LK_EXPORT void lkDcUnregisterObserver(lkDataChannel* dc); + +LK_EXPORT lkDcState lkDcGetState(lkDataChannel* dc); + +LK_EXPORT int lkDcGetId(lkDataChannel* dc); + +LK_EXPORT void lkDcSendAsync(lkDataChannel* dc, + const uint8_t* data, + uint64_t size, + bool binary, + void (*onComplete)(lkRtcError* error, + void* userdata), + void* userdata); + +LK_EXPORT void lkDcClose(lkDataChannel* dc); + +#ifdef __cplusplus +} +#endif + +#endif // LIVEKIT_CAPI_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/data_channel.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/data_channel.h new file mode 100644 index 000000000..82157f3d3 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/data_channel.h @@ -0,0 +1,64 @@ +#ifndef LIVEKIT_DATA_CHANNEL_H +#define LIVEKIT_DATA_CHANNEL_H + +#include "api/data_channel_interface.h" +#include "api/scoped_refptr.h" +#include "livekit/capi.h" +#include "livekit/utils.h" +#include "rtc_base/copy_on_write_buffer.h" +#include "rtc_base/ref_count.h" +#include "rtc_base/synchronization/mutex.h" + +namespace livekit { + +webrtc::DataChannelInit toNativeDataChannelInit(const lkDataChannelInit& init); + +class DataChannelObserver : public webrtc::DataChannelObserver { + public: + DataChannelObserver(const lkDataChannelObserver* observer, void* userdata) + : observer_(observer), userdata_(userdata) {} + + void OnStateChange() override; + + void OnMessage(const webrtc::DataBuffer& buffer) override; + + void OnBufferedAmountChange(uint64_t sentDataSize) override; + + bool IsOkToCallOnTheNetworkThread() override { return true; } + + private: + const lkDataChannelObserver* observer_; + void* userdata_; +}; + +class DataChannel : public rtc::RefCountInterface { + public: + DataChannel(rtc::scoped_refptr data_channel) + : data_channel_(data_channel) {} + + lkDcState State() const { + return static_cast(data_channel_->state()); + } + + int Id() const { return data_channel_->id(); } + + void RegisterObserver(const lkDataChannelObserver* observer, void* userdata); + void UnregisterObserver(); + + void SendAsync(const uint8_t* data, + uint64_t size, + bool binary, + void (*onComplete)(lkRtcError* error, void* userdata), + void* userdata); + + void Close() { data_channel_->Close(); } + + private: + webrtc::Mutex mutex_; + rtc::scoped_refptr data_channel_; + std::unique_ptr observer_ = nullptr; +}; + +} // namespace livekit + +#endif // LIVEKIT_DATA_CHANNEL_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/objc_video_factory.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/objc_video_factory.h new file mode 100644 index 000000000..c1067ef65 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/objc_video_factory.h @@ -0,0 +1,16 @@ +#ifndef LIVEKIT_OBJC_VIDEO_FACTORY_H +#define LIVEKIT_OBJC_VIDEO_FACTORY_H + +#include + +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" + +namespace livekit { + +std::unique_ptr CreateObjCVideoEncoderFactory(); +std::unique_ptr CreateObjCVideoDecoderFactory(); + +} // namespace livekit + +#endif // LIVEKIT_OBJC_VIDEO_FACTORY_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/peer.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/peer.h new file mode 100644 index 000000000..e2a049474 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/peer.h @@ -0,0 +1,104 @@ +#ifndef LIVEKIT_PEER_H +#define LIVEKIT_PEER_H + +#include "api/peer_connection_interface.h" +#include "api/scoped_refptr.h" +#include "livekit/audio_device.h" +#include "livekit/capi.h" +#include "livekit/data_channel.h" + +namespace livekit { + +webrtc::PeerConnectionInterface::RTCConfiguration toNativeConfig( + const lkRtcConfiguration& config); + +class PeerObserver : public webrtc::PeerConnectionObserver, + public rtc::RefCountInterface { + public: + PeerObserver(const lkPeerObserver* observer, void* userdata) + : observer_(observer), userdata_(userdata) {} + + void OnSignalingChange( + webrtc::PeerConnectionInterface::SignalingState new_state) override; + void OnDataChannel( + rtc::scoped_refptr data_channel) override; + void OnIceGatheringChange( + webrtc::PeerConnectionInterface::IceGatheringState new_state) override; + void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override; + void OnTrack( + rtc::scoped_refptr transceiver) override; + void OnIceCandidateError(const std::string& address, + int port, + const std::string& url, + int error_code, + const std::string& error_text) override; + void OnConnectionChange( + webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; + + private: + const lkPeerObserver* observer_; + void* userdata_; +}; + +class Peer : public rtc::RefCountInterface { + public: + Peer(rtc::scoped_refptr pc, + rtc::scoped_refptr observer) + : observer_(observer), peer_connection_(pc) {} + + rtc::scoped_refptr CreateDataChannel( + const char* label, + const lkDataChannelInit* init); + + bool AddIceCandidate(const lkIceCandidate* candidate, + void (*onComplete)(lkRtcError* error, void* userdata), + void* userdata); + + bool SetLocalDescription(lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata); + + bool SetRemoteDescription(lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata); + + bool CreateOffer(const lkOfferAnswerOptions& options, + const lkCreateSdpObserver* observer, + void* userdata); + + bool CreateAnswer(const lkOfferAnswerOptions& options, + const lkCreateSdpObserver* observer, + void* userdata); + + bool SetConfig(const lkRtcConfiguration* config); + + bool Close(); + + private: + rtc::scoped_refptr observer_; + rtc::scoped_refptr peer_connection_; +}; + +class PeerFactory : public rtc::RefCountInterface { + public: + PeerFactory(); + ~PeerFactory(); + + rtc::scoped_refptr CreatePeer(const lkRtcConfiguration* config, + const lkPeerObserver* observer, + void* userdata); + + private: + std::unique_ptr network_thread_; + std::unique_ptr worker_thread_; + std::unique_ptr signaling_thread_; + + rtc::scoped_refptr audio_device_; + rtc::scoped_refptr peer_factory_; +}; + +} // namespace livekit + +#endif // LIVEKIT_PEER_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/transceiver.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/transceiver.h new file mode 100644 index 000000000..941af1fef --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/transceiver.h @@ -0,0 +1,38 @@ +#ifndef LIVEKIT_TRANSCEIVER_H +#define LIVEKIT_TRANSCEIVER_H + +#include "api/rtp_transceiver_interface.h" +#include "api/scoped_refptr.h" +#include "rtc_base/ref_count.h" + +namespace livekit { + +class RtpSender : public rtc::RefCountInterface { + public: + RtpSender(rtc::scoped_refptr sender); + + private: + rtc::scoped_refptr sender_; +}; + +class RtpReceiver : public rtc::RefCountInterface { + public: + RtpReceiver(rtc::scoped_refptr receiver); + + private: + rtc::scoped_refptr receiver_; +}; + +class RtpTransceiver : public rtc::RefCountInterface { + public: + RtpTransceiver( + rtc::scoped_refptr transceiver); + + private: + rtc::scoped_refptr transceiver_; + rtc::scoped_refptr sender_ = nullptr; + rtc::scoped_refptr receiver_ = nullptr; +}; +} // namespace livekit + +#endif // LIVEKIT_TRANSCEIVER_H diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/utils.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/utils.h new file mode 100644 index 000000000..5d389359f --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/utils.h @@ -0,0 +1,17 @@ +#ifndef LIVEKIT_UTILS_H +#define LIVEKIT_UTILS_H + +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "livekit/capi.h" + +namespace livekit { + +lkRtcError toRtcError(const webrtc::RTCError& error); + +webrtc::PeerConnectionInterface::RTCOfferAnswerOptions +toNativeOfferAnswerOptions(const lkOfferAnswerOptions& options); + +} // namespace livekit + +#endif // LIVEKIT_UTILS_H diff --git a/webrtc-sys/include/livekit/video_decoder_factory.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_decoder.h similarity index 52% rename from webrtc-sys/include/livekit/video_decoder_factory.h rename to webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_decoder.h index 1943601e6..6cf502d2d 100644 --- a/webrtc-sys/include/livekit/video_decoder_factory.h +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_decoder.h @@ -1,20 +1,5 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once +#ifndef LIVEKIT_VIDEO_DECODER_H +#define LIVEKIT_VIDEO_DECODER_H #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -36,3 +21,5 @@ class VideoDecoderFactory : public webrtc::VideoDecoderFactory { std::vector> factories_; }; } // namespace livekit + +#endif // LIVEKIT_VIDEO_DECODER_H diff --git a/webrtc-sys/include/livekit/video_encoder_factory.h b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_encoder.h similarity index 66% rename from webrtc-sys/include/livekit/video_encoder_factory.h rename to webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_encoder.h index 1d7852f81..fc5c9f731 100644 --- a/webrtc-sys/include/livekit/video_encoder_factory.h +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/livekit/video_encoder.h @@ -1,20 +1,5 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once +#ifndef LIVEKIT_VIDEO_ENCODER_H +#define LIVEKIT_VIDEO_ENCODER_H #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" @@ -54,3 +39,5 @@ class VideoEncoderFactory : public webrtc::VideoEncoderFactory { std::unique_ptr internal_factory_; }; } // namespace livekit + +#endif // LIVEKIT_VIDEO_ENCODER_H diff --git a/webrtc-sys/src/android.cpp b/webrtc-sys/libwebrtc/src/livekit_rtc/src/android.cc similarity index 71% rename from webrtc-sys/src/android.cpp rename to webrtc-sys/libwebrtc/src/livekit_rtc/src/android.cc index 30ca78dd5..9177b3ca7 100644 --- a/webrtc-sys/src/android.cpp +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/android.cc @@ -1,19 +1,3 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include "livekit/android.h" #include @@ -29,7 +13,7 @@ namespace livekit { -void init_android(JavaVM* jvm) { +void init_android(void* jvm) { webrtc::InitAndroid(jvm); } diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/audio_device.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/audio_device.cc new file mode 100644 index 000000000..a79d54460 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/audio_device.cc @@ -0,0 +1,53 @@ +#include "livekit/audio_device.h" + +namespace livekit { + +const int kBytesPerSample = 2; +const int kSampleRate = 48000; +const int kChannels = 2; +const int kSamplesPer10Ms = kSampleRate / 100; + +int32_t AudioDevice::Init() { + webrtc::MutexLock lock(&mutex_); + if (initialized_) + return 0; + + audio_queue_ = + std::make_unique(task_queue_factory_->CreateTaskQueue( + "AudioDevice", webrtc::TaskQueueFactory::Priority::NORMAL)); + + audio_task_ = + webrtc::RepeatingTaskHandle::Start(audio_queue_->Get(), [this]() { + webrtc::MutexLock lock(&mutex_); + + if (playing_) { + int64_t elapsed_time_ms = -1; + int64_t ntp_time_ms = -1; + size_t n_samples_out = 0; + void* data = data_.data(); + + audio_transport_->NeedMorePlayData( + kSamplesPer10Ms, kBytesPerSample, kChannels, kSampleRate, data, + n_samples_out, &elapsed_time_ms, &ntp_time_ms); + } + + return webrtc::TimeDelta::Millis(10); + }); + + initialized_ = true; + return 0; +} + +int32_t AudioDevice::Terminate() { + { + webrtc::MutexLock lock(&mutex_); + if (!initialized_) + return 0; + + initialized_ = false; + } + audio_queue_ = nullptr; + return 0; +} + +} // namespace livekit diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/capi.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/capi.cc new file mode 100644 index 000000000..807aaf9da --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/capi.cc @@ -0,0 +1,149 @@ +#include "livekit/capi.h" + +#include "api/make_ref_counted.h" +#include "livekit/data_channel.h" +#include "livekit/peer.h" +#include "rtc_base/logging.h" +#include "rtc_base/ref_count.h" +#include "rtc_base/ssl_adapter.h" + +void lkAddRef(lkRefCounted* rc) { + reinterpret_cast(rc)->AddRef(); +} + +void lkReleaseRef(lkRefCounted* rc) { + reinterpret_cast(rc)->Release(); +} + +int lkInitialize() { + if (!rtc::InitializeSSL()) { + RTC_LOG_ERR(LS_ERROR) << "Failed to InitializeSSL()"; + return 0; + } + +#ifdef WEBRTC_WIN + WSADATA data; + WSAStartup(MAKEWORD(1, 0), &data); +#endif + + return 1; +} + +int lkDispose() { + if (!rtc::CleanupSSL()) { + RTC_LOG_ERR(LS_ERROR) << "Failed to CleanupSSL()"; + return 0; + } + +#ifdef WEBRTC_WIN + WSACleanup(); +#endif + + return 1; +} + +lkPeerFactory* lkCreatePeerFactory() { + return reinterpret_cast( + rtc::make_ref_counted().release()); +} + +lkPeer* lkCreatePeer(lkPeerFactory* factory, + const lkRtcConfiguration* config, + const lkPeerObserver* observer, + void* userdata) { + return reinterpret_cast( + reinterpret_cast(factory) + ->CreatePeer(config, observer, userdata) + .release()); +} + +lkDataChannel* lkCreateDataChannel(lkPeer* peer, + const char* label, + const lkDataChannelInit* init) { + return reinterpret_cast(reinterpret_cast(peer) + ->CreateDataChannel(label, init) + .release()); +} + +bool lkAddIceCandidate(lkPeer* peer, + const lkIceCandidate* candidate, + void (*onComplete)(lkRtcError* error, void* userdata), + void* userdata) { + return reinterpret_cast(peer)->AddIceCandidate( + candidate, onComplete, userdata); +} + +bool lkSetLocalDescription(lkPeer* peer, + lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata) { + return reinterpret_cast(peer)->SetLocalDescription( + type, sdp, observer, userdata); +} + +bool lkSetRemoteDescription(lkPeer* peer, + lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata) { + return reinterpret_cast(peer)->SetRemoteDescription( + type, sdp, observer, userdata); +} + +bool lkCreateOffer(lkPeer* peer, + const lkOfferAnswerOptions* options, + const lkCreateSdpObserver* observer, + void* userdata) { + return reinterpret_cast(peer)->CreateOffer(*options, observer, + userdata); +} + +bool lkCreateAnswer(lkPeer* peer, + const lkOfferAnswerOptions* options, + const lkCreateSdpObserver* observer, + void* userdata) { + return reinterpret_cast(peer)->CreateAnswer( + *options, observer, userdata); +} + +bool lkPeerSetConfig(lkPeer* peer, const lkRtcConfiguration* config) { + return reinterpret_cast(peer)->SetConfig(config); +} + +bool lkPeerClose(lkPeer* peer) { + return reinterpret_cast(peer)->Close(); +} + +void lkDcRegisterObserver(lkDataChannel* dc, + const lkDataChannelObserver* observer, + void* userdata) { + reinterpret_cast(dc)->RegisterObserver(observer, + userdata); +} + +void lkDcUnregisterObserver(lkDataChannel* dc) { + reinterpret_cast(dc)->UnregisterObserver(); +} + +lkDcState lkDcGetState(lkDataChannel* dc) { + return reinterpret_cast(dc)->State(); +} + +int lkDcGetId(lkDataChannel* dc) { + return reinterpret_cast(dc)->Id(); +} + +void lkDcSendAsync(lkDataChannel* dc, + const uint8_t* data, + uint64_t size, + bool binary, + void (*onComplete)(lkRtcError* error, void* userdata), + void* userdata) { + reinterpret_cast(dc)->SendAsync(data, size, binary, + onComplete, userdata); +} + +void lkDcClose(lkDataChannel* dc) { + reinterpret_cast(dc)->Close(); +} diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/data_channel.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/data_channel.cc new file mode 100644 index 000000000..6f2975e99 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/data_channel.cc @@ -0,0 +1,62 @@ +#include "livekit/data_channel.h" + +#include "api/data_channel_interface.h" +#include "api/make_ref_counted.h" +#include "livekit/capi.h" + +namespace livekit { + +webrtc::DataChannelInit toNativeDataChannelInit(const lkDataChannelInit& init) { + webrtc::DataChannelInit nativeInit{}; + nativeInit.reliable = init.reliable; + nativeInit.ordered = init.ordered; + nativeInit.maxRetransmits = init.maxRetransmits; + + return nativeInit; +} + +void DataChannelObserver::OnStateChange() { + observer_->onStateChange(userdata_); +} + +void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer) { + observer_->onMessage(buffer.data.data(), buffer.data.size(), buffer.binary, + userdata_); +} + +void DataChannelObserver::OnBufferedAmountChange(uint64_t sentDataSize) { + observer_->onBufferedAmountChange(sentDataSize, userdata_); +} + +void DataChannel::RegisterObserver(const lkDataChannelObserver* observer, + void* userdata) { + webrtc::MutexLock lock(&mutex_); + observer_ = std::make_unique(observer, userdata); + data_channel_->RegisterObserver(observer_.get()); +} + +void DataChannel::UnregisterObserver() { + webrtc::MutexLock lock(&mutex_); + data_channel_->UnregisterObserver(); + observer_ = nullptr; +} + +void DataChannel::SendAsync(const uint8_t* data, + uint64_t size, + bool binary, + void (*onComplete)(lkRtcError* error, + void* userdata), + void* userdata) { + rtc::CopyOnWriteBuffer cow{data, size}; + webrtc::DataBuffer buffer{cow, binary}; + data_channel_->SendAsync(buffer, [&](webrtc::RTCError err) { + if (err.ok()) { + onComplete(nullptr, userdata); + } else { + lkRtcError lkErr = toRtcError(err); + onComplete(&lkErr, userdata); + } + }); +} + +} // namespace livekit diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/objc_video_factory.mm b/webrtc-sys/libwebrtc/src/livekit_rtc/src/objc_video_factory.mm new file mode 100644 index 000000000..ca650c928 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/objc_video_factory.mm @@ -0,0 +1,22 @@ +#include "livekit/objc_video_factory.h" + +#import +#import + +#include "sdk/objc/native/api/video_decoder_factory.h" +#include "sdk/objc/native/api/video_encoder_factory.h" + +namespace livekit { + +std::unique_ptr CreateObjCVideoEncoderFactory() { + // TODO(theomonnom): Simulcast? + return webrtc::ObjCToNativeVideoEncoderFactory( + [[RTCVideoEncoderFactoryH264 alloc] init]); +} + +std::unique_ptr CreateObjCVideoDecoderFactory() { + return webrtc::ObjCToNativeVideoDecoderFactory( + [[RTCVideoDecoderFactoryH264 alloc] init]); +} + +} // namespace livekit diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/peer.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/peer.cc new file mode 100644 index 000000000..63d483dbe --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/peer.cc @@ -0,0 +1,392 @@ +#include "livekit/peer.h" + +#include +#include + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/jsep.h" +#include "api/make_ref_counted.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/rtc_event_log/rtc_event_log_factory.h" +#include "api/scoped_refptr.h" +#include "api/set_local_description_observer_interface.h" +#include "api/set_remote_description_observer_interface.h" +#include "api/task_queue/default_task_queue_factory.h" +#include "livekit/audio_device.h" +#include "livekit/capi.h" +#include "livekit/data_channel.h" +#include "livekit/transceiver.h" +#include "livekit/utils.h" +#include "livekit/video_decoder.h" +#include "livekit/video_encoder.h" +#include "media/engine/webrtc_media_engine.h" +#include "rtc_base/ssl_adapter.h" +#include "rtc_base/thread.h" + +#ifdef WEBRTC_WIN +#include "rtc_base/win32.h" +#include "rtc_base/win32_socket_init.h" +#endif + +namespace livekit { + +class SetRemoteSdpObserver + : public webrtc::SetRemoteDescriptionObserverInterface { + public: + SetRemoteSdpObserver(const lkSetSdpObserver* observer, void* userdata) + : observer_(observer), userdata_(userdata) {} + + void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override { + if (error.ok()) { + observer_->onSuccess(userdata_); + } else { + lkRtcError err = toRtcError(error); + observer_->onFailure(&err, userdata_); + } + } + + private: + const lkSetSdpObserver* observer_; + void* userdata_; +}; + +class SetLocalSdpObserver + : public webrtc::SetLocalDescriptionObserverInterface { + public: + SetLocalSdpObserver(const lkSetSdpObserver* observer, void* userdata) + : observer_(observer), userdata_(userdata) {} + + void OnSetLocalDescriptionComplete(webrtc::RTCError error) override { + if (error.ok()) { + observer_->onSuccess(userdata_); + } else { + lkRtcError err = toRtcError(error); + observer_->onFailure(&err, userdata_); + } + } + + private: + const lkSetSdpObserver* observer_; + void* userdata_; +}; + +class CreateSdpObserver : public webrtc::CreateSessionDescriptionObserver { + public: + CreateSdpObserver(const lkCreateSdpObserver* observer, void* userdata) + : observer_(observer), userdata_(userdata) {} + + void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { + std::string sdp; + desc->ToString(&sdp); + observer_->onSuccess(static_cast(desc->GetType()), sdp.c_str(), + userdata_); + } + + void OnFailure(webrtc::RTCError error) override { + lkRtcError err = toRtcError(error); + observer_->onFailure(&err, userdata_); + } + + private: + const lkCreateSdpObserver* observer_; + void* userdata_; +}; + +void PeerObserver::OnSignalingChange( + webrtc::PeerConnectionInterface::SignalingState new_state) { + observer_->onSignalingChange(static_cast(new_state), + userdata_); +} + +void PeerObserver::OnDataChannel( + rtc::scoped_refptr data_channel) { + rtc::scoped_refptr lkDc = + rtc::make_ref_counted(data_channel); + observer_->onDataChannel(reinterpret_cast(lkDc.get()), + userdata_); +} + +void PeerObserver::OnIceGatheringChange( + webrtc::PeerConnectionInterface::IceGatheringState new_state) {} + +void PeerObserver::OnIceCandidate( + const webrtc::IceCandidateInterface* candidate) { + std::string sdp; + candidate->ToString(&sdp); + + lkIceCandidate lkCandidate{}; + lkCandidate.sdpMid = candidate->sdp_mid().c_str(); + lkCandidate.sdpMLineIndex = candidate->sdp_mline_index(); + lkCandidate.sdp = sdp.c_str(); + + observer_->onIceCandidate(&lkCandidate, userdata_); +} + +void PeerObserver::OnTrack( + rtc::scoped_refptr transceiver) { + rtc::scoped_refptr lkTransceiver = + rtc::make_ref_counted(transceiver); + + observer_->onTrack(reinterpret_cast(lkTransceiver.get()), + userdata_); +} + +void PeerObserver::OnConnectionChange( + webrtc::PeerConnectionInterface::PeerConnectionState new_state) { + observer_->onConnectionChange(static_cast(new_state), userdata_); +} + +void PeerObserver::OnIceCandidateError(const std::string& address, + int port, + const std::string& url, + int error_code, + const std::string& error_text) { + observer_->onIceCandidateError(address.c_str(), port, url.c_str(), error_code, + error_text.c_str(), userdata_); +} + +PeerFactory::PeerFactory() { + network_thread_ = rtc::Thread::CreateWithSocketServer(); + network_thread_->SetName("lk_network_thread", &network_thread_); + network_thread_->Start(); + worker_thread_ = rtc::Thread::Create(); + worker_thread_->SetName("lk_worker_thread", &worker_thread_); + worker_thread_->Start(); + signaling_thread_ = rtc::Thread::Create(); + signaling_thread_->SetName("lk_signaling_thread", &signaling_thread_); + signaling_thread_->Start(); + + webrtc::PeerConnectionFactoryDependencies dependencies; + dependencies.network_thread = network_thread_.get(); + dependencies.worker_thread = worker_thread_.get(); + dependencies.signaling_thread = signaling_thread_.get(); + dependencies.socket_factory = network_thread_->socketserver(); + dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory(); + dependencies.event_log_factory = std::make_unique( + dependencies.task_queue_factory.get()); + dependencies.call_factory = webrtc::CreateCallFactory(); + dependencies.trials = std::make_unique(); + + cricket::MediaEngineDependencies media_deps; + media_deps.task_queue_factory = dependencies.task_queue_factory.get(); + + audio_device_ = worker_thread_->BlockingCall([&] { + return rtc::make_ref_counted( + media_deps.task_queue_factory); + }); + + media_deps.adm = audio_device_; + media_deps.video_encoder_factory = + std::make_unique(); + media_deps.video_decoder_factory = + std::make_unique(); + media_deps.audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory(); + media_deps.audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory(); + media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); + media_deps.trials = dependencies.trials.get(); + + dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); + + peer_factory_ = + webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); + + if (!peer_factory_) { + RTC_LOG_ERR(LS_ERROR) << "Failed to create PeerConnectionFactory"; + return; + } +} + +PeerFactory::~PeerFactory() { + peer_factory_ = nullptr; + audio_device_ = nullptr; + worker_thread_->Stop(); + signaling_thread_->Stop(); + network_thread_->Stop(); +} + +rtc::scoped_refptr PeerFactory::CreatePeer( + const lkRtcConfiguration* config, + const lkPeerObserver* observer, + void* userdata) { + rtc::scoped_refptr obs = + rtc::make_ref_counted(observer, userdata); + webrtc::PeerConnectionInterface::RTCConfiguration rtcConfig = + toNativeConfig(*config); + + webrtc::PeerConnectionDependencies deps{obs.get()}; + webrtc::RTCErrorOr> res = + peer_factory_->CreatePeerConnectionOrError(rtcConfig, std::move(deps)); + + if (!res.ok()) { + RTC_LOG_ERR(LS_ERROR) << "Failed to create PeerConnection: " + << res.error().message(); + return nullptr; + } + + return rtc::make_ref_counted(res.value(), obs); +} + +rtc::scoped_refptr Peer::CreateDataChannel( + const char* label, + const lkDataChannelInit* init) { + webrtc::DataChannelInit dcInit = toNativeDataChannelInit(*init); + + webrtc::RTCErrorOr> res = + peer_connection_->CreateDataChannelOrError(label, &dcInit); + + if (!res.ok()) { + RTC_LOG_ERR(LS_ERROR) << "Failed to create DataChannel: " + << res.error().message(); + return nullptr; + } + + return rtc::make_ref_counted(res.value()); +} + +bool Peer::AddIceCandidate(const lkIceCandidate* candidate, + void (*onComplete)(lkRtcError* error, + void* userdata), + void* userdata) { + webrtc::SdpParseError error{}; + std::unique_ptr c = + std::unique_ptr(webrtc::CreateIceCandidate( + candidate->sdpMid, candidate->sdpMLineIndex, candidate->sdp, &error)); + + if (!c) { + RTC_LOG_ERR(LS_ERROR) << "Failed to parse SDP: " << error.line << " - " + << error.description; + return false; + } + + peer_connection_->AddIceCandidate(std::move(c), [&](webrtc::RTCError err) { + if (err.ok()) { + onComplete(nullptr, userdata); + } else { + lkRtcError lkErr = toRtcError(err); + onComplete(&lkErr, userdata); + } + }); + return true; +} + +bool Peer::SetLocalDescription(lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata) { + webrtc::SdpParseError error{}; + std::unique_ptr desc = + webrtc::CreateSessionDescription(static_cast(type), sdp, + &error); + + if (!desc) { + RTC_LOG_ERR(LS_ERROR) << "Failed to parse SDP: " << error.line << " - " + << error.description; + return false; + } + + rtc::scoped_refptr setSdpObserver = + rtc::make_ref_counted(observer, userdata); + + peer_connection_->SetLocalDescription(std::move(desc), + std::move(setSdpObserver)); + return true; +} + +bool Peer::SetRemoteDescription(lkSdpType type, + const char* sdp, + const lkSetSdpObserver* observer, + void* userdata) { + webrtc::SdpParseError error{}; + std::unique_ptr desc = + webrtc::CreateSessionDescription(static_cast(type), sdp, + &error); + + if (!desc) { + RTC_LOG_ERR(LS_ERROR) << "Failed to parse SDP: " << error.line << " - " + << error.description; + return false; + } + + rtc::scoped_refptr setSdpObserver = + rtc::make_ref_counted(observer, userdata); + + peer_connection_->SetRemoteDescription(std::move(desc), + std::move(setSdpObserver)); + return true; +} + +bool Peer::CreateOffer(const lkOfferAnswerOptions& options, + const lkCreateSdpObserver* observer, + void* userdata) { + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions rtcOptions = + toNativeOfferAnswerOptions(options); + + rtc::scoped_refptr + createSdpObserver = + rtc::make_ref_counted(observer, userdata); + + peer_connection_->CreateOffer(createSdpObserver.get(), rtcOptions); + return true; +} + +bool Peer::CreateAnswer(const lkOfferAnswerOptions& options, + const lkCreateSdpObserver* observer, + void* userdata) { + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions rtcOptions = + toNativeOfferAnswerOptions(options); + + rtc::scoped_refptr + createSdpObserver = + rtc::make_ref_counted(observer, userdata); + + peer_connection_->CreateAnswer(createSdpObserver.get(), rtcOptions); + return true; +} + +bool Peer::SetConfig(const lkRtcConfiguration* config) { + webrtc::PeerConnectionInterface::RTCConfiguration rtcConfig = + toNativeConfig(*config); + webrtc::RTCError err = peer_connection_->SetConfiguration(rtcConfig); + if (!err.ok()) { + RTC_LOG_ERR(LS_ERROR) << "Failed to set configuration: " << err.message(); + return false; + } + return true; +} + +bool Peer::Close() { + peer_connection_->Close(); + return true; +} + +webrtc::PeerConnectionInterface::RTCConfiguration toNativeConfig( + const lkRtcConfiguration& config) { + webrtc::PeerConnectionInterface::RTCConfiguration rtc_config{}; + + for (int i = 0; i < config.iceServersCount; ++i) { + const lkIceServer& s = config.iceServers[i]; + + webrtc::PeerConnectionInterface::IceServer ice_server; + ice_server.username = s.username; + ice_server.password = s.password; + + for (int j = 0; j < s.urlsCount; ++j) + ice_server.urls.emplace_back(s.urls[j]); + + rtc_config.servers.push_back(ice_server); + } + + rtc_config.continual_gathering_policy = + static_cast( + config.gatheringPolicy); + + rtc_config.type = + static_cast( + config.iceTransportType); + + return rtc_config; +} + +} // namespace livekit diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/transceiver.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/transceiver.cc new file mode 100644 index 000000000..4d02fd500 --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/transceiver.cc @@ -0,0 +1,24 @@ +#include "livekit/transceiver.h" + +namespace livekit { + +RtpSender::RtpSender(rtc::scoped_refptr sender) + : sender_(sender) {} + +RtpReceiver::RtpReceiver( + rtc::scoped_refptr receiver) + : receiver_(receiver) {} + +RtpTransceiver::RtpTransceiver( + rtc::scoped_refptr transceiver) + : transceiver_(transceiver) { + if (transceiver->sender()) { + sender_ = rtc::make_ref_counted(transceiver->sender()); + } + + if (transceiver->receiver()) { + receiver_ = rtc::make_ref_counted(transceiver->receiver()); + } +} + +} // namespace livekit diff --git a/webrtc-sys/libwebrtc/src/livekit_rtc/src/utils.cc b/webrtc-sys/libwebrtc/src/livekit_rtc/src/utils.cc new file mode 100644 index 000000000..89c59cb8a --- /dev/null +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/utils.cc @@ -0,0 +1,21 @@ +#include "livekit/utils.h" + +#include "api/peer_connection_interface.h" + +namespace livekit { + +lkRtcError toRtcError(const webrtc::RTCError& error) { + lkRtcError err{}; + err.message = error.message(); + return err; +} + +webrtc::PeerConnectionInterface::RTCOfferAnswerOptions +toNativeOfferAnswerOptions(const lkOfferAnswerOptions& options) { + webrtc::PeerConnectionInterface::RTCOfferAnswerOptions nativeOptions{}; + nativeOptions.ice_restart = options.iceRestart; + nativeOptions.use_rtp_mux = options.useRtpMux; + return nativeOptions; +} + +} // namespace livekit diff --git a/webrtc-sys/src/video_decoder_factory.cpp b/webrtc-sys/libwebrtc/src/livekit_rtc/src/video_decoder.cc similarity index 82% rename from webrtc-sys/src/video_decoder_factory.cpp rename to webrtc-sys/libwebrtc/src/livekit_rtc/src/video_decoder.cc index 40e742897..1d3dd84aa 100644 --- a/webrtc-sys/src/video_decoder_factory.cpp +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/video_decoder.cc @@ -1,20 +1,4 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/video_decoder_factory.h" +#include "livekit/video_decoder.h" #include "api/video_codecs/av1_profile.h" #include "api/video_codecs/sdp_video_format.h" @@ -108,15 +92,13 @@ std::unique_ptr VideoDecoderFactory::CreateVideoDecoder( if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName)) return webrtc::H264Decoder::Create(); - #if defined(RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY) if (absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName)) { return webrtc::CreateDav1dDecoder(); } #endif - - RTC_LOG(LS_ERROR) << "No VideoDecoder found for " << format.name; + RTC_LOG(LS_ERROR) << "no VideoDecoder found for " << format.name; return nullptr; } diff --git a/webrtc-sys/src/video_encoder_factory.cpp b/webrtc-sys/libwebrtc/src/livekit_rtc/src/video_encoder.cc similarity index 99% rename from webrtc-sys/src/video_encoder_factory.cpp rename to webrtc-sys/libwebrtc/src/livekit_rtc/src/video_encoder.cc index b2005867c..909c12724 100644 --- a/webrtc-sys/src/video_encoder_factory.cpp +++ b/webrtc-sys/libwebrtc/src/livekit_rtc/src/video_encoder.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "livekit/video_encoder_factory.h" +#include "livekit/video_encoder.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_encoder.h" diff --git a/webrtc-sys/src/android.rs b/webrtc-sys/src/android.rs deleted file mode 100644 index 493cccaf6..000000000 --- a/webrtc-sys/src/android.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[cfg(target_os = "android")] -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - unsafe extern "C++" { - include!("livekit/android.h"); - - type JavaVM; - unsafe fn init_android(vm: *mut JavaVM); - } -} diff --git a/webrtc-sys/src/audio_device.cpp b/webrtc-sys/src/audio_device.cpp deleted file mode 100644 index 1d90c998d..000000000 --- a/webrtc-sys/src/audio_device.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/audio_device.h" - -const int kBytesPerSample = 2; -const int kSampleRate = 48000; -const int kChannels = 2; -const int kSamplesPer10Ms = kSampleRate / 100; - -namespace livekit { - -AudioDevice::AudioDevice(webrtc::TaskQueueFactory* task_queue_factory) - : task_queue_factory_(task_queue_factory), - data_(kSamplesPer10Ms * kChannels) {} - -AudioDevice::~AudioDevice() { - Terminate(); -} - -int32_t AudioDevice::ActiveAudioLayer(AudioLayer* audioLayer) const { - *audioLayer = AudioLayer::kDummyAudio; - return 0; -} - -int32_t AudioDevice::RegisterAudioCallback(webrtc::AudioTransport* transport) { - webrtc::MutexLock lock(&mutex_); - audio_transport_ = transport; - return 0; -} - -int32_t AudioDevice::Init() { - webrtc::MutexLock lock(&mutex_); - if (initialized_) - return 0; - - audio_queue_ = - std::make_unique(task_queue_factory_->CreateTaskQueue( - "AudioDevice", webrtc::TaskQueueFactory::Priority::NORMAL)); - - audio_task_ = - webrtc::RepeatingTaskHandle::Start(audio_queue_->Get(), [this]() { - webrtc::MutexLock lock(&mutex_); - - if (playing_) { - int64_t elapsed_time_ms = -1; - int64_t ntp_time_ms = -1; - size_t n_samples_out = 0; - void* data = data_.data(); - - // Request the AudioData, otherwise WebRTC will ignore the packets. - // 10ms of audio data. - audio_transport_->NeedMorePlayData( - kSamplesPer10Ms, kBytesPerSample, kChannels, kSampleRate, data, - n_samples_out, &elapsed_time_ms, &ntp_time_ms); - } - - return webrtc::TimeDelta::Millis(10); - }); - - initialized_ = true; - return 0; -} - -int32_t AudioDevice::Terminate() { - { - webrtc::MutexLock lock(&mutex_); - if (!initialized_) - return 0; - - initialized_ = false; - } - audio_queue_ = nullptr; - return 0; -} - -bool AudioDevice::Initialized() const { - webrtc::MutexLock lock(&mutex_); - return initialized_; -} - -int16_t AudioDevice::PlayoutDevices() { - return 0; -} - -int16_t AudioDevice::RecordingDevices() { - return 0; -} - -int32_t AudioDevice::PlayoutDeviceName(uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) { - return 0; -} - -int32_t AudioDevice::RecordingDeviceName( - uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) { - return 0; -} - -int32_t AudioDevice::SetPlayoutDevice(uint16_t index) { - return 0; -} - -int32_t AudioDevice::SetPlayoutDevice(WindowsDeviceType device) { - return 0; -} - -int32_t AudioDevice::SetRecordingDevice(uint16_t index) { - return 0; -} - -int32_t AudioDevice::SetRecordingDevice(WindowsDeviceType device) { - return 0; -} - -int32_t AudioDevice::PlayoutIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::InitPlayout() { - return 0; -} - -bool AudioDevice::PlayoutIsInitialized() const { - return false; -} - -int32_t AudioDevice::RecordingIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::InitRecording() { - return 0; -} - -bool AudioDevice::RecordingIsInitialized() const { - return false; -} - -int32_t AudioDevice::StartPlayout() { - webrtc::MutexLock lock(&mutex_); - playing_ = true; - return 0; -} - -int32_t AudioDevice::StopPlayout() { - webrtc::MutexLock lock(&mutex_); - playing_ = false; - return 0; -} - -bool AudioDevice::Playing() const { - webrtc::MutexLock lock(&mutex_); - return playing_; -} - -int32_t AudioDevice::StartRecording() { - return 0; -} - -int32_t AudioDevice::StopRecording() { - return 0; -} - -bool AudioDevice::Recording() const { - return false; -} - -int32_t AudioDevice::InitSpeaker() { - return 0; -} - -bool AudioDevice::SpeakerIsInitialized() const { - return false; -} - -int32_t AudioDevice::InitMicrophone() { - return 0; -} - -bool AudioDevice::MicrophoneIsInitialized() const { - return false; -} - -int32_t AudioDevice::SpeakerVolumeIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::SetSpeakerVolume(uint32_t volume) { - return 0; -} - -int32_t AudioDevice::SpeakerVolume(uint32_t* volume) const { - return 0; -} - -int32_t AudioDevice::MaxSpeakerVolume(uint32_t* maxVolume) const { - return 0; -} - -int32_t AudioDevice::MinSpeakerVolume(uint32_t* minVolume) const { - return 0; -} - -int32_t AudioDevice::MicrophoneVolumeIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::SetMicrophoneVolume(uint32_t volume) { - return 0; -} - -int32_t AudioDevice::MicrophoneVolume(uint32_t* volume) const { - return 0; -} - -int32_t AudioDevice::MaxMicrophoneVolume(uint32_t* maxVolume) const { - return 0; -} - -int32_t AudioDevice::MinMicrophoneVolume(uint32_t* minVolume) const { - return 0; -} - -int32_t AudioDevice::SpeakerMuteIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::SetSpeakerMute(bool enable) { - return 0; -} - -int32_t AudioDevice::SpeakerMute(bool* enabled) const { - return 0; -} - -int32_t AudioDevice::MicrophoneMuteIsAvailable(bool* available) { - return 0; -} - -int32_t AudioDevice::SetMicrophoneMute(bool enable) { - return 0; -} - -int32_t AudioDevice::MicrophoneMute(bool* enabled) const { - return 0; -} - -int32_t AudioDevice::StereoPlayoutIsAvailable(bool* available) const { - *available = true; - return 0; -} - -int32_t AudioDevice::SetStereoPlayout(bool enable) { - return 0; -} - -int32_t AudioDevice::StereoPlayout(bool* enabled) const { - return 0; -} - -int32_t AudioDevice::StereoRecordingIsAvailable(bool* available) const { - return 0; -} - -int32_t AudioDevice::SetStereoRecording(bool enable) { - return 0; -} - -int32_t AudioDevice::StereoRecording(bool* enabled) const { - *enabled = true; - return 0; -} - -int32_t AudioDevice::PlayoutDelay(uint16_t* delayMS) const { - return 0; -} - -bool AudioDevice::BuiltInAECIsAvailable() const { - return false; -} - -bool AudioDevice::BuiltInAGCIsAvailable() const { - return false; -} - -bool AudioDevice::BuiltInNSIsAvailable() const { - return false; -} - -int32_t AudioDevice::EnableBuiltInAEC(bool enable) { - return 0; -} - -int32_t AudioDevice::EnableBuiltInAGC(bool enable) { - return 0; -} - -int32_t AudioDevice::EnableBuiltInNS(bool enable) { - return 0; -} - -#if defined(WEBRTC_IOS) -int AudioDevice::GetPlayoutAudioParameters( - webrtc::AudioParameters* params) const { - return 0; -} - -int AudioDevice::GetRecordAudioParameters( - webrtc::AudioParameters* params) const { - return 0; -} -#endif // WEBRTC_IOS - -int32_t AudioDevice::SetAudioDeviceSink(webrtc::AudioDeviceSink* sink) const { - return 0; -} - -} // namespace livekit diff --git a/webrtc-sys/src/audio_resampler.cpp b/webrtc-sys/src/audio_resampler.cpp deleted file mode 100644 index cbb6060d4..000000000 --- a/webrtc-sys/src/audio_resampler.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/audio_resampler.h" - -#include - -#include "audio/remix_resample.h" - -namespace livekit { - -size_t AudioResampler::remix_and_resample(const int16_t* src, - size_t samples_per_channel, - size_t num_channels, - int sample_rate, - size_t dest_num_channels, - int dest_sample_rate) { - frame_.num_channels_ = dest_num_channels; - frame_.sample_rate_hz_ = dest_sample_rate; - webrtc::voe::RemixAndResample(src, samples_per_channel, num_channels, - sample_rate, &resampler_, &frame_); - - return frame_.num_channels() * frame_.samples_per_channel() * sizeof(int16_t); -} - -const int16_t* AudioResampler::data() const { - return frame_.data(); -} - -std::unique_ptr create_audio_resampler() { - return std::make_unique(); -} - -} // namespace livekit \ No newline at end of file diff --git a/webrtc-sys/src/audio_resampler.rs b/webrtc-sys/src/audio_resampler.rs deleted file mode 100644 index 80dae06d0..000000000 --- a/webrtc-sys/src/audio_resampler.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - unsafe extern "C++" { - include!("livekit/audio_resampler.h"); - - type AudioResampler; - - unsafe fn remix_and_resample( - self: Pin<&mut AudioResampler>, - src: *const i16, - samples_per_channel: usize, - num_channels: usize, - sample_rate: i32, - dst_num_channels: usize, - dst_sample_rate: i32, - ) -> usize; - - unsafe fn data(self: &AudioResampler) -> *const i16; - - fn create_audio_resampler() -> UniquePtr; - } -} - -impl_thread_safety!(ffi::AudioResampler, Send + Sync); diff --git a/webrtc-sys/src/audio_track.cpp b/webrtc-sys/src/audio_track.cpp deleted file mode 100644 index 951208d24..000000000 --- a/webrtc-sys/src/audio_track.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/audio_track.h" - -#include -#include -#include - -#include "api/audio_options.h" -#include "api/media_stream_interface.h" -#include "audio/remix_resample.h" -#include "common_audio/include/audio_util.h" -#include "rtc_base/logging.h" -#include "rtc_base/ref_counted_object.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/time_utils.h" -#include "rust/cxx.h" -#include "webrtc-sys/src/audio_track.rs.h" - -namespace livekit { - -inline cricket::AudioOptions to_native_audio_options( - const AudioSourceOptions& options) { - cricket::AudioOptions rtc_options{}; - rtc_options.echo_cancellation = options.echo_cancellation; - rtc_options.noise_suppression = options.noise_suppression; - rtc_options.auto_gain_control = options.auto_gain_control; - return rtc_options; -} - -inline AudioSourceOptions to_rust_audio_options( - const cricket::AudioOptions& rtc_options) { - AudioSourceOptions options{}; - options.echo_cancellation = rtc_options.echo_cancellation.value_or(false); - options.noise_suppression = rtc_options.noise_suppression.value_or(false); - options.auto_gain_control = rtc_options.auto_gain_control.value_or(false); - return options; -} - -AudioTrack::AudioTrack(std::shared_ptr rtc_runtime, - rtc::scoped_refptr track) - : MediaStreamTrack(rtc_runtime, std::move(track)) {} - -AudioTrack::~AudioTrack() { - webrtc::MutexLock lock(&mutex_); - for (auto& sink : sinks_) { - track()->RemoveSink(sink.get()); - } -} - -void AudioTrack::add_sink(const std::shared_ptr& sink) const { - webrtc::MutexLock lock(&mutex_); - track()->AddSink(sink.get()); - sinks_.push_back(sink); -} - -void AudioTrack::remove_sink( - const std::shared_ptr& sink) const { - webrtc::MutexLock lock(&mutex_); - track()->RemoveSink(sink.get()); - sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); -} - -NativeAudioSink::NativeAudioSink(rust::Box observer) - : observer_(std::move(observer)) {} - -void NativeAudioSink::OnData(const void* audio_data, - int bits_per_sample, - int sample_rate, - size_t number_of_channels, - size_t number_of_frames) { - RTC_CHECK_EQ(16, bits_per_sample); - rust::Slice data(static_cast(audio_data), - number_of_channels * number_of_frames); - observer_->on_data(data, sample_rate, number_of_channels, number_of_frames); -} - -std::shared_ptr new_native_audio_sink( - rust::Box observer) { - return std::make_shared(std::move(observer)); -} - -AudioTrackSource::InternalSource::InternalSource( - const cricket::AudioOptions& options) {} - -webrtc::MediaSourceInterface::SourceState -AudioTrackSource::InternalSource::state() const { - return webrtc::MediaSourceInterface::SourceState::kLive; -} - -bool AudioTrackSource::InternalSource::remote() const { - return false; -} - -const cricket::AudioOptions AudioTrackSource::InternalSource::options() const { - webrtc::MutexLock lock(&mutex_); - return options_; -} - -void AudioTrackSource::InternalSource::set_options( - const cricket::AudioOptions& options) { - webrtc::MutexLock lock(&mutex_); - options_ = options; -} - -void AudioTrackSource::InternalSource::AddSink( - webrtc::AudioTrackSinkInterface* sink) { - webrtc::MutexLock lock(&mutex_); - sinks_.push_back(sink); -} - -void AudioTrackSource::InternalSource::RemoveSink( - webrtc::AudioTrackSinkInterface* sink) { - webrtc::MutexLock lock(&mutex_); - sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); -} - -void AudioTrackSource::InternalSource::on_captured_frame( - rust::Slice data, - uint32_t sample_rate, - uint32_t number_of_channels, - size_t number_of_frames) { - webrtc::MutexLock lock(&mutex_); - for (auto sink : sinks_) { - sink->OnData(data.data(), 16, sample_rate, number_of_channels, - number_of_frames); - } -} - -AudioTrackSource::AudioTrackSource(AudioSourceOptions options) { - source_ = - rtc::make_ref_counted(to_native_audio_options(options)); -} - -AudioSourceOptions AudioTrackSource::audio_options() const { - return to_rust_audio_options(source_->options()); -} - -void AudioTrackSource::set_audio_options( - const AudioSourceOptions& options) const { - source_->set_options(to_native_audio_options(options)); -} - -void AudioTrackSource::on_captured_frame(rust::Slice audio_data, - uint32_t sample_rate, - uint32_t number_of_channels, - size_t number_of_frames) const { - source_->on_captured_frame(audio_data, sample_rate, number_of_channels, - number_of_frames); -} - -rtc::scoped_refptr AudioTrackSource::get() - const { - return source_; -} - -std::shared_ptr new_audio_track_source( - AudioSourceOptions options) { - return std::make_shared(options); -} - -} // namespace livekit diff --git a/webrtc-sys/src/audio_track.rs b/webrtc-sys/src/audio_track.rs deleted file mode 100644 index ee32e475d..000000000 --- a/webrtc-sys/src/audio_track.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - pub struct AudioSourceOptions { - pub echo_cancellation: bool, - pub noise_suppression: bool, - pub auto_gain_control: bool, - } - - extern "C++" { - include!("livekit/media_stream_track.h"); - - type MediaStreamTrack = crate::media_stream_track::ffi::MediaStreamTrack; - } - - unsafe extern "C++" { - include!("livekit/audio_track.h"); - - type AudioTrack; - type NativeAudioSink; - type AudioTrackSource; - - fn add_sink(self: &AudioTrack, sink: &SharedPtr); - fn remove_sink(self: &AudioTrack, sink: &SharedPtr); - fn new_native_audio_sink(observer: Box) -> SharedPtr; - - fn on_captured_frame( - self: &AudioTrackSource, - data: &[i16], - sample_rate: u32, - nb_channels: u32, - nb_frames: usize, - ); - fn audio_options(self: &AudioTrackSource) -> AudioSourceOptions; - fn set_audio_options(self: &AudioTrackSource, options: &AudioSourceOptions); - fn new_audio_track_source(options: AudioSourceOptions) -> SharedPtr; - - fn audio_to_media(track: SharedPtr) -> SharedPtr; - unsafe fn media_to_audio(track: SharedPtr) -> SharedPtr; - fn _shared_audio_track() -> SharedPtr; - } - - extern "Rust" { - type AudioSinkWrapper; - - fn on_data( - self: &AudioSinkWrapper, - data: &[i16], - sample_rate: i32, - nb_channels: usize, - nb_frames: usize, - ); - } -} - -impl_thread_safety!(ffi::AudioTrack, Send + Sync); -impl_thread_safety!(ffi::NativeAudioSink, Send + Sync); -impl_thread_safety!(ffi::AudioTrackSource, Send + Sync); - -pub trait AudioSink: Send { - fn on_data(&self, data: &[i16], sample_rate: i32, nb_channels: usize, nb_frames: usize); -} - -pub struct AudioSinkWrapper { - observer: Arc, -} - -impl AudioSinkWrapper { - pub fn new(observer: Arc) -> Self { - Self { observer } - } - - fn on_data(&self, data: &[i16], sample_rate: i32, nb_channels: usize, nb_frames: usize) { - self.observer.on_data(data, sample_rate, nb_channels, nb_frames); - } -} diff --git a/webrtc-sys/src/candidate.cpp b/webrtc-sys/src/candidate.cpp deleted file mode 100644 index aa7def776..000000000 --- a/webrtc-sys/src/candidate.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/candidate.h" - -namespace livekit { -Candidate::Candidate(const cricket::Candidate& candidate) - : candidate_(candidate) {} -} // namespace livekit diff --git a/webrtc-sys/src/candidate.rs b/webrtc-sys/src/candidate.rs deleted file mode 100644 index db33e525d..000000000 --- a/webrtc-sys/src/candidate.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - unsafe extern "C++" { - include!("livekit/candidate.h"); - - type Candidate; // cricket::Candidate - - fn _shared_candidate() -> SharedPtr; - } -} diff --git a/webrtc-sys/src/data_channel.cpp b/webrtc-sys/src/data_channel.cpp deleted file mode 100644 index 9f2005f6a..000000000 --- a/webrtc-sys/src/data_channel.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/data_channel.h" - -#include - -#include "rtc_base/synchronization/mutex.h" -#include "webrtc-sys/src/data_channel.rs.h" - -namespace livekit { - -webrtc::DataChannelInit to_native_data_channel_init(DataChannelInit init) { - webrtc::DataChannelInit rtc_init{}; - rtc_init.id = init.id; - rtc_init.negotiated = init.negotiated; - rtc_init.ordered = init.ordered; - rtc_init.protocol = init.protocol.c_str(); - - if (init.has_max_retransmit_time) - rtc_init.maxRetransmitTime = init.max_retransmit_time; - - if (init.has_max_retransmits) - rtc_init.maxRetransmits = init.max_retransmits; - - if (init.has_priority) - rtc_init.priority = static_cast(init.priority); - - return rtc_init; -} - -DataChannel::DataChannel( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr data_channel) - : rtc_runtime_(rtc_runtime), data_channel_(std::move(data_channel)) { - RTC_LOG(LS_VERBOSE) << "DataChannel::DataChannel()"; -} - -DataChannel::~DataChannel() { - RTC_LOG(LS_VERBOSE) << "DataChannel::~DataChannel()"; - unregister_observer(); -} - -void DataChannel::register_observer( - rust::Box observer) const { - webrtc::MutexLock lock(&mutex_); - - data_channel_->UnregisterObserver(); - - observer_ = - std::make_unique(std::move(observer), this); - data_channel_->RegisterObserver(observer_.get()); -} - -void DataChannel::unregister_observer() const { - webrtc::MutexLock lock(&mutex_); - data_channel_->UnregisterObserver(); - observer_ = nullptr; -} - -bool DataChannel::send(const DataBuffer& buffer) const { - return data_channel_->Send(webrtc::DataBuffer{ - rtc::CopyOnWriteBuffer(buffer.ptr, buffer.len), buffer.binary}); -} - -int DataChannel::id() const { - return data_channel_->id(); -} - -rust::String DataChannel::label() const { - return data_channel_->label(); -} - -DataState DataChannel::state() const { - return static_cast(data_channel_->state()); -} - -void DataChannel::close() const { - return data_channel_->Close(); -} - -NativeDataChannelObserver::NativeDataChannelObserver( - rust::Box observer, - const DataChannel* dc) - : observer_(std::move(observer)), dc_(dc) {} - -void NativeDataChannelObserver::OnStateChange() { - observer_->on_state_change(dc_->state()); -} - -void NativeDataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer) { - DataBuffer data{}; - data.ptr = buffer.data.data(); - data.len = buffer.data.size(); - data.binary = buffer.binary; - observer_->on_message(data); -} - -void NativeDataChannelObserver::OnBufferedAmountChange( - uint64_t sent_data_size) { - observer_->on_buffered_amount_change(sent_data_size); -} - -} // namespace livekit diff --git a/webrtc-sys/src/data_channel.rs b/webrtc-sys/src/data_channel.rs deleted file mode 100644 index 7073194de..000000000 --- a/webrtc-sys/src/data_channel.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum Priority { - VeryLow, - Low, - Medium, - High, - } - - #[derive(Debug)] - pub struct DataChannelInit { - pub ordered: bool, - pub has_max_retransmit_time: bool, - pub max_retransmit_time: i32, - pub has_max_retransmits: bool, - pub max_retransmits: i32, - pub protocol: String, - pub negotiated: bool, - pub id: i32, - pub has_priority: bool, - pub priority: Priority, - } - - #[derive(Debug)] - pub struct DataBuffer { - pub ptr: *const u8, - pub len: usize, - pub binary: bool, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum DataState { - Connecting, - Open, - Closing, - Closed, - } - - unsafe extern "C++" { - include!("livekit/data_channel.h"); - - type DataChannel; - - fn register_observer(self: &DataChannel, observer: Box); - fn unregister_observer(self: &DataChannel); - - fn send(self: &DataChannel, data: &DataBuffer) -> bool; - fn id(self: &DataChannel) -> i32; - fn label(self: &DataChannel) -> String; - fn state(self: &DataChannel) -> DataState; - fn close(self: &DataChannel); - - fn _shared_data_channel() -> SharedPtr; // Ignore - } - - extern "Rust" { - type DataChannelObserverWrapper; - - fn on_state_change(self: &DataChannelObserverWrapper, state: DataState); - fn on_message(self: &DataChannelObserverWrapper, buffer: DataBuffer); - fn on_buffered_amount_change(self: &DataChannelObserverWrapper, sent_data_size: u64); - } -} - -impl_thread_safety!(ffi::DataChannel, Send + Sync); - -pub trait DataChannelObserver: Send + Sync { - fn on_state_change(&self, state: ffi::DataState); - fn on_message(&self, data: &[u8], is_binary: bool); - fn on_buffered_amount_change(&self, sent_data_size: u64); -} - -pub struct DataChannelObserverWrapper { - observer: Arc, -} - -impl DataChannelObserverWrapper { - pub fn new(observer: Arc) -> Self { - Self { observer } - } - - fn on_state_change(&self, state: ffi::DataState) { - self.observer.on_state_change(state); - } - - fn on_message(&self, buffer: ffi::DataBuffer) { - unsafe { - let data = std::slice::from_raw_parts(buffer.ptr, buffer.len); - self.observer.on_message(data, buffer.binary); - } - } - - fn on_buffered_amount_change(&self, sent_data_size: u64) { - self.observer.on_buffered_amount_change(sent_data_size); - } -} diff --git a/webrtc-sys/src/frame_cryptor.cpp b/webrtc-sys/src/frame_cryptor.cpp deleted file mode 100644 index eca5ec8ad..000000000 --- a/webrtc-sys/src/frame_cryptor.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/frame_cryptor.h" - -#include - -#include "absl/types/optional.h" -#include "api/make_ref_counted.h" -#include "livekit/peer_connection.h" -#include "livekit/peer_connection_factory.h" -#include "livekit/webrtc.h" -#include "rtc_base/thread.h" -#include "webrtc-sys/src/frame_cryptor.rs.h" - -namespace livekit { - -webrtc::FrameCryptorTransformer::Algorithm AlgorithmToFrameCryptorAlgorithm( - Algorithm algorithm) { - switch (algorithm) { - case Algorithm::AesGcm: - return webrtc::FrameCryptorTransformer::Algorithm::kAesGcm; - case Algorithm::AesCbc: - return webrtc::FrameCryptorTransformer::Algorithm::kAesCbc; - default: - return webrtc::FrameCryptorTransformer::Algorithm::kAesGcm; - } -} - -KeyProvider::KeyProvider(KeyProviderOptions options) { - webrtc::KeyProviderOptions rtc_options; - rtc_options.shared_key = options.shared_key; - - std::vector ratchet_salt; - std::copy(options.ratchet_salt.begin(), options.ratchet_salt.end(), - std::back_inserter(ratchet_salt)); - - rtc_options.ratchet_salt = ratchet_salt; - rtc_options.ratchet_window_size = options.ratchet_window_size; - rtc_options.failure_tolerance = options.failure_tolerance; - - impl_ = - new rtc::RefCountedObject(rtc_options); -} - -FrameCryptor::FrameCryptor( - std::shared_ptr rtc_runtime, - const std::string participant_id, - webrtc::FrameCryptorTransformer::Algorithm algorithm, - rtc::scoped_refptr key_provider, - rtc::scoped_refptr sender) - : rtc_runtime_(rtc_runtime), - participant_id_(participant_id), - key_provider_(key_provider), - sender_(sender) { - auto mediaType = - sender->track()->kind() == "audio" - ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame - : webrtc::FrameCryptorTransformer::MediaType::kVideoFrame; - e2ee_transformer_ = rtc::scoped_refptr( - new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(), - participant_id, mediaType, algorithm, - key_provider_)); - sender->SetEncoderToPacketizerFrameTransformer(e2ee_transformer_); - e2ee_transformer_->SetEnabled(false); -} - -FrameCryptor::FrameCryptor( - std::shared_ptr rtc_runtime, - const std::string participant_id, - webrtc::FrameCryptorTransformer::Algorithm algorithm, - rtc::scoped_refptr key_provider, - rtc::scoped_refptr receiver) - : rtc_runtime_(rtc_runtime), - participant_id_(participant_id), - key_provider_(key_provider), - receiver_(receiver) { - auto mediaType = - receiver->track()->kind() == "audio" - ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame - : webrtc::FrameCryptorTransformer::MediaType::kVideoFrame; - e2ee_transformer_ = rtc::scoped_refptr( - new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(), - participant_id, mediaType, algorithm, - key_provider_)); - receiver->SetDepacketizerToDecoderFrameTransformer(e2ee_transformer_); - e2ee_transformer_->SetEnabled(false); -} - -FrameCryptor::~FrameCryptor() { - if (observer_) { - unregister_observer(); - } -} - -void FrameCryptor::register_observer( - rust::Box observer) const { - webrtc::MutexLock lock(&mutex_); - observer_ = rtc::make_ref_counted( - std::move(observer), this); - e2ee_transformer_->RegisterFrameCryptorTransformerObserver(observer_); -} - -void FrameCryptor::unregister_observer() const { - webrtc::MutexLock lock(&mutex_); - observer_ = nullptr; - e2ee_transformer_->UnRegisterFrameCryptorTransformerObserver(); -} - -NativeFrameCryptorObserver::NativeFrameCryptorObserver( - rust::Box observer, - const FrameCryptor* fc) - : observer_(std::move(observer)), fc_(fc) {} - -NativeFrameCryptorObserver::~NativeFrameCryptorObserver() {} - -void NativeFrameCryptorObserver::OnFrameCryptionStateChanged( - const std::string participant_id, - webrtc::FrameCryptionState state) { - observer_->on_frame_cryption_state_change( - participant_id, static_cast(state)); -} - -void FrameCryptor::set_enabled(bool enabled) const { - webrtc::MutexLock lock(&mutex_); - e2ee_transformer_->SetEnabled(enabled); -} - -bool FrameCryptor::enabled() const { - webrtc::MutexLock lock(&mutex_); - return e2ee_transformer_->enabled(); -} - -void FrameCryptor::set_key_index(int32_t index) const { - webrtc::MutexLock lock(&mutex_); - e2ee_transformer_->SetKeyIndex(index); -} - -int32_t FrameCryptor::key_index() const { - webrtc::MutexLock lock(&mutex_); - return e2ee_transformer_->key_index(); -} - -std::shared_ptr new_key_provider(KeyProviderOptions options) { - return std::make_shared(options); -} - -std::shared_ptr new_frame_cryptor_for_rtp_sender( - std::shared_ptr peer_factory, - const ::rust::String participant_id, - Algorithm algorithm, - std::shared_ptr key_provider, - std::shared_ptr sender) { - return std::make_shared( - peer_factory->rtc_runtime(), - std::string(participant_id.data(), participant_id.size()), - AlgorithmToFrameCryptorAlgorithm(algorithm), - key_provider->rtc_key_provider(), sender->rtc_sender()); -} - -std::shared_ptr new_frame_cryptor_for_rtp_receiver( - std::shared_ptr peer_factory, - const ::rust::String participant_id, - Algorithm algorithm, - std::shared_ptr key_provider, - std::shared_ptr receiver) { - return std::make_shared( - peer_factory->rtc_runtime(), - std::string(participant_id.data(), participant_id.size()), - AlgorithmToFrameCryptorAlgorithm(algorithm), - key_provider->rtc_key_provider(), receiver->rtc_receiver()); -} - -} // namespace livekit diff --git a/webrtc-sys/src/frame_cryptor.rs b/webrtc-sys/src/frame_cryptor.rs deleted file mode 100644 index e46e1052f..000000000 --- a/webrtc-sys/src/frame_cryptor.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - #[derive(Debug)] - pub struct KeyProviderOptions { - pub shared_key: bool, - pub ratchet_window_size: i32, - pub ratchet_salt: Vec, - pub failure_tolerance: i32, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum Algorithm { - AesGcm = 0, - AesCbc, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum FrameCryptionState { - New = 0, - Ok, - EncryptionFailed, - DecryptionFailed, - MissingKey, - KeyRatcheted, - InternalError, - } - - unsafe extern "C++" { - include!("livekit/frame_cryptor.h"); - - pub type KeyProvider; - - pub fn new_key_provider(options: KeyProviderOptions) -> SharedPtr; - - pub fn set_shared_key(self: &KeyProvider, key_index: i32, key: Vec) -> bool; - - pub fn ratchet_shared_key(self: &KeyProvider, key_index: i32) -> Result>; - - pub fn get_shared_key(self: &KeyProvider, key_index: i32) -> Result>; - - pub fn set_sif_trailer(&self, trailer: Vec); - - pub fn set_key( - self: &KeyProvider, - participant_id: String, - key_index: i32, - key: Vec, - ) -> bool; - - pub fn ratchet_key( - self: &KeyProvider, - participant_id: String, - key_index: i32, - ) -> Result>; - - pub fn get_key( - self: &KeyProvider, - participant_id: String, - key_index: i32, - ) -> Result>; - } - - unsafe extern "C++" { - include!("livekit/frame_cryptor.h"); - include!("livekit/rtp_sender.h"); - include!("livekit/rtp_receiver.h"); - include!("livekit/peer_connection_factory.h"); - - type RtpSender = crate::rtp_sender::ffi::RtpSender; - type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; - type PeerConnectionFactory = crate::peer_connection_factory::ffi::PeerConnectionFactory; - - pub type FrameCryptor; - - pub fn new_frame_cryptor_for_rtp_sender( - peer_factory: SharedPtr, - participant_id: String, - algorithm: Algorithm, - key_provider: SharedPtr, - sender: SharedPtr, - ) -> SharedPtr; - - pub fn new_frame_cryptor_for_rtp_receiver( - peer_factory: SharedPtr, - participant_id: String, - algorithm: Algorithm, - key_provider: SharedPtr, - receiver: SharedPtr, - ) -> SharedPtr; - - pub fn set_enabled(self: &FrameCryptor, enabled: bool); - - pub fn enabled(self: &FrameCryptor) -> bool; - - pub fn set_key_index(self: &FrameCryptor, index: i32); - - pub fn key_index(self: &FrameCryptor) -> i32; - - pub fn participant_id(self: &FrameCryptor) -> String; - - pub fn register_observer( - self: &FrameCryptor, - observer: Box, - ); - - pub fn unregister_observer(self: &FrameCryptor); - } - - extern "Rust" { - type RtcFrameCryptorObserverWrapper; - - fn on_frame_cryption_state_change( - self: &RtcFrameCryptorObserverWrapper, - participant_id: String, - state: FrameCryptionState, - ); - } -} // namespace livekit - -impl_thread_safety!(ffi::FrameCryptor, Send + Sync); -impl_thread_safety!(ffi::KeyProvider, Send + Sync); - -use ffi::FrameCryptionState; - -pub trait RtcFrameCryptorObserver: Send + Sync { - fn on_frame_cryption_state_change(&self, participant_id: String, state: FrameCryptionState); -} - -pub struct RtcFrameCryptorObserverWrapper { - observer: Arc, -} - -impl RtcFrameCryptorObserverWrapper { - pub fn new(observer: Arc) -> Self { - Self { observer } - } - - fn on_frame_cryption_state_change( - self: &RtcFrameCryptorObserverWrapper, - participant_id: String, - state: FrameCryptionState, - ) { - self.observer.on_frame_cryption_state_change(participant_id, state); - } -} diff --git a/webrtc-sys/src/helper.rs b/webrtc-sys/src/helper.rs deleted file mode 100644 index f77de2bee..000000000 --- a/webrtc-sys/src/helper.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - // Wrapper to opaque C++ objects - // https://github.com/dtolnay/cxx/issues/741 - // Used to allow SharedPtr/UniquePtr type inside a rust::Vec - pub struct MediaStreamPtr { - pub ptr: SharedPtr, - } - - pub struct CandidatePtr { - pub ptr: SharedPtr, - } - - pub struct AudioTrackPtr { - pub ptr: SharedPtr, - } - - pub struct VideoTrackPtr { - pub ptr: SharedPtr, - } - - pub struct RtpSenderPtr { - pub ptr: SharedPtr, - } - - pub struct RtpReceiverPtr { - pub ptr: SharedPtr, - } - - pub struct RtpTransceiverPtr { - pub ptr: SharedPtr, - } - - unsafe extern "C++" { - include!("livekit/helper.h"); - - type MediaStream = crate::media_stream::ffi::MediaStream; - type AudioTrack = crate::media_stream::ffi::AudioTrack; - type VideoTrack = crate::media_stream::ffi::VideoTrack; - type Candidate = crate::candidate::ffi::Candidate; - type RtpSender = crate::rtp_sender::ffi::RtpSender; - type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; - type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver; - - fn _vec_media_stream_ptr() -> Vec; - fn _vec_candidate_ptr() -> Vec; - fn _vec_audio_track_ptr() -> Vec; - fn _vec_video_track_ptr() -> Vec; - fn _vec_rtp_sender_ptr() -> Vec; - fn _vec_rtp_receiver_ptr() -> Vec; - fn _vec_rtp_transceiver_ptr() -> Vec; - } -} diff --git a/webrtc-sys/src/jsep.cpp b/webrtc-sys/src/jsep.cpp deleted file mode 100644 index 0dcc9f0fb..000000000 --- a/webrtc-sys/src/jsep.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/jsep.h" - -#include -#include - -#include "livekit/rtc_error.h" -#include "rtc_base/ref_counted_object.h" -#include "rust/cxx.h" - -namespace livekit { - -std::string serialize_sdp_error(webrtc::SdpParseError error) { - std::stringstream ss; - ss << std::hex << std::setfill('0'); - ss << std::setw(8) << (uint32_t)error.line.length(); - ss << std::dec << std::setw(1) << error.line; - ss << std::dec << std::setw(1) << error.description; - return ss.str(); -} - -IceCandidate::IceCandidate( - std::unique_ptr ice_candidate) - : ice_candidate_(std::move(ice_candidate)) {} - -rust::String IceCandidate::sdp_mid() const { - return ice_candidate_->sdp_mid(); -} - -int IceCandidate::sdp_mline_index() const { - return ice_candidate_->sdp_mline_index(); -} - -rust::String IceCandidate::candidate() const { - return stringify(); -} - -rust::String IceCandidate::stringify() const { - std::string str; - ice_candidate_->ToString(&str); - return rust::String{str}; -} - -std::unique_ptr IceCandidate::release() { - return std::move(ice_candidate_); -} - -std::shared_ptr create_ice_candidate(rust::String sdp_mid, - int sdp_mline_index, - rust::String sdp) { - webrtc::SdpParseError error; - auto ice_rtc = webrtc::CreateIceCandidate(sdp_mid.c_str(), sdp_mline_index, - sdp.c_str(), &error); - if (!ice_rtc) { - throw std::runtime_error(serialize_sdp_error(error)); - } - - return std::make_shared( - std::unique_ptr(ice_rtc)); -} - -SessionDescription::SessionDescription( - std::unique_ptr session_description) - : session_description_(std::move(session_description)) {} - -SdpType SessionDescription::sdp_type() const { - return static_cast(session_description_->GetType()); -} - -rust::String SessionDescription::stringify() const { - std::string str; - session_description_->ToString(&str); - return rust::String{str}; -} - -std::unique_ptr SessionDescription::clone() const { - return std::make_unique(session_description_->Clone()); -} - -std::unique_ptr -SessionDescription::release() { - return std::move(session_description_); -} - -std::unique_ptr create_session_description( - SdpType type, - rust::String sdp) { - webrtc::SdpParseError error; - auto rtc_sdp = webrtc::CreateSessionDescription( - static_cast(type), sdp.c_str(), &error); - if (!rtc_sdp) { - throw std::runtime_error(serialize_sdp_error(error)); - } - - return std::make_unique(std::move(rtc_sdp)); -} - -NativeCreateSdpObserver::NativeCreateSdpObserver( - rust::Box ctx, - rust::Fn, std::unique_ptr)> - on_success, - rust::Fn, RtcError)> on_error) - : ctx_(std::move(ctx)), on_success_(on_success), on_error_(on_error) {} - -void NativeCreateSdpObserver::OnSuccess( - webrtc::SessionDescriptionInterface* desc) { - // We have ownership of desc - on_success_(std::move(ctx_), - std::make_unique( - std::unique_ptr(desc))); -} - -void NativeCreateSdpObserver::OnFailure(webrtc::RTCError error) { - on_error_(std::move(ctx_), to_error(error)); -} - -NativeSetLocalSdpObserver::NativeSetLocalSdpObserver( - rust::Box ctx, - rust::Fn, RtcError)> on_complete) - : ctx_(std::move(ctx)), on_complete_(on_complete) {} - -void NativeSetLocalSdpObserver::OnSetLocalDescriptionComplete( - webrtc::RTCError error) { - on_complete_(std::move(ctx_), to_error(error)); -} - -NativeSetRemoteSdpObserver::NativeSetRemoteSdpObserver( - rust::Box ctx, - rust::Fn, RtcError)> on_complete) - : ctx_(std::move(ctx)), on_complete_(on_complete) {} - -void NativeSetRemoteSdpObserver::OnSetRemoteDescriptionComplete( - webrtc::RTCError error) { - on_complete_(std::move(ctx_), to_error(error)); -} -} // namespace livekit diff --git a/webrtc-sys/src/jsep.rs b/webrtc-sys/src/jsep.rs deleted file mode 100644 index cdbb43664..000000000 --- a/webrtc-sys/src/jsep.rs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - error::Error, - fmt::{Display, Formatter}, -}; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum SdpType { - Offer, - PrAnswer, - Answer, - Rollback, - } - - #[derive(Debug)] - pub struct SdpParseError { - pub line: String, - pub description: String, - } - - extern "C++" { - include!("livekit/rtc_error.h"); - - type RtcError = crate::rtc_error::ffi::RtcError; - } - - unsafe extern "C++" { - include!("livekit/jsep.h"); - - type IceCandidate; - type SessionDescription; - - fn sdp_mid(self: &IceCandidate) -> String; - fn sdp_mline_index(self: &IceCandidate) -> i32; - fn candidate(self: &IceCandidate) -> String; - fn stringify(self: &IceCandidate) -> String; - - fn sdp_type(self: &SessionDescription) -> SdpType; - fn stringify(self: &SessionDescription) -> String; - fn clone(self: &SessionDescription) -> UniquePtr; - - fn create_ice_candidate( - sdp_mid: String, - sdp_mline_index: i32, - sdp: String, - ) -> Result>; - - fn create_session_description( - sdp_type: SdpType, - sdp: String, - ) -> Result>; - - fn _shared_ice_candidate() -> SharedPtr; // Ignore - fn _unique_session_description() -> UniquePtr; // Ignore - } -} - -impl Error for ffi::SdpParseError {} - -impl Display for ffi::SdpParseError { - fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!(f, "SdpParseError occurred {}: {}", self.line, self.description) - } -} - -impl_thread_safety!(ffi::SessionDescription, Send + Sync); -impl_thread_safety!(ffi::IceCandidate, Send + Sync); - -impl ffi::SdpParseError { - /// # Safety - /// The value must be correctly encoded - pub unsafe fn from(value: &str) -> Self { - // Parse the hex encoded error from c++ - let line_length = u32::from_str_radix(&value[0..8], 16).unwrap() as usize + 8; - let line = String::from(&value[8..line_length]); - let description = String::from(&value[line_length..]); - - Self { line, description } - } -} - -#[cfg(test)] -mod tests { - use log::info; - - use crate::jsep::ffi; - - #[test] - fn throw_error() { - let sdp_string = "v=0 -o=- 6549709950142776241 2 IN IP4 127.0.0.1 -s=- -t=0 0 -======================== ERROR HERE -a=group:BUNDLE 0 -a=extmap-allow-mixed -a=msid-semantic: WMS -m=application 9 UDP/DTLS/SCTP webrtc-datachannel -c=IN IP4 0.0.0.0 -a=ice-ufrag:Tw7h -a=ice-pwd:6XOVUD6HpcB4c1M8EB8jXJE9 -a=ice-options:trickle -a=fingerprint:sha-256 4F:EC:23:59:5D:A5:E6:3E:3E:5D:8A:09:B6:FA:04:AA:19:99:49:67:BD:65:93:06:BB:EE:AC:D5:21:0F:57:D6 -a=setup:actpass -a=mid:0 -a=sctp-port:5000 -a=max-message-size:262144 -"; - - let sdp = ffi::create_session_description(ffi::SdpType::Offer, sdp_string.to_string()); - let err = unsafe { ffi::SdpParseError::from(sdp.err().unwrap().what()) }; - info!("parse err: {:?}", err) - } -} diff --git a/webrtc-sys/src/lib.rs b/webrtc-sys/src/lib.rs index 7a3e19e14..0758ba4a8 100644 --- a/webrtc-sys/src/lib.rs +++ b/webrtc-sys/src/lib.rs @@ -1,5 +1,5 @@ -// Copyright 2023 LiveKit, Inc. -// +// Copyright 2024 LiveKit, Inc. + // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -12,43 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(target_os = "android")] -pub mod android; -pub mod audio_resampler; -pub mod audio_track; -pub mod candidate; -pub mod data_channel; -pub mod frame_cryptor; -pub mod helper; -pub mod jsep; -pub mod media_stream; -pub mod media_stream_track; -pub mod peer_connection; -pub mod peer_connection_factory; -pub mod rtc_error; -pub mod rtp_parameters; -pub mod rtp_receiver; -pub mod rtp_sender; -pub mod rtp_transceiver; -pub mod video_frame; -pub mod video_frame_buffer; -pub mod video_track; -pub mod webrtc; -pub mod yuv_helper; - -pub const MEDIA_TYPE_VIDEO: &str = "video"; -pub const MEDIA_TYPE_AUDIO: &str = "audio"; -pub const MEDIA_TYPE_DATA: &str = "data"; - -macro_rules! impl_thread_safety { - ($obj:ty, Send) => { - unsafe impl Send for $obj {} - }; - - ($obj:ty, Send + Sync) => { - unsafe impl Send for $obj {} - unsafe impl Sync for $obj {} - }; -} - -pub(crate) use impl_thread_safety; +pub mod sys; diff --git a/webrtc-sys/src/media_stream.cpp b/webrtc-sys/src/media_stream.cpp deleted file mode 100644 index ed6f78e10..000000000 --- a/webrtc-sys/src/media_stream.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/media_stream.h" - -#include -#include -#include - -#include "api/media_stream_interface.h" -#include "api/video/video_frame.h" -#include "api/video/video_rotation.h" -#include "audio/remix_resample.h" -#include "common_audio/include/audio_util.h" -#include "rtc_base/logging.h" -#include "rtc_base/ref_counted_object.h" -#include "rtc_base/time_utils.h" - -namespace livekit { - -MediaStream::MediaStream( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr stream) - : rtc_runtime_(rtc_runtime), media_stream_(std::move(stream)) {} - -rust::String MediaStream::id() const { - return media_stream_->id(); -} - -rust::Vec MediaStream::get_video_tracks() const { - rust::Vec rust; - for (auto video : media_stream_->GetVideoTracks()) - rust.push_back( - VideoTrackPtr{rtc_runtime_->get_or_create_video_track(video)}); - - return rust; -} - -rust::Vec MediaStream::get_audio_tracks() const { - rust::Vec rust; - for (auto audio : media_stream_->GetAudioTracks()) - rust.push_back( - AudioTrackPtr{rtc_runtime_->get_or_create_audio_track(audio)}); - - return rust; -} - -std::shared_ptr MediaStream::find_audio_track( - rust::String track_id) const { - return rtc_runtime_->get_or_create_audio_track( - media_stream_->FindAudioTrack(track_id.c_str())); -} - -std::shared_ptr MediaStream::find_video_track( - rust::String track_id) const { - return rtc_runtime_->get_or_create_video_track( - media_stream_->FindVideoTrack(track_id.c_str())); -} - -bool MediaStream::add_track(std::shared_ptr track) const { - if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { - return media_stream_->AddTrack( - rtc::scoped_refptr( - static_cast( - track->rtc_track().get()))); - } else { - return media_stream_->AddTrack( - rtc::scoped_refptr( - static_cast( - track->rtc_track().get()))); - } -} - -bool MediaStream::remove_track(std::shared_ptr track) const { - if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { - return media_stream_->RemoveTrack( - rtc::scoped_refptr( - static_cast( - track->rtc_track().get()))); - } else { - return media_stream_->RemoveTrack( - rtc::scoped_refptr( - static_cast( - track->rtc_track().get()))); - } -} - -} // namespace livekit diff --git a/webrtc-sys/src/media_stream.rs b/webrtc-sys/src/media_stream.rs deleted file mode 100644 index 97f26005f..000000000 --- a/webrtc-sys/src/media_stream.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - extern "C++" { - include!("livekit/helper.h"); - include!("livekit/media_stream_track.h"); - include!("livekit/audio_track.h"); - include!("livekit/video_track.h"); - - type MediaStreamTrack = crate::media_stream_track::ffi::MediaStreamTrack; - type AudioTrack = crate::audio_track::ffi::AudioTrack; - type VideoTrack = crate::video_track::ffi::VideoTrack; - type VideoTrackPtr = crate::helper::ffi::VideoTrackPtr; - type AudioTrackPtr = crate::helper::ffi::AudioTrackPtr; - } - - unsafe extern "C++" { - include!("livekit/media_stream.h"); - - type MediaStream; - - fn id(self: &MediaStream) -> String; - fn get_audio_tracks(self: &MediaStream) -> Vec; - fn get_video_tracks(self: &MediaStream) -> Vec; - fn find_audio_track(self: &MediaStream, track_id: String) -> SharedPtr; - fn find_video_track(self: &MediaStream, track_id: String) -> SharedPtr; - fn add_track(self: &MediaStream, audio_track: SharedPtr) -> bool; - fn remove_track(self: &MediaStream, audio_track: SharedPtr) -> bool; - - fn _shared_media_stream() -> SharedPtr; - } -} - -impl_thread_safety!(ffi::MediaStream, Send + Sync); diff --git a/webrtc-sys/src/media_stream_track.cpp b/webrtc-sys/src/media_stream_track.cpp deleted file mode 100644 index dafefca60..000000000 --- a/webrtc-sys/src/media_stream_track.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include "api/media_stream_interface.h" -#include "api/video/video_frame.h" -#include "api/video/video_rotation.h" -#include "audio/remix_resample.h" -#include "common_audio/include/audio_util.h" -#include "livekit/media_stream.h" -#include "rtc_base/logging.h" -#include "rtc_base/ref_counted_object.h" -#include "rtc_base/time_utils.h" - -namespace livekit { - -MediaStreamTrack::MediaStreamTrack( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr track) - : rtc_runtime_(rtc_runtime), track_(std::move(track)) {} - -rust::String MediaStreamTrack::kind() const { - return track_->kind(); -} - -rust::String MediaStreamTrack::id() const { - return track_->id(); -} - -bool MediaStreamTrack::enabled() const { - return track_->enabled(); -} - -bool MediaStreamTrack::set_enabled(bool enable) const { - return track_->set_enabled(enable); -} - -TrackState MediaStreamTrack::state() const { - return static_cast(track_->state()); -} - -} // namespace livekit diff --git a/webrtc-sys/src/media_stream_track.rs b/webrtc-sys/src/media_stream_track.rs deleted file mode 100644 index 18e39ddf3..000000000 --- a/webrtc-sys/src/media_stream_track.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[repr(i32)] - pub enum TrackState { - Live, - Ended, - } - - unsafe extern "C++" { - include!("livekit/media_stream_track.h"); - - type MediaStreamTrack; - - fn kind(self: &MediaStreamTrack) -> String; - fn id(self: &MediaStreamTrack) -> String; - fn enabled(self: &MediaStreamTrack) -> bool; - fn set_enabled(self: &MediaStreamTrack, enable: bool) -> bool; - fn state(self: &MediaStreamTrack) -> TrackState; - - fn _shared_media_stream_track() -> SharedPtr; - } -} - -impl_thread_safety!(ffi::MediaStreamTrack, Send + Sync); diff --git a/webrtc-sys/src/objc_video_factory.mm b/webrtc-sys/src/objc_video_factory.mm deleted file mode 100644 index 1ad79a0e9..000000000 --- a/webrtc-sys/src/objc_video_factory.mm +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/objc_video_factory.h" - -#import -#import -#include "sdk/objc/native/api/video_decoder_factory.h" -#include "sdk/objc/native/api/video_encoder_factory.h" - -namespace livekit { - -std::unique_ptr CreateObjCVideoEncoderFactory() { - // TODO(theomonnom): Simulcast? - return webrtc::ObjCToNativeVideoEncoderFactory([[RTCVideoEncoderFactoryH264 alloc] init]); -} - -std::unique_ptr CreateObjCVideoDecoderFactory() { - return webrtc::ObjCToNativeVideoDecoderFactory([[RTCVideoDecoderFactoryH264 alloc] init]); -} - -} // namespace livekit diff --git a/webrtc-sys/src/peer_connection.cpp b/webrtc-sys/src/peer_connection.cpp deleted file mode 100644 index a3de766c6..000000000 --- a/webrtc-sys/src/peer_connection.cpp +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/peer_connection.h" -#include "livekit/peer_connection_factory.h" - -#include - -#include "api/data_channel_interface.h" -#include "api/peer_connection_interface.h" -#include "api/scoped_refptr.h" -#include "livekit/data_channel.h" -#include "livekit/jsep.h" -#include "livekit/media_stream.h" -#include "livekit/rtc_error.h" -#include "livekit/rtp_transceiver.h" -#include "rtc_base/logging.h" - -namespace livekit { - -webrtc::PeerConnectionInterface::RTCConfiguration to_native_rtc_configuration( - RtcConfiguration config) { - webrtc::PeerConnectionInterface::RTCConfiguration rtc_config{}; - - for (auto item : config.ice_servers) { - webrtc::PeerConnectionInterface::IceServer ice_server; - ice_server.username = item.username.c_str(); - ice_server.password = item.password.c_str(); - - for (auto url : item.urls) - ice_server.urls.emplace_back(url.c_str()); - - rtc_config.servers.push_back(ice_server); - } - - rtc_config.continual_gathering_policy = - static_cast( - config.continual_gathering_policy); - - rtc_config.type = - static_cast( - config.ice_transport_type); - - return rtc_config; -} - -inline webrtc::PeerConnectionInterface::RTCOfferAnswerOptions -to_native_offer_answer_options(const RtcOfferAnswerOptions& options) { - webrtc::PeerConnectionInterface::RTCOfferAnswerOptions rtc_options; - rtc_options.offer_to_receive_video = options.offer_to_receive_video; - rtc_options.offer_to_receive_audio = options.offer_to_receive_audio; - rtc_options.voice_activity_detection = options.voice_activity_detection; - rtc_options.ice_restart = options.ice_restart; - rtc_options.use_rtp_mux = options.use_rtp_mux; - rtc_options.raw_packetization_for_video = options.raw_packetization_for_video; - rtc_options.num_simulcast_layers = options.num_simulcast_layers; - rtc_options.use_obsolete_sctp_sdp = options.use_obsolete_sctp_sdp; - return rtc_options; -} - -PeerConnection::PeerConnection( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr pc_factory, - rust::Box observer) - : rtc_runtime_(std::move(rtc_runtime)), - pc_factory_(std::move(pc_factory)), - observer_(std::move(observer)) { - RTC_LOG(LS_VERBOSE) << "PeerConnection::PeerConnection()"; -} - -PeerConnection::~PeerConnection() { - RTC_LOG(LS_VERBOSE) << "PeerConnection::~PeerConnection()"; -} - -bool PeerConnection::Initialize( - webrtc::PeerConnectionInterface::RTCConfiguration config) { - webrtc::PeerConnectionDependencies deps{this}; - auto result = - pc_factory_->CreatePeerConnectionOrError(config, std::move(deps)); - - if (!result.ok()) { - RTC_LOG(LS_ERROR) << "Failed to create peer connection: " - << result.error().message(); - return false; - } - peer_connection_ = std::move(result.value()); - return true; -} - -void PeerConnection::set_configuration(RtcConfiguration config) const { - auto result = - peer_connection_->SetConfiguration(to_native_rtc_configuration(config)); - - if (!result.ok()) { - throw std::runtime_error(serialize_error(to_error(result))); - } -} - -void PeerConnection::create_offer( - RtcOfferAnswerOptions options, - rust::Box ctx, - rust::Fn, std::unique_ptr)> - on_success, - rust::Fn, RtcError)> on_error) const { - rtc::scoped_refptr observer = - rtc::make_ref_counted(std::move(ctx), on_success, - on_error); - - peer_connection_->CreateOffer(observer.get(), - to_native_offer_answer_options(options)); -} - -void PeerConnection::create_answer( - RtcOfferAnswerOptions options, - rust::Box ctx, - rust::Fn, std::unique_ptr)> - on_success, - rust::Fn, RtcError)> on_error) const { - rtc::scoped_refptr observer = - rtc::make_ref_counted(std::move(ctx), on_success, - on_error); - - peer_connection_->CreateAnswer(observer.get(), - to_native_offer_answer_options(options)); -} - -void PeerConnection::set_local_description( - std::unique_ptr desc, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const { - rtc::scoped_refptr observer = - rtc::make_ref_counted(std::move(ctx), - on_complete); - - peer_connection_->SetLocalDescription(desc->clone()->release(), observer); -} - -void PeerConnection::set_remote_description( - std::unique_ptr desc, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const { - rtc::scoped_refptr observer = - rtc::make_ref_counted(std::move(ctx), - on_complete); - - peer_connection_->SetRemoteDescription(desc->clone()->release(), observer); -} - -void PeerConnection::restart_ice() const { - peer_connection_->RestartIce(); -} - -void PeerConnection::add_ice_candidate( - std::shared_ptr candidate, - rust::Box ctx, - rust::Fn, RtcError)> on_complete) const { - peer_connection_->AddIceCandidate( - candidate->release(), [&](const webrtc::RTCError& err) { - on_complete(std::move(ctx), to_error(err)); - }); -} - -std::shared_ptr PeerConnection::create_data_channel( - rust::String label, - DataChannelInit init) const { - webrtc::DataChannelInit rtc_init = to_native_data_channel_init(init); - auto result = - peer_connection_->CreateDataChannelOrError(label.c_str(), &rtc_init); - - if (!result.ok()) { - throw std::runtime_error(serialize_error(to_error(result.error()))); - } - - return std::make_shared(rtc_runtime_, result.value()); -} - -std::shared_ptr PeerConnection::add_track( - std::shared_ptr track, - const rust::Vec& stream_ids) const { - std::vector std_stream_ids(stream_ids.begin(), stream_ids.end()); - auto result = peer_connection_->AddTrack(track->rtc_track(), std_stream_ids); - if (!result.ok()) { - throw std::runtime_error(serialize_error(to_error(result.error()))); - } - - return std::make_shared(rtc_runtime_, result.value(), - peer_connection_); -} - -void PeerConnection::remove_track(std::shared_ptr sender) const { - auto error = peer_connection_->RemoveTrackOrError(sender->rtc_sender()); - if (!error.ok()) - throw std::runtime_error(serialize_error(to_error(error))); -} - -void PeerConnection::get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const { - auto observer = rtc::make_ref_counted>( - std::move(ctx), on_stats); - peer_connection_->GetStats(observer.get()); -} - -std::shared_ptr PeerConnection::add_transceiver( - std::shared_ptr track, - RtpTransceiverInit init) const { - auto result = peer_connection_->AddTransceiver( - track->rtc_track(), to_native_rtp_transceiver_init(init)); - if (!result.ok()) - throw std::runtime_error(serialize_error(to_error(result.error()))); - - return std::make_shared(rtc_runtime_, result.value(), - peer_connection_); -} - -std::shared_ptr PeerConnection::add_transceiver_for_media( - MediaType media_type, - RtpTransceiverInit init) const { - auto result = peer_connection_->AddTransceiver( - static_cast(media_type), - to_native_rtp_transceiver_init(init)); - - if (!result.ok()) - throw std::runtime_error(serialize_error(to_error(result.error()))); - - return std::make_shared(rtc_runtime_, result.value(), - peer_connection_); -} - -rust::Vec PeerConnection::get_senders() const { - rust::Vec vec; - for (auto sender : peer_connection_->GetSenders()) - vec.push_back(RtpSenderPtr{ - std::make_shared(rtc_runtime_, sender, peer_connection_)}); - - return vec; -} - -rust::Vec PeerConnection::get_receivers() const { - rust::Vec vec; - for (auto receiver : peer_connection_->GetReceivers()) - vec.push_back(RtpReceiverPtr{std::make_shared( - rtc_runtime_, receiver, peer_connection_)}); - - return vec; -} - -rust::Vec PeerConnection::get_transceivers() const { - rust::Vec vec; - for (auto transceiver : peer_connection_->GetTransceivers()) - vec.push_back(RtpTransceiverPtr{std::make_shared( - rtc_runtime_, transceiver, peer_connection_)}); - - return vec; -} - -std::unique_ptr PeerConnection::current_local_description() - const { - auto local_description = peer_connection_->current_local_description(); - if (local_description) - return std::make_unique(local_description->Clone()); - - return nullptr; -} - -std::unique_ptr PeerConnection::current_remote_description() - const { - auto remote_description = peer_connection_->current_remote_description(); - if (remote_description) - return std::make_unique(remote_description->Clone()); - - return nullptr; -} - -std::unique_ptr PeerConnection::pending_local_description() - const { - auto local_description = peer_connection_->pending_local_description(); - if (local_description) - return std::make_unique(local_description->Clone()); - - return nullptr; -} - -std::unique_ptr PeerConnection::pending_remote_description() - const { - auto remote_description = peer_connection_->pending_remote_description(); - if (remote_description) - return std::make_unique(remote_description->Clone()); - - return nullptr; -} - -std::unique_ptr PeerConnection::local_description() const { - auto local_description = peer_connection_->local_description(); - if (local_description) - return std::make_unique(local_description->Clone()); - - return nullptr; -} - -std::unique_ptr PeerConnection::remote_description() const { - auto remote_description = peer_connection_->remote_description(); - if (remote_description) - return std::make_unique(remote_description->Clone()); - - return nullptr; -} - -PeerConnectionState PeerConnection::connection_state() const { - return static_cast( - peer_connection_->peer_connection_state()); -} - -SignalingState PeerConnection::signaling_state() const { - return static_cast(peer_connection_->signaling_state()); -} - -IceGatheringState PeerConnection::ice_gathering_state() const { - return static_cast( - peer_connection_->ice_gathering_state()); -} - -IceConnectionState PeerConnection::ice_connection_state() const { - return static_cast( - peer_connection_->ice_connection_state()); -} - -void PeerConnection::close() const { - peer_connection_->Close(); -} - -// PeerConnectionObserver - -void PeerConnection::OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState new_state) { - observer_->on_signaling_change(static_cast(new_state)); -} - -void PeerConnection::OnAddStream( - rtc::scoped_refptr stream) { - observer_->on_add_stream(std::make_unique(rtc_runtime_, stream)); -} - -void PeerConnection::OnRemoveStream( - rtc::scoped_refptr stream) { - // Find current MediaStream - // observer_->on_remove_stream(std::make_unique(rtc_runtime_, - // stream)); -} - -void PeerConnection::OnDataChannel( - rtc::scoped_refptr data_channel) { - observer_->on_data_channel( - std::make_shared(rtc_runtime_, data_channel)); -} - -void PeerConnection::OnRenegotiationNeeded() { - observer_->on_renegotiation_needed(); -} - -void PeerConnection::OnNegotiationNeededEvent(uint32_t event_id) { - observer_->on_negotiation_needed_event(event_id); -} - -void PeerConnection::OnIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) { - observer_->on_ice_connection_change( - static_cast(new_state)); -} - -void PeerConnection::OnStandardizedIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState new_state) { - observer_->on_standardized_ice_connection_change( - static_cast(new_state)); -} - -void PeerConnection::OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) { - observer_->on_connection_change(static_cast(new_state)); -} - -void PeerConnection::OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState new_state) { - observer_->on_ice_gathering_change(static_cast(new_state)); -} - -void PeerConnection::OnIceCandidate( - const webrtc::IceCandidateInterface* candidate) { - auto new_candidate = webrtc::CreateIceCandidate(candidate->sdp_mid(), - candidate->sdp_mline_index(), - candidate->candidate()); - observer_->on_ice_candidate( - std::make_unique(std::move(new_candidate))); -} - -void PeerConnection::OnIceCandidateError(const std::string& address, - int port, - const std::string& url, - int error_code, - const std::string& error_text) { - observer_->on_ice_candidate_error(address, port, url, error_code, error_text); -} - -void PeerConnection::OnIceCandidatesRemoved( - const std::vector& candidates) { - rust::Vec vec; - - for (const auto& item : candidates) { - vec.push_back(CandidatePtr{std::make_unique(item)}); - } - - observer_->on_ice_candidates_removed(std::move(vec)); -} - -void PeerConnection::OnIceConnectionReceivingChange(bool receiving) { - observer_->on_ice_connection_receiving_change(receiving); -} - -void PeerConnection::OnIceSelectedCandidatePairChanged( - const cricket::CandidatePairChangeEvent& event) { - CandidatePairChangeEvent e{}; - e.selected_candidate_pair.local = - std::make_unique(event.selected_candidate_pair.local); - e.selected_candidate_pair.remote = - std::make_unique(event.selected_candidate_pair.remote); - e.last_data_received_ms = event.last_data_received_ms; - e.reason = event.reason; - e.estimated_disconnected_time_ms = event.estimated_disconnected_time_ms; - - observer_->on_ice_selected_candidate_pair_changed(std::move(e)); -} - -void PeerConnection::OnAddTrack( - rtc::scoped_refptr receiver, - const std::vector>& - streams) { - rust::Vec vec; - - for (const auto& item : streams) { - vec.push_back( - MediaStreamPtr{std::make_unique(rtc_runtime_, item)}); - } - - observer_->on_add_track( - std::make_unique(rtc_runtime_, receiver, peer_connection_), - std::move(vec)); -} - -void PeerConnection::OnTrack( - rtc::scoped_refptr transceiver) { - observer_->on_track(std::make_unique( - rtc_runtime_, transceiver, peer_connection_)); -} - -void PeerConnection::OnRemoveTrack( - rtc::scoped_refptr receiver) { - observer_->on_remove_track( - std::make_unique(rtc_runtime_, receiver, peer_connection_)); -} - -void PeerConnection::OnInterestingUsage(int usage_pattern) { - observer_->on_interesting_usage(usage_pattern); -} - -} // namespace livekit diff --git a/webrtc-sys/src/peer_connection.rs b/webrtc-sys/src/peer_connection.rs index b81c89555..701c58eb2 100644 --- a/webrtc-sys/src/peer_connection.rs +++ b/webrtc-sys/src/peer_connection.rs @@ -1,235 +1,3 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +pub struct PeerConnection {} -use std::any::Any; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[repr(i32)] - pub enum PeerConnectionState { - New, - Connecting, - Connected, - Disconnected, - Failed, - Closed, - } - - #[repr(i32)] - pub enum SignalingState { - Stable, - HaveLocalOffer, - HaveLocalPrAnswer, - HaveRemoteOffer, - HaveRemotePrAnswer, - Closed, - } - - #[repr(i32)] - pub enum IceConnectionState { - IceConnectionNew, - IceConnectionChecking, - IceConnectionConnected, - IceConnectionCompleted, - IceConnectionFailed, - IceConnectionDisconnected, - IceConnectionClosed, - IceConnectionMax, - } - - #[repr(i32)] - pub enum IceGatheringState { - IceGatheringNew, - IceGatheringGathering, - IceGatheringComplete, - } - - #[repr(i32)] - pub enum ContinualGatheringPolicy { - GatherOnce, - GatherContinually, - } - - #[repr(i32)] - pub enum IceTransportsType { - None, - Relay, - NoHost, - All, - } - - pub struct RtcOfferAnswerOptions { - offer_to_receive_video: i32, - offer_to_receive_audio: i32, - voice_activity_detection: bool, - ice_restart: bool, - use_rtp_mux: bool, - raw_packetization_for_video: bool, - num_simulcast_layers: i32, - use_obsolete_sctp_sdp: bool, - } - - pub struct IceServer { - pub urls: Vec, - pub username: String, - pub password: String, - } - - pub struct RtcConfiguration { - pub ice_servers: Vec, - pub continual_gathering_policy: ContinualGatheringPolicy, - pub ice_transport_type: IceTransportsType, - } - - extern "C++" { - include!("livekit/rtc_error.h"); - include!("livekit/helper.h"); - include!("livekit/candidate.h"); - include!("livekit/media_stream.h"); - include!("livekit/rtp_transceiver.h"); - include!("livekit/rtp_sender.h"); - include!("livekit/rtp_receiver.h"); - include!("livekit/data_channel.h"); - include!("livekit/jsep.h"); - include!("livekit/webrtc.h"); - - type RtpSenderPtr = crate::helper::ffi::RtpSenderPtr; - type RtpReceiverPtr = crate::helper::ffi::RtpReceiverPtr; - type RtpTransceiverPtr = crate::helper::ffi::RtpTransceiverPtr; - type RtcError = crate::rtc_error::ffi::RtcError; - type Candidate = crate::candidate::ffi::Candidate; - type IceCandidate = crate::jsep::ffi::IceCandidate; - type DataChannel = crate::data_channel::ffi::DataChannel; - type DataChannelInit = crate::data_channel::ffi::DataChannelInit; - type RtpSender = crate::rtp_sender::ffi::RtpSender; - type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; - type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver; - type RtpTransceiverInit = crate::rtp_transceiver::ffi::RtpTransceiverInit; - type MediaStream = crate::media_stream::ffi::MediaStream; - type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack; - type SessionDescription = crate::jsep::ffi::SessionDescription; - type MediaType = crate::webrtc::ffi::MediaType; - } - - unsafe extern "C++" { - include!("livekit/peer_connection.h"); - - type PeerConnection; - - fn set_configuration(self: &PeerConnection, config: RtcConfiguration) -> Result<()>; - - fn create_offer( - self: &PeerConnection, - options: RtcOfferAnswerOptions, - ctx: Box, - on_success: fn(ctx: Box, sdp: UniquePtr), - on_error: fn(ctx: Box, error: RtcError), - ); - fn create_answer( - self: &PeerConnection, - options: RtcOfferAnswerOptions, - ctx: Box, - on_success: fn(ctx: Box, sdp: UniquePtr), - on_error: fn(ctx: Box, error: RtcError), - ); - fn set_local_description( - self: &PeerConnection, - desc: UniquePtr, - ctx: Box, - on_complete: fn(ctx: Box, error: RtcError), - ); - fn set_remote_description( - self: &PeerConnection, - desc: UniquePtr, - ctx: Box, - on_complete: fn(ctx: Box, error: RtcError), - ); - fn add_track( - self: &PeerConnection, - track: SharedPtr, - stream_ids: &Vec, - ) -> Result>; - fn remove_track(self: &PeerConnection, sender: SharedPtr) -> Result<()>; - fn get_stats( - self: &PeerConnection, - ctx: Box, - on_stats: fn(ctx: Box, json: String), - ); - fn add_transceiver( - self: &PeerConnection, - track: SharedPtr, - init: RtpTransceiverInit, - ) -> Result>; - fn add_transceiver_for_media( - self: &PeerConnection, - media_type: MediaType, - init: RtpTransceiverInit, - ) -> Result>; - fn get_senders(self: &PeerConnection) -> Vec; - fn get_receivers(self: &PeerConnection) -> Vec; - fn get_transceivers(self: &PeerConnection) -> Vec; - fn create_data_channel( - self: &PeerConnection, - label: String, - init: DataChannelInit, - ) -> Result>; - fn add_ice_candidate( - self: &PeerConnection, - candidate: SharedPtr, - ctx: Box, - on_complete: fn(ctx: Box, error: RtcError), - ); - fn restart_ice(self: &PeerConnection); - fn current_local_description(self: &PeerConnection) -> UniquePtr; - fn current_remote_description(self: &PeerConnection) -> UniquePtr; - fn connection_state(self: &PeerConnection) -> PeerConnectionState; - fn signaling_state(self: &PeerConnection) -> SignalingState; - fn ice_gathering_state(self: &PeerConnection) -> IceGatheringState; - fn ice_connection_state(self: &PeerConnection) -> IceConnectionState; - fn close(self: &PeerConnection); - - fn _shared_peer_connection() -> SharedPtr; // Ignore - } - - extern "Rust" { - type PeerContext; - } -} - -#[repr(transparent)] -pub struct PeerContext(pub Box); - -// https://webrtc.github.io/webrtc-org/native-code/native-apis/ -impl_thread_safety!(ffi::PeerConnection, Send + Sync); - -impl Default for ffi::RtcOfferAnswerOptions { - // static const int kUndefined = -1; - // static const int kMaxOfferToReceiveMedia = 1; - // static const int kOfferToReceiveMediaTrue = 1; - - fn default() -> Self { - Self { - offer_to_receive_video: -1, - offer_to_receive_audio: -1, - voice_activity_detection: true, - ice_restart: false, - use_rtp_mux: true, - raw_packetization_for_video: false, - num_simulcast_layers: 1, - use_obsolete_sctp_sdp: false, - } - } -} +impl PeerConnection {} diff --git a/webrtc-sys/src/peer_connection_factory.cpp b/webrtc-sys/src/peer_connection_factory.cpp deleted file mode 100644 index 28e400f63..000000000 --- a/webrtc-sys/src/peer_connection_factory.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/peer_connection_factory.h" - -#include -#include - -#include "api/audio_codecs/builtin_audio_decoder_factory.h" -#include "api/audio_codecs/builtin_audio_encoder_factory.h" -#include "api/peer_connection_interface.h" -#include "api/rtc_error.h" -#include "api/rtc_event_log/rtc_event_log_factory.h" -#include "api/task_queue/default_task_queue_factory.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" -#include "livekit/audio_device.h" -#include "livekit/peer_connection.h" -#include "livekit/rtc_error.h" -#include "livekit/rtp_parameters.h" -#include "livekit/video_decoder_factory.h" -#include "livekit/video_encoder_factory.h" -#include "livekit/webrtc.h" -#include "media/engine/webrtc_media_engine.h" -#include "rtc_base/thread.h" -#include "webrtc-sys/src/peer_connection.rs.h" -#include "webrtc-sys/src/peer_connection_factory.rs.h" - -namespace livekit { - -class PeerConnectionObserver; - -PeerConnectionFactory::PeerConnectionFactory( - std::shared_ptr rtc_runtime) - : rtc_runtime_(rtc_runtime) { - RTC_LOG(LS_VERBOSE) << "PeerConnectionFactory::PeerConnectionFactory()"; - - webrtc::PeerConnectionFactoryDependencies dependencies; - dependencies.network_thread = rtc_runtime_->network_thread(); - dependencies.worker_thread = rtc_runtime_->worker_thread(); - dependencies.signaling_thread = rtc_runtime_->signaling_thread(); - dependencies.socket_factory = rtc_runtime_->network_thread()->socketserver(); - dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory(); - dependencies.event_log_factory = std::make_unique( - dependencies.task_queue_factory.get()); - dependencies.call_factory = webrtc::CreateCallFactory(); - dependencies.trials = std::make_unique(); - - cricket::MediaEngineDependencies media_deps; - media_deps.task_queue_factory = dependencies.task_queue_factory.get(); - - audio_device_ = rtc_runtime_->worker_thread()->BlockingCall([&] { - return rtc::make_ref_counted( - media_deps.task_queue_factory); - }); - - media_deps.adm = audio_device_; - - media_deps.video_encoder_factory = - std::move(std::make_unique()); - media_deps.video_decoder_factory = - std::move(std::make_unique()); - media_deps.audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory(); - media_deps.audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory(); - media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); - media_deps.trials = dependencies.trials.get(); - - dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); - - peer_factory_ = - webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); - - if (peer_factory_.get() == nullptr) { - RTC_LOG_ERR(LS_ERROR) << "Failed to create PeerConnectionFactory"; - return; - } -} - -PeerConnectionFactory::~PeerConnectionFactory() { - RTC_LOG(LS_VERBOSE) << "PeerConnectionFactory::~PeerConnectionFactory()"; - - peer_factory_ = nullptr; - rtc_runtime_->worker_thread()->BlockingCall( - [this] { audio_device_ = nullptr; }); -} - -std::shared_ptr PeerConnectionFactory::create_peer_connection( - RtcConfiguration config, - rust::Box observer) const { - std::shared_ptr pc = std::make_shared( - rtc_runtime_, peer_factory_, std::move(observer)); - - if (!pc->Initialize(to_native_rtc_configuration(config))) { - throw std::runtime_error(serialize_error(to_error(webrtc::RTCError( - webrtc::RTCErrorType::INTERNAL_ERROR, "failed to initialize pc")))); - } - - return pc; -} - -std::shared_ptr PeerConnectionFactory::create_video_track( - rust::String label, - std::shared_ptr source) const { - return std::static_pointer_cast( - rtc_runtime_->get_or_create_media_stream_track( - peer_factory_->CreateVideoTrack(source->get(), label.c_str()))); -} - -std::shared_ptr PeerConnectionFactory::create_audio_track( - rust::String label, - std::shared_ptr source) const { - return std::static_pointer_cast( - rtc_runtime_->get_or_create_media_stream_track( - peer_factory_->CreateAudioTrack(label.c_str(), source->get().get()))); -} -RtpCapabilities PeerConnectionFactory::rtp_sender_capabilities( - MediaType type) const { - return to_rust_rtp_capabilities(peer_factory_->GetRtpSenderCapabilities( - static_cast(type))); -} - -RtpCapabilities PeerConnectionFactory::rtp_receiver_capabilities( - MediaType type) const { - return to_rust_rtp_capabilities(peer_factory_->GetRtpReceiverCapabilities( - static_cast(type))); -} - -std::shared_ptr create_peer_connection_factory() { - return std::make_shared(RtcRuntime::create()); -} - -} // namespace livekit diff --git a/webrtc-sys/src/peer_connection_factory.rs b/webrtc-sys/src/peer_connection_factory.rs deleted file mode 100644 index 51efc2f46..000000000 --- a/webrtc-sys/src/peer_connection_factory.rs +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use cxx::SharedPtr; - -use crate::{ - candidate::ffi::Candidate, data_channel::ffi::DataChannel, impl_thread_safety, - jsep::ffi::IceCandidate, media_stream::ffi::MediaStream, rtp_receiver::ffi::RtpReceiver, - rtp_transceiver::ffi::RtpTransceiver, -}; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - pub struct CandidatePair { - local: SharedPtr, - remote: SharedPtr, - } - - pub struct CandidatePairChangeEvent { - selected_candidate_pair: CandidatePair, - last_data_received_ms: i64, - reason: String, - estimated_disconnected_time_ms: i64, - } - - extern "C++" { - include!("livekit/rtp_parameters.h"); - include!("livekit/rtc_error.h"); - include!("livekit/helper.h"); - include!("livekit/candidate.h"); - include!("livekit/media_stream.h"); - include!("livekit/rtp_transceiver.h"); - include!("livekit/rtp_sender.h"); - include!("livekit/rtp_receiver.h"); - include!("livekit/data_channel.h"); - include!("livekit/jsep.h"); - include!("livekit/webrtc.h"); - include!("livekit/peer_connection.h"); - - type RtcConfiguration = crate::peer_connection::ffi::RtcConfiguration; - type PeerConnectionState = crate::peer_connection::ffi::PeerConnectionState; - type SignalingState = crate::peer_connection::ffi::SignalingState; - type IceConnectionState = crate::peer_connection::ffi::IceConnectionState; - type IceGatheringState = crate::peer_connection::ffi::IceGatheringState; - type AudioTrackSource = crate::audio_track::ffi::AudioTrackSource; - type VideoTrackSource = crate::video_track::ffi::VideoTrackSource; - type RtpCapabilities = crate::rtp_parameters::ffi::RtpCapabilities; - type AudioTrack = crate::audio_track::ffi::AudioTrack; - type VideoTrack = crate::video_track::ffi::VideoTrack; - type MediaStreamPtr = crate::helper::ffi::MediaStreamPtr; - type CandidatePtr = crate::helper::ffi::CandidatePtr; - type RtpSenderPtr = crate::helper::ffi::RtpSenderPtr; - type RtpReceiverPtr = crate::helper::ffi::RtpReceiverPtr; - type RtpTransceiverPtr = crate::helper::ffi::RtpTransceiverPtr; - type RtcError = crate::rtc_error::ffi::RtcError; - type Candidate = crate::candidate::ffi::Candidate; - type IceCandidate = crate::jsep::ffi::IceCandidate; - type DataChannel = crate::data_channel::ffi::DataChannel; - type DataChannelInit = crate::data_channel::ffi::DataChannelInit; - type RtpSender = crate::rtp_sender::ffi::RtpSender; - type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; - type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver; - type RtpTransceiverInit = crate::rtp_transceiver::ffi::RtpTransceiverInit; - type MediaStream = crate::media_stream::ffi::MediaStream; - type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack; - type SessionDescription = crate::jsep::ffi::SessionDescription; - type MediaType = crate::webrtc::ffi::MediaType; - } - - unsafe extern "C++" { - include!("livekit/peer_connection_factory.h"); - - type PeerConnection = crate::peer_connection::ffi::PeerConnection; - type PeerConnectionFactory; - - fn create_peer_connection_factory() -> SharedPtr; - - fn create_peer_connection( - self: &PeerConnectionFactory, - config: RtcConfiguration, - observer: Box, - ) -> Result>; - - fn create_video_track( - self: &PeerConnectionFactory, - label: String, - source: SharedPtr, - ) -> SharedPtr; - - fn create_audio_track( - self: &PeerConnectionFactory, - label: String, - source: SharedPtr, - ) -> SharedPtr; - - fn rtp_sender_capabilities( - self: &PeerConnectionFactory, - kind: MediaType, - ) -> RtpCapabilities; - - fn rtp_receiver_capabilities( - self: &PeerConnectionFactory, - kind: MediaType, - ) -> RtpCapabilities; - } - - extern "Rust" { - type PeerConnectionObserverWrapper; - - fn on_signaling_change(self: &PeerConnectionObserverWrapper, new_state: SignalingState); - fn on_add_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr); - fn on_remove_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr); - fn on_data_channel( - self: &PeerConnectionObserverWrapper, - data_channel: SharedPtr, - ); - fn on_renegotiation_needed(self: &PeerConnectionObserverWrapper); - fn on_negotiation_needed_event(self: &PeerConnectionObserverWrapper, event: u32); - fn on_ice_connection_change( - self: &PeerConnectionObserverWrapper, - new_state: IceConnectionState, - ); - fn on_standardized_ice_connection_change( - self: &PeerConnectionObserverWrapper, - new_state: IceConnectionState, - ); - fn on_connection_change( - self: &PeerConnectionObserverWrapper, - new_state: PeerConnectionState, - ); - fn on_ice_gathering_change( - self: &PeerConnectionObserverWrapper, - new_state: IceGatheringState, - ); - fn on_ice_candidate( - self: &PeerConnectionObserverWrapper, - candidate: SharedPtr, - ); - fn on_ice_candidate_error( - self: &PeerConnectionObserverWrapper, - address: String, - port: i32, - url: String, - error_code: i32, - error_text: String, - ); - fn on_ice_candidates_removed( - self: &PeerConnectionObserverWrapper, - removed: Vec, - ); - fn on_ice_connection_receiving_change( - self: &PeerConnectionObserverWrapper, - receiving: bool, - ); - fn on_ice_selected_candidate_pair_changed( - self: &PeerConnectionObserverWrapper, - event: CandidatePairChangeEvent, - ); - fn on_add_track( - self: &PeerConnectionObserverWrapper, - receiver: SharedPtr, - streams: Vec, - ); - fn on_track(self: &PeerConnectionObserverWrapper, transceiver: SharedPtr); - fn on_remove_track(self: &PeerConnectionObserverWrapper, receiver: SharedPtr); - fn on_interesting_usage(self: &PeerConnectionObserverWrapper, usage_pattern: i32); - } -} - -impl_thread_safety!(ffi::PeerConnectionFactory, Send + Sync); - -pub trait PeerConnectionObserver: Send + Sync { - fn on_signaling_change(&self, new_state: ffi::SignalingState); - fn on_add_stream(&self, stream: SharedPtr); - fn on_remove_stream(&self, stream: SharedPtr); - fn on_data_channel(&self, data_channel: SharedPtr); - fn on_renegotiation_needed(&self); - fn on_negotiation_needed_event(&self, event: u32); - fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState); - fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState); - fn on_connection_change(&self, new_state: ffi::PeerConnectionState); - fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState); - fn on_ice_candidate(&self, candidate: SharedPtr); - fn on_ice_candidate_error( - &self, - address: String, - port: i32, - url: String, - error_code: i32, - error_text: String, - ); - fn on_ice_candidates_removed(&self, removed: Vec>); - fn on_ice_connection_receiving_change(&self, receiving: bool); - fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent); - fn on_add_track(&self, receiver: SharedPtr, streams: Vec>); - fn on_track(&self, transceiver: SharedPtr); - fn on_remove_track(&self, receiver: SharedPtr); - fn on_interesting_usage(&self, usage_pattern: i32); -} - -// Wrapper for PeerConnectionObserver because cxx doesn't support dyn Trait on c++ -// https://github.com/dtolnay/cxx/issues/665 -pub struct PeerConnectionObserverWrapper { - observer: Arc, -} - -impl PeerConnectionObserverWrapper { - pub fn new(observer: Arc) -> Self { - Self { observer } - } - - fn on_signaling_change(&self, new_state: ffi::SignalingState) { - self.observer.on_signaling_change(new_state); - } - - fn on_add_stream(&self, stream: SharedPtr) { - self.observer.on_add_stream(stream); - } - - fn on_remove_stream(&self, stream: SharedPtr) { - self.observer.on_remove_stream(stream); - } - - fn on_data_channel(&self, data_channel: SharedPtr) { - self.observer.on_data_channel(data_channel); - } - - fn on_renegotiation_needed(&self) { - self.observer.on_renegotiation_needed(); - } - - fn on_negotiation_needed_event(&self, event: u32) { - self.observer.on_negotiation_needed_event(event); - } - - fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState) { - self.observer.on_ice_connection_change(new_state); - } - - fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState) { - self.observer.on_standardized_ice_connection_change(new_state); - } - - fn on_connection_change(&self, new_state: ffi::PeerConnectionState) { - self.observer.on_connection_change(new_state); - } - - fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState) { - self.observer.on_ice_gathering_change(new_state); - } - - fn on_ice_candidate(&self, candidate: SharedPtr) { - self.observer.on_ice_candidate(candidate); - } - - fn on_ice_candidate_error( - &self, - address: String, - port: i32, - url: String, - error_code: i32, - error_text: String, - ) { - self.observer.on_ice_candidate_error(address, port, url, error_code, error_text); - } - - fn on_ice_candidates_removed(&self, candidates: Vec) { - self.observer.on_ice_candidates_removed(candidates.into_iter().map(|v| v.ptr).collect()); - } - - fn on_ice_connection_receiving_change(&self, receiving: bool) { - self.observer.on_ice_connection_receiving_change(receiving); - } - - fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent) { - self.observer.on_ice_selected_candidate_pair_changed(event); - } - - fn on_add_track(&self, receiver: SharedPtr, streams: Vec) { - self.observer.on_add_track(receiver, streams.into_iter().map(|v| v.ptr).collect()); - } - - fn on_track(&self, transceiver: SharedPtr) { - self.observer.on_track(transceiver); - } - - fn on_remove_track(&self, receiver: SharedPtr) { - self.observer.on_remove_track(receiver); - } - - fn on_interesting_usage(&self, usage_pattern: i32) { - self.observer.on_interesting_usage(usage_pattern); - } -} diff --git a/webrtc-sys/src/rtc_error.cpp b/webrtc-sys/src/rtc_error.cpp deleted file mode 100644 index 363bb0233..000000000 --- a/webrtc-sys/src/rtc_error.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/rtc_error.h" - -#include -#include -#include - -namespace livekit { - -RtcError to_error(const webrtc::RTCError& error) { - RtcError lk_error; - lk_error.error_detail = static_cast(error.error_detail()); - lk_error.error_type = static_cast(error.type()); - lk_error.has_sctp_cause_code = error.sctp_cause_code().has_value(); - lk_error.sctp_cause_code = error.sctp_cause_code().value_or(0); - lk_error.message = error.message(); - return lk_error; -} - -std::string serialize_error(const RtcError& error) { - std::stringstream ss; - ss << std::hex << std::setfill('0'); - ss << std::setw(8) << (uint32_t)error.error_type; - ss << std::setw(8) << (uint32_t)error.error_detail; - ss << std::setw(2) << (uint16_t)error.has_sctp_cause_code; - ss << std::setw(4) << (uint16_t)error.sctp_cause_code; - ss << std::dec << std::setw(1) << std::string(error.message); - return ss.str(); -} - -#ifdef LIVEKIT_TEST -rust::String serialize_deserialize() { - RtcError lk_error; - lk_error.error_type = RtcErrorType::InternalError; - lk_error.error_detail = RtcErrorDetailType::DataChannelFailure; - lk_error.has_sctp_cause_code = true; - lk_error.sctp_cause_code = 24; - lk_error.message = "this is not a test, I repeat, this is not a test"; - return serialize_error(lk_error); -} - -void throw_error() { - RtcError lk_error; - lk_error.error_type = RtcErrorType::InvalidModification; - lk_error.error_detail = RtcErrorDetailType::None; - lk_error.has_sctp_cause_code = false; - lk_error.sctp_cause_code = 0; - lk_error.message = "exception is thrown!"; - throw std::runtime_error(serialize_error(lk_error)); -} -#endif - -} // namespace livekit diff --git a/webrtc-sys/src/rtc_error.rs b/webrtc-sys/src/rtc_error.rs deleted file mode 100644 index 64c8642c3..000000000 --- a/webrtc-sys/src/rtc_error.rs +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - error::Error, - fmt::{Display, Formatter}, -}; - -// cxx doesn't support custom Exception type, so we serialize RtcError inside the cxx::Exception -// "what" string - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum RtcErrorType { - None, - UnsupportedOperation, - UnsupportedParameter, - InvalidParameter, - InvalidRange, - SyntaxError, - InvalidState, - InvalidModification, - NetworkError, - ResourceExhausted, - InternalError, - OperationErrorWithData, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum RtcErrorDetailType { - None, - DataChannelFailure, - DtlsFailure, - FingerprintFailure, - SctpFailure, - SdpSyntaxError, - HardwareEncoderNotAvailable, - HardwareEncoderError, - } - - #[derive(Debug)] - pub struct RtcError { - pub error_type: RtcErrorType, - pub message: String, - pub error_detail: RtcErrorDetailType, - // cxx doesn't support the Option trait - pub has_sctp_cause_code: bool, - pub sctp_cause_code: u16, - } -} - -impl ffi::RtcError { - /// # Safety - /// The value must be correctly encoded - pub unsafe fn from(value: &str) -> Self { - // Parse the hex encoded error from c++ - let error_type = u32::from_str_radix(&value[0..8], 16).unwrap(); - let error_detail = u32::from_str_radix(&value[8..16], 16).unwrap(); - let has_scp_cause_code = u8::from_str_radix(&value[16..18], 16).unwrap(); - let sctp_cause_code = u16::from_str_radix(&value[18..22], 16).unwrap(); - let message = String::from(&value[22..]); // msg isn't encoded - - Self { - error_type: std::mem::transmute(error_type), - error_detail: std::mem::transmute(error_detail), - sctp_cause_code, - has_sctp_cause_code: has_scp_cause_code == 1, - message, - } - } - - pub fn ok(&self) -> bool { - self.error_type == ffi::RtcErrorType::None - } -} - -impl Error for ffi::RtcError {} - -impl Display for ffi::RtcError { - fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!(f, "RtcError occurred {:?}: {}", self.error_type, self.message) - } -} - -#[cfg(test)] -mod tests { - use crate::rtc_error::ffi::{RtcError, RtcErrorDetailType, RtcErrorType}; - - #[cxx::bridge(namespace = "livekit")] - pub mod ffi { - unsafe extern "C++" { - include!("livekit/rtc_error.h"); - - fn serialize_deserialize() -> String; - fn throw_error() -> Result<()>; - } - } - - #[test] - fn serialize_deserialize() { - let str = ffi::serialize_deserialize(); - let error = unsafe { RtcError::from(&str) }; - - assert_eq!(error.error_type, RtcErrorType::InternalError); - assert_eq!(error.error_detail, RtcErrorDetailType::DataChannelFailure); - assert!(error.has_sctp_cause_code); - assert_eq!(error.sctp_cause_code, 24); - assert_eq!(error.message, "this is not a test, I repeat, this is not a test"); - } - - #[test] - fn throw_error() { - let exc: cxx::Exception = ffi::throw_error().err().unwrap(); - let error = unsafe { RtcError::from(exc.what()) }; - - assert_eq!(error.error_type, RtcErrorType::InvalidModification); - assert_eq!(error.error_detail, RtcErrorDetailType::None); - assert!(!error.has_sctp_cause_code); - assert_eq!(error.sctp_cause_code, 0); - assert_eq!(error.message, "exception is thrown!"); - } -} diff --git a/webrtc-sys/src/rtp_parameters.cpp b/webrtc-sys/src/rtp_parameters.cpp deleted file mode 100644 index 75bbcd4c9..000000000 --- a/webrtc-sys/src/rtp_parameters.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/rtp_parameters.h" - -namespace livekit { - -webrtc::RtcpFeedback to_native_rtcp_feedback(RtcpFeedback feedback) { - webrtc::RtcpFeedback native{}; - native.type = static_cast(feedback.feedback_type); - if (feedback.has_message_type) - native.message_type = - static_cast(feedback.message_type); - - return native; -} - -webrtc::RtpCodecCapability to_native_rtp_codec_capability( - RtpCodecCapability capability) { - webrtc::RtpCodecCapability native{}; - // native.mime_type(); IGNORED - - native.name = capability.name.c_str(); - native.kind = static_cast(capability.kind); - - if (capability.has_clock_rate) - native.clock_rate = capability.clock_rate; - - if (capability.has_preferred_payload_type) - native.preferred_payload_type = capability.preferred_payload_type; - - if (capability.has_num_channels) - native.num_channels = capability.num_channels; - - for (auto feedback : capability.rtcp_feedback) - native.rtcp_feedback.push_back(to_native_rtcp_feedback(feedback)); - - for (auto pair : capability.parameters) - native.parameters.insert(std::pair(pair.key, pair.value)); - - return native; -} - -webrtc::RtpHeaderExtensionCapability to_native_rtp_header_extension_capability( - RtpHeaderExtensionCapability header) { - webrtc::RtpHeaderExtensionCapability native{}; - native.uri = header.uri.c_str(); - - if (header.has_preferred_id) - native.preferred_id = header.preferred_id; - - native.preferred_encrypt = header.preferred_encrypt; - native.direction = - static_cast(header.direction); - - return native; -} - -webrtc::RtpExtension to_native_rtp_extension(RtpExtension ext) { - webrtc::RtpExtension native{}; - native.uri = ext.uri.c_str(); - native.id = ext.id; - native.encrypt = ext.encrypt; - return native; -} - -webrtc::RtpFecParameters to_rtp_fec_parameters(RtpFecParameters fec) { - webrtc::RtpFecParameters native{}; - - if (fec.has_ssrc) - native.ssrc = fec.ssrc; - - native.mechanism = static_cast(fec.mechanism); - return native; -} - -webrtc::RtpRtxParameters to_rtp_rtx_parameters(RtpRtxParameters rtx) { - webrtc::RtpRtxParameters native{}; - - if (rtx.has_ssrc) - native.ssrc = rtx.ssrc; - return native; -} - -webrtc::RtpEncodingParameters to_native_rtp_encoding_paramters( - RtpEncodingParameters parameters) { - webrtc::RtpEncodingParameters native{}; - native.rid = parameters.rid.c_str(); - - if (parameters.has_ssrc) - native.ssrc = parameters.ssrc; - - native.active = parameters.active; - if (parameters.has_max_framerate) - native.max_framerate = parameters.max_framerate; - - native.adaptive_ptime = parameters.adaptive_ptime; - if (parameters.has_max_bitrate_bps) - native.max_bitrate_bps = parameters.max_bitrate_bps; - - if (parameters.has_min_bitrate_bps) - native.min_bitrate_bps = parameters.min_bitrate_bps; - - native.bitrate_priority = parameters.bitrate_priority; - native.network_priority = - static_cast(parameters.network_priority); - - if (parameters.has_scalability_mode) - native.scalability_mode = parameters.scalability_mode.c_str(); - - if (parameters.has_num_temporal_layers) - native.num_temporal_layers = parameters.num_temporal_layers; - - if (parameters.has_scale_resolution_down_by) - native.scale_resolution_down_by = parameters.scale_resolution_down_by; - return native; -} - -webrtc::RtpCodecParameters to_native_rtp_codec_parameters( - RtpCodecParameters params) { - webrtc::RtpCodecParameters native{}; - native.name = params.name.c_str(); - native.kind = static_cast(params.kind); - native.payload_type = params.payload_type; - - for (auto pair : params.parameters) - native.parameters.insert(std::pair(pair.key, pair.value)); - - for (auto feedback : params.rtcp_feedback) - native.rtcp_feedback.push_back(to_native_rtcp_feedback(feedback)); - - if (params.has_num_channels) - native.num_channels = params.num_channels; - - if (params.has_clock_rate) - native.clock_rate = params.clock_rate; - - return native; -} - -webrtc::RtpCapabilities to_rtp_capabilities(RtpCapabilities capabilities) { - webrtc::RtpCapabilities native{}; - for (auto codec : capabilities.codecs) - native.codecs.push_back(to_native_rtp_codec_capability(codec)); - - for (auto header : capabilities.header_extensions) - native.header_extensions.push_back( - to_native_rtp_header_extension_capability(header)); - - for (auto fec : capabilities.fec) - native.fec.push_back(static_cast(fec)); - - return native; -} - -webrtc::RtcpParameters to_native_rtcp_paramaters(RtcpParameters params) { - webrtc::RtcpParameters native{}; - if (params.has_ssrc) - native.ssrc = params.ssrc; - - native.mux = params.mux; - native.cname = params.cname.c_str(); - native.reduced_size = params.reduced_size; - return native; -} - -webrtc::RtpParameters to_native_rtp_parameters(RtpParameters params) { - webrtc::RtpParameters native{}; - native.transaction_id = params.transaction_id.c_str(); - native.mid = params.mid.c_str(); - - for (auto codec : params.codecs) - native.codecs.push_back(to_native_rtp_codec_parameters(codec)); - - for (auto header : params.header_extensions) - native.header_extensions.push_back(to_native_rtp_extension(header)); - - for (auto encoding : params.encodings) - native.encodings.push_back(to_native_rtp_encoding_paramters(encoding)); - - native.rtcp = to_native_rtcp_paramaters(params.rtcp); - - if (params.has_degradation_preference) - native.degradation_preference = static_cast( - params.degradation_preference); - - return native; -} - -RtcpFeedback to_rust_rtcp_feedback(webrtc::RtcpFeedback feedback) { - RtcpFeedback rust{}; - rust.feedback_type = static_cast(feedback.type); - - if (feedback.message_type.has_value()) { - rust.has_message_type = true; - rust.message_type = - static_cast(feedback.message_type.value()); - } - - return rust; -} - -RtpCodecCapability to_rust_rtp_codec_capability( - webrtc::RtpCodecCapability capability) { - RtpCodecCapability rust{}; - rust.mime_type = capability.mime_type(); - rust.name = capability.name; - rust.kind = static_cast(capability.kind); - - if (capability.clock_rate.has_value()) { - rust.has_clock_rate = true; - rust.clock_rate = capability.clock_rate.value(); - } - - if (capability.preferred_payload_type.has_value()) { - rust.has_preferred_payload_type = true; - rust.preferred_payload_type = capability.preferred_payload_type.value(); - } - - if (capability.num_channels) { - rust.has_num_channels = true; - rust.num_channels = capability.num_channels.value(); - } - - for (auto feedback : capability.rtcp_feedback) - rust.rtcp_feedback.push_back(to_rust_rtcp_feedback(feedback)); - - for (auto param : capability.parameters) - rust.parameters.push_back(StringKeyValue{param.first, param.second}); - - return rust; -} - -RtpHeaderExtensionCapability to_rust_rtp_header_extension_capability( - webrtc::RtpHeaderExtensionCapability header) { - RtpHeaderExtensionCapability rust{}; - rust.uri = header.uri; - if (header.preferred_id.has_value()) { - rust.has_preferred_id = true; - rust.preferred_id = header.preferred_id.value(); - } - - rust.preferred_encrypt = header.preferred_encrypt; - rust.direction = static_cast(header.direction); - return rust; -} - -RtpExtension to_rust_rtp_extension(webrtc::RtpExtension ext) { - RtpExtension rust{}; - rust.uri = ext.uri; - rust.id = ext.id; - rust.encrypt = ext.encrypt; - return rust; -} - -RtpFecParameters to_rust_rtp_fec_parameters(webrtc::RtpFecParameters fec) { - RtpFecParameters rust{}; - if (fec.ssrc.has_value()) { - rust.has_ssrc = true; - rust.ssrc = fec.ssrc.value(); - } - - rust.mechanism = static_cast(rust.mechanism); - return rust; -} - -RtpRtxParameters to_rust_rtp_rtx_parameters(webrtc::RtpRtxParameters param) { - RtpRtxParameters rust{}; - if (param.ssrc.has_value()) { - rust.has_ssrc = param.ssrc.has_value(); - rust.ssrc = param.ssrc.value(); - } - return rust; -} - -RtpEncodingParameters to_rust_rtp_encoding_parameters( - webrtc::RtpEncodingParameters params) { - RtpEncodingParameters rust{}; - if (params.ssrc.has_value()) { - rust.has_ssrc = params.ssrc.has_value(); - rust.ssrc = params.ssrc.value(); - } - - rust.bitrate_priority = params.bitrate_priority; - rust.network_priority = static_cast(params.network_priority); - if (params.max_bitrate_bps.has_value()) { - rust.has_max_bitrate_bps = true; - rust.max_bitrate_bps = params.max_bitrate_bps.value(); - } - - if (params.min_bitrate_bps.has_value()) { - rust.has_min_bitrate_bps = true; - rust.min_bitrate_bps = params.min_bitrate_bps.value(); - } - - if (params.max_framerate.has_value()) { - rust.has_max_framerate = true; - rust.max_framerate = params.max_framerate.value(); - } - - if (params.num_temporal_layers.has_value()) { - rust.has_num_temporal_layers = true; - rust.num_temporal_layers = params.num_temporal_layers.value(); - } - - if (params.scale_resolution_down_by.has_value()) { - rust.has_scale_resolution_down_by = true; - rust.scale_resolution_down_by = params.scale_resolution_down_by.value(); - } - - if (params.scalability_mode.has_value()) { - rust.has_scalability_mode = true; - rust.scalability_mode = params.scalability_mode.value(); - } - - rust.active = params.active; - rust.rid = params.rid; - rust.adaptive_ptime = params.adaptive_ptime; - return rust; -} - -RtpCodecParameters to_rust_rtp_codec_parameters( - webrtc::RtpCodecParameters params) { - RtpCodecParameters rust{}; - rust.mime_type = params.mime_type(); - rust.name = params.name; - rust.kind = static_cast(params.kind); - rust.payload_type = params.payload_type; - if (params.clock_rate.has_value()) { - rust.has_clock_rate = true; - rust.clock_rate = params.clock_rate.value(); - } - - if (params.num_channels.has_value()) { - rust.has_num_channels = true; - rust.num_channels = params.num_channels.value(); - } - - for (auto feedback : params.rtcp_feedback) - rust.rtcp_feedback.push_back(to_rust_rtcp_feedback(feedback)); - - for (auto pair : params.parameters) - rust.parameters.push_back(StringKeyValue{pair.first, pair.second}); - - return rust; -} - -RtpCapabilities to_rust_rtp_capabilities(webrtc::RtpCapabilities capabilities) { - RtpCapabilities rust{}; - for (auto codec : capabilities.codecs) - rust.codecs.push_back(to_rust_rtp_codec_capability(codec)); - - for (auto header : capabilities.header_extensions) - rust.header_extensions.push_back( - to_rust_rtp_header_extension_capability(header)); - - for (auto fec : capabilities.fec) - rust.fec.push_back(static_cast(fec)); - - return rust; -} - -RtcpParameters to_rust_rtcp_parameters(webrtc::RtcpParameters params) { - RtcpParameters rust{}; - if (params.ssrc.has_value()) { - rust.has_ssrc = true; - rust.ssrc = params.ssrc.value(); - } - - rust.cname = params.cname; - rust.reduced_size = params.reduced_size; - rust.mux = params.mux; - return rust; -} - -RtpParameters to_rust_rtp_parameters(webrtc::RtpParameters params) { - RtpParameters rust{}; - rust.transaction_id = params.transaction_id; - rust.mid = params.mid; - - for (auto codec : params.codecs) - rust.codecs.push_back(to_rust_rtp_codec_parameters(codec)); - - for (auto header : params.header_extensions) - rust.header_extensions.push_back(to_rust_rtp_extension(header)); - - for (auto encoding : params.encodings) - rust.encodings.push_back(to_rust_rtp_encoding_parameters(encoding)); - - rust.rtcp = to_rust_rtcp_parameters(params.rtcp); - - if (params.degradation_preference.has_value()) { - rust.has_degradation_preference = true; - rust.degradation_preference = static_cast( - params.degradation_preference.value()); - } - - return rust; -} - -} // namespace livekit diff --git a/webrtc-sys/src/rtp_parameters.rs b/webrtc-sys/src/rtp_parameters.rs deleted file mode 100644 index 7d353bd57..000000000 --- a/webrtc-sys/src/rtp_parameters.rs +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub const DEFAULT_BITRATE_PRIORITY: f64 = 1.0; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - // Used to replace std::map - #[derive(Debug)] - pub struct StringKeyValue { - pub key: String, - pub value: String, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum FecMechanism { - Red, - RedAndUlpfec, - FlexFec, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum RtcpFeedbackType { - Ccm, - Lntf, - Nack, - Remb, - TransportCC, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum RtcpFeedbackMessageType { - GenericNack, - Pli, - Fir, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum DegradationPreference { - Disabled, - MaintainFramerate, - MaintainResolution, - Balanced, - } - - #[derive(Debug)] - pub struct RtcpFeedback { - pub feedback_type: RtcpFeedbackType, - pub has_message_type: bool, - pub message_type: RtcpFeedbackMessageType, - } - - #[derive(Debug)] - pub struct RtpCodecCapability { - pub mime_type: String, // filled with mime_type fnc - pub name: String, - pub kind: MediaType, - pub has_clock_rate: bool, - pub clock_rate: i32, - pub has_preferred_payload_type: bool, - pub preferred_payload_type: i32, - pub has_num_channels: bool, - pub num_channels: i32, - pub rtcp_feedback: Vec, - pub parameters: Vec, - } - - #[derive(Debug)] - pub struct RtpHeaderExtensionCapability { - pub uri: String, - pub has_preferred_id: bool, - pub preferred_id: i32, - pub preferred_encrypt: bool, - pub direction: RtpTransceiverDirection, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum RtpExtensionFilter { - DiscardEncryptedExtension, - PreferEncryptedExtension, - RequireEncryptedExtension, - } - - #[derive(Debug)] - pub struct RtpExtension { - // TODO(theomonnom): export available URI inside api/rtp_parameters.h - pub uri: String, - pub id: i32, - pub encrypt: bool, - } - - #[derive(Debug)] - pub struct RtpFecParameters { - pub has_ssrc: bool, - pub ssrc: u32, - pub mechanism: FecMechanism, - } - - #[derive(Debug)] - pub struct RtpRtxParameters { - pub has_ssrc: bool, - pub ssrc: u32, - } - - #[derive(Debug)] - pub struct RtpEncodingParameters { - pub has_ssrc: bool, - pub ssrc: u32, - pub bitrate_priority: f64, - pub network_priority: Priority, // Todo link type - pub has_max_bitrate_bps: bool, - pub max_bitrate_bps: i32, - pub has_min_bitrate_bps: bool, - pub min_bitrate_bps: i32, - pub has_max_framerate: bool, - pub max_framerate: f64, - pub has_num_temporal_layers: bool, - pub num_temporal_layers: i32, - pub has_scale_resolution_down_by: bool, - pub scale_resolution_down_by: f64, - pub has_scalability_mode: bool, - pub scalability_mode: String, - pub active: bool, - pub rid: String, - pub adaptive_ptime: bool, - } - - #[derive(Debug)] - pub struct RtpCodecParameters { - pub mime_type: String, // filled with mime_type fnc - pub name: String, - pub kind: MediaType, - pub payload_type: i32, - pub has_clock_rate: bool, - pub clock_rate: i32, - pub has_num_channels: bool, - pub num_channels: i32, - pub has_max_ptime: bool, - pub max_ptime: i32, - pub has_ptime: bool, - pub ptime: i32, - pub rtcp_feedback: Vec, - pub parameters: Vec, - } - - #[derive(Debug)] - pub struct RtpCapabilities { - pub codecs: Vec, - pub header_extensions: Vec, - pub fec: Vec, - } - - #[derive(Debug)] - pub struct RtcpParameters { - pub has_ssrc: bool, - pub ssrc: u32, - pub cname: String, - pub reduced_size: bool, - pub mux: bool, - } - - #[derive(Debug)] - pub struct RtpParameters { - pub transaction_id: String, - pub mid: String, - pub codecs: Vec, - pub header_extensions: Vec, - pub encodings: Vec, - pub rtcp: RtcpParameters, - pub has_degradation_preference: bool, - pub degradation_preference: DegradationPreference, - } - - extern "C++" { - include!("livekit/webrtc.h"); - - type Priority = crate::webrtc::ffi::Priority; - type MediaType = crate::webrtc::ffi::MediaType; - type RtpTransceiverDirection = crate::webrtc::ffi::RtpTransceiverDirection; - } -} diff --git a/webrtc-sys/src/rtp_receiver.cpp b/webrtc-sys/src/rtp_receiver.cpp deleted file mode 100644 index 857f7a71a..000000000 --- a/webrtc-sys/src/rtp_receiver.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/rtp_receiver.h" -#include "livekit/jsep.h" - -#include - -#include "absl/types/optional.h" -#include "api/peer_connection_interface.h" -#include "api/scoped_refptr.h" - -namespace livekit { - -RtpReceiver::RtpReceiver( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr receiver, - rtc::scoped_refptr peer_connection) - : rtc_runtime_(rtc_runtime), - receiver_(std::move(receiver)), - peer_connection_(std::move(peer_connection)) {} - -std::shared_ptr RtpReceiver::track() const { - return rtc_runtime_->get_or_create_media_stream_track(receiver_->track()); -} - -rust::Vec RtpReceiver::stream_ids() const { - rust::Vec rust; - for (auto id : receiver_->stream_ids()) - rust.push_back(id); - return rust; -} - -void RtpReceiver::get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const { - auto observer = - rtc::make_ref_counted>(std::move(ctx), on_stats); - peer_connection_->GetStats(receiver_, observer); -} - -rust::Vec RtpReceiver::streams() const { - rust::Vec rust; - for (auto stream : receiver_->streams()) - rust.push_back( - MediaStreamPtr{std::make_shared(rtc_runtime_, stream)}); - return rust; -} - -MediaType RtpReceiver::media_type() const { - return static_cast(receiver_->media_type()); -} - -rust::String RtpReceiver::id() const { - return receiver_->id(); -} - -RtpParameters RtpReceiver::get_parameters() const { - return to_rust_rtp_parameters(receiver_->GetParameters()); -} - -void RtpReceiver::set_jitter_buffer_minimum_delay(bool is_some, - double delay_seconds) const { - receiver_->SetJitterBufferMinimumDelay( - is_some ? absl::make_optional(delay_seconds) : absl::nullopt); -} - -} // namespace livekit diff --git a/webrtc-sys/src/rtp_receiver.rs b/webrtc-sys/src/rtp_receiver.rs deleted file mode 100644 index fb59e61c4..000000000 --- a/webrtc-sys/src/rtp_receiver.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::any::Any; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - extern "C++" { - include!("livekit/webrtc.h"); - include!("livekit/rtp_parameters.h"); - include!("livekit/helper.h"); - include!("livekit/media_stream.h"); - - type MediaType = crate::webrtc::ffi::MediaType; - type RtpParameters = crate::rtp_parameters::ffi::RtpParameters; - type MediaStreamPtr = crate::helper::ffi::MediaStreamPtr; - type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack; - type MediaStream = crate::media_stream::ffi::MediaStream; - } - - unsafe extern "C++" { - include!("livekit/rtp_receiver.h"); - - type RtpReceiver; - - fn track(self: &RtpReceiver) -> SharedPtr; - fn get_stats( - self: &RtpReceiver, - ctx: Box, - on_stats: fn(ctx: Box, json: String), - ); - fn stream_ids(self: &RtpReceiver) -> Vec; - fn streams(self: &RtpReceiver) -> Vec; - fn media_type(self: &RtpReceiver) -> MediaType; - fn id(self: &RtpReceiver) -> String; - fn get_parameters(self: &RtpReceiver) -> RtpParameters; - fn set_jitter_buffer_minimum_delay(self: &RtpReceiver, is_some: bool, delay_seconds: f64); - - fn _shared_rtp_receiver() -> SharedPtr; - } - - extern "Rust" { - type ReceiverContext; - } -} - -pub struct ReceiverContext(pub Box); - -impl_thread_safety!(ffi::RtpReceiver, Send + Sync); diff --git a/webrtc-sys/src/rtp_sender.cpp b/webrtc-sys/src/rtp_sender.cpp deleted file mode 100644 index 8d5008f81..000000000 --- a/webrtc-sys/src/rtp_sender.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/rtp_sender.h" -#include "livekit/jsep.h" - -#include "rust/cxx.h" -#include "webrtc-sys/src/rtp_sender.rs.h" - -namespace livekit { - - - -RtpSender::RtpSender( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr sender, - rtc::scoped_refptr peer_connection) - : rtc_runtime_(rtc_runtime), - sender_(std::move(sender)), - peer_connection_(std::move(peer_connection)) {} - -bool RtpSender::set_track(std::shared_ptr track) const { - return sender_->SetTrack(track->rtc_track().get()); -} - -std::shared_ptr RtpSender::track() const { - return rtc_runtime_->get_or_create_media_stream_track(sender_->track()); -} - -uint32_t RtpSender::ssrc() const { - return sender_->ssrc(); -} - -void RtpSender::get_stats( - rust::Box ctx, - rust::Fn, rust::String)> on_stats) const { - auto observer = - rtc::make_ref_counted>(std::move(ctx), on_stats); - peer_connection_->GetStats(sender_, observer); -} - -MediaType RtpSender::media_type() const { - return static_cast(sender_->media_type()); -} - -rust::String RtpSender::id() const { - return sender_->id(); -} - -rust::Vec RtpSender::stream_ids() const { - rust::Vec vec; - for (auto str : sender_->stream_ids()) - vec.push_back(str); - - return vec; -} - -void RtpSender::set_streams(const rust::Vec& stream_ids) const { - std::vector std_stream_ids(stream_ids.begin(), stream_ids.end()); - sender_->SetStreams(std_stream_ids); -} - -rust::Vec RtpSender::init_send_encodings() const { - rust::Vec encodings; - for (auto encoding : sender_->init_send_encodings()) - encodings.push_back(to_rust_rtp_encoding_parameters(encoding)); - return encodings; -} - -RtpParameters RtpSender::get_parameters() const { - return to_rust_rtp_parameters(sender_->GetParameters()); -} - -void RtpSender::set_parameters(RtpParameters params) const { - auto error = sender_->SetParameters(to_native_rtp_parameters(params)); - if (!error.ok()) - throw std::runtime_error(serialize_error(to_error(error))); -} - -} // namespace livekit diff --git a/webrtc-sys/src/rtp_sender.rs b/webrtc-sys/src/rtp_sender.rs deleted file mode 100644 index af5909a22..000000000 --- a/webrtc-sys/src/rtp_sender.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::any::Any; - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - extern "C++" { - include!("livekit/webrtc.h"); - include!("livekit/rtp_parameters.h"); - include!("livekit/media_stream.h"); - - type MediaType = crate::webrtc::ffi::MediaType; - type RtpEncodingParameters = crate::rtp_parameters::ffi::RtpEncodingParameters; - type RtpParameters = crate::rtp_parameters::ffi::RtpParameters; - type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack; - } - - unsafe extern "C++" { - include!("livekit/rtp_sender.h"); - - type RtpSender; - - fn set_track(self: &RtpSender, track: SharedPtr) -> bool; - fn track(self: &RtpSender) -> SharedPtr; - fn get_stats( - self: &RtpSender, - ctx: Box, - on_stats: fn(ctx: Box, json: String), - ); - fn ssrc(self: &RtpSender) -> u32; - fn media_type(self: &RtpSender) -> MediaType; - fn id(self: &RtpSender) -> String; - fn stream_ids(self: &RtpSender) -> Vec; - fn set_streams(self: &RtpSender, stream_ids: &Vec); - fn init_send_encodings(self: &RtpSender) -> Vec; - fn get_parameters(self: &RtpSender) -> RtpParameters; - fn set_parameters(self: &RtpSender, parameters: RtpParameters) -> Result<()>; - - fn _shared_rtp_sender() -> SharedPtr; - } - - extern "Rust" { - type SenderContext; - } -} - -#[repr(transparent)] -pub struct SenderContext(pub Box); - -impl_thread_safety!(ffi::RtpSender, Send + Sync); diff --git a/webrtc-sys/src/rtp_transceiver.cpp b/webrtc-sys/src/rtp_transceiver.cpp deleted file mode 100644 index 82eb73b2f..000000000 --- a/webrtc-sys/src/rtp_transceiver.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/rtp_transceiver.h" - -#include "api/peer_connection_interface.h" -#include "api/scoped_refptr.h" - -namespace livekit { - -webrtc::RtpTransceiverInit to_native_rtp_transceiver_init( - RtpTransceiverInit init) { - { - webrtc::RtpTransceiverInit native{}; - native.direction = - static_cast(init.direction); - native.stream_ids = std::vector(init.stream_ids.begin(), - init.stream_ids.end()); - for (auto encoding : init.send_encodings) - native.send_encodings.push_back( - to_native_rtp_encoding_paramters(encoding)); - return native; - } -} - -RtpTransceiver::RtpTransceiver( - std::shared_ptr rtc_runtime, - rtc::scoped_refptr transceiver, - rtc::scoped_refptr peer_connection) - : rtc_runtime_(rtc_runtime), - transceiver_(std::move(transceiver)), - peer_connection_(std::move(peer_connection)) {} - -MediaType RtpTransceiver::media_type() const { - return static_cast(transceiver_->media_type()); -} - -rust::String RtpTransceiver::mid() const { - // The error/Result is converted into an Option in Rust (Wait for Option - // suport in cxx.rs) (value throws an error if there's no value) - return transceiver_->mid().value(); -} - -std::shared_ptr RtpTransceiver::sender() const { - return std::make_shared(rtc_runtime_, transceiver_->sender(), - peer_connection_); -} - -std::shared_ptr RtpTransceiver::receiver() const { - return std::make_shared(rtc_runtime_, transceiver_->receiver(), - peer_connection_); -} - -bool RtpTransceiver::stopped() const { - return transceiver_->stopped(); -} - -bool RtpTransceiver::stopping() const { - return transceiver_->stopping(); -} - -RtpTransceiverDirection RtpTransceiver::direction() const { - return static_cast(transceiver_->direction()); -} - -void RtpTransceiver::set_direction(RtpTransceiverDirection direction) const { - auto error = transceiver_->SetDirectionWithError( - static_cast(direction)); - - if (!error.ok()) { - throw std::runtime_error(serialize_error(to_error(error))); - } -} - -RtpTransceiverDirection RtpTransceiver::current_direction() const { - return static_cast( - transceiver_->current_direction().value()); -} - -RtpTransceiverDirection RtpTransceiver::fired_direction() const { - return static_cast( - transceiver_->fired_direction().value()); -} - -void RtpTransceiver::stop_standard() const { - auto error = transceiver_->StopStandard(); - if (!error.ok()) - throw std::runtime_error(serialize_error(to_error(error))); -} - -void RtpTransceiver::set_codec_preferences( - rust::Vec codecs) const { - std::vector std_codecs; - - for (auto codec : codecs) - std_codecs.push_back(to_native_rtp_codec_capability(codec)); - - auto error = transceiver_->SetCodecPreferences(std_codecs); - if (!error.ok()) - throw std::runtime_error(serialize_error(to_error(error))); -} - -rust::Vec RtpTransceiver::codec_preferences() const { - rust::Vec rust; - for (auto codec : transceiver_->codec_preferences()) - rust.push_back(to_rust_rtp_codec_capability(codec)); - - return rust; -} - -rust::Vec -RtpTransceiver::header_extensions_to_negotiate() const { - rust::Vec rust; - for (auto header : transceiver_->GetHeaderExtensionsToNegotiate()) - rust.push_back(to_rust_rtp_header_extension_capability(header)); - - return rust; -} - -rust::Vec -RtpTransceiver::negotiated_header_extensions() const { - rust::Vec rust; - for (auto header : transceiver_->GetNegotiatedHeaderExtensions()) - rust.push_back(to_rust_rtp_header_extension_capability(header)); - - return rust; -} - -void RtpTransceiver::set_header_extensions_to_negotiate( - rust::Vec header_extensions_to_offer) const { - std::vector headers; - - for (auto header : header_extensions_to_offer) - headers.push_back(to_native_rtp_header_extension_capability(header)); - - auto error = transceiver_->SetHeaderExtensionsToNegotiate(headers); - if (!error.ok()) - throw std::runtime_error(serialize_error(to_error(error))); -} - -} // namespace livekit diff --git a/webrtc-sys/src/rtp_transceiver.rs b/webrtc-sys/src/rtp_transceiver.rs deleted file mode 100644 index 0bb2d97d8..000000000 --- a/webrtc-sys/src/rtp_transceiver.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - - #[derive(Debug)] - pub struct RtpTransceiverInit { - pub direction: RtpTransceiverDirection, - pub stream_ids: Vec, - pub send_encodings: Vec, - } - - extern "C++" { - include!("livekit/webrtc.h"); - include!("livekit/rtp_parameters.h"); - include!("livekit/rtp_sender.h"); - include!("livekit/rtp_receiver.h"); - - type MediaType = crate::webrtc::ffi::MediaType; - type RtpTransceiverDirection = crate::webrtc::ffi::RtpTransceiverDirection; - type RtpEncodingParameters = crate::rtp_parameters::ffi::RtpEncodingParameters; - type RtpCodecCapability = crate::rtp_parameters::ffi::RtpCodecCapability; - type RtpHeaderExtensionCapability = - crate::rtp_parameters::ffi::RtpHeaderExtensionCapability; - type RtpSender = crate::rtp_sender::ffi::RtpSender; - type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; - type RtcError = crate::rtc_error::ffi::RtcError; - } - - unsafe extern "C++" { - include!("livekit/rtp_transceiver.h"); - - type RtpTransceiver; - - fn media_type(self: &RtpTransceiver) -> MediaType; - fn mid(self: &RtpTransceiver) -> Result; - fn sender(self: &RtpTransceiver) -> SharedPtr; - fn receiver(self: &RtpTransceiver) -> SharedPtr; - fn stopped(self: &RtpTransceiver) -> bool; - fn stopping(self: &RtpTransceiver) -> bool; - fn direction(self: &RtpTransceiver) -> RtpTransceiverDirection; - fn set_direction(self: &RtpTransceiver, direction: RtpTransceiverDirection) -> Result<()>; - fn current_direction(self: &RtpTransceiver) -> Result; - fn fired_direction(self: &RtpTransceiver) -> Result; - fn stop_standard(self: &RtpTransceiver) -> Result<()>; - fn set_codec_preferences( - self: &RtpTransceiver, - codecs: Vec, - ) -> Result<()>; - fn codec_preferences(self: &RtpTransceiver) -> Vec; - fn header_extensions_to_negotiate( - self: &RtpTransceiver, - ) -> Vec; - fn negotiated_header_extensions(self: &RtpTransceiver) - -> Vec; - fn set_header_extensions_to_negotiate( - self: &RtpTransceiver, - headers: Vec, - ) -> Result<()>; - - fn _shared_rtp_transceiver() -> SharedPtr; - } -} - -impl_thread_safety!(ffi::RtpTransceiver, Send + Sync); diff --git a/webrtc-sys/src/sys/ffi.rs b/webrtc-sys/src/sys/ffi.rs new file mode 100644 index 000000000..b28789f07 --- /dev/null +++ b/webrtc-sys/src/sys/ffi.rs @@ -0,0 +1,651 @@ +/* automatically generated by rust-bindgen 0.69.4 */ + +pub type lkRefCounted = ::std::os::raw::c_void; +pub type lkPeerFactory = ::std::os::raw::c_void; +pub type lkPeer = ::std::os::raw::c_void; +pub type lkDataChannel = ::std::os::raw::c_void; +pub type lkRtpTransceiver = ::std::os::raw::c_void; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkIceTransportType { + LK_ICE_TRANSPORT_TYPE_NONE = 0, + LK_ICE_TRANSPORT_TYPE_RELAY = 1, + LK_ICE_TRANSPORT_TYPE_NO_HOST = 2, + LK_ICE_TRANSPORT_TYPE_ALL = 3, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkContinualGatheringPolicy { + LK_GATHERING_POLICY_ONCE = 0, + LK_GATHERING_POLICY_CONTINUALLY = 1, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkPeerState { + LK_PEER_STATE_NEW = 0, + LK_PEER_STATE_CONNECTING = 1, + LK_PEER_STATE_CONNECTED = 2, + LK_PEER_STATE_DISCONNECTED = 3, + LK_PEER_STATE_FAILED = 4, + LK_PEER_STATE_CLOSED = 5, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkSignalingState { + LK_SIGNALING_STATE_STABLE = 0, + LK_SIGNALING_STATE_HAVE_LOCAL_OFFER = 1, + LK_SIGNALING_STATE_HAVE_LOCAL_PRANSWER = 2, + LK_SIGNALING_STATE_HAVE_REMOTE_OFFER = 3, + LK_SIGNALING_STATE_HAVE_REMOTE_PRANSWER = 4, + LK_SIGNALING_STATE_CLOSED = 5, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkIceState { + LK_ICE_STATE_NEW = 0, + LK_ICE_STATE_CHECKING = 1, + LK_ICE_STATE_CONNECTED = 2, + LK_ICE_STATE_COMPLETED = 3, + LK_ICE_STATE_FAILED = 4, + LK_ICE_STATE_DISCONNECTED = 5, + LK_ICE_STATE_CLOSED = 6, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkSdpType { + LK_SDP_TYPE_OFFER = 0, + LK_SDP_TYPE_PRANSWER = 1, + LK_SDP_TYPE_ANSWER = 2, + LK_SDP_TYPE_ROLLBACK = 3, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum lkDcState { + LK_DC_STATE_CONNECTING = 0, + LK_DC_STATE_OPEN = 1, + LK_DC_STATE_CLOSING = 2, + LK_DC_STATE_CLOSED = 3, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkIceCandidate { + pub sdpMid: *const ::std::os::raw::c_char, + pub sdpMLineIndex: ::std::os::raw::c_int, + pub sdp: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_lkIceCandidate() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(lkIceCandidate)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkIceCandidate)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sdpMid) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkIceCandidate), "::", stringify!(sdpMid)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sdpMLineIndex) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lkIceCandidate), "::", stringify!(sdpMLineIndex)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sdp) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(lkIceCandidate), "::", stringify!(sdp)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkPeerObserver { + pub onSignalingChange: ::std::option::Option< + unsafe extern "C" fn(state: lkSignalingState, userdata: *mut ::std::os::raw::c_void), + >, + pub onIceCandidate: ::std::option::Option< + unsafe extern "C" fn( + candidate: *const lkIceCandidate, + userdata: *mut ::std::os::raw::c_void, + ), + >, + pub onDataChannel: ::std::option::Option< + unsafe extern "C" fn(dc: *const lkDataChannel, userdata: *mut ::std::os::raw::c_void), + >, + pub onTrack: ::std::option::Option< + unsafe extern "C" fn( + transceiver: *const lkRtpTransceiver, + userdata: *mut ::std::os::raw::c_void, + ), + >, + pub onConnectionChange: ::std::option::Option< + unsafe extern "C" fn(state: lkPeerState, userdata: *mut ::std::os::raw::c_void), + >, + pub onIceCandidateError: ::std::option::Option< + unsafe extern "C" fn( + address: *const ::std::os::raw::c_char, + port: ::std::os::raw::c_int, + url: *const ::std::os::raw::c_char, + error_code: ::std::os::raw::c_int, + error_text: *const ::std::os::raw::c_char, + userdata: *mut ::std::os::raw::c_void, + ), + >, +} +#[test] +fn bindgen_test_layout_lkPeerObserver() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(lkPeerObserver)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkPeerObserver)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onSignalingChange) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(lkPeerObserver), + "::", + stringify!(onSignalingChange) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onIceCandidate) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lkPeerObserver), "::", stringify!(onIceCandidate)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onDataChannel) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(lkPeerObserver), "::", stringify!(onDataChannel)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onTrack) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(lkPeerObserver), "::", stringify!(onTrack)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onConnectionChange) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(lkPeerObserver), + "::", + stringify!(onConnectionChange) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onIceCandidateError) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(lkPeerObserver), + "::", + stringify!(onIceCandidateError) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkDataChannelObserver { + pub onStateChange: + ::std::option::Option, + pub onMessage: ::std::option::Option< + unsafe extern "C" fn( + data: *const u8, + size: u64, + binary: bool, + userdata: *mut ::std::os::raw::c_void, + ), + >, + pub onBufferedAmountChange: ::std::option::Option< + unsafe extern "C" fn(sentDataSize: u64, userdata: *mut ::std::os::raw::c_void), + >, +} +#[test] +fn bindgen_test_layout_lkDataChannelObserver() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(lkDataChannelObserver)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkDataChannelObserver)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onStateChange) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(lkDataChannelObserver), + "::", + stringify!(onStateChange) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onMessage) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(lkDataChannelObserver), + "::", + stringify!(onMessage) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onBufferedAmountChange) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(lkDataChannelObserver), + "::", + stringify!(onBufferedAmountChange) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkIceServer { + pub urls: *mut *const ::std::os::raw::c_char, + pub urlsCount: ::std::os::raw::c_int, + pub username: *const ::std::os::raw::c_char, + pub password: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_lkIceServer() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(lkIceServer)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkIceServer)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).urls) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkIceServer), "::", stringify!(urls)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).urlsCount) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lkIceServer), "::", stringify!(urlsCount)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).username) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(lkIceServer), "::", stringify!(username)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).password) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(lkIceServer), "::", stringify!(password)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkRtcConfiguration { + pub iceServers: *mut lkIceServer, + pub iceServersCount: ::std::os::raw::c_int, + pub iceTransportType: lkIceTransportType, + pub gatheringPolicy: lkContinualGatheringPolicy, +} +#[test] +fn bindgen_test_layout_lkRtcConfiguration() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(lkRtcConfiguration)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkRtcConfiguration)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).iceServers) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkRtcConfiguration), "::", stringify!(iceServers)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).iceServersCount) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(lkRtcConfiguration), + "::", + stringify!(iceServersCount) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).iceTransportType) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(lkRtcConfiguration), + "::", + stringify!(iceTransportType) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).gatheringPolicy) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(lkRtcConfiguration), + "::", + stringify!(gatheringPolicy) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkDataChannelInit { + pub reliable: bool, + pub ordered: bool, + pub maxRetransmits: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_lkDataChannelInit() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(lkDataChannelInit)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(lkDataChannelInit)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).reliable) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkDataChannelInit), "::", stringify!(reliable)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).ordered) as usize - ptr as usize }, + 1usize, + concat!("Offset of field: ", stringify!(lkDataChannelInit), "::", stringify!(ordered)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).maxRetransmits) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(lkDataChannelInit), + "::", + stringify!(maxRetransmits) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkRtcError { + pub message: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_lkRtcError() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(lkRtcError)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkRtcError)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).message) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkRtcError), "::", stringify!(message)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkSetSdpObserver { + pub onSuccess: + ::std::option::Option, + pub onFailure: ::std::option::Option< + unsafe extern "C" fn(error: *const lkRtcError, userdata: *mut ::std::os::raw::c_void), + >, +} +#[test] +fn bindgen_test_layout_lkSetSdpObserver() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(lkSetSdpObserver)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkSetSdpObserver)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onSuccess) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkSetSdpObserver), "::", stringify!(onSuccess)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onFailure) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lkSetSdpObserver), "::", stringify!(onFailure)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkCreateSdpObserver { + pub onSuccess: ::std::option::Option< + unsafe extern "C" fn( + type_: lkSdpType, + sdp: *const ::std::os::raw::c_char, + userdata: *mut ::std::os::raw::c_void, + ), + >, + pub onFailure: ::std::option::Option< + unsafe extern "C" fn(error: *const lkRtcError, userdata: *mut ::std::os::raw::c_void), + >, +} +#[test] +fn bindgen_test_layout_lkCreateSdpObserver() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(lkCreateSdpObserver)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(lkCreateSdpObserver)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onSuccess) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(lkCreateSdpObserver), "::", stringify!(onSuccess)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).onFailure) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(lkCreateSdpObserver), "::", stringify!(onFailure)) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lkOfferAnswerOptions { + pub iceRestart: bool, + pub useRtpMux: bool, +} +#[test] +fn bindgen_test_layout_lkOfferAnswerOptions() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 2usize, + concat!("Size of: ", stringify!(lkOfferAnswerOptions)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(lkOfferAnswerOptions)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).iceRestart) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(lkOfferAnswerOptions), + "::", + stringify!(iceRestart) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).useRtpMux) as usize - ptr as usize }, + 1usize, + concat!("Offset of field: ", stringify!(lkOfferAnswerOptions), "::", stringify!(useRtpMux)) + ); +} +extern "C" { + pub fn lkInitialize() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lkDispose() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lkAddRef(rc: *mut lkRefCounted); +} +extern "C" { + pub fn lkReleaseRef(rc: *mut lkRefCounted); +} +extern "C" { + pub fn lkCreatePeerFactory() -> *mut lkPeerFactory; +} +extern "C" { + pub fn lkCreatePeer( + factory: *mut lkPeerFactory, + config: *const lkRtcConfiguration, + observer: *const lkPeerObserver, + userdata: *mut ::std::os::raw::c_void, + ) -> *mut lkPeer; +} +extern "C" { + pub fn lkCreateDataChannel( + peer: *mut lkPeer, + label: *const ::std::os::raw::c_char, + init: *const lkDataChannelInit, + ) -> *mut lkDataChannel; +} +extern "C" { + pub fn lkAddIceCandidate( + peer: *mut lkPeer, + candidate: *const lkIceCandidate, + onComplete: ::std::option::Option< + unsafe extern "C" fn(error: *mut lkRtcError, userdata: *mut ::std::os::raw::c_void), + >, + userdata: *mut ::std::os::raw::c_void, + ) -> bool; +} +extern "C" { + pub fn lkSetLocalDescription( + peer: *mut lkPeer, + type_: lkSdpType, + sdp: *const ::std::os::raw::c_char, + observer: *const lkSetSdpObserver, + userdata: *mut ::std::os::raw::c_void, + ) -> bool; +} +extern "C" { + pub fn lkSetRemoteDescription( + peer: *mut lkPeer, + type_: lkSdpType, + sdp: *const ::std::os::raw::c_char, + observer: *const lkSetSdpObserver, + userdata: *mut ::std::os::raw::c_void, + ) -> bool; +} +extern "C" { + pub fn lkCreateOffer( + peer: *mut lkPeer, + options: *const lkOfferAnswerOptions, + observer: *const lkCreateSdpObserver, + userdata: *mut ::std::os::raw::c_void, + ) -> bool; +} +extern "C" { + pub fn lkCreateAnswer( + peer: *mut lkPeer, + options: *const lkOfferAnswerOptions, + observer: *const lkCreateSdpObserver, + userdata: *mut ::std::os::raw::c_void, + ) -> bool; +} +extern "C" { + pub fn lkPeerSetConfig(peer: *mut lkPeer, config: *const lkRtcConfiguration) -> bool; +} +extern "C" { + pub fn lkPeerClose(peer: *mut lkPeer) -> bool; +} +extern "C" { + pub fn lkDcRegisterObserver( + dc: *mut lkDataChannel, + observer: *const lkDataChannelObserver, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + pub fn lkDcUnregisterObserver(dc: *mut lkDataChannel); +} +extern "C" { + pub fn lkDcGetState(dc: *mut lkDataChannel) -> lkDcState; +} +extern "C" { + pub fn lkDcGetId(dc: *mut lkDataChannel) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lkDcSendAsync( + dc: *mut lkDataChannel, + data: *const u8, + size: u64, + binary: bool, + onComplete: ::std::option::Option< + unsafe extern "C" fn(error: *mut lkRtcError, userdata: *mut ::std::os::raw::c_void), + >, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + pub fn lkDcClose(dc: *mut lkDataChannel); +} diff --git a/webrtc-sys/src/sys/mod.rs b/webrtc-sys/src/sys/mod.rs new file mode 100644 index 000000000..10277d13c --- /dev/null +++ b/webrtc-sys/src/sys/mod.rs @@ -0,0 +1,118 @@ +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +#![allow(non_snake_case)] +#![allow(dead_code)] + +mod ffi; +pub use ffi::*; + +#[cfg(test)] +mod tests { + use super::*; + + // PeerObserver + #[allow(non_snake_case)] + extern "C" fn peerOnSignalChange(state: lkSignalingState, _userdata: *mut std::ffi::c_void) { + println!("OnSignalChange: {:?}", state); + } + + #[allow(non_snake_case)] + extern "C" fn peerOnIceCandidate( + state: *const lkIceCandidate, + _userdata: *mut std::ffi::c_void, + ) { + println!("OnIceCandidate: {:?}", state); + } + + #[allow(non_snake_case)] + extern "C" fn peerOnDataChannel(dc: *const lkDataChannel, _userdata: *mut std::ffi::c_void) { + println!("OnDataChannel: {:?}", dc); + } + + #[allow(non_snake_case)] + extern "C" fn peerOnTrack( + transceiver: *const lkRtpTransceiver, + _userdata: *mut std::ffi::c_void, + ) { + println!("OnTrack: {:?}", transceiver); + } + + #[allow(non_snake_case)] + extern "C" fn peerOnConnectionChange(state: lkPeerState, _userdata: *mut std::ffi::c_void) { + println!("OnConnectionChange: {:?}", state); + } + + #[allow(non_snake_case)] + extern "C" fn peerOnIceCandidateError( + address: *const ::std::os::raw::c_char, + port: ::std::os::raw::c_int, + url: *const ::std::os::raw::c_char, + error_code: ::std::os::raw::c_int, + error_text: *const ::std::os::raw::c_char, + _userdata: *mut std::ffi::c_void, + ) { + println!( + "OnIceCandidateError: {:?} {:?} {:?} {:?} {:?}", + address, port, url, error_code, error_text + ); + } + + // Create SDP observer + #[allow(non_snake_case)] + extern "C" fn createSdpOnSuccess( + sdpType: lkSdpType, + sdp: *const ::std::os::raw::c_char, + _userdata: *mut std::ffi::c_void, + ) { + let sdp = unsafe { std::ffi::CStr::from_ptr(sdp).to_str().unwrap() }; + + println!("CreateSdp - OnSuccess: {:?} {:?}", sdpType, sdp); + } + + #[allow(non_snake_case)] + extern "C" fn createSdpOnFailure(error: *const lkRtcError, _userdata: *mut std::ffi::c_void) { + println!("CreateSdp - OnFailure: {:?}", error); + } + + #[test] + fn test_dc_link() { + unsafe { + let observer = lkPeerObserver { + onSignalingChange: Some(peerOnSignalChange), + onIceCandidate: Some(peerOnIceCandidate), + onDataChannel: Some(peerOnDataChannel), + onTrack: Some(peerOnTrack), + onConnectionChange: Some(peerOnConnectionChange), + onIceCandidateError: Some(peerOnIceCandidateError), + }; + + let create_sdp_observer = lkCreateSdpObserver { + onSuccess: Some(createSdpOnSuccess), + onFailure: Some(createSdpOnFailure), + }; + + let rtc_config = lkRtcConfiguration { + iceServers: std::ptr::null_mut(), + iceServersCount: 0, + iceTransportType: lkIceTransportType::LK_ICE_TRANSPORT_TYPE_ALL, + gatheringPolicy: lkContinualGatheringPolicy::LK_GATHERING_POLICY_CONTINUALLY, + }; + + lkInitialize(); + let factory = lkCreatePeerFactory(); + let peer = lkCreatePeer(factory, &rtc_config, &observer, std::ptr::null_mut()); + + let offer_answer_options = lkOfferAnswerOptions { iceRestart: false, useRtpMux: true }; + assert!(lkCreateOffer( + peer, + &offer_answer_options, + &create_sdp_observer, + std::ptr::null_mut(), + )); + + lkReleaseRef(peer); + lkReleaseRef(factory); + lkDispose(); + } + } +} diff --git a/webrtc-sys/src/video_frame.cpp b/webrtc-sys/src/video_frame.cpp deleted file mode 100644 index ad082bdb8..000000000 --- a/webrtc-sys/src/video_frame.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/video_frame.h" - -#include - -#include "api/video/video_frame.h" - -namespace livekit { -VideoFrame::VideoFrame(const webrtc::VideoFrame& frame) - : frame_(std::move(frame)) {} - -unsigned int VideoFrame::width() const { - return frame_.width(); -} -unsigned int VideoFrame::height() const { - return frame_.height(); -} -uint32_t VideoFrame::size() const { - return frame_.size(); -} -uint16_t VideoFrame::id() const { - return frame_.id(); -} -int64_t VideoFrame::timestamp_us() const { - return frame_.timestamp_us(); -} -int64_t VideoFrame::ntp_time_ms() const { - return frame_.ntp_time_ms(); -} -uint32_t VideoFrame::timestamp() const { - return frame_.timestamp(); -} - -VideoRotation VideoFrame::rotation() const { - return static_cast(frame_.rotation()); -} - -// TODO(theomonnom) This shouldn't create a new shared_ptr at each call -std::unique_ptr VideoFrame::video_frame_buffer() const { - return std::make_unique(frame_.video_frame_buffer()); -} - -webrtc::VideoFrame VideoFrame::get() const { - return frame_; -} - -void VideoFrameBuilder::set_video_frame_buffer(const VideoFrameBuffer& buffer) { - builder_.set_video_frame_buffer(buffer.get()); // const & ref_counted -} - -void VideoFrameBuilder::set_timestamp_us(int64_t timestamp_us) { - builder_.set_timestamp_us(timestamp_us); -} - -void VideoFrameBuilder::set_rotation(VideoRotation rotation) { - builder_.set_rotation(static_cast(rotation)); -} - -void VideoFrameBuilder::set_id(uint16_t id) { - builder_.set_id(id); -} - -std::unique_ptr VideoFrameBuilder::build() { - return std::make_unique(builder_.build()); -} - -std::unique_ptr new_video_frame_builder() { - return std::make_unique(); -} - -} // namespace livekit diff --git a/webrtc-sys/src/video_frame.rs b/webrtc-sys/src/video_frame.rs deleted file mode 100644 index 4aee8873b..000000000 --- a/webrtc-sys/src/video_frame.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum VideoRotation { - VideoRotation0 = 0, - VideoRotation90 = 90, - VideoRotation180 = 180, - VideoRotation270 = 270, - } - - extern "C++" { - include!("livekit/video_frame_buffer.h"); - - type VideoFrameBuffer = crate::video_frame_buffer::ffi::VideoFrameBuffer; - } - - unsafe extern "C++" { - include!("livekit/video_frame.h"); - - type VideoFrame; - - fn width(self: &VideoFrame) -> u32; - fn height(self: &VideoFrame) -> u32; - fn size(self: &VideoFrame) -> u32; - fn id(self: &VideoFrame) -> u16; - fn timestamp_us(self: &VideoFrame) -> i64; - fn ntp_time_ms(self: &VideoFrame) -> i64; - fn timestamp(self: &VideoFrame) -> u32; - fn rotation(self: &VideoFrame) -> VideoRotation; - unsafe fn video_frame_buffer(self: &VideoFrame) -> UniquePtr; - - // VideoFrameBuilder - type VideoFrameBuilder; - fn new_video_frame_builder() -> UniquePtr; - fn set_timestamp_us(self: Pin<&mut VideoFrameBuilder>, timestamp_us: i64); - fn set_rotation(self: Pin<&mut VideoFrameBuilder>, rotation: VideoRotation); - fn set_id(self: Pin<&mut VideoFrameBuilder>, id: u16); - fn set_video_frame_buffer(self: Pin<&mut VideoFrameBuilder>, buffer: &VideoFrameBuffer); - - fn build(self: Pin<&mut VideoFrameBuilder>) -> UniquePtr; - - } -} - -impl_thread_safety!(ffi::VideoFrame, Send + Sync); diff --git a/webrtc-sys/src/video_frame_buffer.cpp b/webrtc-sys/src/video_frame_buffer.cpp deleted file mode 100644 index 3a149644e..000000000 --- a/webrtc-sys/src/video_frame_buffer.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/video_frame_buffer.h" - -#include "api/make_ref_counted.h" - -namespace livekit { - -VideoFrameBuffer::VideoFrameBuffer( - rtc::scoped_refptr buffer) - : buffer_(std::move(buffer)) {} - -VideoFrameBufferType VideoFrameBuffer::buffer_type() const { - return static_cast(buffer_->type()); -} - -unsigned int VideoFrameBuffer::width() const { - return buffer_->width(); -} - -unsigned int VideoFrameBuffer::height() const { - return buffer_->height(); -} - -std::unique_ptr VideoFrameBuffer::to_i420() const { - return std::make_unique(buffer_->ToI420()); -} - -// const_cast is valid here because we take the ownership on the rust side -std::unique_ptr VideoFrameBuffer::get_i420() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetI420()))); -} - -std::unique_ptr VideoFrameBuffer::get_i420a() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetI420A()))); -} - -std::unique_ptr VideoFrameBuffer::get_i422() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetI422()))); -} - -std::unique_ptr VideoFrameBuffer::get_i444() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetI444()))); -} - -std::unique_ptr VideoFrameBuffer::get_i010() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetI010()))); -} - -std::unique_ptr VideoFrameBuffer::get_nv12() { - return std::make_unique( - rtc::scoped_refptr( - const_cast(buffer_->GetNV12()))); -} - -rtc::scoped_refptr VideoFrameBuffer::get() const { - return buffer_; -} - -PlanarYuvBuffer::PlanarYuvBuffer( - rtc::scoped_refptr buffer) - : VideoFrameBuffer(buffer) {} - -unsigned int PlanarYuvBuffer::chroma_width() const { - return buffer()->ChromaWidth(); -} - -unsigned int PlanarYuvBuffer::chroma_height() const { - return buffer()->ChromaHeight(); -} - -unsigned int PlanarYuvBuffer::stride_y() const { - return buffer()->StrideY(); -} - -unsigned int PlanarYuvBuffer::stride_u() const { - return buffer()->StrideU(); -} - -unsigned int PlanarYuvBuffer::stride_v() const { - return buffer()->StrideV(); -} - -webrtc::PlanarYuvBuffer* PlanarYuvBuffer::buffer() const { - return static_cast(buffer_.get()); -} - -PlanarYuv8Buffer::PlanarYuv8Buffer( - rtc::scoped_refptr buffer) - : PlanarYuvBuffer(buffer) {} - -const uint8_t* PlanarYuv8Buffer::data_y() const { - return buffer()->DataY(); -} - -const uint8_t* PlanarYuv8Buffer::data_u() const { - return buffer()->DataU(); -} - -const uint8_t* PlanarYuv8Buffer::data_v() const { - return buffer()->DataV(); -} - -webrtc::PlanarYuv8Buffer* PlanarYuv8Buffer::buffer() const { - return static_cast(buffer_.get()); -} - -PlanarYuv16BBuffer::PlanarYuv16BBuffer( - rtc::scoped_refptr buffer) - : PlanarYuvBuffer(buffer) {} - -const uint16_t* PlanarYuv16BBuffer::data_y() const { - return buffer()->DataY(); -} - -const uint16_t* PlanarYuv16BBuffer::data_u() const { - return buffer()->DataU(); -} - -const uint16_t* PlanarYuv16BBuffer::data_v() const { - return buffer()->DataV(); -} - -webrtc::PlanarYuv16BBuffer* PlanarYuv16BBuffer::buffer() const { - return static_cast(buffer_.get()); -} - -BiplanarYuvBuffer::BiplanarYuvBuffer( - rtc::scoped_refptr buffer) - : VideoFrameBuffer(buffer) {} - -unsigned int BiplanarYuvBuffer::chroma_width() const { - return buffer()->ChromaWidth(); -} - -unsigned int BiplanarYuvBuffer::chroma_height() const { - return buffer()->ChromaHeight(); -} - -unsigned int BiplanarYuvBuffer::stride_y() const { - return buffer()->StrideY(); -} - -unsigned int BiplanarYuvBuffer::stride_uv() const { - return buffer()->StrideUV(); -} - -webrtc::BiplanarYuvBuffer* BiplanarYuvBuffer::buffer() const { - return static_cast(buffer_.get()); -} - -BiplanarYuv8Buffer::BiplanarYuv8Buffer( - rtc::scoped_refptr buffer) - : BiplanarYuvBuffer(buffer) {} - -const uint8_t* BiplanarYuv8Buffer::data_y() const { - return buffer()->DataY(); -} - -const uint8_t* BiplanarYuv8Buffer::data_uv() const { - return buffer()->DataUV(); -} - -webrtc::BiplanarYuv8Buffer* BiplanarYuv8Buffer::buffer() const { - return static_cast(buffer_.get()); -} - -I420Buffer::I420Buffer(rtc::scoped_refptr buffer) - : PlanarYuv8Buffer(buffer) {} - -I420ABuffer::I420ABuffer( - rtc::scoped_refptr buffer) - : I420Buffer(buffer) {} - -unsigned int I420ABuffer::stride_a() const { - return buffer()->StrideA(); -} - -const uint8_t* I420ABuffer::data_a() const { - return buffer()->DataA(); -} - -webrtc::I420ABufferInterface* I420ABuffer::buffer() const { - return static_cast(buffer_.get()); -} - -I422Buffer::I422Buffer(rtc::scoped_refptr buffer) - : PlanarYuv8Buffer(buffer) {} - -I444Buffer::I444Buffer(rtc::scoped_refptr buffer) - : PlanarYuv8Buffer(buffer) {} - -I010Buffer::I010Buffer(rtc::scoped_refptr buffer) - : PlanarYuv16BBuffer(buffer) {} - -NV12Buffer::NV12Buffer(rtc::scoped_refptr buffer) - : BiplanarYuv8Buffer(buffer) {} - -std::unique_ptr copy_i420_buffer( - const std::unique_ptr& i420) { - return std::make_unique(webrtc::I420Buffer::Copy(*i420->get())); -} - -std::unique_ptr new_i420_buffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v) { - return std::make_unique( - webrtc::I420Buffer::Create(width, height, stride_y, stride_u, stride_v)); -} - -std::unique_ptr new_i422_buffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v) { - return std::make_unique( - webrtc::I422Buffer::Create(width, height, stride_y, stride_u, stride_v)); -} - -std::unique_ptr new_i444_buffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v) { - return std::make_unique( - webrtc::I444Buffer::Create(width, height, stride_y, stride_u, stride_v)); -} - -std::unique_ptr new_i010_buffer(int width, - int height, - int stride_y, - int stride_u, - int stride_v) { - return std::make_unique(rtc::make_ref_counted( - width, height, stride_y, stride_u, stride_v)); -} - -std::unique_ptr new_nv12_buffer(int width, - int height, - int stride_y, - int stride_uv) { - return std::make_unique( - webrtc::NV12Buffer::Create(width, height, stride_y, stride_uv)); -} - -} // namespace livekit diff --git a/webrtc-sys/src/video_frame_buffer.rs b/webrtc-sys/src/video_frame_buffer.rs deleted file mode 100644 index 20f8b235e..000000000 --- a/webrtc-sys/src/video_frame_buffer.rs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum VideoFrameBufferType { - Native, - I420, - I420A, - I422, - I444, - I010, - NV12, - } - - unsafe extern "C++" { - include!("livekit/video_frame_buffer.h"); - - type VideoFrameBuffer; - type PlanarYuvBuffer; - type PlanarYuv8Buffer; - type PlanarYuv16BBuffer; - type BiplanarYuvBuffer; - type BiplanarYuv8Buffer; - type I420Buffer; - type I420ABuffer; - type I422Buffer; - type I444Buffer; - type I010Buffer; - type NV12Buffer; - - fn buffer_type(self: &VideoFrameBuffer) -> VideoFrameBufferType; - fn width(self: &VideoFrameBuffer) -> u32; - fn height(self: &VideoFrameBuffer) -> u32; - - /// # SAFETY - /// If the buffer type is I420, the buffer must be cloned before - unsafe fn to_i420(self: &VideoFrameBuffer) -> UniquePtr; - - /// # SAFETY - /// The functions require ownership - unsafe fn get_i420(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - unsafe fn get_i420a(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - unsafe fn get_i422(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - unsafe fn get_i444(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - unsafe fn get_i010(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - unsafe fn get_nv12(self: Pin<&mut VideoFrameBuffer>) -> UniquePtr; - - fn chroma_width(self: &PlanarYuvBuffer) -> u32; - fn chroma_height(self: &PlanarYuvBuffer) -> u32; - fn stride_y(self: &PlanarYuvBuffer) -> u32; - fn stride_u(self: &PlanarYuvBuffer) -> u32; - fn stride_v(self: &PlanarYuvBuffer) -> u32; - - fn data_y(self: &PlanarYuv8Buffer) -> *const u8; - fn data_u(self: &PlanarYuv8Buffer) -> *const u8; - fn data_v(self: &PlanarYuv8Buffer) -> *const u8; - - fn data_y(self: &PlanarYuv16BBuffer) -> *const u16; - fn data_u(self: &PlanarYuv16BBuffer) -> *const u16; - fn data_v(self: &PlanarYuv16BBuffer) -> *const u16; - - fn chroma_width(self: &BiplanarYuvBuffer) -> u32; - fn chroma_height(self: &BiplanarYuvBuffer) -> u32; - fn stride_y(self: &BiplanarYuvBuffer) -> u32; - fn stride_uv(self: &BiplanarYuvBuffer) -> u32; - - fn data_y(self: &BiplanarYuv8Buffer) -> *const u8; - fn data_uv(self: &BiplanarYuv8Buffer) -> *const u8; - - fn stride_a(self: &I420ABuffer) -> u32; - fn data_a(self: &I420ABuffer) -> *const u8; - - fn copy_i420_buffer(i420: &UniquePtr) -> UniquePtr; - fn new_i420_buffer( - width: i32, - height: i32, - stride_y: i32, - stride_u: i32, - stride_v: i32, - ) -> UniquePtr; - - fn new_i422_buffer( - width: i32, - height: i32, - stride_y: i32, - stride_u: i32, - stride_v: i32, - ) -> UniquePtr; - - fn new_i444_buffer( - width: i32, - height: i32, - stride_y: i32, - stride_u: i32, - stride_v: i32, - ) -> UniquePtr; - - fn new_i010_buffer( - width: i32, - height: i32, - stride_y: i32, - stride_u: i32, - stride_v: i32, - ) -> UniquePtr; - - fn new_nv12_buffer( - width: i32, - height: i32, - stride_y: i32, - stride_uv: i32, - ) -> UniquePtr; - - unsafe fn yuv_to_vfb(yuv: *const PlanarYuvBuffer) -> *const VideoFrameBuffer; - unsafe fn biyuv_to_vfb(yuv: *const BiplanarYuvBuffer) -> *const VideoFrameBuffer; - unsafe fn yuv8_to_yuv(yuv8: *const PlanarYuv8Buffer) -> *const PlanarYuvBuffer; - unsafe fn yuv16b_to_yuv(yuv16b: *const PlanarYuv16BBuffer) -> *const PlanarYuvBuffer; - unsafe fn biyuv8_to_biyuv(biyuv8: *const BiplanarYuv8Buffer) -> *const BiplanarYuvBuffer; - unsafe fn i420_to_yuv8(i420: *const I420Buffer) -> *const PlanarYuv8Buffer; - unsafe fn i420a_to_yuv8(i420a: *const I420ABuffer) -> *const PlanarYuv8Buffer; - unsafe fn i422_to_yuv8(i422: *const I422Buffer) -> *const PlanarYuv8Buffer; - unsafe fn i444_to_yuv8(i444: *const I444Buffer) -> *const PlanarYuv8Buffer; - unsafe fn i010_to_yuv16b(i010: *const I010Buffer) -> *const PlanarYuv16BBuffer; - unsafe fn nv12_to_biyuv8(nv12: *const NV12Buffer) -> *const BiplanarYuv8Buffer; - - fn _unique_video_frame_buffer() -> UniquePtr; - } -} - -impl_thread_safety!(ffi::VideoFrameBuffer, Send + Sync); -impl_thread_safety!(ffi::PlanarYuvBuffer, Send + Sync); -impl_thread_safety!(ffi::PlanarYuv8Buffer, Send + Sync); -impl_thread_safety!(ffi::PlanarYuv16BBuffer, Send + Sync); -impl_thread_safety!(ffi::BiplanarYuvBuffer, Send + Sync); -impl_thread_safety!(ffi::BiplanarYuv8Buffer, Send + Sync); -impl_thread_safety!(ffi::I420Buffer, Send + Sync); -impl_thread_safety!(ffi::I420ABuffer, Send + Sync); -impl_thread_safety!(ffi::I422Buffer, Send + Sync); -impl_thread_safety!(ffi::I444Buffer, Send + Sync); -impl_thread_safety!(ffi::I010Buffer, Send + Sync); -impl_thread_safety!(ffi::NV12Buffer, Send + Sync); diff --git a/webrtc-sys/src/video_track.cpp b/webrtc-sys/src/video_track.cpp deleted file mode 100644 index 45e07dcae..000000000 --- a/webrtc-sys/src/video_track.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/video_track.h" - -#include -#include -#include - -#include "api/media_stream_interface.h" -#include "api/video/video_frame.h" -#include "api/video/video_rotation.h" -#include "audio/remix_resample.h" -#include "common_audio/include/audio_util.h" -#include "livekit/media_stream.h" -#include "livekit/video_track.h" -#include "rtc_base/logging.h" -#include "rtc_base/ref_counted_object.h" -#include "rtc_base/synchronization/mutex.h" -#include "rtc_base/time_utils.h" -#include "webrtc-sys/src/video_track.rs.h" - -namespace livekit { - -VideoTrack::VideoTrack(std::shared_ptr rtc_runtime, - rtc::scoped_refptr track) - : MediaStreamTrack(rtc_runtime, std::move(track)) {} - -VideoTrack::~VideoTrack() { - webrtc::MutexLock lock(&mutex_); - for (auto& sink : sinks_) { - track()->RemoveSink(sink.get()); - } -} - -void VideoTrack::add_sink(const std::shared_ptr& sink) const { - webrtc::MutexLock lock(&mutex_); - track()->AddOrUpdateSink(sink.get(), - rtc::VideoSinkWants()); // TODO(theomonnom): Expose - // VideoSinkWants to Rust? - sinks_.push_back(sink); -} - -void VideoTrack::remove_sink( - const std::shared_ptr& sink) const { - webrtc::MutexLock lock(&mutex_); - track()->RemoveSink(sink.get()); - sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); -} - -void VideoTrack::set_should_receive(bool should_receive) const { - track()->set_should_receive(should_receive); -} - -bool VideoTrack::should_receive() const { - return track()->should_receive(); -} - -ContentHint VideoTrack::content_hint() const { - return static_cast(track()->content_hint()); -} - -void VideoTrack::set_content_hint(ContentHint hint) const { - track()->set_content_hint( - static_cast(hint)); -} - -NativeVideoSink::NativeVideoSink(rust::Box observer) - : observer_(std::move(observer)) {} - -void NativeVideoSink::OnFrame(const webrtc::VideoFrame& frame) { - observer_->on_frame(std::make_unique(frame)); -} - -void NativeVideoSink::OnDiscardedFrame() { - observer_->on_discarded_frame(); -} - -void NativeVideoSink::OnConstraintsChanged( - const webrtc::VideoTrackSourceConstraints& constraints) { - VideoTrackSourceConstraints cst; - cst.has_min_fps = constraints.min_fps.has_value(); - cst.min_fps = constraints.min_fps.value_or(0); - cst.has_max_fps = constraints.max_fps.has_value(); - cst.max_fps = constraints.max_fps.value_or(0); - observer_->on_constraints_changed(cst); -} - -std::shared_ptr new_native_video_sink( - rust::Box observer) { - return std::make_shared(std::move(observer)); -} - -VideoTrackSource::InternalSource::InternalSource( - const VideoResolution& resolution) - : rtc::AdaptedVideoTrackSource(4), resolution_(resolution) {} - -VideoTrackSource::InternalSource::~InternalSource() {} - -bool VideoTrackSource::InternalSource::is_screencast() const { - return false; -} - -absl::optional VideoTrackSource::InternalSource::needs_denoising() const { - return false; -} - -webrtc::MediaSourceInterface::SourceState -VideoTrackSource::InternalSource::state() const { - return SourceState::kLive; -} - -bool VideoTrackSource::InternalSource::remote() const { - return false; -} - -VideoResolution VideoTrackSource::InternalSource::video_resolution() const { - webrtc::MutexLock lock(&mutex_); - return resolution_; -} - -bool VideoTrackSource::InternalSource::on_captured_frame( - const webrtc::VideoFrame& frame) { - webrtc::MutexLock lock(&mutex_); - - int64_t aligned_timestamp_us = timestamp_aligner_.TranslateTimestamp( - frame.timestamp_us(), rtc::TimeMicros()); - - rtc::scoped_refptr buffer = - frame.video_frame_buffer(); - - if (resolution_.height == 0 || resolution_.width == 0) { - resolution_ = VideoResolution{static_cast(buffer->width()), - static_cast(buffer->height())}; - } - - int adapted_width, adapted_height, crop_width, crop_height, crop_x, crop_y; - if (!AdaptFrame(buffer->width(), buffer->height(), aligned_timestamp_us, - &adapted_width, &adapted_height, &crop_width, &crop_height, - &crop_x, &crop_y)) { - return false; - } - - if (adapted_width != frame.width() || adapted_height != frame.height()) { - buffer = buffer->CropAndScale(crop_x, crop_y, crop_width, crop_height, - adapted_width, adapted_height); - } - - webrtc::VideoRotation rotation = frame.rotation(); - if (apply_rotation() && rotation != webrtc::kVideoRotation_0) { - // If the buffer is I420, rtc::AdaptedVideoTrackSource will handle the - // rotation for us. - buffer = buffer->ToI420(); - } - - OnFrame(webrtc::VideoFrame::Builder() - .set_video_frame_buffer(buffer) - .set_rotation(rotation) - .set_timestamp_us(aligned_timestamp_us) - .build()); - - return true; -} - -VideoTrackSource::VideoTrackSource(const VideoResolution& resolution) { - source_ = rtc::make_ref_counted(resolution); -} - -VideoResolution VideoTrackSource::video_resolution() const { - return source_->video_resolution(); -} - -bool VideoTrackSource::on_captured_frame( - const std::unique_ptr& frame) const { - auto rtc_frame = frame->get(); - return source_->on_captured_frame(rtc_frame); -} - -rtc::scoped_refptr VideoTrackSource::get() - const { - return source_; -} - -std::shared_ptr new_video_track_source( - const VideoResolution& resolution) { - return std::make_shared(resolution); -} - -} // namespace livekit diff --git a/webrtc-sys/src/video_track.rs b/webrtc-sys/src/video_track.rs deleted file mode 100644 index 09fd22309..000000000 --- a/webrtc-sys/src/video_track.rs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use cxx::UniquePtr; - -use crate::{impl_thread_safety, video_frame::ffi::VideoFrame}; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[repr(i32)] - pub enum ContentHint { - None, - Fluid, - Detailed, - Text, - } - - #[derive(Debug)] - pub struct VideoTrackSourceConstraints { - pub has_min_fps: bool, - pub min_fps: f64, - pub has_max_fps: bool, - pub max_fps: f64, - } - - #[derive(Debug)] - pub struct VideoResolution { - pub width: u32, - pub height: u32, - } - - extern "C++" { - include!("livekit/video_frame.h"); - include!("livekit/media_stream_track.h"); - - type VideoFrame = crate::video_frame::ffi::VideoFrame; - type MediaStreamTrack = crate::media_stream_track::ffi::MediaStreamTrack; - } - - unsafe extern "C++" { - include!("livekit/video_track.h"); - - type VideoTrack; - type NativeVideoSink; - type VideoTrackSource; - - fn add_sink(self: &VideoTrack, sink: &SharedPtr); - fn remove_sink(self: &VideoTrack, sink: &SharedPtr); - fn set_should_receive(self: &VideoTrack, should_receive: bool); - fn should_receive(self: &VideoTrack) -> bool; - fn content_hint(self: &VideoTrack) -> ContentHint; - fn set_content_hint(self: &VideoTrack, hint: ContentHint); - fn new_native_video_sink(observer: Box) -> SharedPtr; - - fn video_resolution(self: &VideoTrackSource) -> VideoResolution; - fn on_captured_frame(self: &VideoTrackSource, frame: &UniquePtr) -> bool; - fn new_video_track_source(resolution: &VideoResolution) -> SharedPtr; - fn video_to_media(track: SharedPtr) -> SharedPtr; - unsafe fn media_to_video(track: SharedPtr) -> SharedPtr; - fn _shared_video_track() -> SharedPtr; - } - - extern "Rust" { - type VideoSinkWrapper; - - fn on_frame(self: &VideoSinkWrapper, frame: UniquePtr); - fn on_discarded_frame(self: &VideoSinkWrapper); - fn on_constraints_changed( - self: &VideoSinkWrapper, - constraints: VideoTrackSourceConstraints, - ); - } -} - -impl_thread_safety!(ffi::VideoTrack, Send + Sync); -impl_thread_safety!(ffi::NativeVideoSink, Send + Sync); -impl_thread_safety!(ffi::VideoTrackSource, Send + Sync); - -pub trait VideoSink: Send { - fn on_frame(&self, frame: UniquePtr); - fn on_discarded_frame(&self); - fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints); -} - -pub struct VideoSinkWrapper { - observer: Arc, -} - -impl VideoSinkWrapper { - pub fn new(observer: Arc) -> Self { - Self { observer } - } - - fn on_frame(&self, frame: UniquePtr) { - self.observer.on_frame(frame); - } - - fn on_discarded_frame(&self) { - self.observer.on_discarded_frame(); - } - - fn on_constraints_changed(&self, constraints: ffi::VideoTrackSourceConstraints) { - self.observer.on_constraints_changed(constraints); - } -} diff --git a/webrtc-sys/src/webrtc.cpp b/webrtc-sys/src/webrtc.cpp deleted file mode 100644 index 7305741c5..000000000 --- a/webrtc-sys/src/webrtc.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2023 LiveKit - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "livekit/webrtc.h" - -#include -#include -#include -#include - -#include "livekit/audio_track.h" -#include "livekit/media_stream_track.h" -#include "livekit/rtp_receiver.h" -#include "livekit/rtp_sender.h" -#include "livekit/video_track.h" -#include "rtc_base/helpers.h" -#include "rtc_base/logging.h" -#include "rtc_base/synchronization/mutex.h" - -#ifdef WEBRTC_WIN -#include "rtc_base/win32.h" -#endif - -namespace livekit { - -static webrtc::Mutex g_mutex{}; -// Can't be atomic, we're using a Mutex because we need to wait for the -// execution of the first init -static uint32_t g_release_counter(0); - -RtcRuntime::RtcRuntime() { - RTC_LOG(LS_VERBOSE) << "RtcRuntime()"; - - { - // Not the best way to do it... - webrtc::MutexLock lock(&g_mutex); - if (g_release_counter == 0) { - RTC_CHECK(rtc::InitializeSSL()) << "Failed to InitializeSSL()"; - -#ifdef WEBRTC_WIN - WSADATA data; - WSAStartup(MAKEWORD(1, 0), &data); -#endif - } - g_release_counter++; - } - - network_thread_ = rtc::Thread::CreateWithSocketServer(); - network_thread_->SetName("network_thread", &network_thread_); - network_thread_->Start(); - worker_thread_ = rtc::Thread::Create(); - worker_thread_->SetName("worker_thread", &worker_thread_); - worker_thread_->Start(); - signaling_thread_ = rtc::Thread::Create(); - signaling_thread_->SetName("signaling_thread", &signaling_thread_); - signaling_thread_->Start(); -} - -RtcRuntime::~RtcRuntime() { - RTC_LOG(LS_VERBOSE) << "~RtcRuntime()"; - - worker_thread_->Stop(); - signaling_thread_->Stop(); - network_thread_->Stop(); - - { - webrtc::MutexLock lock(&g_mutex); - g_release_counter--; - if (g_release_counter == 0) { - RTC_CHECK(rtc::CleanupSSL()) << "Failed to CleanupSSL()"; - -#ifdef WEBRTC_WIN - WSACleanup(); -#endif - } - } -} - -rtc::Thread* RtcRuntime::network_thread() const { - return network_thread_.get(); -} - -rtc::Thread* RtcRuntime::worker_thread() const { - return worker_thread_.get(); -} - -rtc::Thread* RtcRuntime::signaling_thread() const { - return signaling_thread_.get(); -} - -std::shared_ptr RtcRuntime::get_or_create_media_stream_track( - rtc::scoped_refptr rtc_track) { - webrtc::MutexLock lock(&mutex_); - for (std::weak_ptr weak_existing_track : - media_stream_tracks_) { - if (std::shared_ptr existing_track = - weak_existing_track.lock()) { - if (existing_track->rtc_track() == rtc_track) { - return existing_track; - } - } - } - - if (rtc_track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { - std::shared_ptr video_track = - std::shared_ptr(new VideoTrack( - shared_from_this(), - rtc::scoped_refptr( - static_cast(rtc_track.get())))); - - media_stream_tracks_.push_back( - std::static_pointer_cast(video_track)); - return video_track; - } else { - std::shared_ptr audio_track = - std::shared_ptr(new AudioTrack( - shared_from_this(), - rtc::scoped_refptr( - static_cast(rtc_track.get())))); - - media_stream_tracks_.push_back( - std::static_pointer_cast(audio_track)); - return audio_track; - } -} - -std::shared_ptr RtcRuntime::get_or_create_audio_track( - rtc::scoped_refptr track) { - return std::static_pointer_cast( - get_or_create_media_stream_track(track)); -} - -std::shared_ptr RtcRuntime::get_or_create_video_track( - rtc::scoped_refptr track) { - return std::static_pointer_cast( - get_or_create_media_stream_track(track)); -} - -LogSink::LogSink( - rust::Fn fnc) - : fnc_(fnc) { - rtc::LogMessage::AddLogToStream(this, rtc::LoggingSeverity::LS_VERBOSE); -} - -LogSink::~LogSink() { - rtc::LogMessage::RemoveLogToStream(this); -} - -void LogSink::OnLogMessage(const std::string& message, - rtc::LoggingSeverity severity) { - fnc_(rust::String::lossy(message), static_cast(severity)); -} - -std::unique_ptr new_log_sink( - rust::Fn fnc) { - return std::make_unique(fnc); -} - -rust::String create_random_uuid() { - return rtc::CreateRandomUuid(); -} - -} // namespace livekit diff --git a/webrtc-sys/src/webrtc.rs b/webrtc-sys/src/webrtc.rs deleted file mode 100644 index 62ff24e99..000000000 --- a/webrtc-sys/src/webrtc.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::impl_thread_safety; - -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - #[derive(Debug)] - #[repr(i32)] - pub enum MediaType { - Audio, - Video, - Data, - Unsupported, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum Priority { - VeryLow, - Low, - Medium, - High, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum RtpTransceiverDirection { - SendRecv, - SendOnly, - RecvOnly, - Inactive, - Stopped, - } - - #[derive(Debug)] - #[repr(i32)] - pub enum LoggingSeverity { - Verbose, - Info, - Warning, - Error, - None, - } - - unsafe extern "C++" { - include!("livekit/webrtc.h"); - - type LogSink; - - fn create_random_uuid() -> String; - fn new_log_sink(fnc: fn(String, LoggingSeverity)) -> UniquePtr; - } -} - -impl_thread_safety!(ffi::LogSink, Send + Sync); diff --git a/webrtc-sys/src/yuv_helper.rs b/webrtc-sys/src/yuv_helper.rs deleted file mode 100644 index c1ddb5c6e..000000000 --- a/webrtc-sys/src/yuv_helper.rs +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[allow(clippy::too_many_arguments)] -#[allow(clippy::missing_safety_doc)] -#[cxx::bridge(namespace = "livekit")] -pub mod ffi { - unsafe extern "C++" { - include!("livekit/yuv_helper.h"); - - unsafe fn i420_to_argb( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_argb: *mut u8, - dst_stride_argb: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i420_to_bgra( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_bgra: *mut u8, - dst_stride_bgra: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i420_to_abgr( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i420_to_rgba( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_rgba: *mut u8, - dst_stride_rgba: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn argb_to_i420( - src_argb: *const u8, - src_stride_argb: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn abgr_to_i420( - src_abgr: *const u8, - src_stride_abgr: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn argb_to_rgb24( - src_argb: *const u8, - src_stride_argb: i32, - dst_rgb24: *mut u8, - dst_stride_rgb24: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn nv12_to_i420( - src_y: *const u8, - src_stride_y: i32, - src_uv: *const u8, - src_stride_uv: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i444_to_i420( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i422_to_i420( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i010_to_i420( - src_y: *const u16, - src_stride_y: i32, - src_u: *const u16, - src_stride_u: i32, - src_v: *const u16, - src_stride_v: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_u: *mut u8, - dst_stride_u: i32, - dst_v: *mut u8, - dst_stride_v: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn nv12_to_argb( - src_y: *const u8, - src_stride_y: i32, - src_uv: *const u8, - src_stride_uv: i32, - dst_argb: *mut u8, - dst_stride_argb: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn nv12_to_abgr( - src_y: *const u8, - src_stride_y: i32, - src_uv: *const u8, - src_stride_uv: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i444_to_argb( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i444_to_abgr( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i422_to_argb( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_argb: *mut u8, - dst_stride_argb: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i422_to_abgr( - src_y: *const u8, - src_stride_y: i32, - src_u: *const u8, - src_stride_u: i32, - src_v: *const u8, - src_stride_v: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i010_to_argb( - src_y: *const u16, - src_stride_y: i32, - src_u: *const u16, - src_stride_u: i32, - src_v: *const u16, - src_stride_v: i32, - dst_argb: *mut u8, - dst_stride_argb: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn i010_to_abgr( - src_y: *const u16, - src_stride_y: i32, - src_u: *const u16, - src_stride_u: i32, - src_v: *const u16, - src_stride_v: i32, - dst_abgr: *mut u8, - dst_stride_abgr: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn abgr_to_nv12( - src_abgr: *const u8, - src_stride_abgr: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_uv: *mut u8, - dst_stride_uv: i32, - width: i32, - height: i32, - ) -> Result<()>; - - unsafe fn argb_to_nv12( - src_argb: *const u8, - src_stride_argb: i32, - dst_y: *mut u8, - dst_stride_y: i32, - dst_uv: *mut u8, - dst_stride_uv: i32, - width: i32, - height: i32, - ) -> Result<()>; - } -} From ffe9bd1540d519dcf7169ecdcb147ff95803b657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Mon, 17 Jun 2024 18:53:28 +0200 Subject: [PATCH 4/5] changing branch --- webrtc-sys/src/lib.rs | 5 ++- webrtc-sys/src/peer.rs | 52 +++++++++++++++++++++++++++++ webrtc-sys/src/peer_connection.rs | 3 -- webrtc-sys/src/sys/conv.rs | 1 + webrtc-sys/src/sys/mod.rs | 4 +++ webrtc-sys/src/sys/refcounted.rs | 54 +++++++++++++++++++++++++++++++ 6 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 webrtc-sys/src/peer.rs delete mode 100644 webrtc-sys/src/peer_connection.rs create mode 100644 webrtc-sys/src/sys/conv.rs create mode 100644 webrtc-sys/src/sys/refcounted.rs diff --git a/webrtc-sys/src/lib.rs b/webrtc-sys/src/lib.rs index 0758ba4a8..b26cf6c97 100644 --- a/webrtc-sys/src/lib.rs +++ b/webrtc-sys/src/lib.rs @@ -12,4 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod sys; +mod peer; +mod sys; + +pub use peer::*; diff --git a/webrtc-sys/src/peer.rs b/webrtc-sys/src/peer.rs new file mode 100644 index 000000000..145e683fe --- /dev/null +++ b/webrtc-sys/src/peer.rs @@ -0,0 +1,52 @@ +use crate::sys; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum IceTransportType { + None, + Relay, + All, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum ContinualGatheringPolicy { + GatherContinually, + GatherOnce, +} + +#[derive(Debug, Clone)] +pub struct IceServer { + pub urls: Vec, + pub username: String, + pub credential: String, +} + +#[derive(Debug, Clone)] +pub struct RtcConfiguration { + pub ice_servers: Vec, + pub ice_transport_type: IceTransportType, + pub continual_gathering_policy: ContinualGatheringPolicy, +} + +#[derive(Debug)] +pub struct PeerFactory { + factory: sys::RefCounted, +} + +impl Default for PeerFactory { + fn default() -> Self { + unsafe { + let factory = sys::lkCreatePeerFactory(); + Self { factory: sys::RefCounted::from_raw(factory) } + } + } +} + +impl PeerFactory { + pub fn create_peer(&self, config: &RtcConfiguration) -> Peer { + todo!() + } +} + +pub struct Peer {} + +impl Peer {} diff --git a/webrtc-sys/src/peer_connection.rs b/webrtc-sys/src/peer_connection.rs deleted file mode 100644 index 701c58eb2..000000000 --- a/webrtc-sys/src/peer_connection.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub struct PeerConnection {} - -impl PeerConnection {} diff --git a/webrtc-sys/src/sys/conv.rs b/webrtc-sys/src/sys/conv.rs new file mode 100644 index 000000000..b6779aa34 --- /dev/null +++ b/webrtc-sys/src/sys/conv.rs @@ -0,0 +1 @@ +use crate::{sys, ContinualGatheringPolicy, IceServer, IceTransportType, RtcConfiguration}; diff --git a/webrtc-sys/src/sys/mod.rs b/webrtc-sys/src/sys/mod.rs index 10277d13c..6f32129f7 100644 --- a/webrtc-sys/src/sys/mod.rs +++ b/webrtc-sys/src/sys/mod.rs @@ -3,8 +3,12 @@ #![allow(non_snake_case)] #![allow(dead_code)] +mod conv; mod ffi; +mod refcounted; + pub use ffi::*; +pub use refcounted::*; #[cfg(test)] mod tests { diff --git a/webrtc-sys/src/sys/refcounted.rs b/webrtc-sys/src/sys/refcounted.rs new file mode 100644 index 000000000..c81daa049 --- /dev/null +++ b/webrtc-sys/src/sys/refcounted.rs @@ -0,0 +1,54 @@ +use std::fmt::Debug; + +use crate::sys; + +#[repr(transparent)] +pub struct RefCounted { + ptr: *mut T, +} + +impl RefCounted { + /// # Safety + /// The ptr must be owned and implement rtc::RefCountInterface + pub unsafe fn from_raw(owned_ptr: *mut T) -> Self { + RefCounted { ptr: owned_ptr } + } + + pub fn as_ptr(&self) -> *mut T { + self.ptr + } + + pub fn is_null(&self) -> bool { + self.ptr.is_null() + } +} + +impl Clone for RefCounted { + fn clone(&self) -> Self { + // increase refcount + unsafe { + if !self.is_null() { + sys::lkAddRef(self.ptr as *mut _); + } + + Self::from_raw(self.ptr) + } + } +} + +impl Drop for RefCounted { + fn drop(&mut self) { + unsafe { + if !self.is_null() { + sys::lkReleaseRef(self.ptr as *mut _); + } + } + } +} + +impl Debug for RefCounted { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let type_name = std::any::type_name::(); + write!(f, "RefCounted<{}>({:p})", type_name, self.ptr) + } +} From 4a28e91a79c441a389f1515ec4f97820e8deee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Mon, 26 Aug 2024 22:03:47 -0700 Subject: [PATCH 5/5] wip --- libwebrtc/src/native/android.rs | 21 - libwebrtc/src/native/audio_resampler.rs | 53 -- libwebrtc/src/native/audio_source.rs | 192 ---- libwebrtc/src/native/audio_stream.rs | 87 -- libwebrtc/src/native/audio_track.rs | 33 - libwebrtc/src/native/data_channel.rs | 138 --- libwebrtc/src/native/frame_cryptor.rs | 213 ----- libwebrtc/src/native/ice_candidate.rs | 60 -- libwebrtc/src/native/media_stream.rs | 49 -- libwebrtc/src/native/media_stream_track.rs | 78 -- libwebrtc/src/native/mod.rs | 67 -- libwebrtc/src/native/peer_connection.rs | 619 ------------- .../src/native/peer_connection_factory.rs | 119 --- libwebrtc/src/native/rtp_parameters.rs | 262 ------ libwebrtc/src/native/rtp_receiver.rs | 65 -- libwebrtc/src/native/rtp_sender.rs | 83 -- libwebrtc/src/native/rtp_transceiver.rs | 98 --- libwebrtc/src/native/session_description.rs | 82 -- libwebrtc/src/native/video_frame.rs | 828 ------------------ libwebrtc/src/native/video_source.rs | 115 --- libwebrtc/src/native/video_stream.rs | 94 -- libwebrtc/src/native/video_track.rs | 33 - libwebrtc/src/native/yuv_helper.rs | 823 ----------------- libwebrtc/src/web/data_channel.rs | 117 --- libwebrtc/src/web/media_stream.rs | 372 -------- libwebrtc/src/web/mod.rs | 15 - 26 files changed, 4716 deletions(-) delete mode 100644 libwebrtc/src/native/android.rs delete mode 100644 libwebrtc/src/native/audio_resampler.rs delete mode 100644 libwebrtc/src/native/audio_source.rs delete mode 100644 libwebrtc/src/native/audio_stream.rs delete mode 100644 libwebrtc/src/native/audio_track.rs delete mode 100644 libwebrtc/src/native/data_channel.rs delete mode 100644 libwebrtc/src/native/frame_cryptor.rs delete mode 100644 libwebrtc/src/native/ice_candidate.rs delete mode 100644 libwebrtc/src/native/media_stream.rs delete mode 100644 libwebrtc/src/native/media_stream_track.rs delete mode 100644 libwebrtc/src/native/mod.rs delete mode 100644 libwebrtc/src/native/peer_connection.rs delete mode 100644 libwebrtc/src/native/peer_connection_factory.rs delete mode 100644 libwebrtc/src/native/rtp_parameters.rs delete mode 100644 libwebrtc/src/native/rtp_receiver.rs delete mode 100644 libwebrtc/src/native/rtp_sender.rs delete mode 100644 libwebrtc/src/native/rtp_transceiver.rs delete mode 100644 libwebrtc/src/native/session_description.rs delete mode 100644 libwebrtc/src/native/video_frame.rs delete mode 100644 libwebrtc/src/native/video_source.rs delete mode 100644 libwebrtc/src/native/video_stream.rs delete mode 100644 libwebrtc/src/native/video_track.rs delete mode 100644 libwebrtc/src/native/yuv_helper.rs delete mode 100644 libwebrtc/src/web/data_channel.rs delete mode 100644 libwebrtc/src/web/media_stream.rs delete mode 100644 libwebrtc/src/web/mod.rs diff --git a/libwebrtc/src/native/android.rs b/libwebrtc/src/native/android.rs deleted file mode 100644 index 42d193aa2..000000000 --- a/libwebrtc/src/native/android.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use webrtc_sys::android::ffi as sys_android; - -pub fn initialize_android(vm: &jni::JavaVM) { - unsafe { - sys_android::init_android(vm.get_java_vm_pointer() as *mut _); - } -} diff --git a/libwebrtc/src/native/audio_resampler.rs b/libwebrtc/src/native/audio_resampler.rs deleted file mode 100644 index 17913f974..000000000 --- a/libwebrtc/src/native/audio_resampler.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::UniquePtr; -use webrtc_sys::audio_resampler as sys_ar; - -pub struct AudioResampler { - sys_handle: UniquePtr, -} - -impl Default for AudioResampler { - fn default() -> Self { - Self { sys_handle: sys_ar::ffi::create_audio_resampler() } - } -} - -impl AudioResampler { - pub fn remix_and_resample<'a>( - &'a mut self, - src: &[i16], - samples_per_channel: u32, - num_channels: u32, - sample_rate: u32, - dst_num_channels: u32, - dst_sample_rate: u32, - ) -> &'a [i16] { - assert!(src.len() >= (samples_per_channel * num_channels) as usize, "src buffer too small"); - - unsafe { - let len = self.sys_handle.pin_mut().remix_and_resample( - src.as_ptr(), - samples_per_channel as usize, - num_channels as usize, - sample_rate as i32, - dst_num_channels as usize, - dst_sample_rate as i32, - ); - - std::slice::from_raw_parts(self.sys_handle.data(), len / 2) - } - } -} diff --git a/libwebrtc/src/native/audio_source.rs b/libwebrtc/src/native/audio_source.rs deleted file mode 100644 index 62f357609..000000000 --- a/libwebrtc/src/native/audio_source.rs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{sync::Arc, time::Duration}; - -use cxx::SharedPtr; -use livekit_runtime::interval; -use tokio::sync::{ - mpsc::{self, error::TryRecvError}, - Mutex as AsyncMutex, -}; -use webrtc_sys::audio_track as sys_at; - -use crate::{audio_frame::AudioFrame, audio_source::AudioSourceOptions, RtcError, RtcErrorType}; - -const BUFFER_SIZE_MS: usize = 50; - -#[derive(Clone)] -pub struct NativeAudioSource { - sys_handle: SharedPtr, - inner: Arc>, - sample_rate: u32, - num_channels: u32, - samples_10ms: usize, - po_tx: mpsc::Sender>, -} - -struct AudioSourceInner { - buf: Box<[i16]>, - - // Amount of data from the previous frame that hasn't been sent to the libwebrtc source - // (because it requires 10ms of data) - len: usize, -} - -impl NativeAudioSource { - pub fn new( - options: AudioSourceOptions, - sample_rate: u32, - num_channels: u32, - ) -> NativeAudioSource { - let samples_10ms = (sample_rate / 100 * num_channels) as usize; - let (po_tx, mut po_rx) = mpsc::channel(BUFFER_SIZE_MS / 10); - - let source = Self { - sys_handle: sys_at::ffi::new_audio_track_source(options.into()), - inner: Arc::new(AsyncMutex::new(AudioSourceInner { - buf: vec![0; samples_10ms].into_boxed_slice(), - len: 0, - })), - sample_rate, - num_channels, - samples_10ms, - po_tx, - }; - - livekit_runtime::spawn({ - let source = source.clone(); - async move { - let mut interval = interval(Duration::from_millis(10)); - interval.set_missed_tick_behavior(livekit_runtime::MissedTickBehavior::Delay); - let blank_data = vec![0; samples_10ms]; - - loop { - interval.tick().await; - - let frame = po_rx.try_recv(); - if let Err(TryRecvError::Disconnected) = frame { - break; - } - - if let Err(TryRecvError::Empty) = frame { - source.sys_handle.on_captured_frame( - &blank_data, - sample_rate, - num_channels, - blank_data.len() / num_channels as usize, - ); - continue; - } - - let frame = frame.unwrap(); - source.sys_handle.on_captured_frame( - &frame, - sample_rate, - num_channels, - frame.len() / num_channels as usize, - ); - } - } - }); - - source - } - - pub fn sys_handle(&self) -> SharedPtr { - self.sys_handle.clone() - } - - pub fn set_audio_options(&self, options: AudioSourceOptions) { - self.sys_handle.set_audio_options(&sys_at::ffi::AudioSourceOptions::from(options)) - } - - pub fn audio_options(&self) -> AudioSourceOptions { - self.sys_handle.audio_options().into() - } - - pub fn sample_rate(&self) -> u32 { - self.sample_rate - } - - pub fn num_channels(&self) -> u32 { - self.num_channels - } - - pub async fn capture_frame(&self, frame: &AudioFrame<'_>) -> Result<(), RtcError> { - if self.sample_rate != frame.sample_rate || self.num_channels != frame.num_channels { - return Err(RtcError { - error_type: RtcErrorType::InvalidState, - message: "sample_rate and num_channels don't match".to_owned(), - }); - } - - let mut inner = self.inner.lock().await; - let mut samples = 0; - - // split frames into 10ms chunks - loop { - let remaining_samples = frame.data.len() - samples; - if remaining_samples == 0 { - break; - } - - if (inner.len != 0 && remaining_samples > 0) || remaining_samples < self.samples_10ms { - let missing_len = self.samples_10ms - inner.len; - let to_add = missing_len.min(remaining_samples); - let start = inner.len; - inner.buf[start..start + to_add] - .copy_from_slice(&frame.data[samples..samples + to_add]); - inner.len += to_add; - samples += to_add; - - if inner.len == self.samples_10ms { - let data = inner.buf.clone().to_vec(); - let _ = self.po_tx.send(data).await; - inner.len = 0; - } - continue; - } - - if remaining_samples >= self.samples_10ms { - // TODO(theomonnom): avoid copying - let data = frame.data[samples..samples + self.samples_10ms].to_vec(); - let _ = self.po_tx.send(data).await; - samples += self.samples_10ms; - } - } - - Ok(()) - } -} - -impl From for AudioSourceOptions { - fn from(options: sys_at::ffi::AudioSourceOptions) -> Self { - Self { - echo_cancellation: options.echo_cancellation, - noise_suppression: options.noise_suppression, - auto_gain_control: options.auto_gain_control, - } - } -} - -impl From for sys_at::ffi::AudioSourceOptions { - fn from(options: AudioSourceOptions) -> Self { - Self { - echo_cancellation: options.echo_cancellation, - noise_suppression: options.noise_suppression, - auto_gain_control: options.auto_gain_control, - } - } -} diff --git a/libwebrtc/src/native/audio_stream.rs b/libwebrtc/src/native/audio_stream.rs deleted file mode 100644 index b86229109..000000000 --- a/libwebrtc/src/native/audio_stream.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; - -use cxx::SharedPtr; -use tokio::sync::mpsc; -use tokio_stream::Stream; -use webrtc_sys::audio_track as sys_at; - -use crate::{audio_frame::AudioFrame, audio_track::RtcAudioTrack}; - -pub struct NativeAudioStream { - native_sink: SharedPtr, - audio_track: RtcAudioTrack, - frame_rx: mpsc::UnboundedReceiver>, -} - -impl NativeAudioStream { - pub fn new(audio_track: RtcAudioTrack) -> Self { - let (frame_tx, frame_rx) = mpsc::unbounded_channel(); - let observer = Arc::new(AudioTrackObserver { frame_tx }); - let native_sink = sys_at::ffi::new_native_audio_sink(Box::new( - sys_at::AudioSinkWrapper::new(observer.clone()), - )); - - let audio = unsafe { sys_at::ffi::media_to_audio(audio_track.sys_handle()) }; - audio.add_sink(&native_sink); - - Self { native_sink, audio_track, frame_rx } - } - - pub fn track(&self) -> RtcAudioTrack { - self.audio_track.clone() - } - - pub fn close(&mut self) { - let audio = unsafe { sys_at::ffi::media_to_audio(self.audio_track.sys_handle()) }; - audio.remove_sink(&self.native_sink); - - self.frame_rx.close(); - } -} - -impl Drop for NativeAudioStream { - fn drop(&mut self) { - self.close(); - } -} - -impl Stream for NativeAudioStream { - type Item = AudioFrame<'static>; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { - self.frame_rx.poll_recv(cx) - } -} - -pub struct AudioTrackObserver { - frame_tx: mpsc::UnboundedSender>, -} - -impl sys_at::AudioSink for AudioTrackObserver { - fn on_data(&self, data: &[i16], sample_rate: i32, nb_channels: usize, nb_frames: usize) { - let _ = self.frame_tx.send(AudioFrame { - data: data.to_owned().into(), - sample_rate: sample_rate as u32, - num_channels: nb_channels as u32, - samples_per_channel: nb_frames as u32, - }); - } -} diff --git a/libwebrtc/src/native/audio_track.rs b/libwebrtc/src/native/audio_track.rs deleted file mode 100644 index 8718b709c..000000000 --- a/libwebrtc/src/native/audio_track.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use sys_at::ffi::audio_to_media; -use webrtc_sys::audio_track as sys_at; - -use super::media_stream_track::impl_media_stream_track; -use crate::media_stream_track::RtcTrackState; - -#[derive(Clone)] -pub struct RtcAudioTrack { - pub(crate) sys_handle: SharedPtr, -} - -impl RtcAudioTrack { - impl_media_stream_track!(audio_to_media); - - pub fn sys_handle(&self) -> SharedPtr { - audio_to_media(self.sys_handle.clone()) - } -} diff --git a/libwebrtc/src/native/data_channel.rs b/libwebrtc/src/native/data_channel.rs deleted file mode 100644 index ba36f041e..000000000 --- a/libwebrtc/src/native/data_channel.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{str, sync::Arc}; - -use cxx::SharedPtr; -use parking_lot::Mutex; -use webrtc_sys::data_channel as sys_dc; - -use crate::data_channel::{ - DataBuffer, DataChannelError, DataChannelInit, DataChannelState, OnBufferedAmountChange, - OnMessage, OnStateChange, -}; - -impl From for DataChannelState { - fn from(value: sys_dc::ffi::DataState) -> Self { - match value { - sys_dc::ffi::DataState::Connecting => Self::Connecting, - sys_dc::ffi::DataState::Open => Self::Open, - sys_dc::ffi::DataState::Closing => Self::Closing, - sys_dc::ffi::DataState::Closed => Self::Closed, - _ => panic!("unknown data channel state"), - } - } -} - -impl From for sys_dc::ffi::DataChannelInit { - fn from(value: DataChannelInit) -> Self { - Self { - ordered: value.ordered, - has_max_retransmit_time: value.max_retransmit_time.is_some(), - max_retransmit_time: value.max_retransmit_time.unwrap_or_default(), - has_max_retransmits: value.max_retransmits.is_some(), - max_retransmits: value.max_retransmits.unwrap_or_default(), - protocol: value.protocol, - id: value.id, - has_priority: false, - priority: sys_dc::ffi::Priority::Medium, - negotiated: value.negotiated, - } - } -} - -#[derive(Clone)] -pub struct DataChannel { - observer: Arc, - pub(crate) sys_handle: SharedPtr, -} - -impl DataChannel { - pub fn configure(sys_handle: SharedPtr) -> Self { - let observer = Arc::new(DataChannelObserver::default()); - let dc = Self { sys_handle: sys_handle.clone(), observer: observer.clone() }; - - dc.sys_handle - .register_observer(Box::new(sys_dc::DataChannelObserverWrapper::new(observer))); - dc - } - - pub fn send(&self, data: &[u8], binary: bool) -> Result<(), DataChannelError> { - if !binary { - str::from_utf8(data)?; - } - - let buffer = sys_dc::ffi::DataBuffer { ptr: data.as_ptr(), len: data.len(), binary }; - - self.sys_handle.send(&buffer).then_some(()).ok_or(DataChannelError::Send) - } - - pub fn id(&self) -> i32 { - self.sys_handle.id() - } - - pub fn label(&self) -> String { - self.sys_handle.label() - } - - pub fn state(&self) -> DataChannelState { - self.sys_handle.state().into() - } - - pub fn close(&self) { - self.sys_handle.close(); - } - - pub fn on_state_change(&self, handler: Option) { - *self.observer.state_change_handler.lock() = handler; - } - - pub fn on_message(&self, handler: Option) { - *self.observer.message_handler.lock() = handler; - } - - pub fn on_buffered_amount_change(&self, handler: Option) { - *self.observer.buffered_amount_change_handler.lock() = handler; - } -} - -#[derive(Default)] -struct DataChannelObserver { - state_change_handler: Mutex>, - message_handler: Mutex>, - buffered_amount_change_handler: Mutex>, -} - -impl sys_dc::DataChannelObserver for DataChannelObserver { - fn on_state_change(&self, state: sys_dc::ffi::DataState) { - let mut handler = self.state_change_handler.lock(); - if let Some(f) = handler.as_mut() { - f(state.into()); - } - } - - fn on_message(&self, data: &[u8], binary: bool) { - let mut handler = self.message_handler.lock(); - if let Some(f) = handler.as_mut() { - f(DataBuffer { data, binary }); - } - } - - fn on_buffered_amount_change(&self, sent_data_size: u64) { - let mut handler = self.buffered_amount_change_handler.lock(); - if let Some(f) = handler.as_mut() { - f(sent_data_size); - } - } -} diff --git a/libwebrtc/src/native/frame_cryptor.rs b/libwebrtc/src/native/frame_cryptor.rs deleted file mode 100644 index 8f64e7711..000000000 --- a/libwebrtc/src/native/frame_cryptor.rs +++ /dev/null @@ -1,213 +0,0 @@ -use std::sync::Arc; - -use cxx::SharedPtr; -use parking_lot::Mutex; -use webrtc_sys::frame_cryptor::{self as sys_fc}; - -use crate::{ - peer_connection_factory::PeerConnectionFactory, rtp_receiver::RtpReceiver, - rtp_sender::RtpSender, -}; - -pub type OnStateChange = Box; - -#[derive(Debug, Clone)] -pub struct KeyProviderOptions { - pub shared_key: bool, - pub ratchet_window_size: i32, - pub ratchet_salt: Vec, - pub failure_tolerance: i32, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum EncryptionAlgorithm { - AesGcm, - AesCbc, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum EncryptionState { - New, - Ok, - EncryptionFailed, - DecryptionFailed, - MissingKey, - KeyRatcheted, - InternalError, -} - -#[derive(Clone)] -pub struct KeyProvider { - pub(crate) sys_handle: SharedPtr, -} - -impl KeyProvider { - pub fn new(options: KeyProviderOptions) -> Self { - Self { sys_handle: sys_fc::ffi::new_key_provider(options.into()) } - } - - pub fn set_shared_key(&self, key_index: i32, key: Vec) -> bool { - self.sys_handle.set_shared_key(key_index, key) - } - - pub fn ratchet_shared_key(&self, key_index: i32) -> Option> { - self.sys_handle.ratchet_shared_key(key_index).ok() - } - - pub fn get_shared_key(&self, key_index: i32) -> Option> { - self.sys_handle.get_shared_key(key_index).ok() - } - - pub fn set_key(&self, participant_id: String, key_index: i32, key: Vec) -> bool { - self.sys_handle.set_key(participant_id, key_index, key) - } - - pub fn ratchet_key(&self, participant_id: String, key_index: i32) -> Option> { - self.sys_handle.ratchet_key(participant_id, key_index).ok() - } - - pub fn get_key(&self, participant_id: String, key_index: i32) -> Option> { - self.sys_handle.get_key(participant_id, key_index).ok() - } - - pub fn set_sif_trailer(&self, trailer: Vec) { - self.sys_handle.set_sif_trailer(trailer); - } -} - -#[derive(Clone)] -pub struct FrameCryptor { - observer: Arc, - pub(crate) sys_handle: SharedPtr, -} - -impl FrameCryptor { - pub fn new_for_rtp_sender( - peer_factory: &PeerConnectionFactory, - participant_id: String, - algorithm: EncryptionAlgorithm, - key_provider: KeyProvider, - sender: RtpSender, - ) -> Self { - let observer = Arc::new(RtcFrameCryptorObserver::default()); - let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_sender( - peer_factory.handle.sys_handle.clone(), - participant_id, - algorithm.into(), - key_provider.sys_handle, - sender.handle.sys_handle, - ); - let fc = Self { observer: observer.clone(), sys_handle: sys_handle.clone() }; - fc.sys_handle - .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new(observer))); - fc - } - - pub fn new_for_rtp_receiver( - peer_factory: &PeerConnectionFactory, - participant_id: String, - algorithm: EncryptionAlgorithm, - key_provider: KeyProvider, - receiver: RtpReceiver, - ) -> Self { - let observer = Arc::new(RtcFrameCryptorObserver::default()); - let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_receiver( - peer_factory.handle.sys_handle.clone(), - participant_id, - algorithm.into(), - key_provider.sys_handle, - receiver.handle.sys_handle, - ); - let fc = Self { observer: observer.clone(), sys_handle: sys_handle.clone() }; - fc.sys_handle - .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new(observer))); - fc - } - - pub fn set_enabled(self: &FrameCryptor, enabled: bool) { - self.sys_handle.set_enabled(enabled); - } - - pub fn enabled(self: &FrameCryptor) -> bool { - self.sys_handle.enabled() - } - - pub fn set_key_index(self: &FrameCryptor, index: i32) { - self.sys_handle.set_key_index(index); - } - - pub fn key_index(self: &FrameCryptor) -> i32 { - self.sys_handle.key_index() - } - - pub fn participant_id(self: &FrameCryptor) -> String { - self.sys_handle.participant_id() - } - - pub fn on_state_change(&self, handler: Option) { - *self.observer.state_change_handler.lock() = handler; - } -} - -#[derive(Default)] -struct RtcFrameCryptorObserver { - state_change_handler: Mutex>, -} - -impl sys_fc::RtcFrameCryptorObserver for RtcFrameCryptorObserver { - fn on_frame_cryption_state_change( - &self, - participant_id: String, - state: sys_fc::ffi::FrameCryptionState, - ) { - let mut handler = self.state_change_handler.lock(); - if let Some(f) = handler.as_mut() { - f(participant_id, state.into()); - } - } -} - -impl From for EncryptionAlgorithm { - fn from(value: sys_fc::ffi::Algorithm) -> Self { - match value { - sys_fc::ffi::Algorithm::AesGcm => Self::AesGcm, - sys_fc::ffi::Algorithm::AesCbc => Self::AesCbc, - _ => panic!("unknown frame cyrptor Algorithm"), - } - } -} - -impl From for sys_fc::ffi::Algorithm { - fn from(value: EncryptionAlgorithm) -> Self { - match value { - EncryptionAlgorithm::AesGcm => Self::AesGcm, - EncryptionAlgorithm::AesCbc => Self::AesCbc, - } - } -} - -impl From for EncryptionState { - fn from(value: sys_fc::ffi::FrameCryptionState) -> Self { - match value { - sys_fc::ffi::FrameCryptionState::New => Self::New, - sys_fc::ffi::FrameCryptionState::Ok => Self::Ok, - sys_fc::ffi::FrameCryptionState::EncryptionFailed => Self::EncryptionFailed, - sys_fc::ffi::FrameCryptionState::DecryptionFailed => Self::DecryptionFailed, - sys_fc::ffi::FrameCryptionState::MissingKey => Self::MissingKey, - sys_fc::ffi::FrameCryptionState::KeyRatcheted => Self::KeyRatcheted, - sys_fc::ffi::FrameCryptionState::InternalError => Self::InternalError, - _ => panic!("unknown frame cyrptor FrameCryptionState"), - } - } -} - -impl From for sys_fc::ffi::KeyProviderOptions { - fn from(value: KeyProviderOptions) -> Self { - Self { - shared_key: value.shared_key, - ratchet_window_size: value.ratchet_window_size, - ratchet_salt: value.ratchet_salt, - failure_tolerance: value.failure_tolerance, - } - } -} diff --git a/libwebrtc/src/native/ice_candidate.rs b/libwebrtc/src/native/ice_candidate.rs deleted file mode 100644 index b26f10d34..000000000 --- a/libwebrtc/src/native/ice_candidate.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use webrtc_sys::jsep as sys_jsep; - -use crate::{ice_candidate as ic, session_description::SdpParseError}; - -#[derive(Clone)] -pub struct IceCandidate { - pub(crate) sys_handle: SharedPtr, -} - -impl IceCandidate { - pub fn parse( - sdp_mid: &str, - sdp_mline_index: i32, - sdp: &str, - ) -> Result { - let res = sys_jsep::ffi::create_ice_candidate( - sdp_mid.to_string(), - sdp_mline_index, - sdp.to_string(), - ); - - match res { - Ok(sys_handle) => Ok(ic::IceCandidate { handle: IceCandidate { sys_handle } }), - Err(e) => Err(unsafe { sys_jsep::ffi::SdpParseError::from(e.what()).into() }), - } - } - - pub fn sdp_mid(&self) -> String { - self.sys_handle.sdp_mid() - } - - pub fn sdp_mline_index(&self) -> i32 { - self.sys_handle.sdp_mline_index() - } - - pub fn candidate(&self) -> String { - self.sys_handle.candidate() - } -} - -impl ToString for IceCandidate { - fn to_string(&self) -> String { - self.sys_handle.stringify() - } -} diff --git a/libwebrtc/src/native/media_stream.rs b/libwebrtc/src/native/media_stream.rs deleted file mode 100644 index c2259d121..000000000 --- a/libwebrtc/src/native/media_stream.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use webrtc_sys::media_stream as sys_ms; - -use crate::{ - audio_track, - imp::{audio_track::RtcAudioTrack, video_track::RtcVideoTrack}, - video_track, -}; - -#[derive(Clone)] -pub struct MediaStream { - pub(crate) sys_handle: SharedPtr, -} - -impl MediaStream { - pub fn id(&self) -> String { - self.sys_handle.id() - } - - pub fn audio_tracks(&self) -> Vec { - self.sys_handle - .get_audio_tracks() - .into_iter() - .map(|t| audio_track::RtcAudioTrack { handle: RtcAudioTrack { sys_handle: t.ptr } }) - .collect() - } - - pub fn video_tracks(&self) -> Vec { - self.sys_handle - .get_video_tracks() - .into_iter() - .map(|t| video_track::RtcVideoTrack { handle: RtcVideoTrack { sys_handle: t.ptr } }) - .collect() - } -} diff --git a/libwebrtc/src/native/media_stream_track.rs b/libwebrtc/src/native/media_stream_track.rs deleted file mode 100644 index 4e96109af..000000000 --- a/libwebrtc/src/native/media_stream_track.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use webrtc_sys::{ - audio_track::ffi::media_to_audio, media_stream_track as sys_mst, - video_track::ffi::media_to_video, MEDIA_TYPE_AUDIO, MEDIA_TYPE_VIDEO, -}; - -use crate::{ - audio_track, - imp::{audio_track::RtcAudioTrack, video_track::RtcVideoTrack}, - media_stream_track::{MediaStreamTrack, RtcTrackState}, - video_track, -}; - -impl From for RtcTrackState { - fn from(state: sys_mst::ffi::TrackState) -> Self { - match state { - sys_mst::ffi::TrackState::Live => RtcTrackState::Live, - sys_mst::ffi::TrackState::Ended => RtcTrackState::Ended, - _ => panic!("unknown TrackState"), - } - } -} - -pub fn new_media_stream_track( - sys_handle: SharedPtr, -) -> MediaStreamTrack { - if sys_handle.kind() == MEDIA_TYPE_AUDIO { - MediaStreamTrack::Audio(audio_track::RtcAudioTrack { - handle: RtcAudioTrack { sys_handle: unsafe { media_to_audio(sys_handle) } }, - }) - } else if sys_handle.kind() == MEDIA_TYPE_VIDEO { - MediaStreamTrack::Video(video_track::RtcVideoTrack { - handle: RtcVideoTrack { sys_handle: unsafe { media_to_video(sys_handle) } }, - }) - } else { - panic!("unknown track kind") - } -} - -macro_rules! impl_media_stream_track { - ($cast:expr) => { - pub fn id(&self) -> String { - let ptr = $cast(self.sys_handle.clone()); - ptr.id() - } - - pub fn enabled(&self) -> bool { - let ptr = $cast(self.sys_handle.clone()); - ptr.enabled() - } - - pub fn set_enabled(&self, enabled: bool) -> bool { - let ptr = $cast(self.sys_handle.clone()); - ptr.set_enabled(enabled) - } - - pub fn state(&self) -> RtcTrackState { - let ptr = $cast(self.sys_handle.clone()); - ptr.state().into() - } - }; -} - -pub(super) use impl_media_stream_track; diff --git a/libwebrtc/src/native/mod.rs b/libwebrtc/src/native/mod.rs deleted file mode 100644 index 4abae953a..000000000 --- a/libwebrtc/src/native/mod.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#[cfg(target_os = "android")] -pub mod android; -pub mod audio_resampler; -pub mod audio_source; -pub mod audio_stream; -pub mod audio_track; -pub mod data_channel; -pub mod frame_cryptor; -pub mod ice_candidate; -pub mod media_stream; -pub mod media_stream_track; -pub mod peer_connection; -pub mod peer_connection_factory; -pub mod rtp_parameters; -pub mod rtp_receiver; -pub mod rtp_sender; -pub mod rtp_transceiver; -pub mod session_description; -pub mod video_frame; -pub mod video_source; -pub mod video_stream; -pub mod video_track; -pub mod yuv_helper; - -use webrtc_sys::{rtc_error as sys_err, webrtc as sys_rtc}; - -use crate::{MediaType, RtcError, RtcErrorType}; - -impl From for RtcErrorType { - fn from(value: sys_err::ffi::RtcErrorType) -> Self { - match value { - sys_err::ffi::RtcErrorType::InvalidState => Self::InvalidState, - _ => Self::Internal, - } - } -} - -impl From for RtcError { - fn from(value: sys_err::ffi::RtcError) -> Self { - Self { error_type: value.error_type.into(), message: value.message } - } -} - -impl From for sys_rtc::ffi::MediaType { - fn from(value: MediaType) -> Self { - match value { - MediaType::Audio => Self::Audio, - MediaType::Video => Self::Video, - MediaType::Data => Self::Data, - MediaType::Unsupported => Self::Unsupported, - } - } -} diff --git a/libwebrtc/src/native/peer_connection.rs b/libwebrtc/src/native/peer_connection.rs deleted file mode 100644 index 769df7491..000000000 --- a/libwebrtc/src/native/peer_connection.rs +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use cxx::SharedPtr; -use parking_lot::Mutex; -use tokio::sync::{mpsc, oneshot}; -use webrtc_sys::{ - data_channel as sys_dc, jsep as sys_jsep, peer_connection as sys_pc, - peer_connection_factory as sys_pcf, rtc_error as sys_err, -}; - -use crate::{ - data_channel::{DataChannel, DataChannelInit}, - ice_candidate::IceCandidate, - imp::{ - data_channel as imp_dc, ice_candidate as imp_ic, media_stream as imp_ms, - media_stream_track as imp_mst, rtp_receiver as imp_rr, rtp_sender as imp_rs, - rtp_transceiver as imp_rt, session_description as imp_sdp, - }, - media_stream::MediaStream, - media_stream_track::MediaStreamTrack, - peer_connection::{ - AnswerOptions, IceCandidateError, IceConnectionState, IceGatheringState, OfferOptions, - OnConnectionChange, OnDataChannel, OnIceCandidate, OnIceCandidateError, - OnIceConnectionChange, OnIceGatheringChange, OnNegotiationNeeded, OnSignalingChange, - OnTrack, PeerConnectionState, SignalingState, TrackEvent, - }, - peer_connection_factory::{ - ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration, - }, - rtp_receiver::RtpReceiver, - rtp_sender::RtpSender, - rtp_transceiver::{RtpTransceiver, RtpTransceiverInit}, - session_description::SessionDescription, - stats::RtcStats, - MediaType, RtcError, RtcErrorType, -}; - -impl From for sys_pc::ffi::RtcOfferAnswerOptions { - fn from(options: OfferOptions) -> Self { - Self { - ice_restart: options.ice_restart, - offer_to_receive_audio: options.offer_to_receive_audio as i32, - offer_to_receive_video: options.offer_to_receive_video as i32, - ..Default::default() - } - } -} - -impl From for sys_pc::ffi::RtcOfferAnswerOptions { - fn from(_options: AnswerOptions) -> Self { - Self::default() - } -} - -impl From for PeerConnectionState { - fn from(state: sys_pc::ffi::PeerConnectionState) -> Self { - match state { - sys_pc::ffi::PeerConnectionState::New => PeerConnectionState::New, - sys_pc::ffi::PeerConnectionState::Connecting => PeerConnectionState::Connecting, - sys_pc::ffi::PeerConnectionState::Connected => PeerConnectionState::Connected, - sys_pc::ffi::PeerConnectionState::Disconnected => PeerConnectionState::Disconnected, - sys_pc::ffi::PeerConnectionState::Failed => PeerConnectionState::Failed, - sys_pc::ffi::PeerConnectionState::Closed => PeerConnectionState::Closed, - _ => panic!("unknown PeerConnectionState"), - } - } -} - -impl From for IceConnectionState { - fn from(state: sys_pc::ffi::IceConnectionState) -> Self { - match state { - sys_pc::ffi::IceConnectionState::IceConnectionNew => IceConnectionState::New, - sys_pc::ffi::IceConnectionState::IceConnectionChecking => IceConnectionState::Checking, - sys_pc::ffi::IceConnectionState::IceConnectionConnected => { - IceConnectionState::Connected - } - sys_pc::ffi::IceConnectionState::IceConnectionCompleted => { - IceConnectionState::Completed - } - sys_pc::ffi::IceConnectionState::IceConnectionFailed => IceConnectionState::Failed, - sys_pc::ffi::IceConnectionState::IceConnectionDisconnected => { - IceConnectionState::Disconnected - } - sys_pc::ffi::IceConnectionState::IceConnectionClosed => IceConnectionState::Closed, - sys_pc::ffi::IceConnectionState::IceConnectionMax => IceConnectionState::Max, - _ => panic!("unknown IceConnectionState"), - } - } -} - -impl From for IceGatheringState { - fn from(state: sys_pc::ffi::IceGatheringState) -> Self { - match state { - sys_pc::ffi::IceGatheringState::IceGatheringNew => IceGatheringState::New, - sys_pc::ffi::IceGatheringState::IceGatheringGathering => IceGatheringState::Gathering, - sys_pc::ffi::IceGatheringState::IceGatheringComplete => IceGatheringState::Complete, - _ => panic!("unknown IceGatheringState"), - } - } -} - -impl From for SignalingState { - fn from(state: sys_pc::ffi::SignalingState) -> Self { - match state { - sys_pc::ffi::SignalingState::Stable => SignalingState::Stable, - sys_pc::ffi::SignalingState::HaveLocalOffer => SignalingState::HaveLocalOffer, - sys_pc::ffi::SignalingState::HaveRemoteOffer => SignalingState::HaveRemoteOffer, - sys_pc::ffi::SignalingState::HaveLocalPrAnswer => SignalingState::HaveLocalPrAnswer, - sys_pc::ffi::SignalingState::HaveRemotePrAnswer => SignalingState::HaveRemotePrAnswer, - sys_pc::ffi::SignalingState::Closed => SignalingState::Closed, - _ => panic!("unknown SignalingState"), - } - } -} - -impl From for sys_pc::ffi::IceServer { - fn from(value: IceServer) -> Self { - sys_pc::ffi::IceServer { - urls: value.urls, - username: value.username, - password: value.password, - } - } -} - -impl From for sys_pc::ffi::ContinualGatheringPolicy { - fn from(value: ContinualGatheringPolicy) -> Self { - match value { - ContinualGatheringPolicy::GatherOnce => { - sys_pc::ffi::ContinualGatheringPolicy::GatherOnce - } - ContinualGatheringPolicy::GatherContinually => { - sys_pc::ffi::ContinualGatheringPolicy::GatherContinually - } - } - } -} - -impl From for sys_pc::ffi::IceTransportsType { - fn from(value: IceTransportsType) -> Self { - match value { - IceTransportsType::Relay => sys_pc::ffi::IceTransportsType::Relay, - IceTransportsType::NoHost => sys_pc::ffi::IceTransportsType::NoHost, - IceTransportsType::All => sys_pc::ffi::IceTransportsType::All, - } - } -} - -impl From for sys_pc::ffi::RtcConfiguration { - fn from(value: RtcConfiguration) -> Self { - Self { - ice_servers: value.ice_servers.into_iter().map(Into::into).collect(), - continual_gathering_policy: value.continual_gathering_policy.into(), - ice_transport_type: value.ice_transport_type.into(), - } - } -} - -#[derive(Clone)] -pub struct PeerConnection { - observer: Arc, - pub(crate) sys_handle: SharedPtr, -} - -impl PeerConnection { - pub fn configure( - sys_handle: SharedPtr, - observer: Arc, - ) -> Self { - Self { sys_handle, observer } - } - - pub fn set_configuration(&self, config: RtcConfiguration) -> Result<(), RtcError> { - let res = self.sys_handle.set_configuration(config.into()); - - match res { - Ok(_) => Ok(()), - Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, - } - } - - pub async fn create_offer( - &self, - options: OfferOptions, - ) -> Result { - let (tx, mut rx) = mpsc::channel::>(1); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - type CtxType = mpsc::Sender>; - - self.sys_handle.create_offer( - options.into(), - ctx, - |ctx, sdp| { - let tx = *ctx.0.downcast::().unwrap(); - let _ = tx.blocking_send(Ok(SessionDescription { - handle: imp_sdp::SessionDescription { sys_handle: sdp }, - })); - }, - |ctx, error| { - let tx = *ctx.0.downcast::().unwrap(); - let _ = tx.blocking_send(Err(error.into())); - }, - ); - - rx.recv().await.unwrap() - } - - pub async fn create_answer( - &self, - options: AnswerOptions, - ) -> Result { - let (tx, mut rx) = mpsc::channel::>(1); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - type CtxType = mpsc::Sender>; - - self.sys_handle.create_answer( - options.into(), - ctx, - |ctx, sdp| { - let tx = *ctx.0.downcast::().unwrap(); - let _ = tx.blocking_send(Ok(SessionDescription { - handle: imp_sdp::SessionDescription { sys_handle: sdp }, - })); - }, - |ctx, error| { - let tx = *ctx.0.downcast::().unwrap(); - let _ = tx.blocking_send(Err(error.into())); - }, - ); - - rx.recv().await.unwrap() - } - - pub async fn set_local_description(&self, desc: SessionDescription) -> Result<(), RtcError> { - let (tx, rx) = oneshot::channel::>(); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - - self.sys_handle.set_local_description(desc.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx.0.downcast::>>().unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); - - rx.await.unwrap() - } - - pub async fn set_remote_description(&self, desc: SessionDescription) -> Result<(), RtcError> { - let (tx, rx) = oneshot::channel::>(); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - - self.sys_handle.set_remote_description(desc.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx.0.downcast::>>().unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); - - rx.await.map_err(|_| RtcError { - error_type: RtcErrorType::Internal, - message: "set_remote_description cancelled".to_owned(), - })? - } - - pub async fn add_ice_candidate(&self, candidate: IceCandidate) -> Result<(), RtcError> { - let (tx, rx) = oneshot::channel::>(); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - - self.sys_handle.add_ice_candidate(candidate.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx.0.downcast::>>().unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); - - rx.await.map_err(|_| RtcError { - error_type: RtcErrorType::Internal, - message: "add_ice_candidate cancelled".to_owned(), - })? - } - - pub fn create_data_channel( - &self, - label: &str, - init: DataChannelInit, - ) -> Result { - let res = self.sys_handle.create_data_channel(label.to_string(), init.into()); - - match res { - Ok(sys_handle) => { - Ok(DataChannel { handle: imp_dc::DataChannel::configure(sys_handle) }) - } - Err(e) => Err(unsafe { sys_err::ffi::RtcError::from(e.what()).into() }), - } - } - - pub fn add_track>( - &self, - track: MediaStreamTrack, - stream_ids: &[T], - ) -> Result { - let stream_ids = stream_ids.iter().map(|s| s.as_ref().to_owned()).collect(); - let res = self.sys_handle.add_track(track.sys_handle(), &stream_ids); - - match res { - Ok(sys_handle) => Ok(RtpSender { handle: imp_rs::RtpSender { sys_handle } }), - Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, - } - } - - pub fn add_transceiver( - &self, - track: MediaStreamTrack, - init: RtpTransceiverInit, - ) -> Result { - let res = self.sys_handle.add_transceiver(track.sys_handle(), init.into()); - - match res { - Ok(sys_handle) => Ok(RtpTransceiver { handle: imp_rt::RtpTransceiver { sys_handle } }), - Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, - } - } - - pub fn add_transceiver_for_media( - &self, - media_type: MediaType, - init: RtpTransceiverInit, - ) -> Result { - let res = self.sys_handle.add_transceiver_for_media(media_type.into(), init.into()); - - match res { - Ok(cxx_handle) => { - Ok(RtpTransceiver { handle: imp_rt::RtpTransceiver { sys_handle: cxx_handle } }) - } - Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, - } - } - - pub fn restart_ice(&self) { - self.sys_handle.restart_ice(); - } - - pub fn close(&self) { - self.sys_handle.close(); - } - - pub fn connection_state(&self) -> PeerConnectionState { - self.sys_handle.connection_state().into() - } - - pub fn ice_connection_state(&self) -> IceConnectionState { - self.sys_handle.ice_connection_state().into() - } - - pub fn ice_gathering_state(&self) -> IceGatheringState { - self.sys_handle.ice_gathering_state().into() - } - - pub fn signaling_state(&self) -> SignalingState { - self.sys_handle.signaling_state().into() - } - - pub fn current_local_description(&self) -> Option { - let sdp = self.sys_handle.current_local_description(); - if sdp.is_null() { - return None; - } - - Some(SessionDescription { handle: imp_sdp::SessionDescription { sys_handle: sdp } }) - } - - pub fn current_remote_description(&self) -> Option { - let sdp = self.sys_handle.current_remote_description(); - if sdp.is_null() { - return None; - } - - Some(SessionDescription { handle: imp_sdp::SessionDescription { sys_handle: sdp } }) - } - - pub fn remove_track(&self, sender: RtpSender) -> Result<(), RtcError> { - self.sys_handle - .remove_track(sender.handle.sys_handle) - .map_err(|e| unsafe { sys_err::ffi::RtcError::from(e.what()).into() }) - } - - pub async fn get_stats(&self) -> Result, RtcError> { - let (tx, rx) = oneshot::channel::, RtcError>>(); - let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - - self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx.0.downcast::, RtcError>>>().unwrap(); - - if stats.is_empty() { - let _ = tx.send(Ok(vec![])); - return; - } - - // Unwrap because it should not happens - let vec = serde_json::from_str(&stats).unwrap(); - let _ = tx.send(Ok(vec)); - }); - - rx.await.map_err(|_| RtcError { - error_type: RtcErrorType::Internal, - message: "get_stats cancelled".to_owned(), - })? - } - - pub fn senders(&self) -> Vec { - self.sys_handle - .get_senders() - .into_iter() - .map(|sender| RtpSender { handle: imp_rs::RtpSender { sys_handle: sender.ptr } }) - .collect() - } - - pub fn receivers(&self) -> Vec { - self.sys_handle - .get_receivers() - .into_iter() - .map(|receiver| RtpReceiver { - handle: imp_rr::RtpReceiver { sys_handle: receiver.ptr }, - }) - .collect() - } - - pub fn transceivers(&self) -> Vec { - self.sys_handle - .get_transceivers() - .into_iter() - .map(|transceiver| RtpTransceiver { - handle: imp_rt::RtpTransceiver { sys_handle: transceiver.ptr }, - }) - .collect() - } - - pub fn on_connection_state_change(&self, f: Option) { - *self.observer.connection_change_handler.lock() = f; - } - - pub fn on_data_channel(&self, f: Option) { - *self.observer.data_channel_handler.lock() = f; - } - - pub fn on_ice_candidate(&self, f: Option) { - *self.observer.ice_candidate_handler.lock() = f; - } - - pub fn on_ice_candidate_error(&self, f: Option) { - *self.observer.ice_candidate_error_handler.lock() = f; - } - - pub fn on_ice_connection_state_change(&self, f: Option) { - *self.observer.ice_connection_change_handler.lock() = f; - } - - pub fn on_ice_gathering_state_change(&self, f: Option) { - *self.observer.ice_gathering_change_handler.lock() = f; - } - - pub fn on_negotiation_needed(&self, f: Option) { - *self.observer.negotiation_needed_handler.lock() = f; - } - - pub fn on_signaling_state_change(&self, f: Option) { - *self.observer.signaling_change_handler.lock() = f; - } - - pub fn on_track(&self, f: Option) { - *self.observer.track_handler.lock() = f; - } -} - -#[derive(Default)] -pub struct PeerObserver { - pub connection_change_handler: Mutex>, - pub data_channel_handler: Mutex>, - pub ice_candidate_handler: Mutex>, - pub ice_candidate_error_handler: Mutex>, - pub ice_connection_change_handler: Mutex>, - pub ice_gathering_change_handler: Mutex>, - pub negotiation_needed_handler: Mutex>, - pub signaling_change_handler: Mutex>, - pub track_handler: Mutex>, -} - -impl sys_pcf::PeerConnectionObserver for PeerObserver { - fn on_signaling_change(&self, new_state: sys_pc::ffi::SignalingState) { - if let Some(f) = self.signaling_change_handler.lock().as_mut() { - f(new_state.into()); - } - } - - fn on_add_stream(&self, _stream: SharedPtr) {} - - fn on_remove_stream(&self, _stream: SharedPtr) {} - - fn on_data_channel(&self, data_channel: SharedPtr) { - if let Some(f) = self.data_channel_handler.lock().as_mut() { - f(DataChannel { handle: imp_dc::DataChannel::configure(data_channel) }); - } - } - - fn on_renegotiation_needed(&self) {} - - fn on_negotiation_needed_event(&self, event: u32) { - if let Some(f) = self.negotiation_needed_handler.lock().as_mut() { - f(event); - } - } - - fn on_ice_connection_change(&self, _new_state: sys_pc::ffi::IceConnectionState) {} - - fn on_standardized_ice_connection_change(&self, new_state: sys_pc::ffi::IceConnectionState) { - if let Some(f) = self.ice_connection_change_handler.lock().as_mut() { - f(new_state.into()); - } - } - - fn on_connection_change(&self, new_state: sys_pc::ffi::PeerConnectionState) { - if let Some(f) = self.connection_change_handler.lock().as_mut() { - f(new_state.into()); - } - } - - fn on_ice_gathering_change(&self, new_state: sys_pc::ffi::IceGatheringState) { - if let Some(f) = self.ice_gathering_change_handler.lock().as_mut() { - f(new_state.into()); - } - } - - fn on_ice_candidate(&self, candidate: SharedPtr) { - if let Some(f) = self.ice_candidate_handler.lock().as_mut() { - f(IceCandidate { handle: imp_ic::IceCandidate { sys_handle: candidate } }); - } - } - - fn on_ice_candidate_error( - &self, - address: String, - port: i32, - url: String, - error_code: i32, - error_text: String, - ) { - if let Some(f) = self.ice_candidate_error_handler.lock().as_mut() { - f(IceCandidateError { address, port, url, error_code, error_text }); - } - } - - fn on_ice_candidates_removed( - &self, - _removed: Vec>, - ) { - } - - fn on_ice_connection_receiving_change(&self, _receiving: bool) {} - - fn on_ice_selected_candidate_pair_changed( - &self, - _event: sys_pcf::ffi::CandidatePairChangeEvent, - ) { - } - - fn on_add_track( - &self, - _receiver: SharedPtr, - _streams: Vec>, - ) { - } - - fn on_track(&self, transceiver: SharedPtr) { - if let Some(f) = self.track_handler.lock().as_mut() { - let receiver = transceiver.receiver(); - let streams = receiver.streams(); - let track = receiver.track(); - - f(TrackEvent { - receiver: RtpReceiver { handle: imp_rr::RtpReceiver { sys_handle: receiver } }, - streams: streams - .into_iter() - .map(|s| MediaStream { handle: imp_ms::MediaStream { sys_handle: s.ptr } }) - .collect(), - track: imp_mst::new_media_stream_track(track), - transceiver: RtpTransceiver { - handle: imp_rt::RtpTransceiver { sys_handle: transceiver }, - }, - }); - } - } - - fn on_remove_track(&self, _receiver: SharedPtr) {} - - fn on_interesting_usage(&self, _usage_pattern: i32) {} -} diff --git a/libwebrtc/src/native/peer_connection_factory.rs b/libwebrtc/src/native/peer_connection_factory.rs deleted file mode 100644 index 8385451c6..000000000 --- a/libwebrtc/src/native/peer_connection_factory.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use cxx::{SharedPtr, UniquePtr}; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use webrtc_sys::{peer_connection_factory as sys_pcf, rtc_error as sys_err, webrtc as sys_rtc}; - -use crate::{ - audio_source::native::NativeAudioSource, - audio_track::RtcAudioTrack, - imp::{audio_track as imp_at, peer_connection as imp_pc, video_track as imp_vt}, - peer_connection::PeerConnection, - peer_connection_factory::RtcConfiguration, - rtp_parameters::RtpCapabilities, - video_source::native::NativeVideoSource, - video_track::RtcVideoTrack, - MediaType, RtcError, -}; - -lazy_static! { - static ref LOG_SINK: Mutex>> = Default::default(); -} - -#[derive(Clone)] -pub struct PeerConnectionFactory { - pub(crate) sys_handle: SharedPtr, -} - -impl Default for PeerConnectionFactory { - fn default() -> Self { - let mut log_sink = LOG_SINK.lock(); - if log_sink.is_none() { - *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, _| { - let msg = msg.strip_suffix("\r\n").or(msg.strip_suffix('\n')).unwrap_or(&msg); - - log::debug!(target: "libwebrtc", "{}", msg); - })); - } - - Self { sys_handle: sys_pcf::ffi::create_peer_connection_factory() } - } -} - -impl PeerConnectionFactory { - pub fn create_peer_connection( - &self, - config: RtcConfiguration, - ) -> Result { - let observer = Arc::new(imp_pc::PeerObserver::default()); - let res = self.sys_handle.create_peer_connection( - config.into(), - Box::new(sys_pcf::PeerConnectionObserverWrapper::new(observer.clone())), - ); - - match res { - Ok(sys_handle) => Ok(PeerConnection { - handle: imp_pc::PeerConnection::configure(sys_handle, observer), - }), - Err(e) => Err(unsafe { sys_err::ffi::RtcError::from(e.what()).into() }), - } - } - - pub fn create_video_track(&self, label: &str, source: NativeVideoSource) -> RtcVideoTrack { - RtcVideoTrack { - handle: imp_vt::RtcVideoTrack { - sys_handle: self - .sys_handle - .create_video_track(label.to_string(), source.handle.sys_handle()), - }, - } - } - - pub fn create_audio_track(&self, label: &str, source: NativeAudioSource) -> RtcAudioTrack { - RtcAudioTrack { - handle: imp_at::RtcAudioTrack { - sys_handle: self - .sys_handle - .create_audio_track(label.to_string(), source.handle.sys_handle()), - }, - } - } - - pub fn get_rtp_sender_capabilities(&self, media_type: MediaType) -> RtpCapabilities { - self.sys_handle.rtp_sender_capabilities(media_type.into()).into() - } - - pub fn get_rtp_receiver_capabilities(&self, media_type: MediaType) -> RtpCapabilities { - self.sys_handle.rtp_receiver_capabilities(media_type.into()).into() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_peer_connection_factory() { - let _ = env_logger::builder().is_test(true).try_init(); - - let factory = PeerConnectionFactory::default(); - let source = NativeVideoSource::default(); - let _track = factory.create_video_track("test", source); - drop(factory); - } -} diff --git a/libwebrtc/src/native/rtp_parameters.rs b/libwebrtc/src/native/rtp_parameters.rs deleted file mode 100644 index 30f206ae7..000000000 --- a/libwebrtc/src/native/rtp_parameters.rs +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use webrtc_sys::{rtp_parameters as sys_rp, webrtc as sys_webrtc}; - -use crate::rtp_parameters::*; - -impl From for Priority { - fn from(value: sys_webrtc::ffi::Priority) -> Self { - match value { - sys_webrtc::ffi::Priority::VeryLow => Self::VeryLow, - sys_webrtc::ffi::Priority::Low => Self::Low, - sys_webrtc::ffi::Priority::Medium => Self::Medium, - sys_webrtc::ffi::Priority::High => Self::High, - _ => panic!("unknown Priority"), - } - } -} - -impl From for RtpHeaderExtensionParameters { - fn from(value: sys_rp::ffi::RtpExtension) -> Self { - Self { uri: value.uri, id: value.id, encrypted: value.encrypt } - } -} - -impl From for RtpParameters { - fn from(value: sys_rp::ffi::RtpParameters) -> Self { - Self { - codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), - rtcp: value.rtcp.into(), - } - } -} - -impl From for RtpCodecParameters { - fn from(value: sys_rp::ffi::RtpCodecParameters) -> Self { - Self { - mime_type: value.mime_type, - payload_type: value.payload_type as u8, - clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64), - channels: value.has_num_channels.then_some(value.num_channels as u16), - } - } -} - -impl From for RtcpParameters { - fn from(value: sys_rp::ffi::RtcpParameters) -> Self { - Self { cname: value.cname, reduced_size: value.reduced_size } - } -} - -impl From for RtpEncodingParameters { - fn from(value: sys_rp::ffi::RtpEncodingParameters) -> Self { - Self { - active: value.active, - max_bitrate: value.has_max_bitrate_bps.then_some(value.max_bitrate_bps as u64), - max_framerate: value.has_max_framerate.then_some(value.max_framerate), - priority: value.network_priority.into(), - rid: value.rid, - scale_resolution_down_by: value - .has_scale_resolution_down_by - .then_some(value.scale_resolution_down_by), - } - } -} - -impl From for RtpCodecCapability { - fn from(value: sys_rp::ffi::RtpCodecCapability) -> Self { - Self { - channels: value.has_num_channels.then_some(value.num_channels as u16), - mime_type: value.mime_type, - clock_rate: value.has_clock_rate.then_some(value.clock_rate as u64), - sdp_fmtp_line: { - let parameters: Vec = value - .parameters - .into_iter() - .map(|key_value| { - if !key_value.key.is_empty() { - format!("{}={}", key_value.key, key_value.value) - } else { - key_value.value - } - }) - .collect(); - - if !parameters.is_empty() { - Some(parameters.join(";")) - } else { - None - } - }, - } - } -} - -impl From for RtpHeaderExtensionCapability { - fn from(value: sys_rp::ffi::RtpHeaderExtensionCapability) -> Self { - Self { direction: value.direction.into(), uri: value.uri } - } -} - -impl From for RtpCapabilities { - fn from(value: sys_rp::ffi::RtpCapabilities) -> Self { - Self { - codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), - } - } -} - -impl From for sys_webrtc::ffi::Priority { - fn from(value: Priority) -> Self { - match value { - Priority::VeryLow => Self::VeryLow, - Priority::Low => Self::Low, - Priority::Medium => Self::Medium, - Priority::High => Self::High, - } - } -} - -impl From for sys_rp::ffi::RtpExtension { - fn from(value: RtpHeaderExtensionParameters) -> Self { - Self { uri: value.uri, id: value.id, encrypt: value.encrypted } - } -} - -impl From for sys_rp::ffi::RtpParameters { - fn from(value: RtpParameters) -> Self { - Self { - codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), - encodings: Vec::new(), - rtcp: value.rtcp.into(), - transaction_id: "".to_string(), - mid: "".to_string(), - has_degradation_preference: false, - degradation_preference: sys_rp::ffi::DegradationPreference::Balanced, - } - } -} - -impl From for sys_rp::ffi::RtpCodecParameters { - fn from(value: RtpCodecParameters) -> Self { - Self { - payload_type: value.payload_type as i32, - mime_type: value.mime_type, - has_clock_rate: value.clock_rate.is_some(), - clock_rate: value.clock_rate.unwrap_or_default() as i32, - has_num_channels: value.channels.is_some(), - num_channels: value.channels.unwrap_or_default() as i32, - name: "".to_string(), - kind: sys_rp::ffi::MediaType::Audio, - has_max_ptime: false, - max_ptime: 0, - has_ptime: false, - ptime: 0, - rtcp_feedback: Vec::new(), - parameters: Vec::new(), - } - } -} - -impl From for sys_rp::ffi::RtcpParameters { - fn from(value: RtcpParameters) -> Self { - Self { - cname: value.cname, - reduced_size: value.reduced_size, - has_ssrc: false, - ssrc: 0, - mux: false, - } - } -} - -impl From for sys_rp::ffi::RtpEncodingParameters { - fn from(value: RtpEncodingParameters) -> Self { - Self { - active: value.active, - has_max_bitrate_bps: value.max_bitrate.is_some(), - max_bitrate_bps: value.max_bitrate.unwrap_or_default() as i32, - has_max_framerate: value.max_framerate.is_some(), - max_framerate: value.max_framerate.unwrap_or_default(), - network_priority: value.priority.into(), - rid: value.rid, - has_scale_resolution_down_by: value.scale_resolution_down_by.is_some(), - scale_resolution_down_by: value.scale_resolution_down_by.unwrap_or_default(), - adaptive_ptime: false, - bitrate_priority: sys_rp::DEFAULT_BITRATE_PRIORITY, - has_min_bitrate_bps: false, - min_bitrate_bps: 0, - has_num_temporal_layers: false, - num_temporal_layers: 0, - has_scalability_mode: false, - scalability_mode: "".to_string(), - has_ssrc: false, - ssrc: 0, - } - } -} - -impl From for sys_rp::ffi::RtpCodecCapability { - fn from(value: RtpCodecCapability) -> Self { - let mime_type: Vec<&str> = value.mime_type.split('/').collect(); - let kind = match mime_type[0] { - "audio" => sys_webrtc::ffi::MediaType::Audio, - "video" => sys_webrtc::ffi::MediaType::Video, - _ => panic!("invalid media type"), - }; - let name = mime_type[1].to_string(); - - Self { - name, - kind, - has_clock_rate: value.clock_rate.is_some(), - clock_rate: value.clock_rate.unwrap_or_default() as i32, - has_num_channels: value.channels.is_some(), - num_channels: value.channels.unwrap_or_default() as i32, - parameters: { - value - .sdp_fmtp_line - .map(|sdp_fmtp_line| { - sdp_fmtp_line - .split(';') - .map(|v| { - let key_value: Vec<&str> = v.split('=').collect(); - if key_value.len() == 2 { - sys_rp::ffi::StringKeyValue { - key: key_value[0].to_string(), - value: key_value[1].to_string(), - } - } else { - sys_rp::ffi::StringKeyValue { - key: "".to_string(), - value: key_value[0].to_string(), - } - } - }) - .collect() - }) - .unwrap_or_default() - }, - // Ignore - mime_type: String::default(), // !! - has_preferred_payload_type: false, - preferred_payload_type: 0, - rtcp_feedback: Vec::default(), - } - } -} diff --git a/libwebrtc/src/native/rtp_receiver.rs b/libwebrtc/src/native/rtp_receiver.rs deleted file mode 100644 index 14fc2fecb..000000000 --- a/libwebrtc/src/native/rtp_receiver.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use tokio::sync::oneshot; -use webrtc_sys::rtp_receiver as sys_rr; - -use crate::{ - imp::media_stream_track::new_media_stream_track, media_stream_track::MediaStreamTrack, - rtp_parameters::RtpParameters, stats::RtcStats, RtcError, RtcErrorType, -}; - -#[derive(Clone)] -pub struct RtpReceiver { - pub(crate) sys_handle: SharedPtr, -} - -impl RtpReceiver { - pub fn track(&self) -> Option { - let track_handle = self.sys_handle.track(); - if track_handle.is_null() { - return None; - } - - Some(new_media_stream_track(track_handle)) - } - - pub async fn get_stats(&self) -> Result, RtcError> { - let (tx, rx) = oneshot::channel::, RtcError>>(); - let ctx = Box::new(sys_rr::ReceiverContext(Box::new(tx))); - - self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx.0.downcast::, RtcError>>>().unwrap(); - - if stats.is_empty() { - let _ = tx.send(Ok(vec![])); - return; - } - - // Unwrap because it should not happens - let vec = serde_json::from_str(&stats).unwrap(); - let _ = tx.send(Ok(vec)); - }); - - rx.await.map_err(|_| RtcError { - error_type: RtcErrorType::Internal, - message: "get_stats cancelled".to_owned(), - })? - } - - pub fn parameters(&self) -> RtpParameters { - self.sys_handle.get_parameters().into() - } -} diff --git a/libwebrtc/src/native/rtp_sender.rs b/libwebrtc/src/native/rtp_sender.rs deleted file mode 100644 index dd5509bd5..000000000 --- a/libwebrtc/src/native/rtp_sender.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use tokio::sync::oneshot; -use webrtc_sys::{rtc_error as sys_err, rtp_sender as sys_rs}; - -use super::media_stream_track::new_media_stream_track; -use crate::{ - media_stream_track::MediaStreamTrack, rtp_parameters::RtpParameters, stats::RtcStats, RtcError, - RtcErrorType, -}; - -#[derive(Clone)] -pub struct RtpSender { - pub(crate) sys_handle: SharedPtr, -} - -impl RtpSender { - pub fn track(&self) -> Option { - let track_handle = self.sys_handle.track(); - if track_handle.is_null() { - return None; - } - - Some(new_media_stream_track(track_handle)) - } - - pub async fn get_stats(&self) -> Result, RtcError> { - let (tx, rx) = oneshot::channel::, RtcError>>(); - let ctx = Box::new(sys_rs::SenderContext(Box::new(tx))); - - self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx.0.downcast::, RtcError>>>().unwrap(); - - if stats.is_empty() { - let _ = tx.send(Ok(vec![])); - return; - } - - // Unwrap because it should not happens - let vec = serde_json::from_str(&stats).unwrap(); - let _ = tx.send(Ok(vec)); - }); - - rx.await.map_err(|_| RtcError { - error_type: RtcErrorType::Internal, - message: "get_stats cancelled".to_owned(), - })? - } - - pub fn set_track(&self, track: Option) -> Result<(), RtcError> { - if !self.sys_handle.set_track(track.map_or(SharedPtr::null(), |t| t.sys_handle())) { - return Err(RtcError { - error_type: RtcErrorType::InvalidState, - message: "Failed to set track".to_string(), - }); - } - - Ok(()) - } - - pub fn parameters(&self) -> RtpParameters { - self.sys_handle.get_parameters().into() - } - - pub fn set_parameters(&self, parameters: RtpParameters) -> Result<(), RtcError> { - self.sys_handle - .set_parameters(parameters.into()) - .map_err(|e| unsafe { sys_err::ffi::RtcError::from(e.what()).into() }) - } -} diff --git a/libwebrtc/src/native/rtp_transceiver.rs b/libwebrtc/src/native/rtp_transceiver.rs deleted file mode 100644 index 128b66599..000000000 --- a/libwebrtc/src/native/rtp_transceiver.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use webrtc_sys::{rtc_error as sys_err, rtp_transceiver as sys_rt, webrtc as sys_webrtc}; - -use crate::{ - imp::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}, - rtp_parameters::RtpCodecCapability, - rtp_receiver, rtp_sender, - rtp_transceiver::{RtpTransceiverDirection, RtpTransceiverInit}, - RtcError, -}; - -impl From for RtpTransceiverDirection { - fn from(value: sys_webrtc::ffi::RtpTransceiverDirection) -> Self { - match value { - sys_webrtc::ffi::RtpTransceiverDirection::SendRecv => Self::SendRecv, - sys_webrtc::ffi::RtpTransceiverDirection::SendOnly => Self::SendOnly, - sys_webrtc::ffi::RtpTransceiverDirection::RecvOnly => Self::RecvOnly, - sys_webrtc::ffi::RtpTransceiverDirection::Inactive => Self::Inactive, - sys_webrtc::ffi::RtpTransceiverDirection::Stopped => Self::Stopped, - _ => panic!("unknown RtpTransceiverDirection"), - } - } -} - -impl From for sys_webrtc::ffi::RtpTransceiverDirection { - fn from(value: RtpTransceiverDirection) -> Self { - match value { - RtpTransceiverDirection::SendRecv => Self::SendRecv, - RtpTransceiverDirection::SendOnly => Self::SendOnly, - RtpTransceiverDirection::RecvOnly => Self::RecvOnly, - RtpTransceiverDirection::Inactive => Self::Inactive, - RtpTransceiverDirection::Stopped => Self::Stopped, - } - } -} - -impl From for sys_rt::ffi::RtpTransceiverInit { - fn from(value: RtpTransceiverInit) -> Self { - Self { - direction: value.direction.into(), - stream_ids: value.stream_ids, - send_encodings: value.send_encodings.into_iter().map(Into::into).collect(), - } - } -} - -#[derive(Clone)] -pub struct RtpTransceiver { - pub(crate) sys_handle: SharedPtr, -} - -impl RtpTransceiver { - pub fn mid(&self) -> Option { - self.sys_handle.mid().ok() - } - - pub fn current_direction(&self) -> Option { - self.sys_handle.current_direction().ok().map(Into::into) - } - - pub fn direction(&self) -> RtpTransceiverDirection { - self.sys_handle.direction().into() - } - - pub fn sender(&self) -> rtp_sender::RtpSender { - rtp_sender::RtpSender { handle: RtpSender { sys_handle: self.sys_handle.sender() } } - } - - pub fn receiver(&self) -> rtp_receiver::RtpReceiver { - rtp_receiver::RtpReceiver { handle: RtpReceiver { sys_handle: self.sys_handle.receiver() } } - } - - pub fn set_codec_preferences(&self, codecs: Vec) -> Result<(), RtcError> { - self.sys_handle - .set_codec_preferences(codecs.into_iter().map(Into::into).collect()) - .map_err(|e| unsafe { sys_err::ffi::RtcError::from(e.what()).into() }) - } - - pub fn stop(&self) -> Result<(), RtcError> { - self.sys_handle - .stop_standard() - .map_err(|e| unsafe { sys_err::ffi::RtcError::from(e.what()).into() }) - } -} diff --git a/libwebrtc/src/native/session_description.rs b/libwebrtc/src/native/session_description.rs deleted file mode 100644 index cb28d1088..000000000 --- a/libwebrtc/src/native/session_description.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::UniquePtr; -use webrtc_sys::jsep as sys_jsep; - -use crate::session_description::{self, SdpParseError, SdpType}; - -impl From for SdpType { - fn from(sdp_type: sys_jsep::ffi::SdpType) -> Self { - match sdp_type { - sys_jsep::ffi::SdpType::Offer => SdpType::Offer, - sys_jsep::ffi::SdpType::PrAnswer => SdpType::PrAnswer, - sys_jsep::ffi::SdpType::Answer => SdpType::Answer, - sys_jsep::ffi::SdpType::Rollback => SdpType::Rollback, - _ => panic!("unknown SdpType"), - } - } -} - -impl From for sys_jsep::ffi::SdpType { - fn from(sdp_type: SdpType) -> Self { - match sdp_type { - SdpType::Offer => sys_jsep::ffi::SdpType::Offer, - SdpType::PrAnswer => sys_jsep::ffi::SdpType::PrAnswer, - SdpType::Answer => sys_jsep::ffi::SdpType::Answer, - SdpType::Rollback => sys_jsep::ffi::SdpType::Rollback, - } - } -} - -impl From for SdpParseError { - fn from(e: sys_jsep::ffi::SdpParseError) -> Self { - Self { line: e.line, description: e.description } - } -} - -pub struct SessionDescription { - pub(crate) sys_handle: UniquePtr, -} - -impl SessionDescription { - pub fn parse( - sdp: &str, - sdp_type: SdpType, - ) -> Result { - let res = sys_jsep::ffi::create_session_description(sdp_type.into(), sdp.to_owned()); - match res { - Ok(sys_handle) => Ok(session_description::SessionDescription { - handle: SessionDescription { sys_handle }, - }), - Err(e) => Err(unsafe { sys_jsep::ffi::SdpParseError::from(e.what()).into() }), - } - } - - pub fn sdp_type(&self) -> SdpType { - self.sys_handle.sdp_type().into() - } -} - -impl ToString for SessionDescription { - fn to_string(&self) -> String { - self.sys_handle.stringify() - } -} - -impl Clone for SessionDescription { - fn clone(&self) -> Self { - SessionDescription { sys_handle: self.sys_handle.clone() } - } -} diff --git a/libwebrtc/src/native/video_frame.rs b/libwebrtc/src/native/video_frame.rs deleted file mode 100644 index 5393d77df..000000000 --- a/libwebrtc/src/native/video_frame.rs +++ /dev/null @@ -1,828 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::slice; - -use cxx::UniquePtr; -use webrtc_sys::{video_frame as vf_sys, video_frame_buffer as vfb_sys}; - -use super::yuv_helper; -use crate::video_frame::{self as vf, VideoFormatType, VideoRotation}; - -/// We don't use vf::VideoFrameBuffer trait for the types inside this module to avoid confusion -/// because directly using platform specific types is not valid (e.g user callback) -/// All the types inside this module are only used internally. For public types, see the top level -/// video_frame.rs - -pub fn new_video_frame_buffer( - mut sys_handle: UniquePtr, -) -> Box { - unsafe { - match sys_handle.buffer_type() { - vfb_sys::ffi::VideoFrameBufferType::Native => { - Box::new(vf::native::NativeBuffer { handle: NativeBuffer { sys_handle } }) - } - vfb_sys::ffi::VideoFrameBufferType::I420 => Box::new(vf::I420Buffer { - handle: I420Buffer { sys_handle: sys_handle.pin_mut().get_i420() }, - }), - vfb_sys::ffi::VideoFrameBufferType::I420A => Box::new(vf::I420ABuffer { - handle: I420ABuffer { sys_handle: sys_handle.pin_mut().get_i420a() }, - }), - vfb_sys::ffi::VideoFrameBufferType::I422 => Box::new(vf::I422Buffer { - handle: I422Buffer { sys_handle: sys_handle.pin_mut().get_i422() }, - }), - vfb_sys::ffi::VideoFrameBufferType::I444 => Box::new(vf::I444Buffer { - handle: I444Buffer { sys_handle: sys_handle.pin_mut().get_i444() }, - }), - vfb_sys::ffi::VideoFrameBufferType::I010 => Box::new(vf::I010Buffer { - handle: I010Buffer { sys_handle: sys_handle.pin_mut().get_i010() }, - }), - vfb_sys::ffi::VideoFrameBufferType::NV12 => Box::new(vf::NV12Buffer { - handle: NV12Buffer { sys_handle: sys_handle.pin_mut().get_nv12() }, - }), - _ => unreachable!(), - } - } -} - -impl From for VideoRotation { - fn from(rotation: vf_sys::ffi::VideoRotation) -> Self { - match rotation { - vf_sys::ffi::VideoRotation::VideoRotation0 => Self::VideoRotation0, - vf_sys::ffi::VideoRotation::VideoRotation90 => Self::VideoRotation90, - vf_sys::ffi::VideoRotation::VideoRotation180 => Self::VideoRotation180, - vf_sys::ffi::VideoRotation::VideoRotation270 => Self::VideoRotation270, - _ => panic!("invalid VideoRotation"), - } - } -} - -impl From for vf_sys::ffi::VideoRotation { - fn from(rotation: VideoRotation) -> Self { - match rotation { - VideoRotation::VideoRotation0 => Self::VideoRotation0, - VideoRotation::VideoRotation90 => Self::VideoRotation90, - VideoRotation::VideoRotation180 => Self::VideoRotation180, - VideoRotation::VideoRotation270 => Self::VideoRotation270, - } - } -} - -macro_rules! recursive_cast { - ($ptr:expr $(, $fnc:ident)*) => { - { - let ptr = $ptr; - $( - let ptr = vfb_sys::ffi::$fnc(ptr); - )* - ptr - } - }; -} - -pub struct NativeBuffer { - sys_handle: UniquePtr, -} - -pub struct I420Buffer { - sys_handle: UniquePtr, -} - -pub struct I420ABuffer { - sys_handle: UniquePtr, -} - -pub struct I422Buffer { - sys_handle: UniquePtr, -} - -pub struct I444Buffer { - sys_handle: UniquePtr, -} - -pub struct I010Buffer { - sys_handle: UniquePtr, -} - -pub struct NV12Buffer { - sys_handle: UniquePtr, -} - -macro_rules! impl_to_argb { - (I420Buffer [$($variant:ident: $fnc:ident),+], $format:ident, $self:ident, $dst:ident, $dst_stride:ident, $dst_width:ident, $dst_height:ident) => { - match $format { - $( - VideoFormatType::$variant => { - let (data_y, data_u, data_v) = $self.data(); - yuv_helper::$fnc( - data_y, - $self.stride_y(), - data_u, - $self.stride_u(), - data_v, - $self.stride_v(), - $dst, - $dst_stride, - $dst_width, - $dst_height, - ) - } - )+ - } - }; - (I420ABuffer) => { - todo!(); - } -} - -#[allow(unused_unsafe)] -impl NativeBuffer { - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - &self.sys_handle - } - - pub fn width(&self) -> u32 { - self.sys_handle.width() - } - - pub fn height(&self) -> u32 { - self.sys_handle.height() - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { sys_handle: unsafe { self.sys_handle.to_i420() } } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } -} - -impl I420Buffer { - pub fn new( - width: u32, - height: u32, - stride_y: u32, - stride_u: u32, - stride_v: u32, - ) -> vf::I420Buffer { - vf::I420Buffer { - handle: I420Buffer { - sys_handle: vfb_sys::ffi::new_i420_buffer( - width.try_into().unwrap(), - height.try_into().unwrap(), - stride_y.try_into().unwrap(), - stride_u.try_into().unwrap(), - stride_v.try_into().unwrap(), - ), - }, - } - } - - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { &*recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb) } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv); - (*ptr).stride_y() - } - } - - pub fn stride_u(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv); - (*ptr).stride_u() - } - } - - pub fn stride_v(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8, yuv8_to_yuv); - (*ptr).stride_v() - } - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - // We make a copy of the buffer because internally, when calling ToI420() - // if the buffer is of type I420, libwebrtc will reuse the same underlying pointer - // for the new created type - let copy = vfb_sys::ffi::copy_i420_buffer(&self.sys_handle); - let ptr = recursive_cast!(&*copy, i420_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - impl_to_argb!( - I420Buffer - [ - ARGB: i420_to_argb, - BGRA: i420_to_bgra, - ABGR: i420_to_abgr, - RGBA: i420_to_rgba - ], - format, self, dst, dst_stride, dst_width, dst_height - ) - } - - pub fn data(&self) -> (&[u8], &[u8], &[u8]) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420_to_yuv8); - let chroma_height = (self.height() + 1) / 2; - ( - slice::from_raw_parts((*ptr).data_y(), (self.stride_y() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_u(), (self.stride_u() * chroma_height) as usize), - slice::from_raw_parts((*ptr).data_v(), (self.stride_v() * chroma_height) as usize), - ) - } - } -} - -impl I420ABuffer { - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { &*recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb) } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv); - (*ptr).stride_y() - } - } - - pub fn stride_u(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv); - (*ptr).stride_u() - } - } - - pub fn stride_v(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv); - (*ptr).stride_v() - } - } - - pub fn stride_a(&self) -> u32 { - self.sys_handle.stride_a() - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - let ptr = - recursive_cast!(&*self.sys_handle, i420a_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } - - pub fn data(&self) -> (&[u8], &[u8], &[u8], Option<&[u8]>) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i420a_to_yuv8); - let chroma_height = (self.height() + 1) / 2; - let data_a = self.sys_handle.data_a(); - let has_data_a = !data_a.is_null(); - ( - slice::from_raw_parts((*ptr).data_y(), (self.stride_y() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_u(), (self.stride_u() * chroma_height) as usize), - slice::from_raw_parts((*ptr).data_v(), (self.stride_v() * chroma_height) as usize), - has_data_a.then_some(slice::from_raw_parts( - data_a, - (self.stride_a() * self.height()) as usize, - )), - ) - } - } -} - -impl I422Buffer { - pub fn new( - width: u32, - height: u32, - stride_y: u32, - stride_u: u32, - stride_v: u32, - ) -> vf::I422Buffer { - vf::I422Buffer { - handle: I422Buffer { - sys_handle: vfb_sys::ffi::new_i422_buffer( - width.try_into().unwrap(), - height.try_into().unwrap(), - stride_y.try_into().unwrap(), - stride_u.try_into().unwrap(), - stride_v.try_into().unwrap(), - ), - }, - } - } - - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { &*recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb) } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv); - (*ptr).stride_y() - } - } - - pub fn stride_u(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv); - (*ptr).stride_u() - } - } - - pub fn stride_v(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv); - (*ptr).stride_v() - } - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } - - pub fn data(&self) -> (&[u8], &[u8], &[u8]) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i422_to_yuv8); - ( - slice::from_raw_parts((*ptr).data_y(), (self.stride_y() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_u(), (self.stride_u() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_v(), (self.stride_v() * self.height()) as usize), - ) - } - } -} -impl I444Buffer { - pub fn new( - width: u32, - height: u32, - stride_y: u32, - stride_u: u32, - stride_v: u32, - ) -> vf::I444Buffer { - vf::I444Buffer { - handle: I444Buffer { - sys_handle: vfb_sys::ffi::new_i444_buffer( - width.try_into().unwrap(), - height.try_into().unwrap(), - stride_y.try_into().unwrap(), - stride_u.try_into().unwrap(), - stride_v.try_into().unwrap(), - ), - }, - } - } - - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { &*recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb) } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv); - (*ptr).stride_y() - } - } - - pub fn stride_u(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv); - (*ptr).stride_u() - } - } - - pub fn stride_v(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv); - (*ptr).stride_v() - } - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8, yuv8_to_yuv, yuv_to_vfb); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } - - pub fn data(&self) -> (&[u8], &[u8], &[u8]) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i444_to_yuv8); - ( - slice::from_raw_parts((*ptr).data_y(), (self.stride_y() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_u(), (self.stride_u() * self.height()) as usize), - slice::from_raw_parts((*ptr).data_v(), (self.stride_v() * self.height()) as usize), - ) - } - } -} - -impl I010Buffer { - pub fn new( - width: u32, - height: u32, - stride_y: u32, - stride_u: u32, - stride_v: u32, - ) -> vf::I010Buffer { - vf::I010Buffer { - handle: I010Buffer { - sys_handle: vfb_sys::ffi::new_i010_buffer( - width.try_into().unwrap(), - height.try_into().unwrap(), - stride_y.try_into().unwrap(), - stride_u.try_into().unwrap(), - stride_v.try_into().unwrap(), - ), - }, - } - } - - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { &*recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb) } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv); - (*ptr).stride_y() - } - } - - pub fn stride_u(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv); - (*ptr).stride_u() - } - } - - pub fn stride_v(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv); - (*ptr).stride_v() - } - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - let ptr = - recursive_cast!(&*self.sys_handle, i010_to_yuv16b, yuv16b_to_yuv, yuv_to_vfb); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } - - pub fn data(&self) -> (&[u16], &[u16], &[u16]) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, i010_to_yuv16b); - let chroma_height = (self.height() + 1) / 2; - ( - slice::from_raw_parts( - (*ptr).data_y(), - (self.stride_y() * self.height()) as usize / 2, - ), - slice::from_raw_parts( - (*ptr).data_u(), - (self.stride_u() * chroma_height) as usize / 2, - ), - slice::from_raw_parts( - (*ptr).data_v(), - (self.stride_v() * chroma_height) as usize / 2, - ), - ) - } - } -} - -impl NV12Buffer { - pub fn new(width: u32, height: u32, stride_y: u32, stride_uv: u32) -> vf::NV12Buffer { - vf::NV12Buffer { - handle: NV12Buffer { - sys_handle: vfb_sys::ffi::new_nv12_buffer( - width.try_into().unwrap(), - height.try_into().unwrap(), - stride_y.try_into().unwrap(), - stride_uv.try_into().unwrap(), - ), - }, - } - } - - pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { - unsafe { - &*recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb) - } - } - - pub fn width(&self) -> u32 { - unsafe { - let ptr = - recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb); - (*ptr).width() - } - } - - pub fn height(&self) -> u32 { - unsafe { - let ptr = - recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb); - (*ptr).height() - } - } - - pub fn chroma_width(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv); - (*ptr).chroma_width() - } - } - - pub fn chroma_height(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv); - (*ptr).chroma_height() - } - } - - pub fn stride_y(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv); - (*ptr).stride_y() - } - } - - pub fn stride_uv(&self) -> u32 { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv); - (*ptr).stride_uv() - } - } - - pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { - let ptr = recursive_cast!( - &*self.sys_handle, - nv12_to_biyuv8, - biyuv8_to_biyuv, - biyuv_to_vfb - ); - (*ptr).to_i420() - }, - } - } - - pub fn to_argb( - &self, - format: VideoFormatType, - dst: &mut [u8], - dst_stride: u32, - dst_width: i32, - dst_height: i32, - ) { - self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) - } - - pub fn data(&self) -> (&[u8], &[u8]) { - unsafe { - let ptr = recursive_cast!(&*self.sys_handle, nv12_to_biyuv8); - let chroma_height = (self.height() + 1) / 2; - - ( - slice::from_raw_parts((*ptr).data_y(), (self.stride_y() * self.height()) as usize), - slice::from_raw_parts( - (*ptr).data_uv(), - (self.stride_uv() * chroma_height) as usize, - ), - ) - } - } -} diff --git a/libwebrtc/src/native/video_source.rs b/libwebrtc/src/native/video_source.rs deleted file mode 100644 index 4313cd61e..000000000 --- a/libwebrtc/src/native/video_source.rs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - sync::Arc, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; - -use cxx::SharedPtr; -use parking_lot::Mutex; -use webrtc_sys::{video_frame as vf_sys, video_frame::ffi::VideoRotation, video_track as vt_sys}; - -use crate::{ - video_frame::{I420Buffer, VideoBuffer, VideoFrame}, - video_source::VideoResolution, -}; - -impl From for VideoResolution { - fn from(res: vt_sys::ffi::VideoResolution) -> Self { - Self { width: res.width, height: res.height } - } -} - -impl From for vt_sys::ffi::VideoResolution { - fn from(res: VideoResolution) -> Self { - Self { width: res.width, height: res.height } - } -} - -#[derive(Clone)] -pub struct NativeVideoSource { - sys_handle: SharedPtr, - inner: Arc>, -} - -struct VideoSourceInner { - captured_frames: usize, -} - -impl NativeVideoSource { - pub fn new(resolution: VideoResolution) -> NativeVideoSource { - let source = Self { - sys_handle: vt_sys::ffi::new_video_track_source(&vt_sys::ffi::VideoResolution::from( - resolution.clone(), - )), - inner: Arc::new(Mutex::new(VideoSourceInner { captured_frames: 0 })), - }; - - livekit_runtime::spawn({ - let source = source.clone(); - let i420 = I420Buffer::new(resolution.width, resolution.height); - async move { - let mut interval = tokio::time::interval(Duration::from_millis(100)); // 10 fps - - loop { - interval.tick().await; - - let inner = source.inner.lock(); - if inner.captured_frames > 0 { - break; - } - - let mut builder = vf_sys::ffi::new_video_frame_builder(); - builder.pin_mut().set_rotation(VideoRotation::VideoRotation0); - builder.pin_mut().set_video_frame_buffer(i420.as_ref().sys_handle()); - - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - builder.pin_mut().set_timestamp_us(now.as_micros() as i64); - - source.sys_handle.on_captured_frame(&builder.pin_mut().build()); - } - } - }); - - source - } - - pub fn sys_handle(&self) -> SharedPtr { - self.sys_handle.clone() - } - - pub fn capture_frame>(&self, frame: &VideoFrame) { - let mut inner = self.inner.lock(); - inner.captured_frames += 1; - - let mut builder = vf_sys::ffi::new_video_frame_builder(); - builder.pin_mut().set_rotation(frame.rotation.into()); - builder.pin_mut().set_video_frame_buffer(frame.buffer.as_ref().sys_handle()); - - if frame.timestamp_us == 0 { - // If the timestamp is set to 0, default to now - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - builder.pin_mut().set_timestamp_us(now.as_micros() as i64); - } else { - builder.pin_mut().set_timestamp_us(frame.timestamp_us); - } - - self.sys_handle.on_captured_frame(&builder.pin_mut().build()); - } - - pub fn video_resolution(&self) -> VideoResolution { - self.sys_handle.video_resolution().into() - } -} diff --git a/libwebrtc/src/native/video_stream.rs b/libwebrtc/src/native/video_stream.rs deleted file mode 100644 index d17357d70..000000000 --- a/libwebrtc/src/native/video_stream.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::{ - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; - -use cxx::{SharedPtr, UniquePtr}; -use tokio::sync::mpsc; -use tokio_stream::Stream; -use webrtc_sys::video_track as sys_vt; - -use super::video_frame::new_video_frame_buffer; -use crate::{ - video_frame::{BoxVideoFrame, VideoFrame}, - video_track::RtcVideoTrack, -}; - -pub struct NativeVideoStream { - native_sink: SharedPtr, - video_track: RtcVideoTrack, - frame_rx: mpsc::UnboundedReceiver, -} - -impl NativeVideoStream { - pub fn new(video_track: RtcVideoTrack) -> Self { - let (frame_tx, frame_rx) = mpsc::unbounded_channel(); - let observer = Arc::new(VideoTrackObserver { frame_tx }); - let native_sink = sys_vt::ffi::new_native_video_sink(Box::new( - sys_vt::VideoSinkWrapper::new(observer.clone()), - )); - - let video = unsafe { sys_vt::ffi::media_to_video(video_track.sys_handle()) }; - video.add_sink(&native_sink); - - Self { native_sink, video_track, frame_rx } - } - - pub fn track(&self) -> RtcVideoTrack { - self.video_track.clone() - } - - pub fn close(&mut self) { - let video = unsafe { sys_vt::ffi::media_to_video(self.video_track.sys_handle()) }; - video.remove_sink(&self.native_sink); - - self.frame_rx.close(); - } -} - -impl Drop for NativeVideoStream { - fn drop(&mut self) { - self.close(); - } -} - -impl Stream for NativeVideoStream { - type Item = BoxVideoFrame; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { - self.frame_rx.poll_recv(cx) - } -} - -struct VideoTrackObserver { - frame_tx: mpsc::UnboundedSender, -} - -impl sys_vt::VideoSink for VideoTrackObserver { - fn on_frame(&self, frame: UniquePtr) { - let _ = self.frame_tx.send(VideoFrame { - rotation: frame.rotation().into(), - timestamp_us: frame.timestamp_us(), - buffer: new_video_frame_buffer(unsafe { frame.video_frame_buffer() }), - }); - } - - fn on_discarded_frame(&self) {} - - fn on_constraints_changed(&self, _constraints: sys_vt::ffi::VideoTrackSourceConstraints) {} -} diff --git a/libwebrtc/src/native/video_track.rs b/libwebrtc/src/native/video_track.rs deleted file mode 100644 index a8bb7e0ee..000000000 --- a/libwebrtc/src/native/video_track.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use cxx::SharedPtr; -use sys_vt::ffi::video_to_media; -use webrtc_sys::video_track as sys_vt; - -use super::media_stream_track::impl_media_stream_track; -use crate::media_stream_track::RtcTrackState; - -#[derive(Clone)] -pub struct RtcVideoTrack { - pub(crate) sys_handle: SharedPtr, -} - -impl RtcVideoTrack { - impl_media_stream_track!(video_to_media); - - pub fn sys_handle(&self) -> SharedPtr { - video_to_media(self.sys_handle.clone()) - } -} diff --git a/libwebrtc/src/native/yuv_helper.rs b/libwebrtc/src/native/yuv_helper.rs deleted file mode 100644 index e14af5b1f..000000000 --- a/libwebrtc/src/native/yuv_helper.rs +++ /dev/null @@ -1,823 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![allow(clippy::too_many_arguments)] - -use webrtc_sys::yuv_helper as yuv_sys; - -fn argb_assert_safety(src: &[u8], src_stride: u32, _width: i32, height: i32) { - let height_abs = height.unsigned_abs(); - let min = (src_stride * height_abs) as usize; - assert!(src.len() >= min, "src isn't large enough"); -} - -fn i420_assert_safety( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - _width: i32, - height: i32, -) { - let height_abs = height.unsigned_abs(); - let chroma_height = (height_abs + 1) / 2; - let min_y = (src_stride_y * height_abs) as usize; - let min_u = (src_stride_u * chroma_height) as usize; - let min_v = (src_stride_v * chroma_height) as usize; - - assert!(src_y.len() >= min_y, "src_y isn't large enough"); - assert!(src_u.len() >= min_u, "src_u isn't large enough"); - assert!(src_v.len() >= min_v, "src_v isn't large enough"); -} - -fn nv12_assert_safety( - src_y: &[u8], - src_stride_y: u32, - src_uv: &[u8], - src_stride_uv: u32, - _width: i32, - height: i32, -) { - let height_abs = height.unsigned_abs(); - let chroma_height = (height_abs + 1) / 2; - - let min_y = (src_stride_y * height_abs) as usize; - let min_uv = (src_stride_uv * chroma_height) as usize; - - assert!(src_y.len() >= min_y, "src_y isn't large enough"); - assert!(src_uv.len() >= min_uv, "src_uv isn't large enough"); -} - -fn i444_assert_safety( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - _width: i32, - height: i32, -) { - let height_abs = height.unsigned_abs(); - let min_y = (src_stride_y * height_abs) as usize; - let min_u = (src_stride_u * height_abs) as usize; - let min_v = (src_stride_v * height_abs) as usize; - - assert!(src_y.len() >= min_y, "src_y isn't large enough"); - assert!(src_u.len() >= min_u, "src_u isn't large enough"); - assert!(src_v.len() >= min_v, "src_v isn't large enough"); -} - -fn i422_assert_safety( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - _width: i32, - height: i32, -) { - let height_abs = height.unsigned_abs(); - let min_y = (src_stride_y * height_abs) as usize; - let min_u = (src_stride_u * height_abs) as usize; - let min_v = (src_stride_v * height_abs) as usize; - - assert!(src_y.len() >= min_y, "src_y isn't large enough"); - assert!(src_u.len() >= min_u, "src_u isn't large enough"); - assert!(src_v.len() >= min_v, "src_v isn't large enough"); -} - -fn i010_assert_safety( - src_y: &[u16], - src_stride_y: u32, - src_u: &[u16], - src_stride_u: u32, - src_v: &[u16], - src_stride_v: u32, - _width: i32, - height: i32, -) { - let height_abs: u32 = height.unsigned_abs(); - let chroma_height = height_abs / 2; - let min_y = (src_stride_y * height_abs) as usize / 2; - let min_u = (src_stride_u * chroma_height) as usize / 2; - let min_v = (src_stride_v * chroma_height) as usize / 2; - - assert!(src_y.len() >= min_y, "src_y isn't large enough"); - assert!(src_u.len() >= min_u, "src_u isn't large enough"); - assert!(src_v.len() >= min_v, "src_v isn't large enough"); -} - -macro_rules! i420_to_rgba { - ($x:ident) => { - pub fn $x( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst: &mut [u8], - dst_stride: u32, - width: i32, - height: i32, - ) { - i420_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst, dst_stride, width, height); - - unsafe { - yuv_sys::ffi::$x( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst.as_mut_ptr(), - dst_stride as i32, - width, - height, - ) - .unwrap(); - } - } - }; -} - -macro_rules! rgba_to_i420 { - ($x:ident) => { - pub fn $x( - src_argb: &[u8], - src_stride_argb: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_u: &mut [u8], - dst_stride_u: u32, - dst_v: &mut [u8], - dst_stride_v: u32, - width: i32, - height: i32, - ) { - i420_assert_safety( - dst_y, - dst_stride_y, - dst_u, - dst_stride_u, - dst_v, - dst_stride_v, - width, - height, - ); - argb_assert_safety(src_argb, src_stride_argb, width, height); - - unsafe { - yuv_sys::ffi::$x( - src_argb.as_ptr(), - src_stride_argb as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_u.as_mut_ptr(), - dst_stride_u as i32, - dst_v.as_mut_ptr(), - dst_stride_v as i32, - width, - height, - ) - .unwrap(); - } - } - }; -} - -pub fn argb_to_rgb24( - src_argb: &[u8], - src_stride_argb: u32, - dst_rgb24: &mut [u8], - dst_stride_rgb24: u32, - width: i32, - height: i32, -) { - argb_assert_safety(src_argb, src_stride_argb, width, height); - argb_assert_safety(dst_rgb24, dst_stride_rgb24, width, height); - - unsafe { - yuv_sys::ffi::argb_to_rgb24( - src_argb.as_ptr(), - src_stride_argb as i32, - dst_rgb24.as_mut_ptr(), - dst_stride_rgb24 as i32, - width, - height, - ) - .unwrap(); - } -} - -// I420 <> RGB conversion -rgba_to_i420!(argb_to_i420); -rgba_to_i420!(abgr_to_i420); - -i420_to_rgba!(i420_to_argb); -i420_to_rgba!(i420_to_bgra); -i420_to_rgba!(i420_to_abgr); -i420_to_rgba!(i420_to_rgba); - -pub fn nv12_to_i420( - src_y: &[u8], - src_stride_y: u32, - src_uv: &[u8], - src_stride_uv: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_u: &mut [u8], - dst_stride_u: u32, - dst_v: &mut [u8], - dst_stride_v: u32, - width: i32, - height: i32, -) { - nv12_assert_safety(src_y, src_stride_y, src_uv, src_stride_uv, width, height); - i420_assert_safety( - dst_y, - dst_stride_y, - dst_u, - dst_stride_u, - dst_v, - dst_stride_v, - width, - height, - ); - - unsafe { - yuv_sys::ffi::nv12_to_i420( - src_y.as_ptr(), - src_stride_y as i32, - src_uv.as_ptr(), - src_stride_uv as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_u.as_mut_ptr(), - dst_stride_u as i32, - dst_v.as_mut_ptr(), - dst_stride_v as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn i444_to_i420( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_u: &mut [u8], - dst_stride_u: u32, - dst_v: &mut [u8], - dst_stride_v: u32, - width: i32, - height: i32, -) { - i444_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - i420_assert_safety( - dst_y, - dst_stride_y, - dst_u, - dst_stride_u, - dst_v, - dst_stride_v, - width, - height, - ); - - unsafe { - yuv_sys::ffi::i444_to_i420( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_u.as_mut_ptr(), - dst_stride_u as i32, - dst_v.as_mut_ptr(), - dst_stride_v as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn i422_to_i420( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_u: &mut [u8], - dst_stride_u: u32, - dst_v: &mut [u8], - dst_stride_v: u32, - width: i32, - height: i32, -) { - i422_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - i420_assert_safety( - dst_y, - dst_stride_y, - dst_u, - dst_stride_u, - dst_v, - dst_stride_v, - width, - height, - ); - - unsafe { - yuv_sys::ffi::i422_to_i420( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_u.as_mut_ptr(), - dst_stride_u as i32, - dst_v.as_mut_ptr(), - dst_stride_v as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn i010_to_i420( - src_y: &[u16], - src_stride_y: u32, - src_u: &[u16], - src_stride_u: u32, - src_v: &[u16], - src_stride_v: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_u: &mut [u8], - dst_stride_u: u32, - dst_v: &mut [u8], - dst_stride_v: u32, - width: i32, - height: i32, -) { - i010_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - i420_assert_safety( - dst_y, - dst_stride_y, - dst_u, - dst_stride_u, - dst_v, - dst_stride_v, - width, - height, - ); - - unsafe { - yuv_sys::ffi::i010_to_i420( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_u.as_mut_ptr(), - dst_stride_u as i32, - dst_v.as_mut_ptr(), - dst_stride_v as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn nv12_to_argb( - src_y: &[u8], - src_stride_y: u32, - src_uv: &[u8], - src_stride_uv: u32, - dst_argb: &mut [u8], - dst_stride_argb: u32, - width: i32, - height: i32, -) { - nv12_assert_safety(src_y, src_stride_y, src_uv, src_stride_uv, width, height); - argb_assert_safety(dst_argb, dst_stride_argb, width, height); - - unsafe { - yuv_sys::ffi::nv12_to_argb( - src_y.as_ptr(), - src_stride_y as i32, - src_uv.as_ptr(), - src_stride_uv as i32, - dst_argb.as_mut_ptr(), - dst_stride_argb as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn nv12_to_abgr( - src_y: &[u8], - src_stride_y: u32, - src_uv: &[u8], - src_stride_uv: u32, - dst_abgr: &mut [u8], - dst_stride_abgr: u32, - width: i32, - height: i32, -) { - nv12_assert_safety(src_y, src_stride_y, src_uv, src_stride_uv, width, height); - argb_assert_safety(dst_abgr, dst_stride_abgr, width, height); - - unsafe { - yuv_sys::ffi::nv12_to_abgr( - src_y.as_ptr(), - src_stride_y as i32, - src_uv.as_ptr(), - src_stride_uv as i32, - dst_abgr.as_mut_ptr(), - dst_stride_abgr as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn i444_to_argb( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_argb: &mut [u8], - dst_stride_argb: u32, - width: i32, - height: i32, -) { - i444_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_argb, dst_stride_argb, width, height); - - unsafe { - yuv_sys::ffi::i444_to_argb( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_argb.as_mut_ptr(), - dst_stride_argb as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn i444_to_abgr( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_abgr: &mut [u8], - dst_stride_abgr: u32, - width: i32, - height: i32, -) { - i444_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_abgr, dst_stride_abgr, width, height); - - unsafe { - yuv_sys::ffi::i444_to_abgr( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_abgr.as_mut_ptr(), - dst_stride_abgr as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn i422_to_argb( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_argb: &mut [u8], - dst_stride_argb: u32, - width: i32, - height: i32, -) { - i422_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_argb, dst_stride_argb, width, height); - - unsafe { - yuv_sys::ffi::i422_to_argb( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_argb.as_mut_ptr(), - dst_stride_argb as i32, - width, - height, - ) - .unwrap(); - } -} - -pub fn i422_to_abgr( - src_y: &[u8], - src_stride_y: u32, - src_u: &[u8], - src_stride_u: u32, - src_v: &[u8], - src_stride_v: u32, - dst_abgr: &mut [u8], - dst_stride_abgr: u32, - width: i32, - height: i32, -) { - i422_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_abgr, dst_stride_abgr, width, height); - - unsafe { - yuv_sys::ffi::i422_to_abgr( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_abgr.as_mut_ptr(), - dst_stride_abgr as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn i010_to_argb( - src_y: &[u16], - src_stride_y: u32, - src_u: &[u16], - src_stride_u: u32, - src_v: &[u16], - src_stride_v: u32, - dst_argb: &mut [u8], - dst_stride_argb: u32, - width: i32, - height: i32, -) { - i010_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_argb, dst_stride_argb, width, height); - - unsafe { - yuv_sys::ffi::i010_to_argb( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_argb.as_mut_ptr(), - dst_stride_argb as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn i010_to_abgr( - src_y: &[u16], - src_stride_y: u32, - src_u: &[u16], - src_stride_u: u32, - src_v: &[u16], - src_stride_v: u32, - dst_abgr: &mut [u8], - dst_stride_abgr: u32, - width: i32, - height: i32, -) { - i010_assert_safety( - src_y, - src_stride_y, - src_u, - src_stride_u, - src_v, - src_stride_v, - width, - height, - ); - argb_assert_safety(dst_abgr, dst_stride_abgr, width, height); - - unsafe { - yuv_sys::ffi::i010_to_abgr( - src_y.as_ptr(), - src_stride_y as i32, - src_u.as_ptr(), - src_stride_u as i32, - src_v.as_ptr(), - src_stride_v as i32, - dst_abgr.as_mut_ptr(), - dst_stride_abgr as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn abgr_to_nv12( - src_abgr: &[u8], - src_stride_abgr: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_uv: &mut [u8], - dst_stride_uv: u32, - width: i32, - height: i32, -) { - argb_assert_safety(src_abgr, src_stride_abgr, width, height); - nv12_assert_safety(dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height); - - unsafe { - yuv_sys::ffi::abgr_to_nv12( - src_abgr.as_ptr(), - src_stride_abgr as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_uv.as_mut_ptr(), - dst_stride_uv as i32, - width, - height, - ) - .unwrap() - } -} - -pub fn argb_to_nv12( - src_argb: &[u8], - src_stride_argb: u32, - dst_y: &mut [u8], - dst_stride_y: u32, - dst_uv: &mut [u8], - dst_stride_uv: u32, - width: i32, - height: i32, -) { - argb_assert_safety(src_argb, src_stride_argb, width, height); - nv12_assert_safety(dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height); - - unsafe { - yuv_sys::ffi::argb_to_nv12( - src_argb.as_ptr(), - src_stride_argb as i32, - dst_y.as_mut_ptr(), - dst_stride_y as i32, - dst_uv.as_mut_ptr(), - dst_stride_uv as i32, - width, - height, - ) - .unwrap() - } -} diff --git a/libwebrtc/src/web/data_channel.rs b/libwebrtc/src/web/data_channel.rs deleted file mode 100644 index 89c367436..000000000 --- a/libwebrtc/src/web/data_channel.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use core::str; -use std::cell::RefCell; -use std::rc::Rc; -use wasm_bindgen::prelude::*; -use web_sys::{MessageEvent, RtcDataChannelEvent, RtcDataChannelState}; - -use crate::data_channel::{ - DataChannelError, DataChannelTrait, DataState, OnBufferedAmountChange, OnMessage, OnStateChange, -}; - -impl From for DataState { - fn from(value: RtcDataChannelState) -> Self { - match value { - RtcDataChannelState::Connecting => Self::Connecting, - RtcDataChannelState::Open => Self::Open, - RtcDataChannelState::Closing => Self::Closing, - RtcDataChannelState::Closed => Self::Closed, - _ => panic!("unknown data channel state"), - } - } -} - -#[derive(Clone)] -pub struct DataChannel { - sys_handle: web_sys::RtcDataChannel, - on_closing: Rc>>, -} - -impl DataChannelTrait for DataChannel { - fn send(&self, data: &[u8], binary: bool) -> Result<(), DataChannelError> { - if binary { - self.sys_handle - .send_with_u8_array(data) - .map_err(|_| DataChannelError::Send) - } else { - let utf8 = str::from_utf8(data)?; - self.sys_handle - .send_with_str(utf8) - .map_err(|_| DataChannelError::Send) - } - } - - fn label(&self) -> String { - self.sys_handle.label() - } - - fn state(&self) -> DataState { - self.sys_handle.ready_state().into() - } - - fn close(&self) { - self.sys_handle.close(); - } - - fn on_state_change(&self, callback: Option) { - if let Some(mut callback) = callback { - let dc = self.clone(); - let js_callback = Closure::new(move |_: RtcDataChannelEvent| { - callback(dc.state()); - }); - let js_callback = js_callback.into_js_value(); - self.sys_handle - .set_onopen(Some(js_callback.unchecked_ref())); - self.sys_handle - .set_onclose(Some(js_callback.unchecked_ref())); - self.sys_handle - .add_event_listener_with_callback("closing", js_callback.unchecked_ref()) - .unwrap(); - - self.on_closing.replace(Some(js_callback)); - } else { - self.sys_handle.set_onopen(None); - self.sys_handle.set_onclose(None); - if let Some(on_closing) = self.on_closing.take() { - self.sys_handle - .remove_event_listener_with_callback("closing", on_closing.unchecked_ref()) - .unwrap(); - } - self.on_closing.replace(None); - } - } - - fn on_message(&self, callback: Option) { - let js_callback = callback.map(|mut callback| { - Closure::new(move |event: MessageEvent| { - if let Some(str) = event.as_string() { - callback(str.as_bytes(), false); - } - }) - .into_js_value() - }); - - self.sys_handle.set_onmessage( - js_callback - .as_ref() - .map(|callback| callback.unchecked_ref()), - ); - } - - fn on_buffered_amount_change(&self, _callback: Option) { - todo!("onbufferedamountlow instead?") - } -} diff --git a/libwebrtc/src/web/media_stream.rs b/libwebrtc/src/web/media_stream.rs deleted file mode 100644 index 23d4fd421..000000000 --- a/libwebrtc/src/web/media_stream.rs +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use super::VideoTrack; -use crate::{ - media_stream::{ - BiplanarYuv8Buffer, BiplanarYuvBuffer, PlanarYuv16BBuffer, PlanarYuv8Buffer, - PlanarYuvBuffer, VideoFrameBuffer, - }, - video_frame::{BiplanarYuv8Buffer, I420Buffer, SinkError, VideoFrame, VideoFrameBuffer}, - I010Buffer, I420ABuffer, I422Buffer, I444Buffer, NV12Buffer, -}; -use std::sync::mpsc; -use web_sys::{WebGlRenderingContext, WebGlTexture}; - -#[derive(Debug)] -pub struct WebGlVideoSink { - track: Arc, - gl_ctx: WebGlRenderingContext, - tex: WebGlTexture, -} - -/// Create a new WebGL texture and update it inside requestAnimationFrame -impl WebGlVideoSink { - pub fn new( - track: Arc, - gl_ctx: WebGlRenderingContext, - ) -> Result<(Self, mpsc::Receiver>), SinkError> { - let (sender, receiver) = mpsc::channel(); - let tex = gl_ctx.create_texture()?; - Ok((Self { track, gl_ctx, tex }, receiver)) - } -} - -#[derive(Debug, Clone)] -pub struct WebGlBuffer { - width: i32, - height: i32, - tex: WebGlTexture, -} - -impl VideoFrameBuffer for WebGlBuffer { - fn width(&self) -> i32 { - self.width - } - - fn height(&self) -> i32 { - self.height - } -} - -/// The following types could be implemented if we want -/// to support VideoFrame with WebCodecs - -#[derive(Debug)] -pub struct I420Buffer {} - -#[derive(Debug)] -pub struct I420ABuffer {} - -#[derive(Debug)] -pub struct I422Buffer {} - -#[derive(Debug)] -pub struct I444Buffer {} - -#[derive(Debug)] -pub struct I010Buffer {} - -#[derive(Debug)] -pub struct NV12Buffer {} - -impl VideoFrameBuffer for I420Buffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl VideoFrameBuffer for I420ABuffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl VideoFrameBuffer for I422Buffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl VideoFrameBuffer for I444Buffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl VideoFrameBuffer for I010Buffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl VideoFrameBuffer for NV12Buffer { - fn width(&self) -> i32 { - unimplemented!() - } - - fn height(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for I420Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for I420ABuffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for I422Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for I444Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for I010Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuvBuffer for NV12Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_u(&self) -> i32 { - unimplemented!() - } - - fn stride_v(&self) -> i32 { - unimplemented!() - } -} - -impl PlanarYuv8Buffer for I420Buffer { - fn data_y(&self) -> &[u8] { - unimplemented!() - } - - fn data_u(&self) -> &[u8] { - unimplemented!() - } - - fn data_v(&self) -> &[u8] { - unimplemented!() - } -} - -impl PlanarYuv8Buffer for I420ABuffer { - fn data_y(&self) -> &[u8] { - unimplemented!() - } - - fn data_u(&self) -> &[u8] { - unimplemented!() - } - - fn data_v(&self) -> &[u8] { - unimplemented!() - } -} - -impl PlanarYuv8Buffer for I422Buffer { - fn data_y(&self) -> &[u8] { - unimplemented!() - } - - fn data_u(&self) -> &[u8] { - unimplemented!() - } - - fn data_v(&self) -> &[u8] { - unimplemented!() - } -} - -impl PlanarYuv8Buffer for I444Buffer { - fn data_y(&self) -> &[u8] { - unimplemented!() - } - - fn data_u(&self) -> &[u8] { - unimplemented!() - } - - fn data_v(&self) -> &[u8] { - unimplemented!() - } -} - -impl PlanarYuv16BBuffer for I010Buffer { - fn data_y(&self) -> &[u16] { - unimplemented!() - } - - fn data_u(&self) -> &[u16] { - unimplemented!() - } - - fn data_v(&self) -> &[u16] { - unimplemented!() - } -} - -impl BiplanarYuvBuffer for NV12Buffer { - fn chroma_width(&self) -> i32 { - unimplemented!() - } - - fn chroma_height(&self) -> i32 { - unimplemented!() - } - - fn stride_y(&self) -> i32 { - unimplemented!() - } - - fn stride_uv(&self) -> i32 { - unimplemented!() - } -} - -impl BiplanarYuv8Buffer for NV12Buffer { - fn data_y(&self) -> &[u8] { - unimplemented!() - } - - fn data_uv(&self) -> &[u8] { - unimplemented!() - } -} diff --git a/libwebrtc/src/web/mod.rs b/libwebrtc/src/web/mod.rs deleted file mode 100644 index 77713ce4b..000000000 --- a/libwebrtc/src/web/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2023 LiveKit, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -unimplemented!();