diff --git a/Cargo.lock b/gst-warp-sink/Cargo.lock similarity index 52% rename from Cargo.lock rename to gst-warp-sink/Cargo.lock index 9f445a2..e6e2804 100644 --- a/Cargo.lock +++ b/gst-warp-sink/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -23,6 +38,167 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +dependencies = [ + "concurrent-queue", + "event-listener 4.0.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.2.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.1.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.1.1", + "async-executor", + "async-io 2.2.2", + "async-lock 3.2.0", + "blocking", + "futures-lite 2.1.0", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +dependencies = [ + "async-lock 3.2.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.1.0", + "parking", + "polling 3.3.1", + "rustix 0.38.28", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +dependencies = [ + "event-listener 4.0.0", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atomic_refcell" version = "0.1.13" @@ -35,12 +211,55 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.1.1", + "async-lock 3.2.0", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite 2.1.0", + "piper", + "tracing", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -98,12 +317,40 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "either" version = "1.9.0" @@ -116,6 +363,88 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.0", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.29" @@ -123,6 +452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -142,6 +472,40 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.29" @@ -171,14 +535,35 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", ] +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "gio-sys" version = "0.19.0" @@ -188,7 +573,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -196,7 +581,7 @@ name = "glib" version = "0.19.0" source = "git+https://github.com/gtk-rs/gtk-rs-core#a0d52347c99a5e1e7186f18e0db9f9e67eae1bb8" dependencies = [ - "bitflags", + "bitflags 2.4.1", "futures-channel", "futures-core", "futures-executor", @@ -235,6 +620,18 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gobject-sys" version = "0.19.0" @@ -497,6 +894,23 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -520,6 +934,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -530,6 +954,26 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "isobmff" version = "0.1.0" @@ -562,17 +1006,41 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "libc" version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "m3u8-rs" @@ -601,6 +1069,7 @@ dependencies = [ "gstreamer-video", "isobmff", "m3u8-rs", + "moq-transport", "mp4", ] @@ -616,6 +1085,42 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "moq-transport" +version = "0.2.0" +source = "git+https://github.com/kixelated/moq-rs#75e7dc03bfc0e64fe243742478bd755b399045a2" +dependencies = [ + "async-trait", + "bytes", + "indexmap", + "log", + "paste", + "quinn", + "thiserror", + "tokio", + "webtransport-quinn", +] + [[package]] name = "mp4" version = "0.14.0" @@ -689,12 +1194,27 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + [[package]] name = "option-operations" version = "0.5.0" @@ -704,12 +1224,24 @@ dependencies = [ "paste", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "paste" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -722,12 +1254,59 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.28", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "pretty-hex" version = "0.3.0" @@ -776,6 +1355,54 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +dependencies = [ + "bytes", + "rand", + "ring 0.16.20", + "rustc-hash", + "rustls", + "rustls-native-certs", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +dependencies = [ + "bytes", + "libc", + "socket2 0.5.5", + "tracing", + "windows-sys 0.48.0", +] + [[package]] name = "quote" version = "1.0.33" @@ -785,12 +1412,194 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "ring 0.17.7", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.193" @@ -846,6 +1655,38 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "syn" version = "1.0.109" @@ -906,6 +1747,48 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "toml" version = "0.8.8" @@ -951,12 +1834,88 @@ dependencies = [ "winnow", ] +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "value-bag" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" + [[package]] name = "version-compare" version = "0.1.1" @@ -969,6 +1928,18 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.89" @@ -994,6 +1965,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.89" @@ -1023,6 +2006,80 @@ version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webtransport-generic" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df712317d761312996f654739debeb3838eb02c6fd9146d9efdfd08a46674e45" +dependencies = [ + "bytes", + "tokio", +] + +[[package]] +name = "webtransport-proto" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebeada5037d6302980ae2e0ab8d840e329c1697c612c6c077172de2b7631a276" +dependencies = [ + "bytes", + "http", + "thiserror", + "url", +] + +[[package]] +name = "webtransport-quinn" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6536bd7382e3ecaeaf791fefbe8aa98d987eb5809ba7f1bd20617161d3a319" +dependencies = [ + "async-std", + "bytes", + "futures", + "http", + "log", + "quinn", + "quinn-proto", + "thiserror", + "tokio", + "url", + "webtransport-generic", + "webtransport-proto", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.51.1" @@ -1032,6 +2089,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/gst-warp-sink/Cargo.toml similarity index 93% rename from Cargo.toml rename to gst-warp-sink/Cargo.toml index ebbcf3a..1184d8f 100644 --- a/Cargo.toml +++ b/gst-warp-sink/Cargo.toml @@ -21,3 +21,4 @@ m3u8-rs = "5.0.4" isobmff = { git = "https://github.com/LMinJae/isobmff-rs", version = "0.1.0" } bytes = "1.5.0" mp4 = "0.14.0" +moq-transport = { git = "https://github.com/kixelated/moq-rs", version = "0.2.0" } diff --git a/gst-warp-sink/src/moqsink/imp.rs b/gst-warp-sink/src/moqsink/imp.rs index 24f7a1d..638aec0 100644 --- a/gst-warp-sink/src/moqsink/imp.rs +++ b/gst-warp-sink/src/moqsink/imp.rs @@ -1,9 +1,9 @@ use glib::subclass::prelude::*; -use gst::ClockTime; use gst::prelude::*; use gst::subclass::prelude::*; +use gst::ClockTime; #[allow(unused_imports)] -use gst::{gst_debug, gst_error, gst_warning, gst_info, gst_log, gst_trace}; +use gst::{gst_debug, gst_error, gst_info, gst_log, gst_trace, gst_warning}; use once_cell::sync::Lazy; use std::convert::TryInto; use std::sync::Mutex; @@ -11,7 +11,8 @@ use std::sync::Mutex; pub const ELEMENT_NAME: &str = "MoqSink"; const ELEMENT_CLASS_NAME: &str = "MoqSink"; const ELEMENT_LONG_NAME: &str = "Media Over Quic Sink"; -const ELEMENT_DESCRIPTION: &str = "This element accepts fragmented MP4 input from mp4mux and publishes them to a Moq-Relay."; +const ELEMENT_DESCRIPTION: &str = + "This element accepts fragmented MP4 input from mp4mux and publishes them to a Moq-Relay."; const ELEMENT_AUTHOR: &str = "Wanjohi Ryan "; const DEBUG_CATEGORY: &str = ELEMENT_NAME; @@ -40,9 +41,7 @@ struct Mp4Parser { impl Mp4Parser { pub fn new() -> Mp4Parser { - Mp4Parser { - buf: Vec::new(), - } + Mp4Parser { buf: Vec::new() } } pub fn add(&mut self, buf: &[u8]) { @@ -105,9 +104,7 @@ struct StartedState { } enum State { - Started { - state: StartedState, - } + Started { state: StartedState }, } impl Default for State { @@ -124,7 +121,7 @@ impl Default for State { fragment_offset: None, fragment_offset_end: None, fragment_buffer_flags: gst::BufferFlags::DELTA_UNIT, - } + }, } } } @@ -154,10 +151,7 @@ impl MoqSink { let mut state = self.state.lock().unwrap(); let state = match *state { - State::Started { - ref mut state, - .. - } => state, + State::Started { ref mut state, .. } => state, }; let map = buffer.map_readable().map_err(|_| { @@ -179,20 +173,36 @@ impl MoqSink { state.fragment_dts = buffer.dts(); } let pts_plus_duration = buffer.pts() + buffer.duration(); - if state.fragment_max_pts_plus_duration.is_none() || state.fragment_max_pts_plus_duration < pts_plus_duration { + if state.fragment_max_pts_plus_duration.is_none() + || state.fragment_max_pts_plus_duration < pts_plus_duration + { state.fragment_max_pts_plus_duration = pts_plus_duration; } - if buffer.offset() != gst::BUFFER_OFFSET_NONE && (state.fragment_offset.is_none() || state.fragment_offset.unwrap() > buffer.offset()) { + if buffer.offset() != gst::BUFFER_OFFSET_NONE + && (state.fragment_offset.is_none() + || state.fragment_offset.unwrap() > buffer.offset()) + { state.fragment_offset = Some(buffer.offset()); } - if buffer.offset_end() != gst::BUFFER_OFFSET_NONE && (state.fragment_offset_end.is_none() || state.fragment_offset_end.unwrap() < buffer.offset_end()) { + if buffer.offset_end() != gst::BUFFER_OFFSET_NONE + && (state.fragment_offset_end.is_none() + || state.fragment_offset_end.unwrap() < buffer.offset_end()) + { state.fragment_offset_end = Some(buffer.offset_end()); } - if state.fragment_buffer_flags.contains(gst::BufferFlags::DELTA_UNIT) && !buffer.flags().contains(gst::BufferFlags::DELTA_UNIT) { - state.fragment_buffer_flags.remove(gst::BufferFlags::DELTA_UNIT); + if state + .fragment_buffer_flags + .contains(gst::BufferFlags::DELTA_UNIT) + && !buffer.flags().contains(gst::BufferFlags::DELTA_UNIT) + { + state + .fragment_buffer_flags + .remove(gst::BufferFlags::DELTA_UNIT); } if buffer.flags().contains(gst::BufferFlags::DISCONT) { - state.fragment_buffer_flags.insert(gst::BufferFlags::DISCONT); + state + .fragment_buffer_flags + .insert(gst::BufferFlags::DISCONT); } gst_trace!(CAT, obj: pad, "Updated state={:?}", state); } @@ -205,52 +215,75 @@ impl MoqSink { ATOM_TYPE_FTYPE => { state.ftype_atom = Some(atom); gst_log!(CAT, obj: pad, "ftype_atom={:?}", state.ftype_atom); - }, + } ATOM_TYPE_MOOV => { state.moov_atom = Some(atom); gst_log!(CAT, obj: pad, "moov_atom={:?}", state.moov_atom); - }, + } ATOM_TYPE_MOOF => { state.moof_atom = Some(atom); gst_log!(CAT, obj: pad, "moof_atom={:?}", state.moof_atom); - }, + } ATOM_TYPE_MDAT => { let mdat_atom = atom; - match (state.ftype_atom.as_ref(), state.moov_atom.as_ref(), state.moof_atom.as_ref()) { + match ( + state.ftype_atom.as_ref(), + state.moov_atom.as_ref(), + state.moof_atom.as_ref(), + ) { (Some(ftype_atom), Some(moov_atom), Some(moof_atom)) => { - let include_header = !state.fragment_buffer_flags.contains(gst::BufferFlags::DELTA_UNIT); + let include_header = !state + .fragment_buffer_flags + .contains(gst::BufferFlags::DELTA_UNIT); let header_len = if include_header { ftype_atom.len() + moov_atom.len() } else { 0 }; - let output_buf_len = header_len + moof_atom.len() + mdat_atom.len(); + let output_buf_len = + header_len + moof_atom.len() + mdat_atom.len(); gst_log!(CAT, obj: pad, "Pushing buffer; include_header={}, ftype.len={}, moov.len={}, moof.len={}, mdat.len={}", include_header, ftype_atom.len(), moov_atom.len(), moof_atom.len(), mdat_atom.len()); - let mut gst_buffer = gst::Buffer::with_size(output_buf_len).unwrap(); + let mut gst_buffer = + gst::Buffer::with_size(output_buf_len).unwrap(); { let buffer_ref = gst_buffer.get_mut().unwrap(); buffer_ref.set_pts(state.fragment_pts); buffer_ref.set_dts(state.fragment_dts); - let duration = state.fragment_max_pts_plus_duration - state.fragment_pts; + let duration = state.fragment_max_pts_plus_duration + - state.fragment_pts; buffer_ref.set_duration(duration); - buffer_ref.set_offset(state.fragment_offset.unwrap_or(gst::BUFFER_OFFSET_NONE)); - buffer_ref.set_offset_end(state.fragment_offset_end.unwrap_or(gst::BUFFER_OFFSET_NONE)); + buffer_ref.set_offset( + state + .fragment_offset + .unwrap_or(gst::BUFFER_OFFSET_NONE), + ); + buffer_ref.set_offset_end( + state + .fragment_offset_end + .unwrap_or(gst::BUFFER_OFFSET_NONE), + ); buffer_ref.set_flags(state.fragment_buffer_flags); let mut buffer_map = buffer_ref.map_writable().unwrap(); let slice = buffer_map.as_mut_slice(); let mut pos = 0; if include_header { - slice[pos..pos+ftype_atom.len()].copy_from_slice(&ftype_atom.atom_bytes); + slice[pos..pos + ftype_atom.len()] + .copy_from_slice(&ftype_atom.atom_bytes); pos += ftype_atom.len(); - slice[pos..pos+moov_atom.len()].copy_from_slice(&moov_atom.atom_bytes); + slice[pos..pos + moov_atom.len()] + .copy_from_slice(&moov_atom.atom_bytes); pos += moov_atom.len(); } - slice[pos..pos+moof_atom.len()].copy_from_slice(&moof_atom.atom_bytes); + slice[pos..pos + moof_atom.len()] + .copy_from_slice(&moof_atom.atom_bytes); pos += moof_atom.len(); - slice[pos..pos+mdat_atom.len()].copy_from_slice(&mdat_atom.atom_bytes); + slice[pos..pos + mdat_atom.len()] + .copy_from_slice(&mdat_atom.atom_bytes); pos += mdat_atom.len(); assert_eq!(pos, output_buf_len); + + //FIXME: Work on the Json here, instead of redoing it in a new method. } // Clear fragment variables. state.fragment_pts = ClockTime::none(); @@ -262,21 +295,21 @@ impl MoqSink { // Push new buffer. gst_log!(CAT, obj: pad, "Pushing buffer {:?}", gst_buffer); // let _ = self.srcpad.push(gst_buffer)?; - self.send_to_network(gst_buffer)?; - }, + // self.send_to_network(gst_buffer)?; + } _ => { gst_warning!(CAT, obj: pad, "Received mdat without ftype, moov, or moof"); - }, + } } - }, + } _ => { gst_warning!(CAT, obj: pad, "Unknown atom type {:?}", atom); - }, + } } - }, + } None => break, } - }; + } gst_trace!(CAT, obj: element, "sink_chain: END: state={:?}", state); Ok(gst::FlowSuccess::Ok) } @@ -285,12 +318,17 @@ impl MoqSink { self.srcpad.push_event(event) } - fn sink_query(&self, _pad: &gst::Pad, _element: &super::MoqSink, query: &mut gst::QueryRef) -> bool { + fn sink_query( + &self, + _pad: &gst::Pad, + _element: &super::MoqSink, + query: &mut gst::QueryRef, + ) -> bool { self.srcpad.peer_query(query) } - fn send_to_network(&self, data: &[u8]) -> Result<(), Box> { - + fn send_to_network(&self, buffer: gst::Buffer) -> Result<(), Box> { + //Let this be our publisher } } @@ -301,7 +339,6 @@ impl ObjectSubclass for MoqSink { type ParentType = gst::Element; fn with_class(klass: &Self::Class) -> Self { - let templ = klass.pad_template("src").unwrap(); let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) .event_function(|pad, parent, event| { @@ -342,7 +379,7 @@ impl ElementImpl for MoqSink { "Generic", ELEMENT_DESCRIPTION, ELEMENT_AUTHOR, - ) + ) }); Some(&*ELEMENT_METADATA) } @@ -361,4 +398,204 @@ impl ElementImpl for MoqSink { }); PAD_TEMPLATES.as_ref() } -} \ No newline at end of file +} + +//Moq +pub struct Publisher { + track: track::Publisher, +} + +impl Publisher { + pub fn new(track: track::Publisher) -> Self { + Self { track } + } + + pub async fn run(mut self) -> anyhow::Result<()> { + let start = Utc::now(); + let mut now = start; + + // Just for fun, don't start at zero. + let mut sequence = start.minute(); + + loop { + let segment = self + .track + .create_segment(segment::Info { + sequence: VarInt::from_u32(sequence), + priority: 0, + expires: Some(time::Duration::from_secs(60)), + }) + .context("failed to create minute segment")?; + + sequence += 1; + + tokio::spawn(async move { + if let Err(err) = Self::send_segment(segment, now).await { + log::warn!("failed to send minute: {:?}", err); + } + }); + + let next = now + chrono::Duration::minutes(1); + let next = next.with_second(0).unwrap().with_nanosecond(0).unwrap(); + + let delay = (next - now).to_std().unwrap(); + tokio::time::sleep(delay).await; + + now = next; // just assume we didn't undersleep + } + } + + async fn send_segment( + mut segment: segment::Publisher, + mut now: DateTime, + ) -> anyhow::Result<()> { + // Everything but the second. + let base = now.format("%Y-%m-%d %H:%M:").to_string(); + + segment + .fragment(VarInt::ZERO, base.len())? + .chunk(base.clone().into()) + .context("failed to write base")?; + + loop { + let delta = now.format("%S").to_string(); + let sequence = VarInt::from_u32(now.second() + 1); + + segment + .fragment(sequence, delta.len())? + .chunk(delta.clone().into()) + .context("failed to write delta")?; + + println!("{}{}", base, delta); + + let next = now + chrono::Duration::seconds(1); + let next = next.with_nanosecond(0).unwrap(); + + let delay = (next - now).to_std().unwrap(); + tokio::time::sleep(delay).await; + + // Get the current time again to check if we overslept + let next = Utc::now(); + if next.minute() != now.minute() { + return Ok(()); + } + + now = next; + } + } +} + +//Sends to remote +pub struct Sender { + track: track::Publisher, +} + +impl Sender { + pub fn new(track: track::Publisher) -> Self { + Self { track } + } + + pub async fn start(mut self) -> anyhow::Result<()> { + // Disable tracing so we don't get a bunch of Quinn spam. + let tracer = tracing_subscriber::FmtSubscriber::builder() + .with_max_level(tracing::Level::WARN) + .finish(); + tracing::subscriber::set_global_default(tracer).unwrap(); + + let config = cli::Config::parse(); + + // Create a list of acceptable root certificates. + let mut roots = rustls::RootCertStore::empty(); + + if config.tls_root.is_empty() { + // Add the platform's native root certificates. + for cert in + rustls_native_certs::load_native_certs().context("could not load platform certs")? + { + roots + .add(&rustls::Certificate(cert.0)) + .context("failed to add root cert")?; + } + } else { + // Add the specified root certificates. + for root in &config.tls_root { + let root = fs::File::open(root).context("failed to open root cert file")?; + let mut root = io::BufReader::new(root); + + let root = rustls_pemfile::certs(&mut root).context("failed to read root cert")?; + anyhow::ensure!(root.len() == 1, "expected a single root cert"); + let root = rustls::Certificate(root[0].to_owned()); + + roots.add(&root).context("failed to add root cert")?; + } + } + + let mut tls_config = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(roots) + .with_no_client_auth(); + + // Allow disabling TLS verification altogether. + if config.tls_disable_verify { + let noop = NoCertificateVerification {}; + tls_config + .dangerous() + .set_certificate_verifier(Arc::new(noop)); + } + } + + async fn send_segment( + mut segment: segment::Publisher, + mut now: DateTime, + ) -> anyhow::Result<()> { + // Everything but the second. + let base = now.format("%Y-%m-%d %H:%M:").to_string(); + + segment + .fragment(VarInt::ZERO, base.len())? + .chunk(base.clone().into()) + .context("failed to write base")?; + + loop { + let delta = now.format("%S").to_string(); + let sequence = VarInt::from_u32(now.second() + 1); + + segment + .fragment(sequence, delta.len())? + .chunk(delta.clone().into()) + .context("failed to write delta")?; + + println!("{}{}", base, delta); + + let next = now + chrono::Duration::seconds(1); + let next = next.with_nanosecond(0).unwrap(); + + let delay = (next - now).to_std().unwrap(); + tokio::time::sleep(delay).await; + + // Get the current time again to check if we overslept + let next = Utc::now(); + if next.minute() != now.minute() { + return Ok(()); + } + + now = next; + } + } +} + +pub struct NoCertificateVerification {} + +impl rustls::client::ServerCertVerifier for NoCertificateVerification { + fn verify_server_cert( + &self, + _end_entity: &rustls::Certificate, + _intermediates: &[rustls::Certificate], + _server_name: &rustls::ServerName, + _scts: &mut dyn Iterator, + _ocsp_response: &[u8], + _now: time::SystemTime, + ) -> Result { + Ok(rustls::client::ServerCertVerified::assertion()) + } +} diff --git a/gst-warp-sink/src/moqsink/test.sink.txt b/gst-warp-sink/src/moqsink/test.sink.txt new file mode 100644 index 0000000..0c8fdea --- /dev/null +++ b/gst-warp-sink/src/moqsink/test.sink.txt @@ -0,0 +1,85 @@ +In the code example you provided, the Mp4Parser struct is responsible for parsing and extracting MP4 atoms from the incoming buffer. When the pop_atom method is called, it checks if there is enough data to form an atom and then extracts it. + +To extract precise atoms like mdat, ftyp, moof, and moov, you can follow the pattern already established in the loop in the sink_chain function. This loop calls pop_atom repeatedly to extract atoms from the incoming buffer. When an atom is extracted, it checks the atom's type and processes it accordingly. + +Here's a simplified version of the loop that extracts and processes the atoms: + +loop { + match state.mp4_parser.pop_atom() { + Some(atom) => { + match atom.atom_type { + ATOM_TYPE_FTYPE => { + state.ftype_atom = Some(atom); + // ... process ftype atom + }, + ATOM_TYPE_MOOV => { + state.moov_atom = Some(atom); + // ... process moov atom + }, + ATOM_TYPE_MOOF => { + state.moof_atom = Some(atom); + // ... process moof atom + }, + ATOM_TYPE_MDAT => { + // ... process mdat atom + }, + _ => { + // Unknown or unhandled atom type + }, + } + }, + None => break, // No more atoms to pop, exit the loop + } +} +In your send_to_network method, you will need to send these atoms over the network. This means you should collect the necessary atoms and then send them in the correct order, depending on whether it's a keyframe or not. + +To do this, you can create a FragmentData struct that includes the atoms you need: + +struct FragmentData { + ftype_atom: Option, + moov_atom: Option, + moof_atom: Mp4Atom, + mdat_atom: Mp4Atom, + // ... include other metadata like timestamps +} +Then, in your loop, when you have all the necessary atoms (e.g., after you've processed the mdat atom), you can create an instance of FragmentData and pass it to send_to_network: + +// Inside the loop, after processing the mdat atom +let fragment_data = FragmentData { + ftype_atom: state.ftype_atom.clone(), + moov_atom: state.moov_atom.clone(), + moof_atom: state.moof_atom.take().unwrap(), + mdat_atom: mdat_atom, + // ... set other metadata +}; + +// Send the fragment data over the network +self.send_to_network(fragment_data)?; +Finally, in your send_to_network method, you can construct the buffer to send based on the FragmentData: + +impl MoqSink { + // ... + fn send_to_network(&self, fragment_data: FragmentData) -> Result<(), Box> { + // Construct the buffer to send + let mut buffer_to_send = Vec::new(); + + // If it's a keyframe, include the ftype and moov atoms + if let (Some(ftype_atom), Some(moov_atom)) = (fragment_data.ftype_atom, fragment_data.moov_atom) { + buffer_to_send.extend_from_slice(&ftype_atom.atom_bytes); + buffer_to_send.extend_from_slice(&moov_atom.atom_bytes); + } + + // Always include the moof and mdat atoms + buffer_to_send.extend_from_slice(&fragment_data.moof_atom.atom_bytes); + buffer_to_send.extend_from_slice(&fragment_data.mdat_atom.atom_bytes); + + // Send the buffer over the network using your QUIC implementation + // ... + + Ok(()) + } + // ... +} +Remember to handle cases where the ftype and moov atoms might not be present, as they're only included for keyframes. The send_to_network method will need to take this into account and only include these atoms when necessary. + +The actual network transmission code will depend on the QUIC library you're using, and you'll need to implement the details of establishing connections, creating streams, and sending data accordingly. \ No newline at end of file