Decoder validation
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
kieran 2024-08-28 23:23:45 +01:00
parent 8cca7a174c
commit 759492d974
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
10 changed files with 2756 additions and 62 deletions

440
Cargo.lock generated
View File

@ -17,6 +17,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "aes"
version = "0.8.4"
@ -58,6 +64,18 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
[[package]]
name = "arrayref"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a"
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "async-trait"
version = "0.1.77"
@ -85,7 +103,7 @@ dependencies = [
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"miniz_oxide 0.7.2",
"object",
"rustc-demangle",
]
@ -96,6 +114,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bindgen"
version = "0.64.0"
@ -140,12 +164,24 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bytemuck"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "bytes"
version = "1.5.0"
@ -194,6 +230,12 @@ dependencies = [
"libloading",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "config"
version = "0.14.0"
@ -249,6 +291,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core_maths"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3"
dependencies = [
"libm",
]
[[package]]
name = "cpufeatures"
version = "0.2.12"
@ -258,6 +309,15 @@ dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crunchy"
version = "0.2.2"
@ -289,6 +349,12 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]]
name = "data-url"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "derive_more"
version = "0.99.17"
@ -356,6 +422,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fdeflate"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
dependencies = [
"simd-adler32",
]
[[package]]
name = "ffmpeg-sys-next"
version = "6.1.0"
@ -370,12 +445,51 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "flate2"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.0",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fontconfig-parser"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7"
dependencies = [
"roxmltree",
]
[[package]]
name = "fontdb"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37be9fc20d966be438cd57a45767f73349477fb0f85ce86e000557f787298afb"
dependencies = [
"fontconfig-parser",
"log",
"memmap2",
"slotmap",
"tinyvec",
"ttf-parser",
]
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -483,6 +597,16 @@ dependencies = [
"wasi",
]
[[package]]
name = "gif"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "gimli"
version = "0.28.1"
@ -532,7 +656,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
dependencies = [
"base64",
"base64 0.21.7",
"bytes",
"headers-core",
"http",
@ -645,6 +769,22 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "image-webp"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904"
dependencies = [
"byteorder-lite",
"quick-error",
]
[[package]]
name = "imagesize"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285"
[[package]]
name = "indexmap"
version = "2.2.5"
@ -710,6 +850,16 @@ dependencies = [
"indexmap",
]
[[package]]
name = "kurbo"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c"
dependencies = [
"arrayvec",
"smallvec",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -738,6 +888,12 @@ dependencies = [
"windows-targets 0.52.4",
]
[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "linked-hash-map"
version = "0.5.6"
@ -746,9 +902,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "log"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memchr"
@ -756,6 +912,15 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memmap2"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
dependencies = [
"libc",
]
[[package]]
name = "mime"
version = "0.3.17"
@ -785,6 +950,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
"simd-adler32",
]
[[package]]
name = "miniz_oxide"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
]
[[package]]
@ -942,6 +1117,12 @@ dependencies = [
"sha2",
]
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project"
version = "1.1.5"
@ -980,6 +1161,19 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "png"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide 0.7.2",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1011,6 +1205,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quick-error"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quote"
version = "1.0.35"
@ -1079,18 +1279,50 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "resvg"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7314563c59c7ce31c18e23ad3dd092c37b928a0fa4e1c0a1a6504351ab411d1"
dependencies = [
"gif",
"image-webp",
"log",
"pico-args",
"rgb",
"svgtypes",
"tiny-skia",
"usvg",
"zune-jpeg",
]
[[package]]
name = "rgb"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f86ae463694029097b846d8f99fd5536740602ae00022c0c50c5600720b2f71"
dependencies = [
"bytemuck",
]
[[package]]
name = "ron"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64",
"base64 0.21.7",
"bitflags 2.4.2",
"serde",
"serde_derive",
]
[[package]]
name = "roxmltree"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
[[package]]
name = "rust-ini"
version = "0.19.0"
@ -1128,7 +1360,25 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
"base64 0.21.7",
]
[[package]]
name = "rustybuzz"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181"
dependencies = [
"bitflags 2.4.2",
"bytemuck",
"core_maths",
"log",
"smallvec",
"ttf-parser",
"unicode-bidi-mirroring",
"unicode-ccc",
"unicode-properties",
"unicode-script",
]
[[package]]
@ -1240,6 +1490,27 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "simplecss"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d"
dependencies = [
"log",
]
[[package]]
name = "siphasher"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "slab"
version = "0.4.9"
@ -1249,6 +1520,21 @@ dependencies = [
"autocfg",
]
[[package]]
name = "slotmap"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
dependencies = [
"version_check",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.6"
@ -1324,11 +1610,15 @@ dependencies = [
"log",
"pretty-hex",
"pretty_env_logger",
"rand",
"resvg",
"serde",
"srt-tokio",
"tiny-skia",
"tokio",
"tokio-stream",
"url",
"usvg",
"uuid",
"warp",
]
@ -1342,12 +1632,31 @@ dependencies = [
"num-traits",
]
[[package]]
name = "strict-num"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
dependencies = [
"float-cmp",
]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "svgtypes"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "794de53cc48eaabeed0ab6a3404a65f40b3e38c067e4435883a65d2aa4ca000e"
dependencies = [
"kurbo",
"siphasher",
]
[[package]]
name = "syn"
version = "1.0.109"
@ -1414,6 +1723,32 @@ dependencies = [
"crunchy",
]
[[package]]
name = "tiny-skia"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"log",
"png",
"tiny-skia-path",
]
[[package]]
name = "tiny-skia-path"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
dependencies = [
"arrayref",
"bytemuck",
"strict-num",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1561,6 +1896,15 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "ttf-parser"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a"
dependencies = [
"core_maths",
]
[[package]]
name = "tungstenite"
version = "0.20.1"
@ -1607,6 +1951,18 @@ version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-bidi-mirroring"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64af057ad7466495ca113126be61838d8af947f41d93a949980b2389a118082f"
[[package]]
name = "unicode-ccc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42"
[[package]]
name = "unicode-ident"
version = "1.0.12"
@ -1622,12 +1978,30 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-properties"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
[[package]]
name = "unicode-script"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-vo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
[[package]]
name = "url"
version = "2.5.0"
@ -1639,6 +2013,33 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "usvg"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6803057b5cbb426e9fb8ce2216f3a9b4ca1dd2c705ba3cbebc13006e437735fd"
dependencies = [
"base64 0.22.1",
"data-url",
"flate2",
"fontdb",
"imagesize",
"kurbo",
"log",
"pico-args",
"roxmltree",
"rustybuzz",
"simplecss",
"siphasher",
"strict-num",
"svgtypes",
"tiny-skia-path",
"unicode-bidi",
"unicode-script",
"unicode-vo",
"xmlwriter",
]
[[package]]
name = "utf-8"
version = "0.7.6"
@ -1713,6 +2114,12 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "weezl"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "winapi"
version = "0.3.9"
@ -1885,6 +2292,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "xmlwriter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]]
name = "yaml-rust"
version = "0.4.5"
@ -1893,3 +2306,18 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zune-core"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-jpeg"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
dependencies = [
"zune-core",
]

View File

@ -22,3 +22,7 @@ config = { version = "0.14.0", features = ["toml"] }
url = "2.5.0"
itertools = "0.12.1"
warp = "0.3.6"
rand = "0.8.5"
resvg = "0.43.0"
usvg = "0.43.0"
tiny-skia = "0.11.4"

View File

@ -1,11 +1,16 @@
use std::io::Read;
use std::ptr;
use std::sync::Arc;
use std::time::Duration;
use anyhow::Error;
use bytes::Bytes;
use ffmpeg_sys_next::*;
use bytes::{BufMut, Bytes};
use ffmpeg_sys_next::AVMediaType::{AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_VIDEO};
use ffmpeg_sys_next::*;
use log::{info, warn};
use tokio::sync::mpsc::error::TryRecvError;
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
use tokio::sync::Mutex;
use tokio::time::Instant;
use crate::demux::info::{DemuxStreamInfo, StreamChannelType, StreamInfoChannel};
@ -25,34 +30,53 @@ pub mod info;
///
pub(crate) struct Demuxer {
ctx: *mut AVFormatContext,
chan_in: UnboundedReceiver<Bytes>,
chan_out: UnboundedSender<PipelinePayload>,
started: Instant,
state: DemuxerBuffer,
}
unsafe impl Send for Demuxer {}
unsafe impl Sync for Demuxer {}
struct DemuxerBuffer {
pub chan_in: UnboundedReceiver<Bytes>,
pub buffer: bytes::BytesMut,
}
unsafe extern "C" fn read_data(
opaque: *mut libc::c_void,
buffer: *mut libc::c_uchar,
size: libc::c_int,
) -> libc::c_int {
let chan = opaque as *mut UnboundedReceiver<Bytes>;
if let Some(data) = (*chan).blocking_recv() {
let buff_len = data.len();
assert!(size as usize >= buff_len);
if buff_len > 0 {
memcpy(
buffer as *mut libc::c_void,
data.as_ptr() as *const libc::c_void,
buff_len as libc::c_ulonglong,
);
let state = opaque as *mut DemuxerBuffer;
loop {
match (*state).chan_in.try_recv() {
Ok(data) => {
if data.len() > 0 {
(*state).buffer.put(data);
}
if (*state).buffer.len() >= size as usize {
let buf_take = (*state).buffer.split_to(size as usize);
memcpy(
buffer as *mut libc::c_void,
buf_take.as_ptr() as *const libc::c_void,
buf_take.len() as libc::c_ulonglong,
);
return size;
} else {
continue;
}
}
Err(e) => match e {
TryRecvError::Empty => {
}
TryRecvError::Disconnected => {
warn!("EOF");
return AVERROR_EOF;
}
},
}
buff_len as libc::c_int
} else {
AVERROR_EOF
}
}
@ -67,18 +91,22 @@ impl Demuxer {
Self {
ctx: ps,
chan_in,
chan_out,
state: DemuxerBuffer {
chan_in,
buffer: bytes::BytesMut::new(),
},
started: Instant::now(),
}
}
}
unsafe fn probe_input(&mut self) -> Result<DemuxStreamInfo, Error> {
let buf_ptr = ptr::from_mut(&mut self.chan_in) as *mut libc::c_void;
const BUFFER_SIZE: usize = 4096;
let buf_ptr = ptr::from_mut(&mut self.state) as *mut libc::c_void;
let pb = avio_alloc_context(
av_mallocz(4096) as *mut libc::c_uchar,
4096,
av_mallocz(BUFFER_SIZE) as *mut libc::c_uchar,
BUFFER_SIZE as libc::c_int,
0,
buf_ptr,
Some(read_data),

View File

@ -3,7 +3,11 @@ use std::collections::HashSet;
use std::fmt::Display;
use anyhow::Error;
use ffmpeg_sys_next::{av_dump_format, av_guess_format, av_interleaved_write_frame, av_strdup, avformat_alloc_context, avformat_alloc_output_context2, avformat_free_context, avformat_write_header, AVFormatContext, AVIO_FLAG_READ_WRITE, avio_flush, avio_open2, AVPacket};
use ffmpeg_sys_next::{
av_dump_format, av_guess_format, av_interleaved_write_frame, av_strdup, avformat_alloc_context
, avformat_free_context,
AVFormatContext, AVIO_FLAG_READ_WRITE, avio_open2, AVPacket,
};
use tokio::sync::mpsc::UnboundedReceiver;
use uuid::Uuid;
@ -54,11 +58,11 @@ impl RecorderEgress {
}
let base = format!("{}/{}", self.config.out_dir, self.id);
let out_file = format!("{}/recording.mkv\0", base).as_ptr() as *const libc::c_char;
let out_file = format!("{}/recording.mkv\0", base);
fs::create_dir_all(base.clone())?;
let ret = avio_open2(
&mut (*ctx).pb,
out_file,
out_file.as_ptr() as *const libc::c_char,
AVIO_FLAG_READ_WRITE,
ptr::null(),
ptr::null_mut(),
@ -68,16 +72,16 @@ impl RecorderEgress {
}
(*ctx).oformat = av_guess_format(
"matroska\0".as_ptr() as *const libc::c_char,
out_file,
out_file.as_ptr() as *const libc::c_char,
ptr::null(),
);
if (*ctx).oformat.is_null() {
return Err(Error::msg("Output format not found"));
}
(*ctx).url = av_strdup(out_file);
(*ctx).url = av_strdup(out_file.as_ptr() as *const libc::c_char);
map_variants_to_streams(ctx, &mut self.config.variants)?;
let ret = avformat_write_header(ctx, ptr::null_mut());
//let ret = avformat_write_header(ctx, ptr::null_mut());
if ret < 0 {
return Err(Error::msg(get_ffmpeg_error_msg(ret)));
}

70
src/ingress/file.rs Normal file
View File

@ -0,0 +1,70 @@
use std::{ptr, slice};
use std::mem::transmute;
use std::ops::Add;
use std::path::PathBuf;
use std::time::{Duration, SystemTime};
use bytes::BufMut;
use ffmpeg_sys_next::{
av_frame_alloc, av_frame_copy_props, av_frame_free, av_frame_get_buffer, av_packet_alloc,
av_packet_free, AV_PROFILE_AV1_HIGH, AV_PROFILE_H264_HIGH, av_q2d, av_write_frame,
avcodec_alloc_context3, avcodec_find_encoder, avcodec_get_name, avcodec_open2,
avcodec_receive_packet, avcodec_send_frame, AVERROR, avformat_alloc_context,
avformat_alloc_output_context2, AVRational, EAGAIN, sws_alloc_context, SWS_BILINEAR, sws_getContext,
sws_scale_frame,
};
use ffmpeg_sys_next::AVCodecID::{
AV_CODEC_ID_H264, AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, AV_CODEC_ID_MPEG4,
AV_CODEC_ID_VP8, AV_CODEC_ID_WMV1,
};
use ffmpeg_sys_next::AVColorSpace::AVCOL_SPC_RGB;
use ffmpeg_sys_next::AVPictureType::{AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_NONE};
use ffmpeg_sys_next::AVPixelFormat::{AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV420P};
use futures_util::StreamExt;
use libc::memcpy;
use log::{error, info, warn};
use rand::random;
use tokio::io::AsyncReadExt;
use tokio::sync::mpsc::unbounded_channel;
use crate::ingress::ConnectionInfo;
use crate::pipeline::builder::PipelineBuilder;
pub async fn listen(path: PathBuf, builder: PipelineBuilder) -> Result<(), anyhow::Error> {
info!("Sending file {}", path.to_str().unwrap());
tokio::spawn(async move {
let (tx, rx) = unbounded_channel();
let info = ConnectionInfo {
ip_addr: "".to_owned(),
endpoint: "file-input".to_owned(),
};
if let Ok(mut pl) = builder.build_for(info, rx).await {
std::thread::spawn(move || loop {
if let Err(e) = pl.run() {
warn!("Pipeline error: {}", e.backtrace());
break;
}
});
if let Ok(mut stream) = tokio::fs::File::open(path).await {
let mut buf = [0u8; 1500];
loop {
if let Ok(r) = stream.read(&mut buf).await {
if r > 0 {
tx.send(bytes::Bytes::copy_from_slice(&buf[..r])).unwrap();
} else {
break;
}
} else {
break;
}
}
info!("EOF");
}
}
});
Ok(())
}

View File

@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
pub mod srt;
pub mod tcp;
pub mod test;
pub mod file;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConnectionInfo {

158
src/ingress/test.rs Normal file
View File

@ -0,0 +1,158 @@
use std::{ptr, slice};
use std::mem::transmute;
use std::ops::Add;
use std::time::{Duration, SystemTime};
use bytes::BufMut;
use ffmpeg_sys_next::{
av_frame_alloc, av_frame_copy_props, av_frame_free, av_frame_get_buffer, av_packet_alloc,
av_packet_free, AV_PROFILE_AV1_HIGH, AV_PROFILE_H264_HIGH, AV_PROFILE_H264_MAIN, av_q2d,
av_write_frame, avcodec_alloc_context3, avcodec_find_encoder, avcodec_get_name,
avcodec_open2, avcodec_receive_packet, avcodec_send_frame, AVERROR,
avformat_alloc_context, avformat_alloc_output_context2, AVRational, EAGAIN, sws_alloc_context,
SWS_BILINEAR, sws_getContext, sws_scale_frame,
};
use ffmpeg_sys_next::AVCodecID::{
AV_CODEC_ID_H264, AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, AV_CODEC_ID_MPEG4,
AV_CODEC_ID_VP8, AV_CODEC_ID_WMV1,
};
use ffmpeg_sys_next::AVColorSpace::{AVCOL_SPC_BT709, AVCOL_SPC_RGB};
use ffmpeg_sys_next::AVPictureType::{AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_NONE};
use ffmpeg_sys_next::AVPixelFormat::{AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV420P};
use futures_util::StreamExt;
use libc::memcpy;
use log::{error, info, warn};
use rand::random;
use tokio::sync::mpsc::unbounded_channel;
use crate::ingress::ConnectionInfo;
use crate::pipeline::builder::PipelineBuilder;
pub async fn listen(builder: PipelineBuilder) -> Result<(), anyhow::Error> {
info!("Test pattern enabled");
const WIDTH: libc::c_int = 1280;
const HEIGHT: libc::c_int = 720;
const TBN: libc::c_int = 30;
tokio::spawn(async move {
let (tx, rx) = unbounded_channel();
let info = ConnectionInfo {
ip_addr: "".to_owned(),
endpoint: "test-pattern".to_owned(),
};
if let Ok(mut pl) = builder.build_for(info, rx).await {
std::thread::spawn(move || loop {
if let Err(e) = pl.run() {
warn!("Pipeline error: {}", e.backtrace());
break;
}
});
unsafe {
let codec = avcodec_find_encoder(AV_CODEC_ID_H264);
let enc_ctx = avcodec_alloc_context3(codec);
(*enc_ctx).width = WIDTH;
(*enc_ctx).height = HEIGHT;
(*enc_ctx).pix_fmt = AV_PIX_FMT_YUV420P;
(*enc_ctx).colorspace = AVCOL_SPC_BT709;
(*enc_ctx).bit_rate = 1_000_000;
(*enc_ctx).framerate = AVRational { num: 30, den: 1 };
(*enc_ctx).gop_size = 30;
(*enc_ctx).level = 40;
(*enc_ctx).profile = AV_PROFILE_H264_MAIN;
(*enc_ctx).time_base = AVRational { num: 1, den: TBN };
(*enc_ctx).pkt_timebase = (*enc_ctx).time_base;
avcodec_open2(enc_ctx, codec, ptr::null_mut());
let src_frame = av_frame_alloc();
(*src_frame).width = WIDTH;
(*src_frame).height = HEIGHT;
(*src_frame).pict_type = AV_PICTURE_TYPE_NONE;
(*src_frame).key_frame = 1;
(*src_frame).colorspace = AVCOL_SPC_RGB;
(*src_frame).format = AV_PIX_FMT_RGB24 as libc::c_int;
(*src_frame).time_base = (*enc_ctx).time_base;
av_frame_get_buffer(src_frame, 0);
let sws = sws_getContext(
WIDTH as libc::c_int,
HEIGHT as libc::c_int,
transmute((*src_frame).format),
WIDTH as libc::c_int,
HEIGHT as libc::c_int,
(*enc_ctx).pix_fmt,
SWS_BILINEAR,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
);
let svg_data = std::fs::read("./test.svg").unwrap();
let tree = usvg::Tree::from_data(&svg_data, &Default::default()).unwrap();
let mut pixmap = tiny_skia::Pixmap::new(WIDTH as u32, HEIGHT as u32).unwrap();
let render_ts = tiny_skia::Transform::from_scale(0.5, 0.5);
resvg::render(&tree, render_ts, &mut pixmap.as_mut());
for x in 0..WIDTH as u32 {
for y in 0..HEIGHT as u32 {
if let Some(px) = pixmap.pixel(x, y) {
let offset = 3 * x + y * (*src_frame).linesize[0] as u32;
let pixel = (*src_frame).data[0].add(offset as usize);
*pixel.offset(0) = px.red();
*pixel.offset(1) = px.green();
*pixel.offset(2) = px.blue();
}
}
}
let mut frame_number: u64 = 0;
let start = SystemTime::now();
loop {
frame_number += 1;
(*src_frame).pts = (TBN as u64 * frame_number) as i64;
let mut dst_frame = av_frame_alloc();
av_frame_copy_props(dst_frame, src_frame);
sws_scale_frame(sws, dst_frame, src_frame);
// encode
let mut ret = avcodec_send_frame(enc_ctx, dst_frame);
av_frame_free(&mut dst_frame);
while ret > 0 || ret == AVERROR(libc::EAGAIN) {
let mut av_pkt = av_packet_alloc();
ret = avcodec_receive_packet(enc_ctx, av_pkt);
if ret != 0 {
if ret == AVERROR(EAGAIN) {
av_packet_free(&mut av_pkt);
break;
}
error!("Encoder failed: {}", ret);
break;
}
let buf = bytes::Bytes::from(slice::from_raw_parts(
(*av_pkt).data,
(*av_pkt).size as usize,
));
for z in 0..(buf.len() as f32 / 1024.0).ceil() as usize {
if let Err(e) = tx.send(buf.slice(z..(z + 1024).min(buf.len()))) {
error!("Failed to write data {}", e);
break;
}
}
}
let stream_time = Duration::from_secs_f64(
frame_number as libc::c_double * av_q2d((*enc_ctx).time_base),
);
let real_time = SystemTime::now().duration_since(start).unwrap();
let wait_time = stream_time - real_time;
std::thread::sleep(wait_time);
}
}
}
});
Ok(())
}

View File

@ -64,6 +64,11 @@ async fn main() -> anyhow::Result<()> {
"0.0.0.0:8080".to_owned(),
settings.clone(),
)));
listeners.push(tokio::spawn(ingress::file::listen(
"/home/kieran/high_flight.mp4".parse().unwrap(),
builder.clone(),
)));
//listeners.push(tokio::spawn(ingress::test::listen(builder.clone())));
for handle in listeners {
if let Err(e) = handle.await {

View File

@ -41,19 +41,6 @@ impl Webhook {
level: 51,
keyframe_interval: 2,
}));
vars.push(VariantStream::Video(VideoVariant {
id: Uuid::new_v4(),
src_index: video_src.index,
dst_index: 1,
width: 640,
height: 360,
fps: video_src.fps as u16,
bitrate: 1_000_000,
codec: 27,
profile: 100,
level: 51,
keyframe_interval: 2,
}));
}
if let Some(audio_src) = stream_info
@ -71,32 +58,22 @@ impl Webhook {
sample_rate: 48_000,
sample_fmt: "s16".to_owned(),
}));
vars.push(VariantStream::Audio(AudioVariant {
id: Uuid::new_v4(),
src_index: audio_src.index,
dst_index: 1,
bitrate: 220_000,
codec: 86018,
channels: 2,
sample_rate: 48_000,
sample_fmt: "s16".to_owned(),
}));
}
PipelineConfig {
id: Uuid::new_v4(),
recording: vec![],
egress: vec![
EgressType::Recorder(EgressConfig {
name: "Recorder".to_owned(),
out_dir: self.config.output_dir.clone(),
variants: vars.clone(),
}),
/*EgressType::MPEGTS(EgressConfig {
name: "MPEGTS".to_owned(),
/*EgressType::Recorder(EgressConfig {
name: "REC".to_owned(),
out_dir: self.config.output_dir.clone(),
variants: vars.clone(),
}),*/
EgressType::HLS(EgressConfig {
name: "HLS".to_owned(),
out_dir: self.config.output_dir.clone(),
variants: vars.clone(),
}),
],
}
}

2018
test.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 39 KiB