diff --git a/Cargo.lock b/Cargo.lock index f1a13e1b..cabc39e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,23 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "binary-space-partition" version = "0.1.2" @@ -91,6 +108,11 @@ dependencies = [ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.0.3" @@ -121,6 +143,15 @@ name = "byteorder" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bytes" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bzip2" version = "0.3.3" @@ -202,6 +233,15 @@ dependencies = [ "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "core-foundation" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "core-foundation" version = "0.6.1" @@ -211,6 +251,14 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "core-foundation-sys" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "core-foundation-sys" version = "0.6.1" @@ -278,6 +326,15 @@ dependencies = [ "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-epoch" version = "0.3.1" @@ -286,7 +343,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -300,7 +357,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -338,7 +395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -384,11 +441,16 @@ dependencies = [ "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "servo-media 0.1.0", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "webrender 0.57.2 (git+https://github.com/servo/webrender/)", + "websocket 0.20.3 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -447,6 +509,20 @@ name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "futures" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-cpupool" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fxhash" version = "0.2.1" @@ -490,7 +566,7 @@ dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -514,7 +590,7 @@ dependencies = [ "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)", "gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -560,7 +636,7 @@ dependencies = [ "gstreamer-base 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-base-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -575,7 +651,7 @@ dependencies = [ "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "muldiv 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -693,6 +769,33 @@ dependencies = [ "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gstreamer-sdp" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "glib 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sdp-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gstreamer-sdp-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gstreamer-sys" version = "0.6.1" @@ -734,6 +837,66 @@ dependencies = [ "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gstreamer-webrtc" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glib 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sdp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-webrtc-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gstreamer-webrtc-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sdp-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "h2" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "http" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "httparse" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "humantime" version = "1.1.1" @@ -742,6 +905,50 @@ dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper" +version = "0.10.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "idna" version = "0.1.5" @@ -752,6 +959,11 @@ dependencies = [ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "indexmap" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "iovec" version = "0.1.2" @@ -769,7 +981,7 @@ dependencies = [ "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -778,6 +990,11 @@ dependencies = [ "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itoa" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "jni" version = "0.5.3" @@ -809,9 +1026,19 @@ name = "khronos_api" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" -version = "1.0.2" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -901,6 +1128,14 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miniz_oxide" version = "0.1.3" @@ -939,6 +1174,16 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.2.1" @@ -964,6 +1209,20 @@ name = "muldiv" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "native-tls" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "net2" version = "0.2.33" @@ -1029,6 +1288,29 @@ dependencies = [ "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "openssl" +version = "0.9.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-sys" +version = "0.9.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ordered-float" version = "1.0.1" @@ -1134,6 +1416,16 @@ dependencies = [ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.2" @@ -1177,7 +1469,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1234,6 +1526,16 @@ dependencies = [ "stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ryu" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safemem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "same-file" version = "1.0.4" @@ -1242,11 +1544,45 @@ dependencies = [ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "schannel" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scoped-tls" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "security-framework" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "security-framework-sys" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde" version = "1.0.66" @@ -1273,6 +1609,16 @@ dependencies = [ "syn 0.14.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_json" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo-freetype-sys" version = "4.0.3" @@ -1289,6 +1635,7 @@ dependencies = [ "servo-media-audio 0.1.0", "servo-media-gstreamer 0.1.0", "servo-media-player 0.1.0", + "servo-media-webrtc 0.1.0", ] [[package]] @@ -1311,6 +1658,7 @@ dependencies = [ name = "servo-media-gstreamer" version = "0.1.0" dependencies = [ + "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1321,12 +1669,16 @@ dependencies = [ "gstreamer-app 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-audio 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-player 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-sdp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-video 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gstreamer-webrtc 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "servo-media-audio 0.1.0", "servo-media-player 0.1.0", + "servo-media-webrtc 0.1.0", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1340,6 +1692,13 @@ dependencies = [ "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "servo-media-webrtc" +version = "0.1.0" +dependencies = [ + "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo_media_android" version = "0.1.0" @@ -1357,12 +1716,17 @@ dependencies = [ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "shared_library" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1387,7 +1751,7 @@ dependencies = [ "andrew 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1409,6 +1773,11 @@ dependencies = [ "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "string" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.14.7" @@ -1429,6 +1798,15 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempfile" version = "3.0.3" @@ -1464,7 +1842,7 @@ name = "thread_local" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1483,11 +1861,216 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-fs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-reactor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tcp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tls" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "try-lock" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ucd-util" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1538,6 +2121,16 @@ dependencies = [ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "vcpkg" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -1553,6 +2146,16 @@ dependencies = [ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "want" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wayland-client" version = "0.21.4" @@ -1602,7 +2205,7 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1623,7 +2226,7 @@ dependencies = [ "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "plane-split 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1653,6 +2256,27 @@ dependencies = [ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "websocket" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -1708,7 +2332,7 @@ dependencies = [ "cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1734,7 +2358,7 @@ name = "x11-dl" version = "2.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1772,14 +2396,18 @@ dependencies = [ "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" +"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff" "checksum bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2fb9e29e72fd6bc12071533d5dc7664cb01480c59406f656d7ac25c7bd8ff7" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" "checksum boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbec60c560f322d8e3cd403f91d8908cfd965fff53ba97154bd1b9d90149d98e" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-slice-cast 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28346c117b50270785fbc123bd6e4ecad20d0c6d5f43d081dc80a3abcc62be64" "checksum byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9" +"checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62" "checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" @@ -1790,7 +2418,9 @@ dependencies = [ "checksum cmake 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "b56821938fa1a3aaf4f0c4f49504928c5a7fcc56cbc9855be8fc2e98567e750c" "checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b" "checksum combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1645a65a99c7c8d345761f4b75a6ffe5be3b3b27a93ee731fccc5050ba6be97c" +"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cc3532ec724375c7cb7ff0a097b714fde180bb1f6ed2ab27cfcd99ffca873cd2" +"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum core-foundation-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a3fb15cdbdd9cf8b82d97d0296bb5cd3631bba58d6e31650a002a8e7fb5721f9" "checksum core-graphics 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92801c908ea6301ae619ed842a72e01098085fc321b9c2f3f833dad555bba055" "checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" @@ -1798,6 +2428,7 @@ dependencies = [ "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crossbeam-channel 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6c0a94250b0278d7fc5a894c3d276b11ea164edc8bf8feb10ca1ea517b44a649" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" @@ -1817,6 +2448,8 @@ dependencies = [ "checksum freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b659e75b7a7338fe75afd7f909fc2b71937845cffb6ebe54ba2e50f13d8e903d" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ffaf173cf76c73a73e080366bf556b4776ece104b06961766ff11449f38604" @@ -1836,18 +2469,31 @@ dependencies = [ "checksum gstreamer-base-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1eb57a7d013604ab7af2b843b62b13b8fb30f22d066919f7e198f528c3296cd0" "checksum gstreamer-player 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1144c6c5c3af25dd1f89b4f9d2762f1c2d8789e65cdc79e2451dd24350d84dd2" "checksum gstreamer-player-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e642cb58d3733e2724def7186101bb00144fc97d45b2c379eba6d0c0662dec" +"checksum gstreamer-sdp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ade1226bb5a0622125e49f1a801ac6b673986d96513862ff0b1f21b0b3595ae" +"checksum gstreamer-sdp-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "816628556bc2c9a627efd6e7d9b67ab4abb246b143bff2b3ad7fff6923f11cb1" "checksum gstreamer-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3aec69f30ab98a7b0cf4a29179eeffa8a1e7d6062f5ee55e9792917cb0980bda" "checksum gstreamer-video 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c1f04816d7e183714830da26274f97e7aeff09ae6641058538d21443b4ec07d" "checksum gstreamer-video-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e2efb301a0b94fa4af503122faa04247085936dd888fd59fa4e21eab3cbd37" +"checksum gstreamer-webrtc 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f7fc9422d65781cfe8d2f9994b1010476ce0839b8fce7db97eb87bdf75b614e" +"checksum gstreamer-webrtc-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "38a27025af94512f0d798ff9dd0b269951ce305879873c4ab6266885c7bd207f" +"checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed" +"checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" +"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" +"checksum hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "95ffee0d1d30de4313fdaaa485891ce924991d45bbc18adfc8ac5b1639e62fbb" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd75debad4ffd295c00c6e3634d254df30050b0837a85e5cd039ac424365f24a" +"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum jni 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cffc930ce6a38a4013e30567b559bdc79f601013ba4a81e65dbda9207263efd4" "checksum jni-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de0aaaba8809ab8d83a53fe2b313b996b79e8632b855eae9f70ad4323dca91b8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum khronos_api 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62237e6d326bd5871cd21469323bf096de81f1618cd82cbaf5d87825335aeb49" -"checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" +"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" @@ -1860,12 +2506,15 @@ dependencies = [ "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba430291c9d6cedae28bcd2d49d1c32fc57d60cd49086646c5dd5673a870eb5" "checksum miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5b8234d6103ebfba71e29786da4608540f862de5ce980a1c94f86a40ca0d51" "checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729" "checksum muldiv 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "451a9a05d2a32c566c897835e0ea95cf79ed2fdfe957924045a1721a36c9980f" +"checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" @@ -1874,6 +2523,8 @@ dependencies = [ "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9833ab0efe5361b1e2122a0544a5d3359576911a42cb098c2e59be8650807367" +"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" +"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106" "checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" @@ -1888,6 +2539,7 @@ dependencies = [ "checksum proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "cccdc7557a98fe98453030f077df7f3a042052fae465bb61d2c2c41435cfd9b6" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3372dc35766b36a99ce2352bd1b6ea0137c38d215cc0c8780bf6de6df7842ba9" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" @@ -1899,27 +2551,55 @@ dependencies = [ "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rusttype 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "436c67ae0d0d24f14e1177c3ed96780ee16db82b405f0fba1bb80b46c9a30625" +"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" +"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" +"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" +"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" +"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95" "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" "checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79" +"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" "checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b" +"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" "checksum smithay-client-toolkit 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef227bd9251cf8f8e54f8dd9a4b164307e515f5312cd632ebc87b56f723893a2" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "48fa7d3136d8645909de1f7c7eb5416cc43057a75ace08fc39ae736bc9da8af1" +"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" "checksum syn 0.14.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e13df71f29f9440b50261a5882c86eac334f1badb3134ec26f0de2f1418e44" "checksum syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)" = "3391038ebc3e4ab24eb028cb0ef2f2dc4ba0cbf72ee895ed6a6fad730640b5bc" +"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5920e77802b177479ab5795767fa48e68f61b2f516c2ac0041e2978dd8efe483" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" +"checksum tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f90fcd90952f0a496d438a976afba8e5c205fb12123f813d8ab3aa1c8436638c" +"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" +"checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" +"checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" +"checksum tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4b26fd37f1125738b2170c80b551f69ff6fecb277e6e5ca885e53eec2b005018" +"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" +"checksum tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3929aee321c9220ed838ed6c3928be7f9b69986b0e3c22c972a66dbf8a298c68" +"checksum tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3a52f00c97fedb6d535d27f65cccb7181c8dd4c6edc3eda9ea93f6d45d05168e" +"checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" +"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" +"checksum tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df195376b43508f01570bacc73e13a1de0854dc59e79d1ec09913e8db6dd2a70" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" @@ -1927,8 +2607,11 @@ dependencies = [ "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" +"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" +"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum wayland-client 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ff03d0651389f99aba804e89685c6211fc1d66fb3c234ed52d028904675adbcb" "checksum wayland-commons 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6f06d6b155a2be033ee1684fd084c1c1821e0d61d4c303f11fc9400a911fa24a" "checksum wayland-protocols 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f6cebb98963f028d397e9bad2acf9d3b2f6b76fae65aea191edd9e7c0df88c" @@ -1936,6 +2619,7 @@ dependencies = [ "checksum wayland-sys 0.21.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ca41ed78a12256f81df6f53fcbe4503213ba442e02cdad3c9c888a64a668eaf4" "checksum webrender 0.57.2 (git+https://github.com/servo/webrender/)" = "" "checksum webrender_api 0.57.2 (git+https://github.com/servo/webrender/)" = "" +"checksum websocket 0.20.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9234b4e667c19995475227172446884f516ec0963380afa960d962ab9f4c0bfa" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index cded2571..8bb4a8c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,6 @@ members = [ "player", "servo-media", "servo-media-derive", + "webrtc" ] +license = "MPL-2.0" diff --git a/backends/gstreamer/Cargo.toml b/backends/gstreamer/Cargo.toml index 7bbfe285..82407e1f 100644 --- a/backends/gstreamer/Cargo.toml +++ b/backends/gstreamer/Cargo.toml @@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"] regex = "1.0" zip = "0.3.1" +[dependencies] +boxfnonce = "0.1.0" + [dependencies.byte-slice-cast] version = "0.2" @@ -40,12 +43,21 @@ version = "0.12" [dependencies.gstreamer-sys] version = "0.6.1" +[dependencies.gstreamer-sdp] +version = "0.12" + +[dependencies.gstreamer-webrtc] +version = "0.12" + [dependencies.gstreamer-video] version = "0.12" [dependencies.ipc-channel] version = "0.11" +[dependencies.lazy_static] +version = "1.2.0" + [dependencies.servo-media-audio] path = "../../audio" @@ -54,3 +66,6 @@ path = "../../player" [dependencies.url] version = "1.7.2" + +[dependencies.servo-media-webrtc] +path = "../../webrtc" diff --git a/backends/gstreamer/src/lib.rs b/backends/gstreamer/src/lib.rs index 7085d774..70015729 100644 --- a/backends/gstreamer/src/lib.rs +++ b/backends/gstreamer/src/lib.rs @@ -1,3 +1,4 @@ +extern crate boxfnonce; extern crate byte_slice_cast; #[macro_use] @@ -12,20 +13,30 @@ extern crate gstreamer_app as gst_app; extern crate gstreamer_audio as gst_audio; extern crate gstreamer_player as gst_player; extern crate gstreamer_sys as gst_ffi; +extern crate gstreamer_sdp as gst_sdp; extern crate gstreamer_video as gst_video; +extern crate gstreamer_webrtc as gst_webrtc; extern crate ipc_channel; +#[macro_use] +extern crate lazy_static; + extern crate servo_media_audio; extern crate servo_media_player; +extern crate servo_media_webrtc; extern crate url; use servo_media_audio::sink::AudioSinkError; use servo_media_audio::AudioBackend; use servo_media_player::PlayerBackend; +use servo_media_webrtc::{WebRtcBackend, WebRtcSignaller, WebRtcController}; pub mod audio_decoder; pub mod audio_sink; +pub mod media_capture; +pub mod media_stream; pub mod player; mod source; +pub mod webrtc; pub struct GStreamerBackend; @@ -47,8 +58,35 @@ impl PlayerBackend for GStreamerBackend { } } +impl WebRtcBackend for GStreamerBackend { + type Controller = webrtc::GStreamerWebRtcController; + + fn construct_webrtc_controller( + signaller: Box, + thread: WebRtcController, + ) -> Self::Controller { + webrtc::construct(signaller, thread) + } +} + impl GStreamerBackend { pub fn init() { gst::init().unwrap(); } + + pub fn create_audiostream() -> media_stream::GStreamerMediaStream { + media_stream::GStreamerMediaStream::create_audio() + } + + pub fn create_videostream() -> media_stream::GStreamerMediaStream { + media_stream::GStreamerMediaStream::create_video() + } + + pub fn create_audioinput_stream() -> Option { + media_capture::create_audioinput_stream() + } + + pub fn create_videoinput_stream() -> Option { + media_capture::create_videoinput_stream() + } } diff --git a/backends/gstreamer/src/media_capture.rs b/backends/gstreamer/src/media_capture.rs new file mode 100644 index 00000000..859e15e2 --- /dev/null +++ b/backends/gstreamer/src/media_capture.rs @@ -0,0 +1,158 @@ +use crate::media_stream::{GStreamerMediaStream, StreamType}; +use gst::{DeviceMonitor, DeviceMonitorExt, DeviceExt}; +use gst::{Fraction, FractionRange, List, IntRange}; +use gst::caps::{Builder, Caps}; +use std::i32; + +pub enum Constrain { + Value(T), + Range(ConstrainRange) +} + +impl Constrain { + fn add_to_caps(self, name: &str, min: u64, max: u64, builder: Builder) -> Option { + match self { + Constrain::Value(v) => Some(builder.field(name, &(v as i64 as i32))), + Constrain::Range(r) => { + let min = into_i32(r.min.unwrap_or(min)); + let max = into_i32(r.max.unwrap_or(max)); + let range = IntRange::::new(min, max); + if let Some(ideal) = r.ideal { + let ideal = into_i32(ideal); + let array = List::new(&[&ideal, &range]); + Some(builder.field(name, &array)) + } else { + Some(builder.field(name, &range)) + } + } + } + } +} + +fn into_i32(x: u64) -> i32 { + if x > i32::MAX as u64 { + i32::MAX + } else { + x as i64 as i32 + } +} + +impl Constrain { + fn add_to_caps(self, name: &str, min: i32, max: i32, builder: Builder) -> Option { + match self { + Constrain::Value(v) => Some(builder.field("name", &Fraction::approximate_f64(v)?)), + Constrain::Range(r) => { + let min = r.min.and_then(|v| Fraction::approximate_f64(v)).unwrap_or(Fraction::new(min, 1)); + let max = r.max.and_then(|v| Fraction::approximate_f64(v)).unwrap_or(Fraction::new(max, 1)); + let range = FractionRange::new(min, max); + if let Some(ideal) = r.ideal.and_then(|v| Fraction::approximate_f64(v)) { + let array = gst::List::new(&[&ideal, &range]); + Some(builder.field(name, &array)) + } else { + Some(builder.field(name, &range)) + } + } + } + } +} + +pub struct ConstrainRange { + min: Option, + max: Option, + ideal: Option, +} + +pub enum ConstrainBool { + Ideal(bool), + Exact(bool), +} + +#[derive(Default)] +pub struct MediaTrackConstraintSet { + width: Option>, + height: Option>, + aspect: Option>, + frame_rate: Option>, + sample_rate: Option>, +} + +// TODO(Manishearth): Should support a set of constraints +impl MediaTrackConstraintSet { + fn into_caps(self, format: &str) -> Option { + let mut builder = Caps::builder(format); + if let Some(w) = self.width { + builder = w.add_to_caps("width", 0, 1000000, builder)?; + } + if let Some(h) = self.height { + builder = h.add_to_caps("height", 0, 1000000, builder)?; + } + if let Some(aspect) = self.aspect { + builder = aspect.add_to_caps("pixel-aspect-ratio", 0, 1000000, builder)?; + } + if let Some(fr) = self.frame_rate { + builder = fr.add_to_caps("framerate", 0, 1000000, builder)?; + } + if let Some(sr) = self.sample_rate { + builder = sr.add_to_caps("rate", 0, 1000000, builder)?; + } + Some(builder.build()) + } +} + +struct GstMediaDevices { + monitor: DeviceMonitor, +} + +impl GstMediaDevices { + pub fn new() -> Self { + Self { + monitor: DeviceMonitor::new() + } + } + + pub fn get_track(&self, video: bool, constraints: MediaTrackConstraintSet) -> Option { + let (format, filter) = if video { ("video/x-raw", "Video/Source") } else { ("audio/x-raw", "Audio/Source") }; + let caps = constraints.into_caps(format)?; + println!("requesting {:?}", caps); + let f = self.monitor.add_filter(filter, &caps); + let devices = self.monitor.get_devices(); + if f != 0 { + self.monitor.remove_filter(f); + } + if let Some(d) = devices.get(0) { + println!("{:?}", d.get_caps()); + let element = d.create_element(None)?; + Some(GstMediaTrack { + element + }) + } else { + None + } + } +} + +pub struct GstMediaTrack { + element: gst::Element, +} + +fn create_input_stream(stream_type: StreamType) -> Option { + let devices = GstMediaDevices::new(); + let constraints = MediaTrackConstraintSet::default(); + devices + .get_track(stream_type == StreamType::Video, constraints) + .map(|track| { + let f = match stream_type { + StreamType::Audio => GStreamerMediaStream::create_audio_from, + StreamType::Video => GStreamerMediaStream::create_video_from, + }; + f(track.element) + }) +} + +pub fn create_audioinput_stream() -> Option { + create_input_stream(StreamType::Audio) +} + +pub fn create_videoinput_stream() -> Option { + create_input_stream(StreamType::Video) +} diff --git a/backends/gstreamer/src/media_stream.rs b/backends/gstreamer/src/media_stream.rs new file mode 100644 index 00000000..0084b9c7 --- /dev/null +++ b/backends/gstreamer/src/media_stream.rs @@ -0,0 +1,125 @@ +use glib::ObjectExt; +use gst::{self, BinExtManual, ElementExt, GObjectExtManualGst}; +use servo_media_webrtc::MediaStream; +use std::any::Any; + +lazy_static! { + static ref RTP_CAPS_OPUS: gst::Caps = { + gst::Caps::new_simple( + "application/x-rtp", + &[ + ("media", &"audio"), + ("encoding-name", &"OPUS"), + ("payload", &(97i32)), + ], + ) + }; + static ref RTP_CAPS_VP8: gst::Caps = { + gst::Caps::new_simple( + "application/x-rtp", + &[ + ("media", &"video"), + ("encoding-name", &"VP8"), + ("payload", &(96i32)), + ], + ) + }; +} + +#[derive(Debug, PartialEq)] +pub enum StreamType { + Audio, + Video, +} + +pub struct GStreamerMediaStream { + type_: StreamType, + elements: Vec, +} + +impl MediaStream for GStreamerMediaStream { + fn as_any(&self) -> &Any { + self + } +} + +impl GStreamerMediaStream { + pub fn attach_to_pipeline(&self, pipeline: &gst::Pipeline, webrtcbin: &gst::Element) { + println!("atttaching a {:?} stream", self.type_); + let elements: Vec<_> = self.elements.iter().collect(); + pipeline.add_many(&elements[..]).unwrap(); + gst::Element::link_many(&elements[..]).unwrap(); + for element in elements { + element.sync_state_with_parent().unwrap(); + } + + let caps = match self.type_ { + StreamType::Audio => &*RTP_CAPS_OPUS, + StreamType::Video => &*RTP_CAPS_VP8, + }; + self.elements.last().as_ref().unwrap().link_filtered(webrtcbin, caps).unwrap(); + } + + pub fn create_video() -> GStreamerMediaStream { + let videotestsrc = gst::ElementFactory::make("videotestsrc", None).unwrap(); + videotestsrc.set_property_from_str("pattern", "ball"); + videotestsrc.set_property("is-live", &true).unwrap(); + + Self::create_video_from(videotestsrc) + } + + pub fn create_video_from(source: gst::Element) -> GStreamerMediaStream { + let videoconvert = gst::ElementFactory::make("videoconvert", None).unwrap(); + let queue = gst::ElementFactory::make("queue", None).unwrap(); + let vp8enc = gst::ElementFactory::make("vp8enc", None).unwrap(); + + vp8enc.set_property("deadline", &1i64).unwrap(); + + let rtpvp8pay = gst::ElementFactory::make("rtpvp8pay", None).unwrap(); + let queue2 = gst::ElementFactory::make("queue", None).unwrap(); + + GStreamerMediaStream { + type_: StreamType::Video, + elements: vec![ + source, + videoconvert, + queue, + vp8enc, + rtpvp8pay, + queue2, + ], + } + } + + pub fn create_audio() -> GStreamerMediaStream { + let audiotestsrc = gst::ElementFactory::make("audiotestsrc", None).unwrap(); + audiotestsrc.set_property_from_str("wave", "red-noise"); + audiotestsrc.set_property("is-live", &true).unwrap(); + + Self::create_audio_from(audiotestsrc) + } + + pub fn create_audio_from(source: gst::Element) -> GStreamerMediaStream { + let queue = gst::ElementFactory::make("queue", None).unwrap(); + let audioconvert = gst::ElementFactory::make("audioconvert", None).unwrap(); + let audioresample = gst::ElementFactory::make("audioresample", None).unwrap(); + let queue2 = gst::ElementFactory::make("queue", None).unwrap(); + let opusenc = gst::ElementFactory::make("opusenc", None).unwrap(); + let rtpopuspay = gst::ElementFactory::make("rtpopuspay", None).unwrap(); + let queue3 = gst::ElementFactory::make("queue", None).unwrap(); + + GStreamerMediaStream { + type_: StreamType::Audio, + elements: vec![ + source, + queue, + audioconvert, + audioresample, + queue2, + opusenc, + rtpopuspay, + queue3, + ], + } + } +} diff --git a/backends/gstreamer/src/webrtc.rs b/backends/gstreamer/src/webrtc.rs new file mode 100644 index 00000000..9f5372bb --- /dev/null +++ b/backends/gstreamer/src/webrtc.rs @@ -0,0 +1,416 @@ +use boxfnonce::SendBoxFnOnce; +use glib::{self, ObjectExt}; +use gst::{self, BinExt, BinExtManual, ElementExt, GObjectExtManualGst, PadDirection, PadExt}; +use gst_sdp; +use gst_webrtc::{self, WebRTCSDPType}; +use media_stream::GStreamerMediaStream; +use servo_media_webrtc::thread::InternalEvent; +use servo_media_webrtc::WebRtcController as WebRtcThread; +use servo_media_webrtc::*; +use std::sync::Mutex; +use std::error::Error; + +// TODO: +// - add a proper error enum +// - figure out purpose of glib loop + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum MediaType { + Audio, + Video, +} + +#[derive(PartialEq, PartialOrd, Eq, Debug, Copy, Clone, Ord)] +#[allow(unused)] +enum AppState { + Error = 1, + ServerConnected, + ServerRegistering = 2000, + ServerRegisteringError, + ServerRegistered, + PeerConnecting = 3000, + PeerConnectionError, + PeerConnected, + PeerCallNegotiating = 4000, + PeerCallNegotiatingHaveLocal, + PeerCallNegotiatingHaveRemote, + PeerCallStarted, + PeerCallError, +} + +pub struct GStreamerWebRtcController { + webrtc: Option, + app_state: AppState, + pipeline: gst::Pipeline, + thread: WebRtcThread, + signaller: Box, + ready_to_negotiate: bool, + //send_msg_tx: mpsc::Sender, + //peer_id: String, + _main_loop: glib::MainLoop, + //bus: gst::Bus, +} + +impl WebRtcControllerBackend for GStreamerWebRtcController { + fn add_ice_candidate(&mut self, candidate: IceCandidate) { + self.webrtc + .as_ref() + .unwrap() + .emit( + "add-ice-candidate", + &[&candidate.sdp_mline_index, &candidate.candidate], + ) + .unwrap(); + } + + fn set_remote_description(&mut self, desc: SessionDescription, cb: SendBoxFnOnce<'static, ()>) { + assert!( + self.app_state == AppState::PeerCallNegotiating + || self.app_state == AppState::PeerCallNegotiatingHaveLocal, + "Not ready to handle sdp" + ); + + self.set_description(desc, false, cb); + + if self.app_state == AppState::PeerCallNegotiating { + self.app_state = AppState::PeerCallNegotiatingHaveRemote; + } else { + self.app_state = AppState::PeerCallStarted; + } + } + + fn set_local_description(&mut self, desc: SessionDescription, cb: SendBoxFnOnce<'static, ()>) { + assert!( + self.app_state == AppState::PeerCallNegotiating + || self.app_state == AppState::PeerCallNegotiatingHaveRemote, + "Not ready to handle sdp" + ); + + self.set_description(desc, true, cb); + + if self.app_state == AppState::PeerCallNegotiating { + self.app_state = AppState::PeerCallNegotiatingHaveLocal; + } else { + self.app_state = AppState::PeerCallStarted; + } + } + + fn create_offer(&mut self, cb: SendBoxFnOnce<'static, (SessionDescription,)>) { + let webrtc = self.webrtc.as_ref().unwrap(); + assert!( + self.app_state == AppState::PeerCallNegotiating, + "Not negotiating call when creating offer" + ); + let promise = gst::Promise::new_with_change_func(move |promise| { + on_offer_or_answer_created(SdpType::Offer, promise, cb); + }); + + webrtc + .emit("create-offer", &[&None::, &promise]) + .unwrap(); + } + + fn create_answer(&mut self, cb: SendBoxFnOnce<'static, (SessionDescription,)>) { + let webrtc = self.webrtc.as_ref().unwrap(); + assert!( + self.app_state == AppState::PeerCallNegotiatingHaveRemote, + "No offfer received when creating answer" + ); + let promise = gst::Promise::new_with_change_func(move |promise| { + on_offer_or_answer_created(SdpType::Answer, promise, cb); + }); + + webrtc + .emit("create-answer", &[&None::, &promise]) + .unwrap(); + } + + fn add_stream(&mut self, stream: &MediaStream) { + println!("adding a stream"); + let stream = stream + .as_any() + .downcast_ref::() + .unwrap(); + stream.attach_to_pipeline(&self.pipeline, self.webrtc.as_ref().unwrap()); + self.prepare_for_negotiation(); + } + + fn configure(&mut self, stun_server: &str, policy: BundlePolicy) { + let webrtc = self.webrtc.as_ref().unwrap(); + webrtc.set_property_from_str("stun-server", stun_server); + webrtc.set_property_from_str("bundle-policy", policy.as_str()); + } + + fn internal_event(&mut self, e: thread::InternalEvent) { + match e { + InternalEvent::OnNegotiationNeeded => { + self.app_state = AppState::PeerCallNegotiating; + self.signaller.on_negotiation_needed(&self.thread); + } + InternalEvent::OnIceCandidate(candidate) => { + self.signaller.on_ice_candidate(&self.thread, candidate); + } + } + } + + fn quit(&mut self) { + self.signaller.close(); + + self.pipeline + .set_state(gst::State::Null) + .into_result() + .unwrap(); + + //main_loop.quit(); + } +} + +impl GStreamerWebRtcController { + fn set_description( + &self, + desc: SessionDescription, + local: bool, + cb: SendBoxFnOnce<'static, ()>, + ) { + let ty = match desc.type_ { + SdpType::Answer => WebRTCSDPType::Answer, + SdpType::Offer => WebRTCSDPType::Offer, + SdpType::Pranswer => WebRTCSDPType::Pranswer, + SdpType::Rollback => WebRTCSDPType::Rollback, + }; + + let kind = if local { + "set-local-description" + } else { + "set-remote-description" + }; + + let ret = gst_sdp::SDPMessage::parse_buffer(desc.sdp.as_bytes()).unwrap(); + let answer = gst_webrtc::WebRTCSessionDescription::new(ty, ret); + let promise = gst::Promise::new_with_change_func(move |_promise| cb.call()); + self.webrtc + .as_ref() + .unwrap() + .emit(kind, &[&answer, &promise]) + .unwrap(); + } +} + +impl GStreamerWebRtcController { + fn prepare_for_negotiation(&mut self) { + if self.ready_to_negotiate { + return; + } + self.ready_to_negotiate = true; + let webrtc = self.webrtc.as_ref().unwrap(); + // gstreamer needs Sync on these callbacks for some reason + // https://github.com/sdroege/gstreamer-rs/issues/154 + let thread = Mutex::new(self.thread.clone()); + // If the pipeline starts playing and this signal is present before there are any + // media streams, an invalid SDP offer will be created. Therefore, delay setting up + // the signal and starting the pipeline until after the first stream has been added. + webrtc + .connect("on-negotiation-needed", false, move |_values| { + thread + .lock() + .unwrap() + .internal_event(InternalEvent::OnNegotiationNeeded); + None + }) + .unwrap(); + self.pipeline + .set_state(gst::State::Playing) + .into_result() + .unwrap(); + } + + fn start_pipeline(&mut self) { + let webrtc = gst::ElementFactory::make("webrtcbin", "sendrecv").unwrap(); + self.pipeline.add(&webrtc).unwrap(); + + // gstreamer needs Sync on these callbacks for some reason + // https://github.com/sdroege/gstreamer-rs/issues/154 + let thread = Mutex::new(self.thread.clone()); + webrtc + .connect("on-ice-candidate", false, move |values| { + thread + .lock() + .unwrap() + .internal_event(InternalEvent::OnIceCandidate(candidate(values))); + None + }) + .unwrap(); + + let pipe_clone = self.pipeline.clone(); + webrtc + .connect("pad-added", false, move |values| { + println!("pad-added"); + process_new_stream(values, &pipe_clone); + None + }) + .unwrap(); + + self.webrtc = Some(webrtc); + } +} + +pub fn construct( + signaller: Box, + thread: WebRtcThread, +) -> GStreamerWebRtcController { + let main_loop = glib::MainLoop::new(None, false); + let pipeline = gst::Pipeline::new("main"); + + let mut controller = GStreamerWebRtcController { + webrtc: None, + pipeline, + signaller, + thread, + app_state: AppState::ServerConnected, + ready_to_negotiate: false, + _main_loop: main_loop, + }; + controller.start_pipeline(); + controller +} + +fn on_offer_or_answer_created( + ty: SdpType, + promise: &gst::Promise, + cb: SendBoxFnOnce<'static, (SessionDescription,)>, +) { + debug_assert!(ty == SdpType::Offer || ty == SdpType::Answer); + + let reply = promise.get_reply().unwrap(); + + let reply = reply + .get_value(ty.as_str()) + .unwrap() + .get::() + .expect("Invalid argument"); + + let type_ = match reply.get_type() { + WebRTCSDPType::Answer => SdpType::Answer, + WebRTCSDPType::Offer => SdpType::Offer, + WebRTCSDPType::Pranswer => SdpType::Pranswer, + WebRTCSDPType::Rollback => SdpType::Rollback, + _ => panic!("unknown sdp response"), + }; + + let desc = SessionDescription { + sdp: reply.get_sdp().as_text().unwrap(), + type_, + }; + cb.call(desc); +} + +fn handle_media_stream( + pad: &gst::Pad, + pipe: &gst::Pipeline, + media_type: MediaType, +) -> Result<(), Box> { + println!("Trying to handle stream {:?}", media_type); + + let (q, conv, sink) = match media_type { + MediaType::Audio => { + let q = gst::ElementFactory::make("queue", None).unwrap(); + let conv = gst::ElementFactory::make("audioconvert", None).unwrap(); + let sink = gst::ElementFactory::make("autoaudiosink", None).unwrap(); + let resample = gst::ElementFactory::make("audioresample", None).unwrap(); + + pipe.add_many(&[&q, &conv, &resample, &sink])?; + gst::Element::link_many(&[&q, &conv, &resample, &sink])?; + + resample.sync_state_with_parent()?; + + (q, conv, sink) + } + MediaType::Video => { + let q = gst::ElementFactory::make("queue", None).unwrap(); + let conv = gst::ElementFactory::make("videoconvert", None).unwrap(); + let sink = gst::ElementFactory::make("autovideosink", None).unwrap(); + + pipe.add_many(&[&q, &conv, &sink])?; + gst::Element::link_many(&[&q, &conv, &sink])?; + + (q, conv, sink) + } + }; + q.sync_state_with_parent()?; + conv.sync_state_with_parent()?; + sink.sync_state_with_parent()?; + + let qpad = q.get_static_pad("sink").unwrap(); + pad.link(&qpad).into_result()?; + + Ok(()) +} + +fn on_incoming_decodebin_stream( + values: &[glib::Value], + pipe: &gst::Pipeline, +) -> Option { + let pad = values[1].get::().expect("Invalid argument"); + if !pad.has_current_caps() { + println!("Pad {:?} has no caps, can't do anything, ignoring", pad); + return None; + } + + let caps = pad.get_current_caps().unwrap(); + let name = caps.get_structure(0).unwrap().get_name(); + + let handled = if name.starts_with("video") { + handle_media_stream(&pad, &pipe, MediaType::Video) + } else if name.starts_with("audio") { + handle_media_stream(&pad, &pipe, MediaType::Audio) + } else { + println!("Unknown pad {:?}, ignoring", pad); + Ok(()) + }; + + if let Err(err) = handled { + eprintln!("Error adding pad with caps {} {:?}", name, err); + } + + None +} + +fn on_incoming_stream(values: &[glib::Value], pipe: &gst::Pipeline) -> Option { + let webrtc = values[0].get::().expect("Invalid argument"); + + let decodebin = gst::ElementFactory::make("decodebin", None).unwrap(); + let pipe_clone = pipe.clone(); + decodebin + .connect("pad-added", false, move |values| { + println!("decodebin pad-added"); + on_incoming_decodebin_stream(values, &pipe_clone) + }) + .unwrap(); + + pipe.add(&decodebin).unwrap(); + + decodebin.sync_state_with_parent().unwrap(); + webrtc.link(&decodebin).unwrap(); + + None +} + +fn process_new_stream(values: &[glib::Value], pipe: &gst::Pipeline) -> Option { + let pad = values[1].get::().expect("not a pad??"); + if pad.get_direction() != PadDirection::Src { + // Ignore outgoing pad notifications. + return None; + } + on_incoming_stream(values, pipe) +} + +fn candidate(values: &[glib::Value]) -> IceCandidate { + let _webrtc = values[0].get::().expect("Invalid argument"); + let sdp_mline_index = values[1].get::().expect("Invalid argument"); + let candidate = values[2].get::().expect("Invalid argument"); + + IceCandidate { + sdp_mline_index, + candidate, + } +} diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 6238c3f7..38be14fd 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -7,10 +7,15 @@ license = "MPL-2.0" env_logger = "0.5" euclid = "0.19.0" gleam = "0.6.8" +hyper = "0.12" rand = "0.5.0" time = "0.1.40" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" servo-media = { path = "../servo-media" } webrender = { git = "https://github.com/servo/webrender/" } +websocket = "0.20" ipc-channel = "0.11" [target.'cfg(not(target_os = "android"))'.dependencies] @@ -80,3 +85,7 @@ path = "oscillator.rs" [[bin]] name = "constant_source" path = "constant_source.rs" + +[[bin]] +name = "simple_webrtc" +path = "simple_webrtc.rs" diff --git a/examples/simple_webrtc.rs b/examples/simple_webrtc.rs new file mode 100644 index 00000000..ae55c7f7 --- /dev/null +++ b/examples/simple_webrtc.rs @@ -0,0 +1,381 @@ +//! To run this, clone https://github.com/centricular/gstwebrtc-demos, then: +//! $ cd signalling +//! $ ./simple-server.py +//! $ cd ../sendrcv/js +//! $ python -m SimpleHTTPServer +//! Then load http://localhost:8000 in a web browser, note the client id. +//! Then run this example with arguments `8443 {id}`. + +extern crate env_logger; +extern crate rand; +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate serde_json; +extern crate servo_media; +extern crate websocket; + +use rand::Rng; +use servo_media::webrtc::*; +use servo_media::ServoMedia; +use std::env; +use std::net; +use std::sync::{mpsc, Arc}; +use std::thread; +use websocket::OwnedMessage; + +const STUN_SERVER: &str = "stun://stun.l.google.com:19302"; + +#[derive(PartialEq, PartialOrd, Eq, Debug, Copy, Clone, Ord)] +#[allow(unused)] +enum AppState { + Error = 1, + ServerConnected, + ServerRegistering = 2000, + ServerRegisteringError, + ServerRegistered, + PeerConnecting = 3000, + PeerConnectionError, + PeerConnected, + PeerCallNegotiating = 4000, + PeerCallStarted, + PeerCallError, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +enum JsonMsg { + Ice { + candidate: String, + #[serde(rename = "sdpMLineIndex")] + sdp_mline_index: u32, + }, + Sdp { + #[serde(rename = "type")] + type_: String, + sdp: String, + }, +} + +fn send_loop( + mut sender: websocket::sender::Writer, + send_msg_rx: mpsc::Receiver, +) -> thread::JoinHandle<()> { + thread::spawn(move || loop { + let msg = match send_msg_rx.recv() { + Ok(msg) => msg, + Err(err) => { + println!("Send loop error {:?}", err); + return; + } + }; + + if let OwnedMessage::Close(_) = msg { + let _ = sender.send_message(&msg); + return; + } + + if let Err(err) = sender.send_message(&msg) { + println!("Error sending {:?}", err); + } + }) +} + +struct State { + app_state: AppState, + send_msg_tx: mpsc::Sender, + _uid: u32, + peer_id: Option, + media: Arc, + webrtc: Option, + signaller: Option, +} + +impl State { + fn handle_error(&self) { + let _error = match self.app_state { + AppState::ServerRegistering => AppState::ServerRegisteringError, + AppState::PeerConnecting => AppState::PeerConnectionError, + AppState::PeerConnected => AppState::PeerCallError, + AppState::PeerCallNegotiating => AppState::PeerCallError, + AppState::ServerRegisteringError => AppState::ServerRegisteringError, + AppState::PeerConnectionError => AppState::PeerConnectionError, + AppState::PeerCallError => AppState::PeerCallError, + AppState::Error => AppState::Error, + AppState::ServerConnected => AppState::Error, + AppState::ServerRegistered => AppState::Error, + AppState::PeerCallStarted => AppState::Error, + }; + } + + fn handle_hello(&mut self) { + assert_eq!(self.app_state, AppState::ServerRegistering); + self.app_state = AppState::ServerRegistered; + // if we know who we want to connect to, request a connection + if let Some(ref peer_id) = self.peer_id { + self.send_msg_tx + .send(OwnedMessage::Text(format!("SESSION {}", peer_id))) + .unwrap(); + self.app_state = AppState::PeerConnecting; + } else { + // else just spin up the RTC object and wait + self.start_rtc(); + } + } + + fn handle_session_ok(&mut self) { + assert!( + self.peer_id.is_some(), + "SESSION OK should only be received by those attempting to connect to an existing peer" + ); + println!("session is ok; creating webrtc objects"); + assert_eq!(self.app_state, AppState::PeerConnecting); + self.app_state = AppState::PeerConnected; + self.start_rtc(); + } + + fn start_rtc(&mut self) { + let signaller = Signaller::new(self.send_msg_tx.clone(), self.peer_id.is_some()); + let s = signaller.clone(); + self.webrtc = Some(self.media.create_webrtc(Box::new(signaller))); + self.signaller = Some(s); + let webrtc = self.webrtc.as_ref().unwrap(); + let (video, audio) = if self.peer_id.is_some() { + ( + self.media + .create_videoinput_stream() + .unwrap_or_else(|| self.media.create_videostream()), + self.media + .create_audioinput_stream() + .unwrap_or_else(|| self.media.create_audiostream()), + ) + } else { + ( + self.media.create_videostream(), + self.media.create_audiostream(), + ) + }; + webrtc.add_stream(video); + webrtc.add_stream(audio); + webrtc.configure(STUN_SERVER.into(), BundlePolicy::MaxBundle); + } +} + +#[derive(Clone)] +struct Signaller { + sender: mpsc::Sender, + initiate_negotiation: bool, +} + +impl WebRtcSignaller for Signaller { + fn close(&self) { + let _ = self + .sender + .send(OwnedMessage::Close(Some(websocket::message::CloseData { + status_code: 1011, //Internal Error + reason: "explicitly closed".into(), + }))); + } + + fn on_ice_candidate(&self, _: &WebRtcController, candidate: IceCandidate) { + let message = serde_json::to_string(&JsonMsg::Ice { + candidate: candidate.candidate, + sdp_mline_index: candidate.sdp_mline_index, + }) + .unwrap(); + self.sender.send(OwnedMessage::Text(message)).unwrap(); + } + + fn on_negotiation_needed(&self, controller: &WebRtcController) { + if !self.initiate_negotiation { + return; + } + let c2 = controller.clone(); + let s2 = self.clone(); + controller.create_offer( + (move |offer: SessionDescription| { + c2.set_local_description(offer.clone(), (move || s2.send_sdp(offer)).into()) + }) + .into(), + ); + } +} + +impl Signaller { + fn send_sdp(&self, desc: SessionDescription) { + let message = serde_json::to_string(&JsonMsg::Sdp { + type_: desc.type_.as_str().into(), + sdp: desc.sdp, + }) + .unwrap(); + self.sender.send(OwnedMessage::Text(message)).unwrap(); + } + fn new(sender: mpsc::Sender, initiate_negotiation: bool) -> Self { + Signaller { + sender, + initiate_negotiation, + } + } +} + +fn receive_loop( + mut receiver: websocket::receiver::Reader, + send_msg_tx: mpsc::Sender, + mut state: State, +) -> thread::JoinHandle<()> { + thread::spawn(move || { + for message in receiver.incoming_messages() { + let message = match message { + Ok(m) => m, + Err(e) => { + println!("Receive Loop error: {:?}", e); + let _ = send_msg_tx.send(OwnedMessage::Close(None)); + return; + } + }; + + match message { + OwnedMessage::Close(_) => { + let _ = send_msg_tx.send(OwnedMessage::Close(None)); + return; + } + + OwnedMessage::Ping(data) => { + if let Err(e) = send_msg_tx.send(OwnedMessage::Pong(data)) { + println!("Receive Loop error: {:?}", e); + return; + } + } + + OwnedMessage::Text(msg) => { + println!("{:?}", msg); + match &*msg { + "HELLO" => state.handle_hello(), + + "SESSION_OK" => state.handle_session_ok(), + + x if x.starts_with("ERROR") => { + println!("Got error message! {}", msg); + state.handle_error() + } + + _ => { + let json_msg: JsonMsg = serde_json::from_str(&msg).unwrap(); + + match json_msg { + JsonMsg::Sdp { type_, sdp } => { + let desc = SessionDescription { + type_: type_.parse().unwrap(), + sdp: sdp.into(), + }; + let controller = state.webrtc.as_ref().unwrap(); + if state.peer_id.is_some() { + controller.set_remote_description(desc, (|| {}).into()); + } else { + let c2 = controller.clone(); + let c3 = controller.clone(); + let s2 = state.signaller.clone().unwrap(); + controller.set_remote_description( + desc, + (move || { + c3.create_answer( + (move |answer: SessionDescription| { + c2.set_local_description( + answer.clone(), + (move || s2.send_sdp(answer)).into(), + ) + }) + .into(), + ) + }) + .into(), + ); + } + } + JsonMsg::Ice { + sdp_mline_index, + candidate, + } => { + let candidate = IceCandidate { + sdp_mline_index, + candidate, + }; + state + .webrtc + .as_ref() + .unwrap() + .add_ice_candidate(candidate) + .into() + } + }; + } + } + } + + _ => { + println!("Unmatched message type: {:?}", message); + } + } + } + }) +} + +fn run_example(servo_media: Arc) { + env_logger::init(); + let mut args = env::args(); + let _ = args.next(); + let server_port = if let Some(port) = args.next() { + port.parse::().unwrap() + } else { + // we don't panic here so that we can run this + // as a test on Travis + println!("Usage: simple_webrtc "); + return; + }; + let server = format!("ws://localhost:{}", server_port); + let peer_id = args.next(); + + println!("Connecting to server {}", server); + let client = match websocket::client::ClientBuilder::new(&server) + .unwrap() + .connect_insecure() + { + Ok(client) => client, + Err(err) => { + println!("Failed to connect to {} with error: {:?}", server, err); + panic!("uh oh"); + } + }; + let (receiver, sender) = client.split().unwrap(); + + let (send_msg_tx, send_msg_rx) = mpsc::channel::(); + let send_loop = send_loop(sender, send_msg_rx); + + let our_id = rand::thread_rng().gen_range(10, 10_000); + println!("Registering id {} with server", our_id); + send_msg_tx + .send(OwnedMessage::Text(format!("HELLO {}", our_id))) + .expect("error sending"); + + let state = State { + app_state: AppState::ServerRegistering, + send_msg_tx: send_msg_tx.clone(), + _uid: our_id, + peer_id: peer_id, + media: servo_media, + webrtc: None, + signaller: None, + }; + + let receive_loop = receive_loop(receiver, send_msg_tx, state); + let _ = send_loop.join(); + let _ = receive_loop.join(); +} + +fn main() { + if let Ok(servo_media) = ServoMedia::get() { + run_example(servo_media); + } else { + unreachable!(); + } +} diff --git a/servo-media/Cargo.toml b/servo-media/Cargo.toml index d03f6151..ec3c18be 100644 --- a/servo-media/Cargo.toml +++ b/servo-media/Cargo.toml @@ -12,5 +12,8 @@ path = "../audio" [dependencies.servo-media-player] path = "../player" +[dependencies.servo-media-webrtc] +path = "../webrtc" + [target.'cfg(any(all(target_os = "android", target_arch = "arm"), target_arch = "x86_64"))'.dependencies.servo-media-gstreamer] path = "../backends/gstreamer" diff --git a/servo-media/src/lib.rs b/servo-media/src/lib.rs index 13938c1c..49aa2ba3 100644 --- a/servo-media/src/lib.rs +++ b/servo-media/src/lib.rs @@ -5,6 +5,8 @@ pub extern crate servo_media_audio as audio; ))] extern crate servo_media_gstreamer; pub extern crate servo_media_player as player; +pub extern crate servo_media_webrtc as webrtc; +use std::any::Any; use std::sync::{self, Arc, Mutex, Once}; use audio::context::{AudioContext, AudioContextOptions}; @@ -12,12 +14,19 @@ use audio::decoder::DummyAudioDecoder; use audio::sink::{AudioSinkError, DummyAudioSink}; use audio::AudioBackend; use player::{DummyPlayer, Player, PlayerBackend}; +use webrtc::{WebRtcController, WebRtcSignaller, MediaStream}; +use webrtc::{WebRtcBackend, DummyWebRtcController}; pub struct ServoMedia; static INITIALIZER: Once = sync::ONCE_INIT; static mut INSTANCE: *mut Mutex>> = 0 as *mut _; +pub struct DummyMediaStream; +impl MediaStream for DummyMediaStream { + fn as_any(&self) -> &Any { self } +} + pub struct DummyBackend {} impl AudioBackend for DummyBackend { @@ -39,8 +48,33 @@ impl PlayerBackend for DummyBackend { } } +impl WebRtcBackend for DummyBackend { + type Controller = DummyWebRtcController; + fn construct_webrtc_controller( + _: Box, + _: WebRtcController, + ) -> Self::Controller { + DummyWebRtcController + } +} + impl DummyBackend { pub fn init() {} + pub fn create_audiostream() -> DummyMediaStream { + DummyMediaStream + } + + pub fn create_videostream() -> DummyMediaStream { + DummyMediaStream + } + + pub fn create_audioinput_stream(&self) -> Option { + Some(DummyMediaStream) + } + + pub fn create_videoinput_stream(&self) -> Option { + Some(DummyMediaStream) + } } #[cfg(any( @@ -54,6 +88,7 @@ pub type Backend = servo_media_gstreamer::GStreamerBackend; )))] pub type Backend = DummyBackend; + impl ServoMedia { pub fn new() -> Self { Backend::init(); @@ -79,4 +114,24 @@ impl ServoMedia { pub fn create_player(&self) -> Box { Box::new(Backend::make_player()) } + + pub fn create_webrtc(&self, signaller: Box) -> WebRtcController { + WebRtcController::new::(signaller) + } + + pub fn create_audiostream(&self) -> Box { + Box::new(Backend::create_audiostream()) + } + + pub fn create_videostream(&self) -> Box { + Box::new(Backend::create_videostream()) + } + + pub fn create_audioinput_stream(&self) -> Option> { + Backend::create_audioinput_stream().map(|s| Box::new(s) as Box) + } + + pub fn create_videoinput_stream(&self) -> Option> { + Backend::create_videoinput_stream().map(|s| Box::new(s) as Box) + } } diff --git a/webrtc/Cargo.toml b/webrtc/Cargo.toml new file mode 100644 index 00000000..b7d344ca --- /dev/null +++ b/webrtc/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "servo-media-webrtc" +version = "0.1.0" +authors = ["Josh Matthews "] + +[dependencies] +boxfnonce = "0.1.0" diff --git a/webrtc/src/lib.rs b/webrtc/src/lib.rs new file mode 100644 index 00000000..df0521f7 --- /dev/null +++ b/webrtc/src/lib.rs @@ -0,0 +1,127 @@ +extern crate boxfnonce; + +use std::any::Any; +use std::str::FromStr; + +use boxfnonce::SendBoxFnOnce; + +pub mod thread; + +pub trait MediaStream: Any + Send { + fn as_any(&self) -> &Any; +} + +pub use thread::WebRtcController; + +/// This trait is implemented by backends and should never be used directly by +/// the client. Use WebRtcController instead +pub trait WebRtcControllerBackend: Send { + fn configure(&mut self, stun_server: &str, policy: BundlePolicy); + fn set_remote_description(&mut self, SessionDescription, cb: SendBoxFnOnce<'static, ()>); + fn set_local_description(&mut self, SessionDescription, cb: SendBoxFnOnce<'static, ()>); + fn add_ice_candidate(&mut self, candidate: IceCandidate); + fn create_offer(&mut self, cb: SendBoxFnOnce<'static, (SessionDescription,)>); + fn create_answer(&mut self, cb: SendBoxFnOnce<'static, (SessionDescription,)>); + fn add_stream(&mut self, stream: &MediaStream); + fn internal_event(&mut self, event: thread::InternalEvent); + fn quit(&mut self); +} + +pub struct DummyWebRtcController; + +impl WebRtcControllerBackend for DummyWebRtcController { + fn configure(&mut self, _: &str, _: BundlePolicy) {} + fn set_remote_description(&mut self, _: SessionDescription, _: SendBoxFnOnce<'static, ()>) {} + fn set_local_description(&mut self, _: SessionDescription, _: SendBoxFnOnce<'static, ()>) {} + fn add_ice_candidate(&mut self, _: IceCandidate) {} + fn create_offer(&mut self, _: SendBoxFnOnce<'static, (SessionDescription,)>) {} + fn create_answer(&mut self, _: SendBoxFnOnce<'static, (SessionDescription,)>) {} + fn add_stream(&mut self, _: &MediaStream) {} + fn internal_event(&mut self, _: thread::InternalEvent) {} + fn quit(&mut self) {} +} + +pub trait WebRtcSignaller: Send { + fn on_ice_candidate(&self, controller: &WebRtcController, candidate: IceCandidate); + /// Invariant: Must not reentrantly invoke any methods on the controller + fn on_negotiation_needed(&self, controller: &WebRtcController); + fn close(&self); +} + +pub trait WebRtcBackend { + type Controller: WebRtcControllerBackend + 'static; + + fn construct_webrtc_controller( + signaller: Box, + thread: WebRtcController, + ) -> Self::Controller; +} + +/// https://www.w3.org/TR/webrtc/#rtcsdptype +#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq)] +pub enum SdpType { + Answer, + Offer, + Pranswer, + Rollback, +} + +impl SdpType { + pub fn as_str(self) -> &'static str { + match self { + SdpType::Answer => "answer", + SdpType::Offer => "offer", + SdpType::Pranswer => "pranswer", + SdpType::Rollback => "rollback", + } + } +} + +impl FromStr for SdpType { + type Err = (); + fn from_str(s: &str) -> Result { + Ok(match s { + "answer" => SdpType::Answer, + "offer" => SdpType::Offer, + "pranswer" => SdpType::Pranswer, + "rollback" => SdpType::Rollback, + _ => return Err(()), + }) + } +} + +/// https://www.w3.org/TR/webrtc/#rtcsessiondescription-class +/// +/// https://developer.mozilla.org/en-US/docs/Web/API/RTCSessionDescription +#[derive(Clone, Hash, Debug, PartialEq, Eq)] +pub struct SessionDescription { + pub type_: SdpType, + pub sdp: String, +} + +/// https://www.w3.org/TR/webrtc/#rtcicecandidate-interface +/// +/// https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate +#[derive(Clone, Hash, Debug, PartialEq, Eq)] +pub struct IceCandidate { + pub sdp_mline_index: u32, + pub candidate: String, + // XXXManishearth this is missing a bunch +} + +/// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection#RTCBundlePolicy_enum +pub enum BundlePolicy { + Balanced, + MaxCompat, + MaxBundle, +} + +impl BundlePolicy { + pub fn as_str(self) -> &'static str { + match self { + BundlePolicy::Balanced => "balanced", + BundlePolicy::MaxCompat => "max-compat", + BundlePolicy::MaxBundle => "max-bundle", + } + } +} diff --git a/webrtc/src/thread.rs b/webrtc/src/thread.rs new file mode 100644 index 00000000..618d281a --- /dev/null +++ b/webrtc/src/thread.rs @@ -0,0 +1,112 @@ +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +use boxfnonce::SendBoxFnOnce; + +use crate::{BundlePolicy, IceCandidate, MediaStream, SessionDescription}; +use crate::{WebRtcBackend, WebRtcControllerBackend, WebRtcSignaller}; + +#[derive(Clone)] +/// Entry point for all client webrtc interactions. +pub struct WebRtcController { + sender: Sender, +} + +impl WebRtcController { + pub fn new(signaller: Box) -> Self { + let (sender, receiver) = channel(); + + let t = WebRtcController { sender }; + + let mut controller = T::construct_webrtc_controller(signaller, t.clone()); + + thread::spawn(move || { + while let Ok(event) = receiver.recv() { + if !handle_rtc_event(&mut controller, event) { + // shut down event loop + break; + } + } + }); + + t + } + pub fn configure(&self, stun_server: String, policy: BundlePolicy) { + let _ = self + .sender + .send(RtcThreadEvent::ConfigureStun(stun_server, policy)); + } + pub fn set_remote_description(&self, desc: SessionDescription, cb: SendBoxFnOnce<'static, ()>) { + let _ = self + .sender + .send(RtcThreadEvent::SetRemoteDescription(desc, cb)); + } + pub fn set_local_description(&self, desc: SessionDescription, cb: SendBoxFnOnce<'static, ()>) { + let _ = self + .sender + .send(RtcThreadEvent::SetLocalDescription(desc, cb)); + } + pub fn add_ice_candidate(&self, candidate: IceCandidate) { + let _ = self.sender.send(RtcThreadEvent::AddIceCandidate(candidate)); + } + pub fn create_offer(&self, cb: SendBoxFnOnce<'static, (SessionDescription,)>) { + let _ = self.sender.send(RtcThreadEvent::CreateOffer(cb)); + } + pub fn create_answer(&self, cb: SendBoxFnOnce<'static, (SessionDescription,)>) { + let _ = self.sender.send(RtcThreadEvent::CreateAnswer(cb)); + } + pub fn add_stream(&self, stream: Box) { + let _ = self.sender.send(RtcThreadEvent::AddStream(stream)); + } + + /// This should not be invoked by clients + pub fn internal_event(&self, event: InternalEvent) { + let _ = self.sender.send(RtcThreadEvent::InternalEvent(event)); + } + + pub fn quit(&self) { + let _ = self.sender.send(RtcThreadEvent::Quit); + } +} + +pub enum RtcThreadEvent { + ConfigureStun(String, BundlePolicy), + SetRemoteDescription(SessionDescription, SendBoxFnOnce<'static, ()>), + SetLocalDescription(SessionDescription, SendBoxFnOnce<'static, ()>), + AddIceCandidate(IceCandidate), + CreateOffer(SendBoxFnOnce<'static, (SessionDescription,)>), + CreateAnswer(SendBoxFnOnce<'static, (SessionDescription,)>), + AddStream(Box), + InternalEvent(InternalEvent), + Quit, +} + +/// To allow everything to occur on the event loop, +/// the backend may need to send signals to itself +/// +/// This is a somewhat leaky abstraction, but we don't +/// plan on having too many backends anyway +pub enum InternalEvent { + OnNegotiationNeeded, + OnIceCandidate(IceCandidate), +} + +pub fn handle_rtc_event(controller: &mut WebRtcControllerBackend, event: RtcThreadEvent) -> bool { + match event { + RtcThreadEvent::ConfigureStun(server, policy) => controller.configure(&server, policy), + RtcThreadEvent::SetRemoteDescription(desc, cb) => { + controller.set_remote_description(desc, cb) + } + RtcThreadEvent::SetLocalDescription(desc, cb) => controller.set_local_description(desc, cb), + RtcThreadEvent::AddIceCandidate(candidate) => controller.add_ice_candidate(candidate), + RtcThreadEvent::CreateOffer(cb) => controller.create_offer(cb), + RtcThreadEvent::CreateAnswer(cb) => controller.create_answer(cb), + RtcThreadEvent::AddStream(media) => controller.add_stream(&*media), + RtcThreadEvent::InternalEvent(e) => controller.internal_event(e), + RtcThreadEvent::Quit => { + controller.quit(); + return false; + } + } + true +}