From e5a3621705ce59f2bd81a90be602c75b9938f144 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Wed, 1 Jul 2020 19:21:13 +0100 Subject: [PATCH] Initial checkin --- .gitignore | 1 + .gitmodules | 4 + Cargo.lock | 1425 +++++++++++++++++++++++++++++++++++ Cargo.toml | 29 + janus-web-app/igalia-bg.png | Bin 0 -> 153763 bytes janus-web-app/index.html | 21 + janus-web-app/webrtc.js | 84 +++ src/app.rs | 53 ++ src/janus.rs | 618 +++++++++++++++ src/macros.rs | 14 + src/main.rs | 27 + src/pipeline.rs | 213 ++++++ src/settings.rs | 79 ++ src/utils.rs | 27 + wpe-graphics-overlays | 1 + 15 files changed, 2596 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 janus-web-app/igalia-bg.png create mode 100644 janus-web-app/index.html create mode 100644 janus-web-app/webrtc.js create mode 100644 src/app.rs create mode 100644 src/janus.rs create mode 100644 src/macros.rs create mode 100644 src/main.rs create mode 100644 src/pipeline.rs create mode 100644 src/settings.rs create mode 100644 src/utils.rs create mode 160000 wpe-graphics-overlays diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..275bbfb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "wpe-graphics-overlays"] + path = wpe-graphics-overlays + url = https://github.com/Igalia/wpe-graphics-overlays.git + branch = igalia diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..bee110c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1425 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602d785912f476e480434627e8732e6766b760c045bbf897d9dfaa9f4fbd399c" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler32" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" + +[[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" + +[[package]] +name = "async-tungstenite" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c35882200d230428ae9cf74acb72aaa9c0a912911b4dad8fb890da49608e127" +dependencies = [ + "futures-io", + "futures-util", + "gio", + "glib", + "log 0.4.8", + "pin-project", + "tungstenite", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +dependencies = [ + "byteorder", + "safemem", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "bytes" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" +dependencies = [ + "loom", +] + +[[package]] +name = "cc" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c1f1d60091c1b73e2b1f4560ab419204b178e625fa945ded7b660becd2bd46" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "clap" +version = "2.33.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" +dependencies = [ + "bitflags 1.2.1", + "textwrap", + "unicode-width", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dtoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" + +[[package]] +name = "embedded-gst-wpe-demo" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-tungstenite", + "base64 0.11.0", + "env_logger", + "futures", + "gio", + "glib", + "gstreamer", + "gstreamer-sdp", + "gstreamer-webrtc", + "http", + "log 0.4.8", + "num", + "rand", + "serde", + "serde_any", + "serde_derive", + "serde_json", + "strfmt", + "structopt", + "url 2.1.1", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log 0.4.8", + "regex", + "termcolor", +] + +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +dependencies = [ + "backtrace", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" + +[[package]] +name = "futures-executor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" + +[[package]] +name = "futures-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" + +[[package]] +name = "futures-task" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +dependencies = [ + "once_cell", +] + +[[package]] +name = "futures-util" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generator" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" +dependencies = [ + "cc", + "libc", + "log 0.4.8", + "rustc_version", + "winapi", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" + +[[package]] +name = "gio" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cd10f9415cce39b53f8024bf39a21f84f8157afa52da53837b102e585a296a5" +dependencies = [ + "bitflags 1.2.1", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "lazy_static", + "libc", +] + +[[package]] +name = "gio-sys" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fad225242b9eae7ec8a063bb86974aca56885014672375e5775dc0ea3533911" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", +] + +[[package]] +name = "glib" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40fb573a09841b6386ddf15fd4bc6655b4f5b106ca962f57ecaecde32a0061c0" +dependencies = [ + "bitflags 1.2.1", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "glib-sys", + "gobject-sys", + "lazy_static", + "libc", +] + +[[package]] +name = "glib-sys" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95856f3802f446c05feffa5e24859fe6a183a7cb849c8449afc35c86b1e316e2" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "gobject-sys" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d1a804f62034eccf370006ccaef3708a71c31d561fee88564abe71177553d9" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", +] + +[[package]] +name = "gstreamer" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8664a114cd6ec16bece783d5eee59496919915b1f6884400ba4a953274a163" +dependencies = [ + "bitflags 1.2.1", + "cfg-if", + "futures-channel", + "futures-core", + "futures-util", + "glib", + "glib-sys", + "gobject-sys", + "gstreamer-sys", + "lazy_static", + "libc", + "muldiv", + "num-rational", + "paste", +] + +[[package]] +name = "gstreamer-sdp" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "547b3b0eb9e01e13ab5cc066c817e2ab758f83790145f80f62d3c8e43c2966af" +dependencies = [ + "glib", + "glib-sys", + "gobject-sys", + "gstreamer", + "gstreamer-sdp-sys", + "gstreamer-sys", +] + +[[package]] +name = "gstreamer-sdp-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e88ac4f9f20323ef3409dddcea3bbf58364ff8eea10b14da5303bfcb23347a" +dependencies = [ + "glib-sys", + "gobject-sys", + "gstreamer-sys", + "libc", + "pkg-config", +] + +[[package]] +name = "gstreamer-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d18da01b97d0ab5896acd5151e4c155acefd0e6c03c3dd24dd133ba054053db" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", +] + +[[package]] +name = "gstreamer-webrtc" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f433d1294266fb1d65e1dc2d4de365f7f4caf23cb72db3a3bd6904eeec88cf1" +dependencies = [ + "glib", + "glib-sys", + "gobject-sys", + "gstreamer", + "gstreamer-sdp", + "gstreamer-sys", + "gstreamer-webrtc-sys", + "libc", +] + +[[package]] +name = "gstreamer-webrtc-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f392bd821b42efecfc21016c8ef20da188b45a45bbb5ddf81758704f93aae615" +dependencies = [ + "glib-sys", + "gobject-sys", + "gstreamer-sdp-sys", + "gstreamer-sys", + "libc", + "pkg-config", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909" +dependencies = [ + "libc", +] + +[[package]] +name = "http" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "input_buffer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754" +dependencies = [ + "bytes", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +dependencies = [ + "log 0.4.8", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", +] + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "muldiv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204" + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" + +[[package]] +name = "once_cell" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "paste" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" +dependencies = [ + "paste-impl", + "proc-macro-hack", +] + +[[package]] +name = "paste-impl" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" +dependencies = [ + "proc-macro-hack", +] + +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" + +[[package]] +name = "ppv-lite86" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" + +[[package]] +name = "proc-macro-error" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "syn-mid", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" + +[[package]] +name = "proc-macro-nested" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" + +[[package]] +name = "proc-macro2" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" + +[[package]] +name = "ron" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9fa11b7a38511d46ff1959ae46ebb60bd8a746f17bdd0206b4c8de7559ac47b" +dependencies = [ + "base64 0.9.3", + "bitflags 1.2.1", + "serde", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "scoped-tls" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-xml-any" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281928a3e3104e809dbd19b78cef7ef7c29662cf2583a94c032485aa2e7586b" +dependencies = [ + "error-chain", + "log 0.3.9", + "serde", + "xml-rs", +] + +[[package]] +name = "serde_any" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cb506febacc2cf6533279947bd37b69ce91782af1aedf31c7e6181a77d46ee" +dependencies = [ + "failure", + "ron", + "serde", + "serde-xml-any", + "serde_json", + "serde_urlencoded", + "serde_yaml", + "toml", +] + +[[package]] +name = "serde_derive" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" +dependencies = [ + "dtoa", + "itoa", + "serde", + "url 1.7.2", +] + +[[package]] +name = "serde_yaml" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8099d3df28273c99a1728190c7a9f19d444c941044f64adf986bee7ec53051" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "strfmt" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b278b244ef7aa5852b277f52dd0c6cac3a109919e1f6d699adde63251227a30f" + +[[package]] +name = "structopt" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tinyvec" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" + +[[package]] +name = "toml" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +dependencies = [ + "serde", +] + +[[package]] +name = "tungstenite" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5c7d464221cb0b538a1cd12f6d9127ed1e6bb7f3ffca98fb3cd4c6e3af8175c" +dependencies = [ + "base64 0.12.3", + "byteorder", + "bytes", + "http", + "httparse", + "input_buffer", + "log 0.4.8", + "rand", + "sha-1", + "url 2.1.1", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +dependencies = [ + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", +] + +[[package]] +name = "url" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +dependencies = [ + "idna 0.2.0", + "matches", + "percent-encoding 2.1.0", +] + +[[package]] +name = "utf-8" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xml-rs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621" +dependencies = [ + "bitflags 0.9.1", +] + +[[package]] +name = "yaml-rust" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..edd11bb --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "embedded-gst-wpe-demo" +version = "0.1.0" +authors = ["Philippe Normand "] +edition = "2018" + +[dependencies] +anyhow = "1.0.31" +async-tungstenite = { version = "0.7", features = ["gio-runtime"] } +base64 = "0.11" +futures = "0.3" +gio = "0.8" +glib = "0.9" +gst = { package = "gstreamer", version = "0.15", features = ["v1_10"] } +gst-sdp = { package = "gstreamer-sdp", version = "0.15", features = ["v1_14"] } +gst-webrtc = { package = "gstreamer-webrtc", version = "0.15" } +http = "0.2" +num = "0.2" +rand = "0.7" +serde = "1" +serde_any = "0.5" +serde_derive = "1" +serde_json = "1.0.53" +strfmt = "0.1.6" +url = "2" +structopt = { version = "0.3", default-features = false } +env_logger = "0.7.1" +log = "0.4.8" + diff --git a/janus-web-app/igalia-bg.png b/janus-web-app/igalia-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..476213c3ffdbf6c5b48b6a3bc9d3120cfcb21014 GIT binary patch literal 153763 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�{;U9`KmjZODX|M2@$pPC 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%0AG-dfexxy`Y3+*1Rt=+cLUI@P`hkI{`ENc2l;c+c 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 gmxD + + + + + + + + + + + + + diff --git a/janus-web-app/webrtc.js b/janus-web-app/webrtc.js new file mode 100644 index 0000000..a2e9c48 --- /dev/null +++ b/janus-web-app/webrtc.js @@ -0,0 +1,84 @@ +var remoteVideo; +var peerConnection; +var janusConnection; +var sessionId; +var handleId; +const roomId = 1234; +const feedId = 42; +const CONFIG = { audio: false, video: false, iceServers: [ {urls: 'stun:stun.l.google.com:19302'}, ] }; +const RECEIVERS = { create_session, create_handle, publish, join_subscriber, ack }; + +function send(msg) { + janusConnection.send(JSON.stringify(msg)); +} + +function ack(payload) {} + +function start() { + remoteVideo = document.getElementById('remoteVideo'); + janusConnection = new WebSocket('wss://' + window.location.hostname + ':8989', 'janus-protocol'); + janusConnection.onmessage = function(message) { + var payload = JSON.parse(message.data); + var receiver = RECEIVERS[payload.janus] || RECEIVERS[payload.transaction] || console.log; + receiver(payload); + }; + janusConnection.onopen = function(event) { + send({janus: 'create', transaction: 'create_session'}); + }; +} + +function join_broadcast() { + peerConnection = new RTCPeerConnection(CONFIG); + peerConnection.onicecandidate = on_ice_candidate; + peerConnection.ontrack = on_track; + + send({janus: 'message', transaction: 'join_subscriber', + body: {request : 'join', ptype: 'subscriber', room: roomId, feed: feedId}, + session_id: sessionId, handle_id: handleId}); +} + +function on_ice_candidate(event) { + send({janus: 'trickle', transaction: 'candidate', candidate: event.candidate, + session_id: sessionId, handle_id: handleId}); +} + +function on_track(event) { + remoteVideo.srcObject = event.streams[0]; + remoteVideo.play(); +} + +function keepalive() { + send({janus: 'keepalive', transaction: 'keepalive', session_id: sessionId}); +} + +function create_session(payload) { + sessionId = payload.data.id; + setInterval(keepalive, 30000); + send({janus: 'attach', transaction: 'create_handle', plugin: 'janus.plugin.videoroom', session_id: sessionId}); +} + +function create_handle(payload) { + handleId = payload.data.id; + join_broadcast(); +} + +function publish(payload) { + peerConnection.setRemoteDescription(new RTCSessionDescription(payload.jsep)); +} + +function join_subscriber(payload) { + if (!payload.jsep) { + var container = document.getElementById('message'); + if (payload.plugindata.data.error_code == 428) { + container.innerHTML = "GstWPE demo is offline. "; + } + container.innerHTML += payload.plugindata.data.error; + return; + } + peerConnection.setRemoteDescription(new RTCSessionDescription(payload.jsep)); + peerConnection.createAnswer().then(function(answer) { + peerConnection.setLocalDescription(answer); + send({janus: 'message', transaction: 'blah', body: {request: 'start'}, + jsep: answer, session_id: sessionId, handle_id: handleId}); + }); +} diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..6e35bb3 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,53 @@ +use crate::janus; +use crate::pipeline::Pipeline; + +use anyhow::anyhow; +use gst::prelude::*; +use std::ops; +use std::rc::Rc; + +// Our refcounted application struct for containing all the state we have to carry around. +// +// This represents our main application window. +#[derive(Clone)] +pub struct App(Rc); + +// Deref into the contained struct to make usage a bit more ergonomic +impl ops::Deref for App { + type Target = AppInner; + + fn deref(&self) -> &AppInner { + &*self.0 + } +} + +pub struct AppInner { + pipeline: Pipeline, +} + +impl App { + pub fn new() -> Result { + let pipeline = + Pipeline::new().map_err(|err| anyhow!("Error creating pipeline: {:?}", err))?; + + let app = App(Rc::new(AppInner { pipeline })); + Ok(app) + } + + pub async fn run(&self) -> Result<(), anyhow::Error> { + self.pipeline.prepare()?; + let bin = self.pipeline.pipeline.clone().upcast::(); + let mut gw = janus::JanusGateway::new(bin).await?; + self.pipeline.start()?; + gw.run().await?; + Ok(()) + } +} + +// Make sure to shut down the pipeline when it goes out of scope +// to release any system resources +impl Drop for AppInner { + fn drop(&mut self) { + let _ = self.pipeline.stop(); + } +} diff --git a/src/janus.rs b/src/janus.rs new file mode 100644 index 0000000..f5df082 --- /dev/null +++ b/src/janus.rs @@ -0,0 +1,618 @@ +// GStreamer +// +// Copyright (C) 2018 maxmcd +// Copyright (C) 2019 Sebastian Dröge +// Copyright (C) 2020 Philippe Normand +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301, USA. + +use { + anyhow::{anyhow, bail, Context}, + async_tungstenite::{gio::connect_async, tungstenite}, + futures::channel::mpsc, + futures::sink::{Sink, SinkExt}, + futures::stream::{Stream, StreamExt}, + gst::gst_element_error, + gst::prelude::*, + http::Request, + rand::prelude::*, + serde_derive::{Deserialize, Serialize}, + serde_json::json, + std::sync::{Arc, Mutex, Weak}, + structopt::StructOpt, + tungstenite::Message as WsMessage, +}; + +#[derive(Debug, StructOpt)] +pub struct Args { + #[structopt(short, long, default_value = "wss://janus.conf.meetecho.com/ws:8989")] + server: String, + #[structopt(short, long, default_value = "1234")] + room_id: u32, + #[structopt(short, long, default_value = "666")] + feed_id: u32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Base { + janus: String, + transaction: Option, + session_id: Option, + sender: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +struct DataHolder { + id: i64, +} + +#[derive(Serialize, Deserialize, Debug)] +struct PluginDataHolder { + videoroom: String, + room: Option, + #[serde(rename = "current-bitrate")] + current_bitrate: Option, + description: Option, + id: Option, + configured: Option, + video_codec: Option, + unpublished: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +struct PluginHolder { + plugin: String, + data: PluginDataHolder, +} + +#[derive(Serialize, Deserialize, Debug)] +struct IceHolder { + candidate: String, + #[serde(rename = "sdpMLineIndex")] + sdp_mline_index: u32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct JsepHolder { + #[serde(rename = "type")] + type_: String, + sdp: Option, + ice: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +struct JsonReply { + #[serde(flatten)] + base: Base, + data: Option, + #[serde(rename = "plugindata")] + plugin_data: Option, + jsep: Option, +} + +fn transaction_id() -> String { + thread_rng() + .sample_iter(&rand::distributions::Alphanumeric) + .take(30) + .collect() +} + +// Strong reference to the state of one peer +#[derive(Debug, Clone)] +struct Peer(Arc); + +// Weak reference to the state of one peer +#[derive(Debug, Clone)] +struct PeerWeak(Weak); + +impl PeerWeak { + // Try upgrading a weak reference to a strong one + fn upgrade(&self) -> Option { + self.0.upgrade().map(Peer) + } +} + +// To be able to access the Peers's fields directly +impl std::ops::Deref for Peer { + type Target = PeerInner; + + fn deref(&self) -> &PeerInner { + &self.0 + } +} + +#[derive(Clone, Copy, Debug)] +struct ConnectionHandle { + id: i64, + session_id: i64, +} + +// Actual peer state +#[derive(Debug)] +struct PeerInner { + handle: ConnectionHandle, + bin: gst::Bin, + webrtcbin: gst::Element, + send_msg_tx: Arc>>, +} + +impl Peer { + // Downgrade the strong reference to a weak reference + fn downgrade(&self) -> PeerWeak { + PeerWeak(Arc::downgrade(&self.0)) + } + + // Whenever webrtcbin tells us that (re-)negotiation is needed, simply ask + // for a new offer SDP from webrtcbin without any customization and then + // asynchronously send it to the peer via the WebSocket connection + fn on_negotiation_needed(&self) -> Result<(), anyhow::Error> { + info!("starting negotiation with peer"); + + let peer_clone = self.downgrade(); + let promise = gst::Promise::new_with_change_func(move |res| { + let s = res.expect("no answer"); + let peer = upgrade_weak!(peer_clone); + + if let Err(err) = peer.on_offer_created(&s.to_owned()) { + gst_element_error!( + peer.bin, + gst::LibraryError::Failed, + ("Failed to send SDP offer: {:?}", err) + ); + } + }); + + self.webrtcbin + .emit("create-offer", &[&None::, &promise])?; + + Ok(()) + } + + // Once webrtcbin has create the offer SDP for us, handle it by sending it to the peer via the + // WebSocket connection + fn on_offer_created(&self, reply: &gst::Structure) -> Result<(), anyhow::Error> { + let offer = reply + .get_value("offer")? + .get::() + .expect("Invalid argument") + .expect("Invalid offer"); + self.webrtcbin + .emit("set-local-description", &[&offer, &None::])?; + + info!("sending SDP offer to peer: {:?}", offer.get_sdp().as_text()); + + let transaction = transaction_id(); + let sdp_data = offer.get_sdp().as_text()?; + let msg = WsMessage::Text( + json!({ + "janus": "message", + "transaction": transaction, + "session_id": self.handle.session_id, + "handle_id": self.handle.id, + "body": { + "request": "publish", + "audio": true, + "video": true, + }, + "jsep": { + "sdp": sdp_data, + "trickle": true, + "type": "offer" + } + }) + .to_string(), + ); + self.send_msg_tx + .lock() + .expect("Invalid message sender") + .unbounded_send(msg) + .with_context(|| "Failed to send SDP offer".to_string())?; + + Ok(()) + } + + // Once webrtcbin has create the answer SDP for us, handle it by sending it to the peer via the + // WebSocket connection + fn on_answer_created(&self, reply: &gst::Structure) -> Result<(), anyhow::Error> { + let answer = reply + .get_value("answer")? + .get::() + .expect("Invalid argument") + .expect("Invalid answer"); + self.webrtcbin + .emit("set-local-description", &[&answer, &None::])?; + + info!( + "sending SDP answer to peer: {:?}", + answer.get_sdp().as_text() + ); + + Ok(()) + } + + // Handle incoming SDP answers from the peer + fn handle_sdp(&self, type_: &str, sdp: &str) -> Result<(), anyhow::Error> { + if type_ == "answer" { + info!("Received answer:\n{}\n", sdp); + + let ret = gst_sdp::SDPMessage::parse_buffer(sdp.as_bytes()) + .map_err(|_| anyhow!("Failed to parse SDP answer"))?; + let answer = + gst_webrtc::WebRTCSessionDescription::new(gst_webrtc::WebRTCSDPType::Answer, ret); + + self.webrtcbin + .emit("set-remote-description", &[&answer, &None::])?; + + Ok(()) + } else if type_ == "offer" { + info!("Received offer:\n{}\n", sdp); + + let ret = gst_sdp::SDPMessage::parse_buffer(sdp.as_bytes()) + .map_err(|_| anyhow!("Failed to parse SDP offer"))?; + + // And then asynchronously start our pipeline and do the next steps. The + // pipeline needs to be started before we can create an answer + let peer_clone = self.downgrade(); + self.bin.call_async(move |_pipeline| { + let peer = upgrade_weak!(peer_clone); + + let offer = gst_webrtc::WebRTCSessionDescription::new( + gst_webrtc::WebRTCSDPType::Offer, + ret, + ); + + peer.0 + .webrtcbin + .emit("set-remote-description", &[&offer, &None::]) + .expect("Unable to set remote description"); + + let peer_clone = peer.downgrade(); + let promise = gst::Promise::new_with_change_func(move |reply| { + let s = reply.expect("No answer"); + let peer = upgrade_weak!(peer_clone); + + if let Err(err) = peer.on_answer_created(&s.to_owned()) { + gst_element_error!( + peer.bin, + gst::LibraryError::Failed, + ("Failed to send SDP answer: {:?}", err) + ); + } + }); + + peer.0 + .webrtcbin + .emit("create-answer", &[&None::, &promise]) + .expect("Unable to create answer"); + }); + + Ok(()) + } else { + bail!("Sdp type is not \"answer\" but \"{}\"", type_) + } + } + + // Handle incoming ICE candidates from the peer by passing them to webrtcbin + fn handle_ice(&self, sdp_mline_index: u32, candidate: &str) -> Result<(), anyhow::Error> { + info!( + "Received remote ice-candidate {} {}", + sdp_mline_index, candidate + ); + self.webrtcbin + .emit("add-ice-candidate", &[&sdp_mline_index, &candidate])?; + + Ok(()) + } + + // Asynchronously send ICE candidates to the peer via the WebSocket connection as a JSON + // message + fn on_ice_candidate(&self, mlineindex: u32, candidate: String) -> Result<(), anyhow::Error> { + let transaction = transaction_id(); + info!("Sending ICE {} {}", mlineindex, &candidate); + let msg = WsMessage::Text( + json!({ + "janus": "trickle", + "transaction": transaction, + "session_id": self.handle.session_id, + "handle_id": self.handle.id, + "candidate": { + "candidate": candidate, + "sdpMLineIndex": mlineindex + }, + }) + .to_string(), + ); + self.send_msg_tx + .lock() + .expect("Invalid message sender") + .unbounded_send(msg) + .with_context(|| "Failed to send ICE candidate".to_string())?; + + Ok(()) + } +} + +// At least shut down the bin here if it didn't happen so far +impl Drop for PeerInner { + fn drop(&mut self) { + let _ = self.bin.set_state(gst::State::Null); + } +} + +type WsStream = + std::pin::Pin> + Send>>; +type WsSink = std::pin::Pin + Send>>; + +pub struct JanusGateway { + ws_stream: Option, + ws_sink: Option, + handle: ConnectionHandle, + peer: Mutex, + send_ws_msg_rx: Option>, +} + +impl JanusGateway { + pub async fn new(pipeline: gst::Bin) -> Result { + let args = Args::from_args(); + let request = Request::builder() + .uri(&args.server) + .header("Sec-WebSocket-Protocol", "janus-protocol") + .body(())?; + + let (mut ws, _) = connect_async(request).await?; + + let transaction = transaction_id(); + let msg = WsMessage::Text( + json!({ + "janus": "create", + "transaction": transaction, + }) + .to_string(), + ); + ws.send(msg).await?; + + let msg = ws + .next() + .await + .ok_or_else(|| anyhow!("didn't receive anything"))??; + let payload = msg.to_text()?; + let json_msg: JsonReply = serde_json::from_str(payload)?; + assert_eq!(json_msg.base.janus, "success"); + assert_eq!(json_msg.base.transaction, Some(transaction)); + let session_id = json_msg.data.expect("no session id").id; + + let transaction = transaction_id(); + let msg = WsMessage::Text( + json!({ + "janus": "attach", + "transaction": transaction, + "plugin": "janus.plugin.videoroom", + "session_id": session_id, + }) + .to_string(), + ); + ws.send(msg).await?; + + let msg = ws + .next() + .await + .ok_or_else(|| anyhow!("didn't receive anything"))??; + let payload = msg.to_text()?; + let json_msg: JsonReply = serde_json::from_str(payload)?; + assert_eq!(json_msg.base.janus, "success"); + assert_eq!(json_msg.base.transaction, Some(transaction)); + let handle = json_msg.data.expect("no session id").id; + + let transaction = transaction_id(); + let msg = WsMessage::Text( + json!({ + "janus": "message", + "transaction": transaction, + "session_id": session_id, + "handle_id": handle, + "body": { + "request": "join", + "ptype": "publisher", + "room": args.room_id, + "id": args.feed_id, + }, + }) + .to_string(), + ); + ws.send(msg).await?; + + let webrtcbin = pipeline + .get_by_name("webrtcbin") + .expect("can't find webrtcbin"); + + if let Ok(transceiver) = webrtcbin.emit("get-transceiver", &[&0.to_value()]) { + if let Some(t) = transceiver { + if let Ok(obj) = t.get::() { + obj.expect("Invalid transceiver") + .set_property("do-nack", &true.to_value())?; + } + } + } + + let (send_ws_msg_tx, send_ws_msg_rx) = mpsc::unbounded::(); + + let connection_handle = ConnectionHandle { + id: handle, + session_id, + }; + + let peer = Peer(Arc::new(PeerInner { + handle: connection_handle, + bin: pipeline, + webrtcbin, + send_msg_tx: Arc::new(Mutex::new(send_ws_msg_tx)), + })); + + // Connect to on-negotiation-needed to handle sending an Offer + let peer_clone = peer.downgrade(); + peer.webrtcbin + .connect("on-negotiation-needed", false, move |_| { + let peer = upgrade_weak!(peer_clone, None); + if let Err(err) = peer.on_negotiation_needed() { + gst_element_error!( + peer.bin, + gst::LibraryError::Failed, + ("Failed to negotiate: {:?}", err) + ); + } + + None + })?; + + // Whenever there is a new ICE candidate, send it to the peer + let peer_clone = peer.downgrade(); + peer.webrtcbin + .connect("on-ice-candidate", false, move |values| { + let mlineindex = values[1] + .get::() + .expect("Invalid argument") + .expect("Invalid type"); + let candidate = values[2] + .get::() + .expect("Invalid argument") + .expect("Invalid type"); + + let peer = upgrade_weak!(peer_clone, None); + if let Err(err) = peer.on_ice_candidate(mlineindex, candidate) { + gst_element_error!( + peer.bin, + gst::LibraryError::Failed, + ("Failed to send ICE candidate: {:?}", err) + ); + } + + None + })?; + + // Split the websocket into the Sink and Stream + let (ws_sink, ws_stream) = ws.split(); + + Ok(Self { + ws_stream: Some(ws_stream.boxed()), + ws_sink: Some(Box::pin(ws_sink)), + handle: connection_handle, + peer: Mutex::new(peer), + send_ws_msg_rx: Some(send_ws_msg_rx), + }) + } + + pub async fn run(&mut self) -> Result<(), anyhow::Error> { + if let Some(ws_stream) = self.ws_stream.take() { + // Fuse the Stream, required for the select macro + let mut ws_stream = ws_stream.fuse(); + + // Channel for outgoing WebSocket messages from other threads + let send_ws_msg_rx = self + .send_ws_msg_rx + .take() + .expect("Invalid message receiver"); + let mut send_ws_msg_rx = send_ws_msg_rx.fuse(); + + let timer = glib::interval_stream(10_000); + let mut timer_fuse = timer.fuse(); + + let mut sink = self.ws_sink.take().expect("Invalid websocket sink"); + loop { + let ws_msg = futures::select! { + // Handle the WebSocket messages here + ws_msg = ws_stream.select_next_some() => { + match ws_msg? { + WsMessage::Close(_) => { + info!("peer disconnected"); + break + }, + WsMessage::Ping(data) => Some(WsMessage::Pong(data)), + WsMessage::Pong(_) => None, + WsMessage::Binary(_) => None, + WsMessage::Text(text) => { + if let Err(err) = self.handle_websocket_message(&text) { + error!("Failed to parse message: {} ... error: {}", &text, err); + } + None + }, + } + }, + // Handle WebSocket messages we created asynchronously + // to send them out now + ws_msg = send_ws_msg_rx.select_next_some() => Some(ws_msg), + + // Handle keepalive ticks, fired every 10 seconds + ws_msg = timer_fuse.select_next_some() => { + let transaction = transaction_id(); + Some(WsMessage::Text( + json!({ + "janus": "keepalive", + "transaction": transaction, + "handle_id": self.handle.id, + "session_id": self.handle.session_id, + }).to_string(), + )) + }, + // Once we're done, break the loop and return + complete => break, + }; + + // If there's a message to send out, do so now + if let Some(ws_msg) = ws_msg { + sink.send(ws_msg).await?; + } + } + } + Ok(()) + } + + fn handle_jsep(&self, jsep: &JsepHolder) -> Result<(), anyhow::Error> { + if let Some(sdp) = &jsep.sdp { + assert_eq!(jsep.type_, "answer"); + let peer = self.peer.lock().expect("Invalid peer"); + return peer.handle_sdp(&jsep.type_, &sdp); + } else if let Some(ice) = &jsep.ice { + let peer = self.peer.lock().expect("Invalid peer"); + return peer.handle_ice(ice.sdp_mline_index, &ice.candidate); + } + + Ok(()) + } + + // Handle WebSocket messages, both our own as well as WebSocket protocol messages + fn handle_websocket_message(&self, msg: &str) -> Result<(), anyhow::Error> { + trace!("Incoming raw message: {}", msg); + let json_msg: JsonReply = serde_json::from_str(msg)?; + let payload_type = &json_msg.base.janus; + if payload_type == "ack" { + trace!( + "Ack transaction {:#?}, sessionId {:#?}", + json_msg.base.transaction, + json_msg.base.session_id + ); + } else { + debug!("Incoming JSON WebSocket message: {:#?}", json_msg); + } + if payload_type == "event" { + if let Some(_plugin_data) = json_msg.plugin_data { + if let Some(jsep) = json_msg.jsep { + return self.handle_jsep(&jsep); + } + } + } + Ok(()) + } +} diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..ca8bc11 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,14 @@ +// Macro for upgrading a weak reference or returning the given value +// +// This works for glib/gtk objects as well as anything else providing an upgrade method +macro_rules! upgrade_weak { + ($x:ident, $r:expr) => {{ + match $x.upgrade() { + Some(o) => o, + None => return $r, + } + }}; + ($x:ident) => { + upgrade_weak!($x, ()) + }; +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0c50395 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,27 @@ +#![recursion_limit = "256"] + +#[macro_use] +mod macros; +mod app; +mod janus; +mod pipeline; +mod settings; +mod utils; + +use crate::app::App; +#[macro_use] +extern crate log; + +pub const APPLICATION_NAME: &str = "com.igalia.gstwpe.broadcast.demo"; + +async fn async_main() -> Result<(), anyhow::Error> { + gst::init()?; + let app = App::new()?; + app.run().await +} + +fn main() -> Result<(), anyhow::Error> { + env_logger::init(); + let main_context = glib::MainContext::default(); + main_context.block_on(async_main()) +} diff --git a/src/pipeline.rs b/src/pipeline.rs new file mode 100644 index 0000000..9ba24ca --- /dev/null +++ b/src/pipeline.rs @@ -0,0 +1,213 @@ +use crate::settings::VideoResolution; +use crate::utils; +use gst::{self, prelude::*}; +use std::error; +use std::ops; +use std::rc::{Rc, Weak}; + +// Our refcounted pipeline struct for containing all the media state we have to carry around. +#[derive(Clone)] +pub struct Pipeline(Rc); + +// Deref into the contained struct to make usage a bit more ergonomic +impl ops::Deref for Pipeline { + type Target = PipelineInner; + + fn deref(&self) -> &PipelineInner { + &*self.0 + } +} + +pub struct PipelineInner { + pub pipeline: gst::Pipeline, +} + +// Weak reference to our pipeline struct +// +// Weak references are important to prevent reference cycles. Reference cycles are cases where +// struct A references directly or indirectly struct B, and struct B references struct A again +// while both are using reference counting. +pub struct PipelineWeak(Weak); +impl PipelineWeak { + pub fn upgrade(&self) -> Option { + self.0.upgrade().map(Pipeline) + } +} + +impl Pipeline { + pub fn new() -> Result> { + let settings = utils::load_settings(); + + let (width, height) = match settings.video_resolution { + VideoResolution::V480P => (640, 480), + VideoResolution::V720P => (1280, 720), + VideoResolution::V1080P => (1920, 1080), + }; + + let pipeline = gst::parse_launch(&format!( + "webrtcbin name=webrtcbin stun-server=stun://stun2.l.google.com:19302 \ + glvideomixerelement name=mixer sink_1::zorder=0 sink_1::height={height} sink_1::width={width} \ + ! tee name=video-tee ! queue ! gtkglsink enable-last-sample=0 name=sink qos=0 \ + wpesrc location=http://127.0.0.1:3000 name=wpesrc draw-background=0 \ + ! capsfilter name=wpecaps caps=\"video/x-raw(memory:GLMemory),width={width},height={height},pixel-aspect-ratio=(fraction)1/1\" ! glcolorconvert ! queue ! mixer. \ + v4l2src name=videosrc ! capsfilter name=camcaps caps=\"image/jpeg,width={width},height={height},framerate=30/1\" ! queue ! jpegparse ! queue ! jpegdec ! videoconvert ! queue ! glupload ! glcolorconvert + ! queue ! mixer. \ + ", width=width, height=height) + )?; + + // Upcast to a gst::Pipeline as the above function could've also returned an arbitrary + // gst::Element if a different string was passed + let pipeline = pipeline + .downcast::() + .expect("Couldn't downcast pipeline"); + + // Request that the pipeline forwards us all messages, even those that it would otherwise + // aggregate first + pipeline.set_property_message_forward(true); + + let pipeline = Pipeline(Rc::new(PipelineInner { pipeline })); + + // Install a message handler on the pipeline's bus to catch errors + let bus = pipeline.pipeline.get_bus().expect("Pipeline had no bus"); + + // GStreamer is thread-safe and it is possible to attach bus watches from any thread, which + // are then nonetheless called from the main thread. So by default, add_watch() requires + // the passed closure to be Send. We want to pass non-Send values into the closure though. + // + // As we are on the main thread and the closure will be called on the main thread, this + // is actually perfectly fine and safe to do and we can use add_watch_local(). + // add_watch_local() would panic if we were not calling it from the main thread. + let pipeline_weak = pipeline.downgrade(); + bus.add_watch_local(move |_bus, msg| { + let pipeline = upgrade_weak!(pipeline_weak, glib::Continue(false)); + + pipeline.on_pipeline_message(msg); + + glib::Continue(true) + }) + .expect("Unable to add bus watch"); + + Ok(pipeline) + } + + // Downgrade to a weak reference + pub fn downgrade(&self) -> PipelineWeak { + PipelineWeak(Rc::downgrade(&self.0)) + } + + pub fn prepare(&self) -> Result { + let settings = utils::load_settings(); + let webrtc_codec = settings.webrtc_codec_params(); + let bin_description = &format!( + "queue name=webrtc-vqueue ! gldownload ! videoconvert ! {encoder} ! {payloader} ! queue ! capsfilter name=webrtc-vsink caps=\"application/x-rtp,media=video,encoding-name={encoding_name},payload=96\"", + encoder=webrtc_codec.encoder, payloader=webrtc_codec.payloader, + encoding_name=webrtc_codec.encoding_name + ); + + let bin = gst::parse_bin_from_description(bin_description, false).unwrap(); + bin.set_name("webrtc-vbin").unwrap(); + + let video_queue = bin + .get_by_name("webrtc-vqueue") + .expect("No webrtc-vqueue found"); + let video_tee = self + .pipeline + .get_by_name("video-tee") + .expect("No video-tee found"); + + self.pipeline + .add(&bin) + .expect("Failed to add recording bin"); + + let srcpad = video_tee + .get_request_pad("src_%u") + .expect("Failed to request new pad from tee"); + let sinkpad = video_queue + .get_static_pad("sink") + .expect("Failed to get sink pad from recording bin"); + + if let Ok(video_ghost_pad) = gst::GhostPad::new(Some("video_sink"), &sinkpad) { + bin.add_pad(&video_ghost_pad).unwrap(); + srcpad.link(&video_ghost_pad).unwrap(); + } + + let webrtcbin = self.pipeline.get_by_name("webrtcbin").unwrap(); + let sinkpad2 = webrtcbin.get_request_pad("sink_%u").unwrap(); + let vsink = bin + .get_by_name("webrtc-vsink") + .expect("No webrtc-vqueue found"); + let srcpad = vsink.get_static_pad("src").unwrap(); + if let Ok(webrtc_ghost_pad) = gst::GhostPad::new(Some("webrtc_video_src"), &srcpad) { + bin.add_pad(&webrtc_ghost_pad).unwrap(); + webrtc_ghost_pad.link(&sinkpad2).unwrap(); + } + + self.pipeline.set_state(gst::State::Ready) + } + + pub fn start(&self) -> Result { + // This has no effect if called multiple times + self.pipeline.set_state(gst::State::Playing) + } + + pub fn stop(&self) -> Result { + // This has no effect if called multiple times + self.pipeline.set_state(gst::State::Null) + } + + // Here we handle all message we get from the GStreamer pipeline. These are notifications sent + // from GStreamer, including errors that happend at runtime. + // + // This is always called from the main application thread by construction. + fn on_pipeline_message(&self, msg: &gst::MessageRef) { + use gst::MessageView; + + // A message can contain various kinds of information but + // here we are only interested in errors so far + match msg.view() { + MessageView::Error(err) => { + panic!( + "Error from {:?}: {} ({:?})", + err.get_src().map(|s| s.get_path_string()), + err.get_error(), + err.get_debug() + ); + } + MessageView::Application(msg) => match msg.get_structure() { + // Here we can send ourselves messages from any thread and show them to the user in + // the UI in case something goes wrong + Some(s) if s.get_name() == "warning" => { + let text = s + .get::<&str>("text") + .expect("Warning message without text") + .unwrap(); + panic!("{}", text); + } + _ => (), + }, + MessageView::StateChanged(state_changed) => { + if let Some(element) = msg.get_src() { + if element == self.pipeline { + let bin_ref = element.downcast_ref::().unwrap(); + let filename = format!( + "gst-wpe-broadcast-demo-{:#?}_to_{:#?}", + state_changed.get_old(), + state_changed.get_current() + ); + bin_ref.debug_to_dot_file_with_ts(gst::DebugGraphDetails::all(), filename); + } + } + } + MessageView::AsyncDone(_) => { + if let Some(element) = msg.get_src() { + let bin_ref = element.downcast_ref::().unwrap(); + bin_ref.debug_to_dot_file_with_ts( + gst::DebugGraphDetails::all(), + "gst-wpe-broadcast-demo-async-done", + ); + } + } + _ => (), + }; + } +} diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 0000000..6e011e8 --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,79 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize)] +pub enum VideoResolution { + V480P, + V720P, + V1080P, +} + +impl Default for VideoResolution { + fn default() -> Self { + VideoResolution::V720P + } +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize)] +pub enum WebRTCCodec { + VP8, + VP9, + H264, +} + +impl Default for WebRTCCodec { + fn default() -> Self { + WebRTCCodec::VP8 + } +} + +#[derive(Debug)] +pub struct VideoParameter { + pub encoder: &'static str, + pub encoding_name: &'static str, + pub payloader: &'static str, +} + +const VP8_PARAM: VideoParameter = VideoParameter { + encoder: "vp8enc target-bitrate=400000 threads=4 overshoot=25 undershoot=100 deadline=33000 keyframe-max-dist=1", + encoding_name: "VP8", + payloader: "rtpvp8pay picture-id-mode=2" +}; + +const VP9_PARAM: VideoParameter = VideoParameter { + encoder: "vp9enc target-bitrate=128000 undershoot=100 deadline=33000 keyframe-max-dist=1", + encoding_name: "VP9", + payloader: "rtpvp9pay picture-id-mode=2", +}; + +const H264_PARAM: VideoParameter = VideoParameter { + //encoder: "x264enc tune=zerolatency", + encoder: "vaapih264enc", + encoding_name: "H264", + payloader: "rtph264pay", +}; + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct Settings { + pub video_resolution: VideoResolution, + pub webrtc_codec: WebRTCCodec, +} + +impl Default for Settings { + fn default() -> Settings { + Settings { + //h264_encoder: "video/x-raw,format=NV12 ! vaapih264enc bitrate=20000 keyframe-period=60 ! video/x-h264,profile=main".to_string(), + video_resolution: VideoResolution::default(), + webrtc_codec: WebRTCCodec::default(), + } + } +} + +impl Settings { + pub fn webrtc_codec_params(&self) -> VideoParameter { + match self.webrtc_codec { + WebRTCCodec::VP8 => VP8_PARAM, + WebRTCCodec::VP9 => VP9_PARAM, + WebRTCCodec::H264 => H264_PARAM, + } + } +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..c8b9ae7 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,27 @@ +use std::path::PathBuf; + +use crate::settings::Settings; +use crate::APPLICATION_NAME; + +// Get the default path for the settings file +pub fn get_settings_file_path() -> PathBuf { + let mut path = glib::get_user_config_dir().unwrap_or_else(|| PathBuf::from(".")); + path.push(APPLICATION_NAME); + path.push("settings.toml"); + path +} + +// Load the current settings +pub fn load_settings() -> Settings { + let s = get_settings_file_path(); + if s.exists() && s.is_file() { + match serde_any::from_file::(&s) { + Ok(s) => s, + Err(e) => { + panic!("Error while opening '{}': {}", s.display(), e); + } + } + } else { + Settings::default() + } +} diff --git a/wpe-graphics-overlays b/wpe-graphics-overlays new file mode 160000 index 0000000..1e23f78 --- /dev/null +++ b/wpe-graphics-overlays @@ -0,0 +1 @@ +Subproject commit 1e23f781adef05d6d2f291d9bb67c28f9bb9b2f1