From 635bcede7160962d9240e72cf7e80dee70d48037 Mon Sep 17 00:00:00 2001 From: quietvoid <39477805+quietvoid@users.noreply.github.com> Date: Tue, 3 Oct 2023 22:16:48 -0400 Subject: [PATCH] Improve export subcommand for different data outputs Implements #223 --- Cargo.lock | 404 +++++++----------- Cargo.toml | 19 +- README.md | 20 +- dolby_vision/Cargo.toml | 8 +- .../rpu/extension_metadata/blocks/level5.rs | 2 +- src/commands/export.rs | 75 +++- src/commands/mod.rs | 2 +- src/dovi/exporter.rs | 155 ++++++- tests/rpu/export.rs | 31 +- 9 files changed, 434 insertions(+), 282 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1807704..04440e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" +checksum = "b1061f3ff92c2f65800df1f12fc7b4ff44ee14783104187dd04dfee6f11b0fd2" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -26,39 +26,38 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -74,9 +73,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -84,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "assert_cmd" @@ -132,9 +131,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bitstream-io" @@ -165,9 +164,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", "regex-automata", @@ -176,27 +175,30 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -206,20 +208,19 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.19" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", @@ -230,9 +231,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", @@ -242,9 +243,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "cmake" @@ -362,6 +363,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + [[package]] name = "difflib" version = "0.4.0" @@ -427,11 +434,12 @@ dependencies = [ "bitvec", "bitvec_helpers", "clap", + "clap_lex", "dolby_vision", "hdr10plus", "hevc_parser", "indicatif", - "itertools 0.11.0", + "itertools", "madvr_parse", "plotters", "predicates", @@ -472,9 +480,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", @@ -493,9 +501,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" @@ -508,9 +516,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", @@ -617,9 +625,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" dependencies = [ "aho-corasick", "bstr", @@ -641,9 +649,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "hdr10plus" @@ -663,12 +671,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - [[package]] name = "hevc_parser" version = "0.6.1" @@ -700,9 +702,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.6" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" dependencies = [ "bytemuck", "byteorder", @@ -715,9 +717,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown", @@ -725,9 +727,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", "instant", @@ -745,37 +747,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix 0.38.4", - "windows-sys 0.48.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.11.0" @@ -814,15 +785,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libloading" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", "windows-sys 0.48.0", @@ -830,21 +801,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "madvr_parse" @@ -858,9 +823,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "minimal-lexical" @@ -951,7 +916,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" dependencies = [ - "ttf-parser 0.19.1", + "ttf-parser 0.19.2", ] [[package]] @@ -966,23 +931,13 @@ dependencies = [ [[package]] name = "pathfinder_simd" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" +checksum = "0444332826c70dc47be74a7c6a5fc44e23a7905ad6858d4162b658320455ef93" dependencies = [ "rustc_version", ] -[[package]] -name = "pest" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" -dependencies = [ - "thiserror", - "ucd-trie", -] - [[package]] name = "pkg-config" version = "0.3.27" @@ -1026,9 +981,9 @@ dependencies = [ [[package]] name = "png" -version = "0.17.9" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1039,20 +994,20 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.4.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" [[package]] name = "predicates" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9" +checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0" dependencies = [ "anstyle", "difflib", "float-cmp", - "itertools 0.10.5", + "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -1076,18 +1031,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1129,9 +1084,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", "memchr", @@ -1141,9 +1096,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -1152,52 +1107,38 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "roxmltree" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f595a457b6b8c6cda66a48503e92ee8d19342f905948f29c383200ec9eb1d8" +checksum = "862340e351ce1b271a378ec53f304a5558f7db87f3769dc655a8f6ecbb68b302" dependencies = [ "xmlparser", ] [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.4" +version = "0.38.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -1224,36 +1165,24 @@ dependencies = [ [[package]] name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" -version = "1.0.175" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.175" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", @@ -1262,9 +1191,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "indexmap", "itoa", @@ -1286,9 +1215,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.27" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -1303,24 +1232,24 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.7.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.4", + "rustix", "windows-sys 0.48.0", ] [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -1332,18 +1261,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", @@ -1362,10 +1291,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" dependencies = [ + "deranged", "itoa", "libc", "num_threads", @@ -1376,15 +1306,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -1397,27 +1327,21 @@ checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" [[package]] name = "ttf-parser" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "utf8parse" @@ -1427,9 +1351,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vergen" -version = "8.2.4" +version = "8.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc5ad0d9d26b2c49a5ab7da76c3e79d3ee37e7821799f8223fcb8f2f391a2e7" +checksum = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" dependencies = [ "anyhow", "rustversion", @@ -1447,9 +1371,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -1543,9 +1467,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -1571,7 +1495,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -1591,17 +1515,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1612,9 +1536,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -1624,9 +1548,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -1636,9 +1560,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -1648,9 +1572,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -1660,9 +1584,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -1672,9 +1596,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -1684,9 +1608,9 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "wio" @@ -1708,9 +1632,9 @@ dependencies = [ [[package]] name = "xmlparser" -version = "0.13.5" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "yeslogic-fontconfig-sys" diff --git a/Cargo.toml b/Cargo.toml index 456997c..4817f18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "dovi_tool" version = "2.0.3" authors = ["quietvoid"] edition = "2021" -rust-version = "1.65.0" +rust-version = "1.70.0" license = "MIT" build = "build.rs" @@ -18,22 +18,23 @@ hevc_parser = { version = "0.6.1", features = ["hevc_io"] } madvr_parse = "1.0.1" hdr10plus = { version = "2.1.0", features = ["json"] } -anyhow = "1.0.72" -clap = { version = "4.3.19", features = ["derive", "wrap_help", "deprecated"] } -indicatif = "0.17.5" +anyhow = "1.0.75" +clap = { version = "4.4.6", features = ["derive", "wrap_help", "deprecated"] } +clap_lex = "*" +indicatif = "0.17.7" bitvec = "1.0.1" -serde = { version = "1.0.175", features = ["derive"] } -serde_json = { version = "1.0.103", features = ["preserve_order"] } +serde = { version = "1.0.188", features = ["derive"] } +serde_json = { version = "1.0.107", features = ["preserve_order"] } itertools = "0.11.0" plotters = { version = "0.3.5", default-features = false, features = ["bitmap_backend", "bitmap_encoder", "all_series"] } [dev-dependencies] -assert_cmd = "2.0.11" +assert_cmd = "2.0.12" assert_fs = "1.0.13" -predicates = "3.0.3" +predicates = "3.0.4" [build-dependencies] -vergen = { version = "8.2.4", default-features = false, features = ["build", "git", "gitcl"] } +vergen = { version = "8.2.5", default-features = false, features = ["build", "git", "gitcl"] } [features] default = ["system-font"] diff --git a/README.md b/README.md index 180a2bf..596af67 100644 --- a/README.md +++ b/README.md @@ -124,11 +124,25 @@ dovi_tool --help   * ### **export** - Allows exporting a binary RPU file to JSON for simpler analysis. + Allows exporting a binary RPU file to text files containing relevant information. + The command allows specifying the desired data to export as file. + **Default**: `export` outputs the full RPU serialized to JSON (equivalent to `--data all`). - **Example**: + * `-d`, `--data`: List of key-value export parameters formatted as `key=output,key2...` + * `all` - Exports the list of RPUs as a JSON file + * `scenes` - Exports the frame indices at which `scene_refresh_flag` is set to 1 + * `level5` - Exports the video's L5 metadata in the form of an `editor` config JSON + +   + + **Example to export the whole RPU list to JSON**: + ```console + dovi_tool export -i RPU.bin -d all=RPU_export.json + ``` + + **Example to export both scene change frames and L5 metadata (with specific path)** ```console - dovi_tool export -i RPU.bin -o RPU_export.json + dovi_tool export -i RPU.bin -d scenes,level5=L5.json ```   diff --git a/dolby_vision/Cargo.toml b/dolby_vision/Cargo.toml index d677064..02b5fec 100644 --- a/dolby_vision/Cargo.toml +++ b/dolby_vision/Cargo.toml @@ -10,12 +10,12 @@ repository = "https://github.com/quietvoid/dovi_tool/tree/main/dolby_vision" [dependencies] bitvec_helpers = { version = "3.1.2", default-features = false, features = ["bitstream-io"] } -anyhow = "1.0.72" +anyhow = "1.0.75" bitvec = "1.0.1" crc = "3.0.1" -serde = { version = "1.0.175", features = ["derive"], "optional" = true } -serde_json = { version = "1.0.103", features = ["preserve_order"], "optional" = true } -roxmltree = { version = "0.18.0", optional = true } +serde = { version = "1.0.188", features = ["derive"], "optional" = true } +serde_json = { version = "1.0.107", features = ["preserve_order"], "optional" = true } +roxmltree = { version = "0.18.1", optional = true } libc = { version = "0.2", optional = true } diff --git a/dolby_vision/src/rpu/extension_metadata/blocks/level5.rs b/dolby_vision/src/rpu/extension_metadata/blocks/level5.rs index e815ac0..d7033e9 100644 --- a/dolby_vision/src/rpu/extension_metadata/blocks/level5.rs +++ b/dolby_vision/src/rpu/extension_metadata/blocks/level5.rs @@ -12,7 +12,7 @@ const MAX_RESOLUTION_13_BITS: u16 = 8191; /// Active area of the picture (letterbox, aspect ratio) #[repr(C)] -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct ExtMetadataBlockLevel5 { pub active_area_left_offset: u16, diff --git a/src/commands/export.rs b/src/commands/export.rs index 19fbd29..99041ce 100644 --- a/src/commands/export.rs +++ b/src/commands/export.rs @@ -1,6 +1,11 @@ -use clap::{Args, ValueHint}; use std::path::PathBuf; +use clap::{ + builder::{EnumValueParser, PossibleValue, TypedValueParser}, + Args, ValueEnum, ValueHint, +}; +use clap_lex::OsStrExt as _; + #[derive(Args, Debug)] pub struct ExportArgs { #[arg( @@ -23,12 +28,78 @@ pub struct ExportArgs { )] pub input_pos: Option, + #[arg( + id = "data", + help = "List of key-value export parameters formatted as `key=output`, where `output` is an output file path.\nSupports multiple occurences prefixed by --data or delimited by ','", + long, + short = 'd', + conflicts_with = "output", + value_parser = ExportOptionParser, + value_delimiter = ',' + )] + pub data: Vec<(ExportData, Option)>, + + // FIXME: export single output deprecation #[arg( id = "output", + help = "Output JSON file name. Deprecated, replaced by `--data all=output`", long, short = 'o', - help = "Output JSON file name", + conflicts_with = "data", + hide = true, value_hint = ValueHint::FilePath )] pub output: Option, } + +#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExportData { + /// Exports the list of RPUs as a JSON file + All, + /// Exports the frame indices at which `scene_refresh_flag` is set to 1 + Scenes, + /// Exports the video's L5 metadata in the form of an `editor` config JSON + Level5, +} + +impl ExportData { + pub fn default_output_file(&self) -> &'static str { + match self { + ExportData::All => "RPU_export.json", + ExportData::Scenes => "RPU_scenes.txt", + ExportData::Level5 => "RPU_L5_edit_config.json", + } + } +} + +#[derive(Clone)] +struct ExportOptionParser; +impl TypedValueParser for ExportOptionParser { + type Value = (ExportData, Option); + + fn parse_ref( + &self, + cmd: &clap::Command, + arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result { + let data_parser = EnumValueParser::::new(); + + if let Some((data_str, output_str)) = value.split_once("=") { + Ok(( + data_parser.parse_ref(cmd, arg, data_str)?, + output_str.to_str().map(str::parse).and_then(Result::ok), + )) + } else { + Ok((data_parser.parse_ref(cmd, arg, value)?, None)) + } + } + + fn possible_values(&self) -> Option + '_>> { + Some(Box::new( + ExportData::value_variants() + .iter() + .filter_map(|v| v.to_possible_value()), + )) + } +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index eea2d3c..772ab7e 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -16,7 +16,7 @@ mod plot; pub use convert::ConvertArgs; pub use demux::DemuxArgs; pub use editor::EditorArgs; -pub use export::ExportArgs; +pub use export::{ExportArgs, ExportData}; pub use extract_rpu::ExtractRpuArgs; pub use generate::{ArgHdr10PlusPeakBrightnessSource, GenerateArgs}; pub use info::InfoArgs; diff --git a/src/dovi/exporter.rs b/src/dovi/exporter.rs index 48e1517..30d7aef 100644 --- a/src/dovi/exporter.rs +++ b/src/dovi/exporter.rs @@ -1,21 +1,26 @@ +use std::borrow::Cow; use std::fs::File; use std::io::{stdout, BufWriter, Write}; +use std::ops::Range; use std::path::PathBuf; use anyhow::Result; +use dolby_vision::rpu::extension_metadata::blocks::{ExtMetadataBlock, ExtMetadataBlockLevel5}; +use itertools::Itertools; use serde::ser::SerializeSeq; use serde::Serializer; use dolby_vision::rpu::utils::parse_rpu_file; +use serde_json::json; -use crate::commands::ExportArgs; +use crate::commands::{ExportArgs, ExportData}; use crate::dovi::input_from_either; use super::DoviRpu; pub struct Exporter { input: PathBuf, - output: PathBuf, + data: Vec<(ExportData, Option)>, } impl Exporter { @@ -23,21 +28,18 @@ impl Exporter { let ExportArgs { input, input_pos, + data, output, } = args; let input = input_from_either("editor", input, input_pos)?; + let mut exporter = Exporter { input, data }; - let out_path = if let Some(out_path) = output { - out_path - } else { - PathBuf::from("RPU_export.json".to_string()) - }; + if exporter.data.is_empty() { + exporter.data.push((ExportData::All, output)); + } - let exporter = Exporter { - input, - output: out_path, - }; + exporter.data.dedup_by_key(|(k, _)| *k); println!("Parsing RPU file..."); stdout().flush().ok(); @@ -51,20 +53,131 @@ impl Exporter { } fn execute(&self, rpus: &[DoviRpu]) -> Result<()> { - println!("Exporting metadata..."); + for (data, maybe_output) in &self.data { + let out_path = if let Some(out_path) = maybe_output { + Cow::Borrowed(out_path) + } else { + Cow::Owned(PathBuf::from(data.default_output_file())) + }; + + let writer_buf_len = if matches!(data, ExportData::All) { + 100_000 + } else { + 1000 + }; + let mut writer = BufWriter::with_capacity( + writer_buf_len, + File::create(out_path.as_path()).expect("Can't create file"), + ); + + match data { + ExportData::All => { + println!("Exporting serialized RPU list..."); + + let mut ser = serde_json::Serializer::new(&mut writer); + let mut seq = ser.serialize_seq(Some(rpus.len()))?; + + for rpu in rpus { + seq.serialize_element(&rpu)?; + } + seq.end()?; + } + ExportData::Scenes => { + println!("Exporting scenes list..."); + + let scene_refresh_indices = rpus + .iter() + .enumerate() + .filter(|(_, rpu)| { + rpu.vdr_dm_data + .as_ref() + .is_some_and(|vdr| vdr.scene_refresh_flag == 1) + }) + .map(|e| e.0); + for i in scene_refresh_indices { + writeln!(&mut writer, "{i}")?; + } + } + ExportData::Level5 => { + self.export_level5_config(rpus, &mut writer)?; + } + } + + writer.flush()?; + } - let writer = BufWriter::with_capacity( - 100_000, - File::create(&self.output).expect("Can't create file"), - ); + Ok(()) + } - let mut ser = serde_json::Serializer::new(writer); - let mut seq = ser.serialize_seq(Some(rpus.len()))?; + fn export_level5_config(&self, rpus: &[DoviRpu], writer: &mut W) -> Result<()> { + println!("Exporting L5 metadata config..."); + + let default_l5 = ExtMetadataBlockLevel5::default(); + + let l5_groups = rpus.iter().enumerate().group_by(|(_, rpu)| { + rpu.vdr_dm_data + .as_ref() + .and_then(|vdr| { + vdr.get_block(5).and_then(|b| match b { + ExtMetadataBlock::Level5(b) => Some(b), + _ => None, + }) + }) + .unwrap_or(&default_l5) + }); + let l5_indices = l5_groups + .into_iter() + .map(|(k, group)| (k, group.take(1).map(|(i, _)| i).next().unwrap())); + + let mut l5_presets = + Vec::<&ExtMetadataBlockLevel5>::with_capacity(l5_indices.size_hint().0); + let mut l5_edits = Vec::<(Range, usize)>::new(); + + for (k, start_index) in l5_indices { + if !l5_presets.iter().any(|l5| *l5 == k) { + l5_presets.push(k); + } + + if let Some(last_edit) = l5_edits.last_mut() { + last_edit.0.end = start_index - 1; + } + + let preset_idx = l5_presets.iter().position(|l5| *l5 == k).unwrap(); + l5_edits.push((start_index..start_index, preset_idx)); + } - for rpu in rpus { - seq.serialize_element(&rpu)?; + // Set last edit end index + if let Some(last_edit) = l5_edits.last_mut() { + last_edit.0.end = rpus.len() - 1; } - seq.end()?; + + let l5_presets = l5_presets + .iter() + .enumerate() + .map(|(id, l5)| { + json!({ + "id": id, + "left": l5.active_area_left_offset, + "right": l5.active_area_right_offset, + "top": l5.active_area_top_offset, + "bottom": l5.active_area_bottom_offset + }) + }) + .collect::>(); + let l5_edits = l5_edits.iter().map(|(edit_range, id)| { + ( + format!("{}-{}", edit_range.start, edit_range.end), + json!(id), + ) + }); + let l5_edits = serde_json::Value::Object(l5_edits.collect()); + + let edit_config = json!({ + "crop": true, + "presets": l5_presets, + "edits": l5_edits, + }); + serde_json::to_writer_pretty(writer, &edit_config)?; Ok(()) } diff --git a/tests/rpu/export.rs b/tests/rpu/export.rs index 31b2a75..b972354 100644 --- a/tests/rpu/export.rs +++ b/tests/rpu/export.rs @@ -39,9 +39,38 @@ fn exports_json() -> Result<()> { assert .success() .stderr(predicate::str::is_empty()) - .stdout(predicate::str::contains("Exporting metadata...")); + .stdout(predicate::str::contains("Exporting serialized RPU list...")); output_json.assert(predicate::path::is_file()); Ok(()) } + +#[test] +fn export_all_and_scenes() -> Result<()> { + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))?; + let temp = assert_fs::TempDir::new().unwrap(); + + let root_path = Path::new(env!("CARGO_MANIFEST_DIR")); + let input_rpu = root_path.join("assets/tests/fel_orig.bin"); + let all_json = temp.child("RPU_export.json"); + let scenes_file = temp.child("RPU_scenes_test.txt"); + + let assert = cmd + .current_dir(temp.canonicalize().unwrap()) + .arg(SUBCOMMAND) + .arg(input_rpu) + .arg("--data") + .arg(format!("all,scenes={}", scenes_file.to_str().unwrap())) + .assert(); + + assert.success().stderr(predicate::str::is_empty()).stdout( + predicate::str::contains("Exporting serialized RPU list...") + .and(predicate::str::contains("Exporting scenes list...")), + ); + + all_json.assert(predicate::path::is_file()); + scenes_file.assert(predicate::path::is_file()); + + Ok(()) +}