mirror of
https://github.com/icewind1991/purpledot.git
synced 2026-06-03 17:44:11 +02:00
experiments
This commit is contained in:
parent
c7506b61d8
commit
be1d68bb48
5 changed files with 1235 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
/target
|
||||
data
|
||||
|
|
|
|||
727
Cargo.lock
generated
Normal file
727
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.58.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9966d2ab714d0f785dbac0a0396251a35280aeb42413281617d0209ab4898435"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[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.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[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.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ffimage"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81151bca3c183c68a129fdee7b89b22e1d6e37c607bcba7b1308e525f4989c21"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"num",
|
||||
"num-traits",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ffimage_yuv"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e74255e35266c3ede4909fd078b939f869cf87b2fdba8f3bf878fcd2d1a10eda"
|
||||
dependencies = [
|
||||
"ffimage",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[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 = "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 = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
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 = "nom"
|
||||
version = "5.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational 0.4.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[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 = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "purpledot"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ffimage",
|
||||
"ffimage_yuv",
|
||||
"image",
|
||||
"rusty_ffmpeg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rusty_ffmpeg"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d8947836839aa2f04df1aeb16e64b7207e904f261baf02284722f795457545d"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[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 = "shlex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "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 = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
@ -3,6 +3,8 @@ name = "purpledot"
|
|||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rusty_ffmpeg = "0.7"
|
||||
image = "0.23"
|
||||
ffimage = "0.9.0"
|
||||
ffimage_yuv = "0.9.0"
|
||||
253
src/framestream.rs
Normal file
253
src/framestream.rs
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
//! Port from Original code: https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/0_hello_world.c
|
||||
|
||||
use rusty_ffmpeg::ffi;
|
||||
use rusty_ffmpeg::ffi::{
|
||||
AVCodec, AVCodecContext, AVFormatContext, AVFrame, AVPacket, AVPixelFormat_AV_PIX_FMT_RGB24,
|
||||
AVPixelFormat_AV_PIX_FMT_YUV420P,
|
||||
};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
fs::File,
|
||||
io::Write,
|
||||
ptr, slice,
|
||||
};
|
||||
|
||||
pub struct RawFrameIter {
|
||||
frame_context: OwnedAvFormatContext,
|
||||
packet: OwnedAvPacket,
|
||||
frame: OwnedAvFrame,
|
||||
codec_context: OwnedAvCodecContext,
|
||||
}
|
||||
|
||||
impl RawFrameIter {
|
||||
pub fn new(filepath: CString) -> Self {
|
||||
println!("initializing all the containers, codecs and protocols.");
|
||||
|
||||
let mut format_context = OwnedAvFormatContext::new();
|
||||
|
||||
println!(
|
||||
"opening the input file ({}) and loading format (container) header",
|
||||
filepath.to_str().unwrap()
|
||||
);
|
||||
|
||||
if unsafe {
|
||||
ffi::avformat_open_input(
|
||||
&mut (format_context.deref_mut() as *mut _) as *mut *mut _,
|
||||
filepath.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
} != 0
|
||||
{
|
||||
panic!("ERROR could not open the file");
|
||||
}
|
||||
|
||||
let format_name = unsafe { CStr::from_ptr((*format_context.iformat).name) }
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
println!(
|
||||
"format {}, duration {} us, bit_rate {}",
|
||||
format_name, format_context.duration, format_context.bit_rate
|
||||
);
|
||||
|
||||
println!("finding stream info from format");
|
||||
|
||||
if unsafe { ffi::avformat_find_stream_info(format_context.deref_mut(), ptr::null_mut()) }
|
||||
< 0
|
||||
{
|
||||
panic!("ERROR could not get the stream info");
|
||||
}
|
||||
|
||||
let mut codec_ptr: *const ffi::AVCodec = ptr::null_mut();
|
||||
let mut codec_parameters_ptr: *const ffi::AVCodecParameters = ptr::null_mut();
|
||||
let mut video_stream_index = None;
|
||||
let mut resolution = None;
|
||||
|
||||
let streams = unsafe {
|
||||
slice::from_raw_parts(format_context.streams, format_context.nb_streams as usize)
|
||||
};
|
||||
|
||||
for (i, stream) in streams
|
||||
.iter()
|
||||
.map(|stream| unsafe { stream.as_ref() }.unwrap())
|
||||
.enumerate()
|
||||
{
|
||||
println!(
|
||||
"AVStream->time_base before open coded {}/{}",
|
||||
stream.time_base.num, stream.time_base.den
|
||||
);
|
||||
println!(
|
||||
"AVStream->r_frame_rate before open coded {}/{}",
|
||||
stream.r_frame_rate.num, stream.r_frame_rate.den
|
||||
);
|
||||
println!("AVStream->start_time {}", stream.start_time);
|
||||
println!("AVStream->duration {}", stream.duration);
|
||||
println!("finding the proper decoder (CODEC)");
|
||||
|
||||
let local_codec_params = unsafe { stream.codecpar.as_ref() }.unwrap();
|
||||
let local_codec =
|
||||
unsafe { ffi::avcodec_find_decoder(local_codec_params.codec_id).as_ref() }
|
||||
.expect("ERROR unsupported codec!");
|
||||
|
||||
match local_codec_params.codec_type {
|
||||
ffi::AVMediaType_AVMEDIA_TYPE_VIDEO => {
|
||||
if video_stream_index.is_none() {
|
||||
video_stream_index = Some(i);
|
||||
codec_ptr = local_codec;
|
||||
codec_parameters_ptr = local_codec_params;
|
||||
}
|
||||
|
||||
println!(
|
||||
"Video Codec: resolution {} x {}",
|
||||
local_codec_params.width, local_codec_params.height
|
||||
);
|
||||
resolution = Some((local_codec_params.width, local_codec_params.height));
|
||||
}
|
||||
ffi::AVMediaType_AVMEDIA_TYPE_AUDIO => {
|
||||
println!(
|
||||
"Audio Codec: {} channels, sample rate {}",
|
||||
local_codec_params.channels, local_codec_params.sample_rate
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let codec_name = unsafe { CStr::from_ptr(local_codec.name) }
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
println!(
|
||||
"\tCodec {} ID {} bit_rate {}",
|
||||
codec_name, local_codec.id, local_codec_params.bit_rate
|
||||
);
|
||||
}
|
||||
let (width, height) = resolution.expect("No resolution found");
|
||||
|
||||
let mut codec_context = OwnedAvCodecContext::new(codec_ptr);
|
||||
|
||||
if unsafe {
|
||||
ffi::avcodec_parameters_to_context(codec_context.deref_mut(), codec_parameters_ptr)
|
||||
} < 0
|
||||
{
|
||||
panic!("failed to copy codec params to codec context");
|
||||
}
|
||||
|
||||
if unsafe { ffi::avcodec_open2(codec_context.deref_mut(), codec_ptr, ptr::null_mut()) } < 0
|
||||
{
|
||||
panic!("failed to open codec through avcodec_open2");
|
||||
}
|
||||
|
||||
let frame = OwnedAvFrame::new();
|
||||
let packet = OwnedAvPacket::new();
|
||||
|
||||
let mut packets_waiting = 8;
|
||||
|
||||
RawFrameIter {
|
||||
frame_context: format_context,
|
||||
packet,
|
||||
frame,
|
||||
codec_context,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RawFrameIter {
|
||||
fn next(&mut self) -> Option<&OwnedAvFrame> {
|
||||
if unsafe { ffi::av_read_frame(format_context, packet) } >= 0 {
|
||||
if video_stream_index == Some(packet.stream_index as usize) {
|
||||
println!("AVPacket->pts {}", packet.pts);
|
||||
decode_packet(packet, codec_context, frame).unwrap();
|
||||
packets_waiting -= 1;
|
||||
if packets_waiting <= 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsafe { ffi::av_packet_unref(packet) };
|
||||
Some(&self.frame)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! owned_ptr {
|
||||
($name:ident, $ptr:path) => {
|
||||
struct $name {
|
||||
ptr: NonNull<$ptr>,
|
||||
}
|
||||
|
||||
impl Deref for $name {
|
||||
type Target = $ptr;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { self.ptr.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for $name {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { self.ptr.as_mut() }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($name:ident, $ptr:path, $alloc:path, $free:path) => {
|
||||
owned_ptr!($name, $ptr);
|
||||
|
||||
impl $name {
|
||||
pub fn new() -> Self {
|
||||
let ptr = NonNull::new(unsafe { $alloc() })
|
||||
.expect("failed to allocated memory for $name");
|
||||
$name { ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for $name {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
$free(&mut (self.ptr.as_ptr()));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
owned_ptr!(
|
||||
OwnedAvFrame,
|
||||
AVFrame,
|
||||
ffi::av_frame_alloc,
|
||||
ffi::av_frame_free
|
||||
);
|
||||
owned_ptr!(
|
||||
OwnedAvPacket,
|
||||
AVPacket,
|
||||
ffi::av_packet_alloc,
|
||||
ffi::av_packet_free
|
||||
);
|
||||
owned_ptr!(
|
||||
OwnedAvFormatContext,
|
||||
AVFormatContext,
|
||||
ffi::avformat_alloc_context,
|
||||
ffi::avformat_close_input
|
||||
);
|
||||
|
||||
owned_ptr!(OwnedAvCodecContext, AVCodecContext);
|
||||
impl OwnedAvCodecContext {
|
||||
pub fn new(codec: *const ffi::AVCodec) -> Self {
|
||||
let ptr = NonNull::new(unsafe { ffi::avcodec_alloc_context3(codec) })
|
||||
.expect("failed to allocated memory for $name");
|
||||
OwnedAvCodecContext { ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OwnedAvCodecContext {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::avcodec_free_context(&mut (self.ptr.as_ptr()));
|
||||
}
|
||||
}
|
||||
}
|
||||
251
src/main.rs
251
src/main.rs
|
|
@ -1,3 +1,252 @@
|
|||
//! Port from Original code: https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/0_hello_world.c
|
||||
mod framestream;
|
||||
|
||||
use rusty_ffmpeg::ffi;
|
||||
|
||||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
fs::File,
|
||||
io::Write,
|
||||
ptr, slice,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let filepath: CString = CString::new("./data/track3.mp4").unwrap();
|
||||
|
||||
println!("initializing all the containers, codecs and protocols.");
|
||||
|
||||
let mut format_context_ptr = unsafe { ffi::avformat_alloc_context() };
|
||||
if format_context_ptr.is_null() {
|
||||
panic!("ERROR could not allocate memory for Format Context");
|
||||
}
|
||||
|
||||
println!(
|
||||
"opening the input file ({}) and loading format (container) header",
|
||||
filepath.to_str().unwrap()
|
||||
);
|
||||
|
||||
if unsafe {
|
||||
ffi::avformat_open_input(
|
||||
&mut format_context_ptr,
|
||||
filepath.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
} != 0
|
||||
{
|
||||
panic!("ERROR could not open the file");
|
||||
}
|
||||
|
||||
let format_context = unsafe { format_context_ptr.as_mut() }.unwrap();
|
||||
|
||||
let format_name = unsafe { CStr::from_ptr((*format_context.iformat).name) }
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
println!(
|
||||
"format {}, duration {} us, bit_rate {}",
|
||||
format_name, format_context.duration, format_context.bit_rate
|
||||
);
|
||||
|
||||
println!("finding stream info from format");
|
||||
|
||||
if unsafe { ffi::avformat_find_stream_info(format_context, ptr::null_mut()) } < 0 {
|
||||
panic!("ERROR could not get the stream info");
|
||||
}
|
||||
|
||||
let mut codec_ptr: *const ffi::AVCodec = ptr::null_mut();
|
||||
let mut codec_parameters_ptr: *const ffi::AVCodecParameters = ptr::null_mut();
|
||||
let mut video_stream_index = None;
|
||||
let mut resolution = None;
|
||||
|
||||
let streams = unsafe {
|
||||
slice::from_raw_parts(format_context.streams, format_context.nb_streams as usize)
|
||||
};
|
||||
|
||||
for (i, stream) in streams
|
||||
.iter()
|
||||
.map(|stream| unsafe { stream.as_ref() }.unwrap())
|
||||
.enumerate()
|
||||
{
|
||||
println!(
|
||||
"AVStream->time_base before open coded {}/{}",
|
||||
stream.time_base.num, stream.time_base.den
|
||||
);
|
||||
println!(
|
||||
"AVStream->r_frame_rate before open coded {}/{}",
|
||||
stream.r_frame_rate.num, stream.r_frame_rate.den
|
||||
);
|
||||
println!("AVStream->start_time {}", stream.start_time);
|
||||
println!("AVStream->duration {}", stream.duration);
|
||||
println!("finding the proper decoder (CODEC)");
|
||||
|
||||
let local_codec_params = unsafe { stream.codecpar.as_ref() }.unwrap();
|
||||
let local_codec =
|
||||
unsafe { ffi::avcodec_find_decoder(local_codec_params.codec_id).as_ref() }
|
||||
.expect("ERROR unsupported codec!");
|
||||
|
||||
match local_codec_params.codec_type {
|
||||
ffi::AVMediaType_AVMEDIA_TYPE_VIDEO => {
|
||||
if video_stream_index.is_none() {
|
||||
video_stream_index = Some(i);
|
||||
codec_ptr = local_codec;
|
||||
codec_parameters_ptr = local_codec_params;
|
||||
}
|
||||
|
||||
println!(
|
||||
"Video Codec: resolution {} x {}",
|
||||
local_codec_params.width, local_codec_params.height
|
||||
);
|
||||
resolution = Some((local_codec_params.width, local_codec_params.height));
|
||||
}
|
||||
ffi::AVMediaType_AVMEDIA_TYPE_AUDIO => {
|
||||
println!(
|
||||
"Audio Codec: {} channels, sample rate {}",
|
||||
local_codec_params.channels, local_codec_params.sample_rate
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let codec_name = unsafe { CStr::from_ptr(local_codec.name) }
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
println!(
|
||||
"\tCodec {} ID {} bit_rate {}",
|
||||
codec_name, local_codec.id, local_codec_params.bit_rate
|
||||
);
|
||||
}
|
||||
let (width, height) = resolution.expect("No resolution found");
|
||||
|
||||
let codec_context = unsafe { ffi::avcodec_alloc_context3(codec_ptr).as_mut() }
|
||||
.expect("failed to allocated memory for AVCodecContext");
|
||||
|
||||
if unsafe { ffi::avcodec_parameters_to_context(codec_context, codec_parameters_ptr) } < 0 {
|
||||
panic!("failed to copy codec params to codec context");
|
||||
}
|
||||
|
||||
if unsafe { ffi::avcodec_open2(codec_context, codec_ptr, ptr::null_mut()) } < 0 {
|
||||
panic!("failed to open codec through avcodec_open2");
|
||||
}
|
||||
|
||||
let frame =
|
||||
unsafe { ffi::av_frame_alloc().as_mut() }.expect("failed to allocated memory for AVFrame");
|
||||
let packet = unsafe { ffi::av_packet_alloc().as_mut() }
|
||||
.expect("failed to allocated memory for AVPacket");
|
||||
|
||||
let byte_size =
|
||||
unsafe { ffi::avpicture_get_size(AVPixelFormat_AV_PIX_FMT_RGB24, width, height) };
|
||||
let rgb_buffer = vec![0; byte_size as usize];
|
||||
let rgb_frame =
|
||||
unsafe { ffi::av_frame_alloc().as_mut() }.expect("failed to allocated memory for AVFrame");
|
||||
unsafe {
|
||||
ffi::avpicture_fill(
|
||||
rgb_frame as *mut _ as *mut _,
|
||||
rgb_buffer.as_ptr(),
|
||||
AVPixelFormat_AV_PIX_FMT_RGB24,
|
||||
width,
|
||||
height,
|
||||
);
|
||||
}
|
||||
|
||||
let mut packets_waiting = 8;
|
||||
|
||||
while unsafe { ffi::av_read_frame(format_context, packet) } >= 0 {
|
||||
if video_stream_index == Some(packet.stream_index as usize) {
|
||||
println!("AVPacket->pts {}", packet.pts);
|
||||
decode_packet(packet, codec_context, frame).unwrap();
|
||||
packets_waiting -= 1;
|
||||
if packets_waiting <= 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsafe { ffi::av_packet_unref(packet) };
|
||||
}
|
||||
|
||||
println!("releasing all the resources");
|
||||
|
||||
unsafe {
|
||||
ffi::avformat_close_input(&mut (format_context as *mut _));
|
||||
ffi::av_packet_free(&mut (packet as *mut _));
|
||||
ffi::av_frame_free(&mut (frame as *mut _));
|
||||
ffi::avcodec_free_context(&mut (codec_context as *mut _));
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_packet(
|
||||
packet: &ffi::AVPacket,
|
||||
codec_context: &mut ffi::AVCodecContext,
|
||||
frame: &mut ffi::AVFrame,
|
||||
) -> Result<(), String> {
|
||||
let mut response = unsafe { ffi::avcodec_send_packet(codec_context, packet) };
|
||||
|
||||
if response < 0 {
|
||||
return Err(String::from("Error while sending a packet to the decoder."));
|
||||
}
|
||||
|
||||
while response >= 0 {
|
||||
response = unsafe { ffi::avcodec_receive_frame(codec_context, frame) };
|
||||
if response == ffi::AVERROR(ffi::EAGAIN) || response == ffi::AVERROR_EOF {
|
||||
break;
|
||||
} else if response < 0 {
|
||||
return Err(String::from(
|
||||
"Error while receiving a frame from the decoder.",
|
||||
));
|
||||
} else {
|
||||
println!(
|
||||
"Frame {} (type={}, size={} bytes) pts {} key_frame {} [DTS {}]",
|
||||
codec_context.frame_number,
|
||||
unsafe { ffi::av_get_picture_type_char(frame.pict_type) },
|
||||
frame.pkt_size,
|
||||
frame.pts,
|
||||
frame.key_frame,
|
||||
frame.coded_picture_number
|
||||
);
|
||||
|
||||
let frame_filename = format!("./data/output/frame-{}.pgm", codec_context.frame_number);
|
||||
let width = frame.width as usize;
|
||||
let height = frame.height as usize;
|
||||
let wrap = frame.linesize[0] as usize;
|
||||
let data = unsafe { slice::from_raw_parts(frame.data[0], wrap * height) };
|
||||
|
||||
if frame.format != AVPixelFormat_AV_PIX_FMT_YUV420P {
|
||||
panic!("Input has to be yuv420p, got :{}", frame.format);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// ffi::sws_scale(codec_context, frame.data,
|
||||
// wrap, 0, height, pFrameRGB->data,
|
||||
// pFrameRGB->linesize);
|
||||
}
|
||||
|
||||
dbg!(wrap, width, height);
|
||||
|
||||
save_gray_frame(data, wrap, width, height, frame_filename).unwrap();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
use ffimage::packed::{ImageBuffer, ImageView};
|
||||
use ffimage::traits::Convert;
|
||||
use ffimage_yuv::yuv;
|
||||
use ffimage_yuv::yuv::Yuv;
|
||||
use rusty_ffmpeg::ffi::{AVPixelFormat_AV_PIX_FMT_RGB24, AVPixelFormat_AV_PIX_FMT_YUV420P};
|
||||
|
||||
fn save_gray_frame(
|
||||
buf: &[u8],
|
||||
wrap: usize,
|
||||
xsize: usize,
|
||||
ysize: usize,
|
||||
filename: String,
|
||||
) -> Result<(), std::io::Error> {
|
||||
let mut file = File::create(filename)?;
|
||||
let data = format!("P5\n{} {}\n{}\n", xsize, ysize, 255);
|
||||
file.write_all(data.as_bytes())?;
|
||||
|
||||
for i in 0..ysize {
|
||||
file.write_all(&buf[i * wrap..(i * wrap + xsize)])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue