diff --git a/Cargo.lock b/Cargo.lock index 8b51124..acad895 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "aho-corasick" version = "0.7.18" @@ -17,6 +29,12 @@ version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +[[package]] +name = "atomic_refcell" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d" + [[package]] name = "atty" version = "0.2.14" @@ -34,12 +52,52 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bytemuck" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cairo-rs" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.16.0" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "cc" version = "1.0.73" @@ -61,6 +119,92 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "color-name" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cabd7573f60c1096a1e2bd82b2dc03a8063e607c698e15189a476c3541d65c" + +[[package]] +name = "color-thief" +version = "0.2.1" +source = "git+https://github.com/philn/color-thief-rs?branch=max-colors-respect#8ce42596946124a0b67a2b3145814ab562fd5ee7" +dependencies = [ + "rgb", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if", + "lazy_static", +] + [[package]] name = "ctrlc" version = "3.2.1" @@ -71,6 +215,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "env_logger" version = "0.7.1" @@ -151,10 +311,20 @@ dependencies = [ "slab", ] +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "glib" version = "0.16.0" -source = "git+https://github.com/gtk-rs/gtk-rs-core#226367126031d1a3d29d853a6398abff895d6e32" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" dependencies = [ "bitflags", "futures-channel", @@ -174,7 +344,7 @@ dependencies = [ [[package]] name = "glib-macros" version = "0.16.0" -source = "git+https://github.com/gtk-rs/gtk-rs-core#226367126031d1a3d29d853a6398abff895d6e32" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" dependencies = [ "anyhow", "heck", @@ -188,7 +358,7 @@ dependencies = [ [[package]] name = "glib-sys" version = "0.16.0" -source = "git+https://github.com/gtk-rs/gtk-rs-core#226367126031d1a3d29d853a6398abff895d6e32" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" dependencies = [ "libc", "system-deps", @@ -197,17 +367,41 @@ dependencies = [ [[package]] name = "gobject-sys" version = "0.16.0" -source = "git+https://github.com/gtk-rs/gtk-rs-core#226367126031d1a3d29d853a6398abff895d6e32" +source = "git+https://github.com/gtk-rs/gtk-rs-core#b460288e2bf547463ba909e30e58d1eefc46568e" dependencies = [ "glib-sys", "libc", "system-deps", ] +[[package]] +name = "gst-plugin-version-helper" +version = "0.9.0" +dependencies = [ + "chrono", +] + +[[package]] +name = "gst-plugin-videofx" +version = "0.9.0" +dependencies = [ + "atomic_refcell", + "cairo-rs", + "color-name", + "color-thief", + "gst-plugin-version-helper", + "gstreamer", + "gstreamer-base", + "gstreamer-video", + "image", + "img_hash", + "once_cell", +] + [[package]] name = "gstreamer" version = "0.19.0" -source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f095b6f0bad17485ffd541bdef88f950cbff9753" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" dependencies = [ "bitflags", "cfg-if", @@ -219,7 +413,7 @@ dependencies = [ "libc", "muldiv", "num-integer", - "num-rational", + "num-rational 0.4.0", "once_cell", "option-operations", "paste", @@ -227,10 +421,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gstreamer-base" +version = "0.19.0" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" +dependencies = [ + "bitflags", + "cfg-if", + "glib", + "gstreamer", + "gstreamer-base-sys", + "libc", +] + [[package]] name = "gstreamer-base-sys" version = "0.19.0" -source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f095b6f0bad17485ffd541bdef88f950cbff9753" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" dependencies = [ "glib-sys", "gobject-sys", @@ -242,7 +449,7 @@ dependencies = [ [[package]] name = "gstreamer-mpegts-sys" version = "0.19.0" -source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f095b6f0bad17485ffd541bdef88f950cbff9753" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" dependencies = [ "glib-sys", "gstreamer-base-sys", @@ -254,7 +461,7 @@ dependencies = [ [[package]] name = "gstreamer-sys" version = "0.19.0" -source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f095b6f0bad17485ffd541bdef88f950cbff9753" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" dependencies = [ "glib-sys", "gobject-sys", @@ -262,6 +469,35 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gstreamer-video" +version = "0.19.0" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" +dependencies = [ + "bitflags", + "cfg-if", + "futures-channel", + "glib", + "gstreamer", + "gstreamer-base", + "gstreamer-video-sys", + "libc", + "once_cell", +] + +[[package]] +name = "gstreamer-video-sys" +version = "0.19.0" +source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#61a3f5296c3093e9811d883256ad38bd5483b6db" +dependencies = [ + "glib-sys", + "gobject-sys", + "gstreamer-base-sys", + "gstreamer-sys", + "libc", + "system-deps", +] + [[package]] name = "heck" version = "0.4.0" @@ -286,12 +522,59 @@ dependencies = [ "quick-error", ] +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational 0.3.2", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "img_hash" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea4eac6fc4f64ed363d5c210732b747bfa5ddd8a25ac347d887f298c3a70b49" +dependencies = [ + "base64", + "image", + "rustdct", + "serde", + "transpose 0.2.1", +] + [[package]] name = "indenter" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.123" @@ -322,6 +605,25 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "muldiv" version = "1.0.0" @@ -341,6 +643,16 @@ dependencies = [ "memoffset", ] +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -351,6 +663,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.0" @@ -371,6 +705,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.10.0" @@ -410,6 +754,18 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + [[package]] name = "pretty-hex" version = "0.2.1" @@ -484,6 +840,30 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "regex" version = "1.5.5" @@ -501,11 +881,68 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "rgb" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74fdc210d8f24a7dbfedc13b04ba5764f5232754ccebfdf5fff1bad791ccbc6" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "rustdct" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4d167674b4cf68c2114bdbcd34c95aa9071652b73b0f43b19298f1d2780b7d" +dependencies = [ + "rustfft", +] + +[[package]] +name = "rustfft" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77008ed59a8923c8b4ac2e5eaa6d28fbe893d3b9515098a4a5fc7767d6430fe5" +dependencies = [ + "num-complex", + "num-integer", + "num-traits", + "strength_reduce", + "transpose 0.1.0", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "signal-hook" @@ -538,6 +975,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "strength_reduce" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ff2f71c82567c565ba4b3009a9350a96a7269eaa4001ebedae926230bc2254" + [[package]] name = "syn" version = "1.0.91" @@ -591,6 +1034,17 @@ dependencies = [ "syn", ] +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.4", + "weezl", +] + [[package]] name = "toml" version = "0.5.8" @@ -600,6 +1054,22 @@ dependencies = [ "serde", ] +[[package]] +name = "transpose" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643e21580bb0627c7bb09e5cedbb42c8705b19d012de593ed6b0309270b3cd1e" + +[[package]] +name = "transpose" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95f9c900aa98b6ea43aee227fd680550cdec726526aab8ac801549eadb25e39f" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "unicode-xid" version = "0.2.2" @@ -625,6 +1095,7 @@ dependencies = [ "ctrlc", "eyre", "glib", + "gst-plugin-videofx", "gstreamer", "gstreamer-mpegts-sys", "log", @@ -632,6 +1103,12 @@ dependencies = [ "signal-hook", ] +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index a267f39..cc48619 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ eyre = "0.6.6" glib = { git = "https://github.com/gtk-rs/gtk-rs-core" } gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] } gst-mpegts = { package = "gstreamer-mpegts-sys", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] } +gst-plugin-videofx = { path = "../gst-plugins-rs/video/videofx" } ctrlc = "3.2.1" signal-hook = "0.3.13" #tokio = { version = "1.17", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index ed781d5..04717c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use log::{debug, info}; use std::fs::File; use std::io::Write; use std::process; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Duration; @@ -53,10 +54,10 @@ impl EventId { } } - fn main() -> eyre::Result<()> { pretty_env_logger::init_timed(); gst::init()?; + gstvideofx::plugin_register_static()?; unsafe { gst_mpegts::gst_mpegts_initialize(); } @@ -65,14 +66,12 @@ fn main() -> eyre::Result<()> { let pipeline = gst::parse_launch( r#" - audiotestsrc is-live=true ! audioconvert ! avenc_aac bitrate=128000 ! queue ! mux. + urisourcebin uri=https://plutolive-msl.akamaized.net/hls/live/2008623/defy/master.m3u8 ! tsdemux name=demux ! queue ! h264parse ! tee name=v - videotestsrc is-live=true ! video/x-raw,framerate=30/1,width=1280,height=720 ! timeoverlay ! x264enc tune=zerolatency name=encoder - - encoder. ! video/x-h264,profile=main ! queue ! mpegtsmux name=mux scte-35-pid=500 scte-35-null-interval=450000 - - mux. ! filesink sync=true location=out.ts + v. ! queue ! mpegtsmux name=mux scte-35-pid=500 scte-35-null-interval=450000 ! filesink sync=true location=video.ts + v. ! queue ! decodebin ! videoconvert ! imgcmp name=imgcmp location=/Users/rafaelcaricio/Downloads/defy-AD-SLATE-APRIL3022.jpeg ! autovideosink + demux. ! queue ! aacparse ! mux. "#, )? .downcast::() @@ -80,46 +79,6 @@ fn main() -> eyre::Result<()> { info!("Starting pipeline..."); - let event_counter = EventId::new(); - - // Every 60 seconds we will loop on an ad scheduling process.. - glib::timeout_add(Duration::from_secs(60), { - let pipeline_weak = pipeline.downgrade(); - let event_counter = event_counter.clone(); - move || { - if let Some(pipeline) = pipeline_weak.upgrade() { - let muxer = pipeline.by_name("mux").unwrap(); - - // We need to notify a specific time in the stream where the SCTE-35 marker - // is, so we use the pipeline running time to base our timing calculations - let now = pipeline.current_running_time().unwrap(); - - // How much ahead should the ad be inserted, we say 0 seconds in the future (immediate) - let ahead = gst::ClockTime::from_seconds(0); - - // Trigger the Splice Out event in the SCTE-35 stream - send_splice_out(&muxer, event_counter.next(), now + ahead); - - // Now we add a timed call for the duration of the ad from now to indicate via - // splice in that the stream can go back to normal programming. - glib::timeout_add(Duration::from_secs(30), { - let muxer_weak = muxer.downgrade(); - let event_counter = event_counter.clone(); - move || { - if let Some(muxer) = muxer_weak.upgrade() { - let now = muxer.current_running_time().unwrap(); - send_splice_in(&muxer, event_counter.next(), now + ahead); - } - // This shall not run again - glib::Continue(false) - } - }); - } - // Run this again after the timeout... - glib::Continue(true) - } - }); - let context = glib::MainContext::default(); let main_loop = glib::MainLoop::new(Some(&context), false); @@ -127,8 +86,12 @@ fn main() -> eyre::Result<()> { let bus = pipeline.bus().unwrap(); bus.add_watch({ + let event_counter = EventId::new(); + let ad_running = Arc::new(AtomicBool::new(false)); let main_loop = main_loop.clone(); let pipeline_weak = pipeline.downgrade(); + let imgcmp_weak = pipeline.by_name("imgcmp").unwrap().downgrade(); + let muxer_weak = pipeline.by_name("mux").unwrap().downgrade(); move |_, msg| { use gst::MessageView; @@ -149,14 +112,57 @@ fn main() -> eyre::Result<()> { if s.src().map(|e| e == pipeline).unwrap_or(false) { debug!("Writing dot file for status: {:?}", s.current()); - let mut file = File::create(format!("Pipeline-{:?}.dot", s.current())).unwrap(); - let dot_data = pipeline.debug_to_dot_data( - gst::DebugGraphDetails::all(), - ); + let mut file = + File::create(format!("Pipeline-{:?}.dot", s.current())).unwrap(); + let dot_data = + pipeline.debug_to_dot_data(gst::DebugGraphDetails::all()); file.write_all(dot_data.as_bytes()).unwrap(); } } } + MessageView::Element(elem_msg) => { + if let (Some(pipeline), Some(imgcmp), Some(muxer)) = ( + pipeline_weak.upgrade(), + imgcmp_weak.upgrade(), + muxer_weak.upgrade(), + ) { + info!("Element Message: {:?}", elem_msg); + if elem_msg.src().map(|e| e == imgcmp).unwrap_or(false) + && elem_msg.message().has_name("image-detected") + && !ad_running.load(Ordering::Relaxed) + { + // We need to notify a specific time in the stream where the SCTE-35 marker + // is, so we use the pipeline running time to base our timing calculations + let now = pipeline.current_running_time().unwrap(); + + // How much ahead should the ad be inserted, we say 0 seconds in the future (immediate) + let ahead = gst::ClockTime::from_seconds(0); + + // Trigger the Splice Out event in the SCTE-35 stream + send_splice_out(&muxer, event_counter.next(), now + ahead); + ad_running.store(true, Ordering::Relaxed); + info!("Ad started.."); + + // Now we add a timed call for the duration of the ad from now to indicate via + // splice in that the stream can go back to normal programming. + glib::timeout_add(Duration::from_secs(30), { + let muxer_weak = muxer.downgrade(); + let event_counter = event_counter.clone(); + let ad_running = Arc::clone(&ad_running); + move || { + if let Some(muxer) = muxer_weak.upgrade() { + let now = muxer.current_running_time().unwrap(); + send_splice_in(&muxer, event_counter.next(), now + ahead); + ad_running.store(false, Ordering::Relaxed); + info!("Ad ended!") + } + // This shall not run again + glib::Continue(false) + } + }); + } + } + } _ => (), }; @@ -175,6 +181,11 @@ fn main() -> eyre::Result<()> { main_loop.run(); bus.remove_watch().unwrap(); + debug!("Writing Final dot file"); + let mut file = File::create("Pipeline-Final.dot").unwrap(); + let dot_data = pipeline.debug_to_dot_data(gst::DebugGraphDetails::all()); + file.write_all(dot_data.as_bytes()).unwrap(); + pipeline.set_state(gst::State::Null)?; Ok(())