Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db15c2615d | ||
|
|
5c6b09a5c5 | ||
|
|
9c10b97e31 | ||
|
|
31087697a9 | ||
|
|
2a57ee36f8 | ||
|
|
e4d8573475 | ||
|
|
6d8f3b45b5 | ||
|
|
c985438db1 | ||
|
|
55bc664eca | ||
|
|
a34f4051fc | ||
|
|
370b0ab494 | ||
|
|
cf5db2d485 | ||
|
|
dc0766b2f3 | ||
|
|
e6d6498a49 | ||
|
|
ca92dab6fd | ||
|
|
6331ae7fd9 | ||
|
|
d0659d2b61 | ||
|
|
540c0d3027 | ||
|
|
d24f7fc6ac | ||
|
|
0a359525a7 | ||
|
|
896bb47235 | ||
|
|
b5e54aea6e | ||
|
|
119ec0dd83 | ||
|
|
110ac9b663 | ||
|
|
1d6f4760f3 | ||
|
|
9dfbc2f895 | ||
|
|
56adb47026 | ||
|
|
52a9d02355 | ||
|
|
e5ca213339 | ||
|
|
e5416646f9 | ||
|
|
b79d90b463 | ||
|
|
8983ec04b9 |
Generated
+175
-24
@@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05b07e8e73d720a1f2e4b6014766e6039fd2e96a4fa44e2a78d0e1fa2ff49826"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"env_filter",
|
||||
"env_filter 0.1.4",
|
||||
"log",
|
||||
]
|
||||
|
||||
@@ -446,7 +446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
||||
dependencies = [
|
||||
"annotate-snippets",
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.13.0",
|
||||
@@ -475,6 +475,12 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.13.0"
|
||||
@@ -556,7 +562,7 @@ version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc8d9aa793480744cd9a0524fef1a2e197d9eaa0f739cde19d16aba530dcb95"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"cairo-sys-rs",
|
||||
"glib",
|
||||
"libc",
|
||||
@@ -885,6 +891,15 @@ dependencies = [
|
||||
"itertools 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cros-codecs"
|
||||
version = "0.0.5"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
@@ -991,6 +1006,37 @@ version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
|
||||
|
||||
[[package]]
|
||||
name = "defmt"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"defmt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-macros"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
|
||||
dependencies = [
|
||||
"defmt-parser",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "defmt-parser"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
|
||||
dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.10"
|
||||
@@ -1101,6 +1147,29 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter 2.0.0",
|
||||
"jiff",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@@ -1193,7 +1262,7 @@ version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c4bd5ab1ac61f29c634df1175d350ded29cf74c3c6d4f7030431a5ae3c7d5d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"ffmpeg-sys-next",
|
||||
"libc",
|
||||
]
|
||||
@@ -1584,7 +1653,7 @@ version = "0.22.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c207e04e51605dcf7b2924c41591b3a10e1438eaac5bcf448fb91f325381104a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
@@ -2127,6 +2196,42 @@ version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
"jiff-core",
|
||||
"jiff-static",
|
||||
"log",
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiff-core"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09"
|
||||
dependencies = [
|
||||
"defmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204"
|
||||
dependencies = [
|
||||
"jiff-core",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
@@ -2291,7 +2396,7 @@ version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"cc",
|
||||
"convert_case",
|
||||
"cookie-factory",
|
||||
@@ -2493,7 +2598,7 @@ dependencies = [
|
||||
name = "ndk"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"jni-sys 0.3.1",
|
||||
"log",
|
||||
"ndk-sys",
|
||||
@@ -2517,7 +2622,7 @@ version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@@ -2530,7 +2635,7 @@ version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@@ -2848,6 +2953,14 @@ version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pf-bitstream"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"cros-codecs",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-capture"
|
||||
version = "0.24.0"
|
||||
@@ -2879,8 +2992,10 @@ dependencies = [
|
||||
"ffmpeg-next",
|
||||
"mdns-sd",
|
||||
"opus",
|
||||
"pf-dxvadec",
|
||||
"pf-ffvk",
|
||||
"pf-update-check",
|
||||
"pf-vkdecode",
|
||||
"pipewire",
|
||||
"punktfunk-core",
|
||||
"pyrowave-sys",
|
||||
@@ -2935,6 +3050,16 @@ dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-dxvadec"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"cros-codecs",
|
||||
"pf-bitstream",
|
||||
"pf-vkdecode",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-encode"
|
||||
version = "0.24.0"
|
||||
@@ -3075,7 +3200,7 @@ version = "0.24.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ashpd",
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"bytemuck",
|
||||
"futures-util",
|
||||
"hex",
|
||||
@@ -3102,6 +3227,17 @@ dependencies = [
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-vkdecode"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"cros-codecs",
|
||||
"pf-bitstream",
|
||||
"sha2",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-win-display"
|
||||
version = "0.24.0"
|
||||
@@ -3153,7 +3289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"libc",
|
||||
"libspa",
|
||||
"libspa-sys",
|
||||
@@ -3207,7 +3343,7 @@ version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
@@ -3251,6 +3387,21 @@ dependencies = [
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic-util"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.5"
|
||||
@@ -3311,7 +3462,7 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"bit-vec",
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"num-traits",
|
||||
"rand 0.9.4",
|
||||
"rand_chacha 0.9.0",
|
||||
@@ -3777,7 +3928,7 @@ version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3934,7 +4085,7 @@ version = "0.40.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11438310b19e3109b6446c33d1ed5e889428cf2e278407bc7896bc4aaea43323"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
@@ -3973,7 +4124,7 @@ version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@@ -4127,7 +4278,7 @@ version = "0.18.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bd22eb1bbc9137e914022b4994ed35591eea0884e9e3e98e6d9895cad6e1d2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"libc",
|
||||
"sdl3-image-sys",
|
||||
"sdl3-mixer-sys",
|
||||
@@ -4222,7 +4373,7 @@ version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -4428,7 +4579,7 @@ version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7d94f3e7537c71ad4cf132eb26e3be8c8a886ed3649c4525c089041fc312b2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"lazy_static",
|
||||
"skia-bindings",
|
||||
]
|
||||
@@ -5301,7 +5452,7 @@ version = "0.31.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"rustix",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
@@ -5313,7 +5464,7 @@ version = "0.32.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-scanner",
|
||||
@@ -5325,7 +5476,7 @@ version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
@@ -5338,7 +5489,7 @@ version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
@@ -5690,7 +5841,7 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d24d6bcc7f734a4091ecf8d7a64c5f7d7066f45585c1861eba06449909609c8a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.13.0",
|
||||
"widestring",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@@ -5,6 +5,8 @@ members = [
|
||||
"crates/punktfunk-host",
|
||||
"crates/punktfunk-host/vendor/usbip-sim",
|
||||
"crates/punktfunk-tray",
|
||||
"crates/pf-bitstream",
|
||||
"crates/pf-bitstream/vendor/cros-codecs",
|
||||
"crates/pf-client-core",
|
||||
"crates/pf-clipboard",
|
||||
"crates/pf-presenter",
|
||||
@@ -23,6 +25,8 @@ members = [
|
||||
"crates/pf-capture",
|
||||
"crates/pf-inject",
|
||||
"crates/pf-vdisplay",
|
||||
"crates/pf-vkdecode",
|
||||
"crates/pf-dxvadec",
|
||||
"crates/pyrowave-sys",
|
||||
"crates/libvpl-sys",
|
||||
"clients/probe",
|
||||
|
||||
@@ -49,19 +49,40 @@ path + per-stage latency equation); any tier but Off also emits the stdout mirro
|
||||
`--no-default-features` is the ~5 MB power-user build — same streaming, stats on stdout
|
||||
only, no Skia anywhere in the dependency tree.
|
||||
|
||||
Decode follows the Settings preference (auto: Vulkan Video → VAAPI → software on Linux,
|
||||
Vulkan Video → D3D11VA → software on Windows): FFmpeg's Vulkan Video decoder runs on the
|
||||
presenter's own device where the stack supports it (every vendor, zero copy); VAAPI
|
||||
dmabufs import per-plane elsewhere (D3D11VA textures on Windows); software is the
|
||||
universal fallback. 10-bit Main10 and HDR10 are advertised
|
||||
(`VIDEO_CAP_10BIT|HDR`): P010 decodes through all three paths, and PQ streams present
|
||||
Decode follows the Settings preference (auto is vendor-ordered: hardware Vulkan Video →
|
||||
VAAPI → software on Linux, hardware Vulkan Video → D3D11VA → software on Windows, with
|
||||
VAAPI/D3D11VA first on Intel; on H.264 and HEVC the native pf-vkdecode Vulkan decoder
|
||||
is tried immediately before FFmpeg-Vulkan): the Vulkan decoders run on the presenter's own
|
||||
device where the stack supports it (every vendor, zero copy); VAAPI dmabufs import
|
||||
per-plane elsewhere (D3D11VA textures on Windows); software is the universal fallback.
|
||||
10-bit Main10 and HDR10 are advertised (`VIDEO_CAP_10BIT|HDR`): P010 decodes through the
|
||||
native, FFmpeg-Vulkan, VAAPI/D3D11VA and software paths alike, and PQ streams present
|
||||
on an HDR10/ST.2084 swapchain when the desktop offers one (KDE HDR, gamescope) or
|
||||
tone-map in-shader to SDR when it doesn't (`PUNKTFUNK_TONEMAP_PEAK` tunes the rolloff,
|
||||
default ≈1000 nits). The host still gates the upgrade behind its `PUNKTFUNK_10BIT`
|
||||
policy.
|
||||
|
||||
Debug/bisect knobs: `PUNKTFUNK_DECODER=vulkan|vaapi|d3d11va|software`, `PUNKTFUNK_PRESENT_MODE=
|
||||
Debug/bisect knobs: `PUNKTFUNK_DECODER=native-vulkan|vulkan|vaapi|d3d11va|software`, `PUNKTFUNK_PRESENT_MODE=
|
||||
mailbox|fifo|immediate|fifo_relaxed` (default MAILBOX, FIFO where the surface offers no
|
||||
MAILBOX — AMD on Windows), `PUNKTFUNK_VK_DEVICE=<index>` (multi-GPU), and
|
||||
`PUNKTFUNK_HW_FAULT=import` (fault every VAAPI dmabuf import — proves the three-strike
|
||||
demotion to software on healthy hardware).
|
||||
|
||||
`PUNKTFUNK_AU_FAULT=drop|truncate|flip[:period]` deliberately corrupts decoder input on the
|
||||
native Vulkan lane (default period 60 — one AU a second at 60 fps; inert everywhere else, and
|
||||
inert entirely if the value doesn't parse). `drop` swallows the AU, so the next one references a
|
||||
picture that was never decoded — the bitstream planner catches it immediately. `truncate` delivers
|
||||
a picture whose slice data stops mid-frame and `flip` alters one byte deep in the payload: both
|
||||
parse perfectly, so only the driver's per-frame decode-status query can see them, and neither is
|
||||
visible at all on a driver without `queryResultStatusSupport` or on any FFmpeg lane. Watch the
|
||||
result on the Detailed stats line's `integrity:` term (`damaged` = concealment the planner caught,
|
||||
`refused` = AUs the decoder rejected outright, `driver-failed` = the hardware's own verdict, `run`
|
||||
= consecutive frames with no picture, `worst run` = the longest such stretch of the session — the
|
||||
once-a-second `run` sample misses the bad moment almost every time — and `no driver status` = this
|
||||
device cannot answer the driver question at all). A session that lands on any other lane says so
|
||||
in the log rather than faulting silently.
|
||||
|
||||
Note that `PUNKTFUNK_AU_DUMP` records the AU as it arrived from the HOST, while the fault injector
|
||||
runs later, at the native decoder's own entry. On a faulted run the dump is therefore the clean
|
||||
bitstream — reconstruct the damaged bytes from the spec if you need them (the injector is pure and
|
||||
deterministic).
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "pf-bitstream"
|
||||
description = "Client-side bitstream layer for native decode: AU parsing, POC/DPB/reference derivation and per-AU DecodePlans (H.264/HEVC/AV1) on the vendored cros-codecs parsers — the layer libavcodec used to be (design/client-native-decode.md §3.1)"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
cros-codecs = { path = "vendor/cros-codecs" }
|
||||
tracing = "0.1"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
//! The client's bitstream layer for native decode (design/client-native-decode.md §3.1):
|
||||
//! everything a stateless hardware decoder needs to know about an AU before submission —
|
||||
//! parsed headers, POC, DPB state, reference lists (including MMCO/LTR, which the hosts'
|
||||
//! RFI recovery actively uses), recovery-point SEI — derived once here and consumed by
|
||||
//! every backend (Vulkan `StdVideo*`, DXVA picparams, libva buffers).
|
||||
//!
|
||||
//! Parsing primitives come from the vendored cros-codecs parser layer
|
||||
//! (`vendor/cros-codecs`, see its PROVENANCE.md); this crate owns what upstream keeps in
|
||||
//! its Linux-only `decoder::stateless` half — the per-AU orchestration — plus the pieces
|
||||
//! upstream lacks (SEI payload parsing: their parsers classify SEI NALUs but never read
|
||||
//! them).
|
||||
//!
|
||||
//! Scope discipline: punktfunk clients decode punktfunk hosts — zero-reorder, no
|
||||
//! B-frames, progressive, parameter sets from encoders we control. Implement to spec
|
||||
//! where cheap; reject-with-log outside that envelope rather than half-decode.
|
||||
//!
|
||||
//! Nothing in this crate may touch a GPU API, an OS handle, or the network: CPU-only by
|
||||
//! construction, so its tests run on every CI leg including macOS. And no `unsafe`,
|
||||
//! compiler-enforced — this layer exists to replace C parsers; it does not get to
|
||||
//! reintroduce their failure mode.
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod h264;
|
||||
pub mod h265;
|
||||
pub mod sei;
|
||||
|
||||
// The vendor-pinning smoke tests below assert against byte counts and golden values from
|
||||
// the vendored snapshot's own test vectors; a cros-codecs re-sync that shifts parser
|
||||
// behavior must trip HERE, in our tree, not in a decode session.
|
||||
#[cfg(test)]
|
||||
mod vendor_smoke {
|
||||
use std::io::Cursor;
|
||||
|
||||
use cros_codecs::bitstream_utils::IvfIterator;
|
||||
use cros_codecs::codec::av1::parser::ObuAction;
|
||||
use cros_codecs::codec::av1::parser::ParsedObu;
|
||||
use cros_codecs::codec::h264::parser::Nalu as H264Nalu;
|
||||
use cros_codecs::codec::h264::parser::Parser as H264Parser;
|
||||
use cros_codecs::codec::h265::parser::Nalu as H265Nalu;
|
||||
use cros_codecs::codec::h265::parser::Parser as H265Parser;
|
||||
|
||||
const H264_25FPS: &[u8] =
|
||||
include_bytes!("../vendor/cros-codecs/src/codec/h264/test_data/test-25fps.h264");
|
||||
const H265_25FPS: &[u8] =
|
||||
include_bytes!("../vendor/cros-codecs/src/codec/h265/test_data/test-25fps.h265");
|
||||
const AV1_25FPS: &[u8] =
|
||||
include_bytes!("../vendor/cros-codecs/src/codec/av1/test_data/test-25fps.ivf.av1");
|
||||
const VP9_25FPS: &[u8] =
|
||||
include_bytes!("../vendor/cros-codecs/src/codec/vp9/test_data/test-25fps.vp9");
|
||||
|
||||
#[test]
|
||||
fn h264_parses_the_vendored_vector_to_its_goldens() {
|
||||
let mut cursor = Cursor::new(H264_25FPS);
|
||||
let mut parser = H264Parser::default();
|
||||
let (mut nalus, mut sps, mut slices) = (0u32, 0u32, 0u32);
|
||||
let mut coded = (0u32, 0u32);
|
||||
while let Ok(nalu) = H264Nalu::next(&mut cursor) {
|
||||
nalus += 1;
|
||||
if let Ok(s) = parser.parse_sps(&nalu) {
|
||||
sps += 1;
|
||||
coded = (
|
||||
(s.pic_width_in_mbs_minus1 as u32 + 1) * 16,
|
||||
(s.pic_height_in_map_units_minus1 as u32 + 1) * 16,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if parser.parse_pps(&nalu).is_ok() {
|
||||
continue;
|
||||
}
|
||||
if parser.parse_slice_header(nalu).is_ok() {
|
||||
slices += 1;
|
||||
}
|
||||
}
|
||||
// 759 is upstream's own golden for this stream (chromium h264_parser_unittest lineage).
|
||||
assert_eq!(nalus, 759);
|
||||
assert_eq!(sps, 4);
|
||||
assert_eq!(slices, 500);
|
||||
assert_eq!(coded, (320, 240));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn h265_parses_the_vendored_vector() {
|
||||
let mut cursor = Cursor::new(H265_25FPS);
|
||||
let mut parser = H265Parser::default();
|
||||
let (mut nalus, mut sps, mut slices) = (0u32, 0u32, 0u32);
|
||||
while let Ok(nalu) = H265Nalu::next(&mut cursor) {
|
||||
nalus += 1;
|
||||
if parser.parse_sps(&nalu).is_ok() {
|
||||
sps += 1;
|
||||
continue;
|
||||
}
|
||||
if parser.parse_pps(&nalu).is_ok() {
|
||||
continue;
|
||||
}
|
||||
if parser.parse_slice_header(nalu).is_ok() {
|
||||
slices += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(nalus, 254);
|
||||
assert_eq!(sps, 1);
|
||||
assert_eq!(slices, 250);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn av1_walks_obus_and_maintains_ref_slots_across_the_stream() {
|
||||
let mut parser = cros_codecs::codec::av1::parser::Parser::default();
|
||||
let (mut obus, mut frames) = (0u32, 0u32);
|
||||
for packet in IvfIterator::new(AV1_25FPS) {
|
||||
let mut consumed = 0;
|
||||
while let Ok(action) = parser.read_obu(&packet[consumed..]) {
|
||||
let obu = match action {
|
||||
ObuAction::Process(obu) => obu,
|
||||
ObuAction::Drop(n) => {
|
||||
consumed += n as usize;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
consumed += obu.bytes_used;
|
||||
obus += 1;
|
||||
// `ref_frame_update` is the parser's ref-slot bookkeeping; without it,
|
||||
// inter frames fail with "Reference is invalid" — the parser validates
|
||||
// reference integrity rather than trusting the stream.
|
||||
match parser.parse_obu(obu).expect("parse_obu") {
|
||||
ParsedObu::FrameHeader(fh) => {
|
||||
frames += 1;
|
||||
parser.ref_frame_update(&fh).expect("ref slot update");
|
||||
}
|
||||
ParsedObu::Frame(f) => {
|
||||
frames += 1;
|
||||
parser.ref_frame_update(&f.header).expect("ref slot update");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 525 is upstream's own golden (cross-checked against GStreamer's OBU walk).
|
||||
assert_eq!(obus, 525);
|
||||
assert_eq!(frames, 274);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vp9_splits_superframes_and_parses_headers() {
|
||||
let mut parser = cros_codecs::codec::vp9::parser::Parser::default();
|
||||
let (mut chunks, mut frames) = (0u32, 0u32);
|
||||
for packet in IvfIterator::new(VP9_25FPS) {
|
||||
chunks += 1;
|
||||
frames += parser
|
||||
.parse_chunk(packet.as_ref())
|
||||
.expect("vp9 chunk")
|
||||
.len() as u32;
|
||||
}
|
||||
assert_eq!(chunks, 250);
|
||||
// > chunks proves superframe splitting engaged.
|
||||
assert_eq!(frames, 269);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
//! SEI payload parsing — the piece the vendored parser layer lacks: upstream classifies
|
||||
//! SEI NALUs but never reads a payload. punktfunk needs exactly one payload type per
|
||||
//! codec: the recovery point SEI, which hosts emit on RFI recovery so the client knows
|
||||
//! where a decode-from-here point lands. Every other payload type is skipped by its
|
||||
//! declared size.
|
||||
//!
|
||||
//! Both codecs put the recovery point at payload type 6 with the same D.1 message
|
||||
//! framing, but the payload syntax differs: H.264 (D.1.8/D.2.8) counts recovery in
|
||||
//! `frame_num` increments (`recovery_frame_cnt`, ue(v)) and carries a slice-group bit
|
||||
//! pair; H.265 (D.2.8/D.3.8) counts in picture order (`recovery_poc_cnt`, se(v) — it
|
||||
//! can be negative) and has no slice-group field. Hence two parsers over one shared
|
||||
//! message walk.
|
||||
|
||||
/// Recovery point SEI (D.2.8).
|
||||
///
|
||||
/// `recovery_frame_cnt` counts in `frame_num` increments from the AU carrying the SEI to
|
||||
/// the picture at which output is exact (`exact_match`) or approximate. `broken_link` set
|
||||
/// means pictures before the recovery point may be visually broken and must not be shown.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct RecoveryPoint {
|
||||
pub recovery_frame_cnt: u32,
|
||||
pub exact_match: bool,
|
||||
pub broken_link: bool,
|
||||
}
|
||||
|
||||
/// Recovery point SEI, H.265 flavour (D.3.8).
|
||||
///
|
||||
/// `recovery_poc_cnt` is the POC delta from the picture carrying the SEI to the
|
||||
/// recovery-point picture — se(v)-coded, so unlike H.264's `recovery_frame_cnt` it can
|
||||
/// be NEGATIVE (a recovery point among leading pictures). `exact_match`/`broken_link`
|
||||
/// keep their H.264 semantics.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct RecoveryPointHevc {
|
||||
pub recovery_poc_cnt: i32,
|
||||
pub exact_match: bool,
|
||||
pub broken_link: bool,
|
||||
}
|
||||
|
||||
/// Parse the first recovery point SEI message out of an H.264 SEI NALU.
|
||||
///
|
||||
/// `sei_payload` are the bytes of the NALU after its one-byte NAL header, emulation
|
||||
/// prevention bytes still in place (they are removed here — 7.4.1 RBSP extraction).
|
||||
/// `Ok(None)` means the NALU parsed cleanly but carries no recovery point.
|
||||
pub fn parse_recovery_point(sei_payload: &[u8]) -> Result<Option<RecoveryPoint>, String> {
|
||||
let rbsp = strip_emulation_prevention(sei_payload);
|
||||
let Some(payload) = first_recovery_point_payload(&rbsp)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let mut r = BitCursor::new(payload);
|
||||
let recovery_frame_cnt = r.read_ue()?;
|
||||
let exact_match = r.read_bit()? != 0;
|
||||
let broken_link = r.read_bit()? != 0;
|
||||
// changing_slice_group_idc u(2): parsed to keep the reader honest, unused —
|
||||
// slice groups are outside every profile punktfunk hosts emit.
|
||||
let _changing_slice_group_idc = r.read_bits(2)?;
|
||||
Ok(Some(RecoveryPoint {
|
||||
recovery_frame_cnt,
|
||||
exact_match,
|
||||
broken_link,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parse the first recovery point SEI message out of an H.265 prefix SEI NALU.
|
||||
///
|
||||
/// `sei_payload` are the bytes of the NALU after its TWO-byte NAL header (H.265 NALU
|
||||
/// headers are 16 bits), emulation prevention still in place. Only prefix SEI NALUs
|
||||
/// (type 39) can carry a recovery point — D.2.1 lists it as prefix-only, so suffix SEI
|
||||
/// NALUs (type 40) need never reach here.
|
||||
pub fn parse_recovery_point_hevc(sei_payload: &[u8]) -> Result<Option<RecoveryPointHevc>, String> {
|
||||
let rbsp = strip_emulation_prevention(sei_payload);
|
||||
let Some(payload) = first_recovery_point_payload(&rbsp)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let mut r = BitCursor::new(payload);
|
||||
let recovery_poc_cnt = r.read_se()?;
|
||||
let exact_match = r.read_bit()? != 0;
|
||||
let broken_link = r.read_bit()? != 0;
|
||||
Ok(Some(RecoveryPointHevc {
|
||||
recovery_poc_cnt,
|
||||
exact_match,
|
||||
broken_link,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Walk the D.1 SEI message framing (shared verbatim between H.264 and H.265) and
|
||||
/// return the payload bytes of the first recovery point message (payload type 6 in
|
||||
/// both codecs), if any. `rbsp` is already emulation-prevention-stripped.
|
||||
fn first_recovery_point_payload(rbsp: &[u8]) -> Result<Option<&[u8]>, String> {
|
||||
let mut i = 0usize;
|
||||
while i < rbsp.len() && !is_rbsp_trailing(rbsp, i) {
|
||||
// D.1: payload type and size are ff-coded — 0xFF bytes each add 255 until a
|
||||
// non-0xFF byte terminates the value. The run length is unbounded, so the type
|
||||
// accumulates saturating: an adversarial ~16M-byte 0xFF run must not overflow
|
||||
// (a saturated type simply never matches 6). The size accumulator is a usize
|
||||
// whose use is bounds-checked below.
|
||||
let mut payload_type = 0u32;
|
||||
while i < rbsp.len() && rbsp[i] == 0xFF {
|
||||
payload_type = payload_type.saturating_add(255);
|
||||
i += 1;
|
||||
}
|
||||
if i >= rbsp.len() {
|
||||
return Err("truncated SEI payload type".into());
|
||||
}
|
||||
payload_type = payload_type.saturating_add(u32::from(rbsp[i]));
|
||||
i += 1;
|
||||
|
||||
let mut payload_size = 0usize;
|
||||
while i < rbsp.len() && rbsp[i] == 0xFF {
|
||||
payload_size += 255;
|
||||
i += 1;
|
||||
}
|
||||
if i >= rbsp.len() {
|
||||
return Err("truncated SEI payload size".into());
|
||||
}
|
||||
payload_size += usize::from(rbsp[i]);
|
||||
i += 1;
|
||||
|
||||
let end = i
|
||||
.checked_add(payload_size)
|
||||
.filter(|&end| end <= rbsp.len())
|
||||
.ok_or_else(|| "SEI payload overruns the NALU".to_string())?;
|
||||
|
||||
if payload_type == 6 {
|
||||
return Ok(Some(&rbsp[i..end]));
|
||||
}
|
||||
|
||||
i = end;
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// 7.4.1: within the RBSP, `00 00 03` encodes two zero bytes; the `03` is the emulation
|
||||
/// prevention byte and is dropped.
|
||||
fn strip_emulation_prevention(data: &[u8]) -> Vec<u8> {
|
||||
let mut out = Vec::with_capacity(data.len());
|
||||
let mut zeros = 0usize;
|
||||
for &byte in data {
|
||||
if zeros >= 2 && byte == 0x03 {
|
||||
zeros = 0;
|
||||
continue;
|
||||
}
|
||||
zeros = if byte == 0 { zeros + 1 } else { 0 };
|
||||
out.push(byte);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// `more_rbsp_data()` at a byte-aligned message boundary: the remainder is trailing bits
|
||||
/// iff it is the stop bit (0x80) followed by nothing but zero bytes.
|
||||
fn is_rbsp_trailing(rbsp: &[u8], i: usize) -> bool {
|
||||
rbsp[i] == 0x80 && rbsp[i + 1..].iter().all(|&b| b == 0)
|
||||
}
|
||||
|
||||
/// Minimal MSB-first bit reader over an already-unescaped RBSP slice. The vendored
|
||||
/// `BitReader` is `pub(crate)` to the vendored crate, so this crate carries its own.
|
||||
struct BitCursor<'a> {
|
||||
data: &'a [u8],
|
||||
/// Position in bits from the start of `data`.
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl<'a> BitCursor<'a> {
|
||||
fn new(data: &'a [u8]) -> Self {
|
||||
Self { data, pos: 0 }
|
||||
}
|
||||
|
||||
fn read_bit(&mut self) -> Result<u32, String> {
|
||||
let byte = *self
|
||||
.data
|
||||
.get(self.pos / 8)
|
||||
.ok_or("SEI payload out of bits")?;
|
||||
let bit = (byte >> (7 - self.pos % 8)) & 1;
|
||||
self.pos += 1;
|
||||
Ok(u32::from(bit))
|
||||
}
|
||||
|
||||
fn read_bits(&mut self, count: usize) -> Result<u32, String> {
|
||||
debug_assert!(count <= 31);
|
||||
let mut out = 0u32;
|
||||
for _ in 0..count {
|
||||
out = (out << 1) | self.read_bit()?;
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// ue(v), spec 9.1.
|
||||
fn read_ue(&mut self) -> Result<u32, String> {
|
||||
let mut leading_zeros = 0usize;
|
||||
while self.read_bit()? == 0 {
|
||||
leading_zeros += 1;
|
||||
if leading_zeros > 31 {
|
||||
return Err("invalid exp-Golomb code in SEI payload".into());
|
||||
}
|
||||
}
|
||||
let suffix = self.read_bits(leading_zeros)?;
|
||||
((1u32 << leading_zeros) - 1)
|
||||
.checked_add(suffix)
|
||||
.ok_or_else(|| "exp-Golomb value overflows u32".to_string())
|
||||
}
|
||||
|
||||
/// se(v), spec 9.1.1: the ue(v) code point k maps to (−1)^(k+1) · ⌈k/2⌉.
|
||||
fn read_se(&mut self) -> Result<i32, String> {
|
||||
let k = self.read_ue()?;
|
||||
let magnitude = k.div_ceil(2);
|
||||
let magnitude =
|
||||
i32::try_from(magnitude).map_err(|_| "exp-Golomb value overflows i32".to_string())?;
|
||||
Ok(if k % 2 == 1 { magnitude } else { -magnitude })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_minimal_recovery_point_message_parses_to_its_field_values() {
|
||||
// Message: type 6, size 1. Payload bits: ue(0)='1', exact=0, broken=0, csg=00,
|
||||
// then payload alignment '1' + zeros -> 0b1000_0100. NALU trailing 0x80.
|
||||
let sei = [0x06, 0x01, 0x84, 0x80];
|
||||
assert_eq!(
|
||||
parse_recovery_point(&sei).unwrap(),
|
||||
Some(RecoveryPoint {
|
||||
recovery_frame_cnt: 0,
|
||||
exact_match: false,
|
||||
broken_link: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recovery_frame_cnt_and_both_flags_round_trip_through_the_bit_reader() {
|
||||
// ue(5)='00110', exact=1, broken=1, csg=00, alignment -> 0b0011_0110 0b0100_0000.
|
||||
let sei = [0x06, 0x02, 0x36, 0x40, 0x80];
|
||||
assert_eq!(
|
||||
parse_recovery_point(&sei).unwrap(),
|
||||
Some(RecoveryPoint {
|
||||
recovery_frame_cnt: 5,
|
||||
exact_match: true,
|
||||
broken_link: true
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn earlier_messages_and_ff_coded_types_are_skipped_to_reach_the_recovery_point() {
|
||||
// First message: ff-coded payload type 255 (0xFF 0x00), size 1, payload 0x55.
|
||||
// Second message: type 5 (user data), size 3. Third: the recovery point.
|
||||
let sei = [
|
||||
0xFF, 0x00, 0x01, 0x55, // type 255
|
||||
0x05, 0x03, 0xAA, 0xBB, 0xCC, // type 5
|
||||
0x06, 0x01, 0x84, // recovery point
|
||||
0x80,
|
||||
];
|
||||
assert_eq!(
|
||||
parse_recovery_point(&sei).unwrap(),
|
||||
Some(RecoveryPoint {
|
||||
recovery_frame_cnt: 0,
|
||||
exact_match: false,
|
||||
broken_link: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emulation_prevention_bytes_inside_the_payload_are_removed_before_reading() {
|
||||
// Unescaped payload (7 bytes): ue with a 22-zero prefix => recovery_frame_cnt
|
||||
// 2^22-1 = 4194303, exact=1, broken=0, csg=00, alignment. Its first bytes are
|
||||
// 00 00 02, which the escaper must have written as 00 00 03 02 on the wire.
|
||||
let sei = [
|
||||
0x06, 0x07, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x04, 0x40, 0x80,
|
||||
];
|
||||
assert!(sei.windows(3).any(|w| w == [0x00, 0x00, 0x03]));
|
||||
assert_eq!(
|
||||
parse_recovery_point(&sei).unwrap(),
|
||||
Some(RecoveryPoint {
|
||||
recovery_frame_cnt: 4194303,
|
||||
exact_match: true,
|
||||
broken_link: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_sei_nalu_without_a_recovery_point_yields_none_not_an_error() {
|
||||
let sei = [0x05, 0x01, 0x00, 0x80];
|
||||
assert_eq!(parse_recovery_point(&sei).unwrap(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_payload_size_overrunning_the_nalu_is_a_parse_error() {
|
||||
let sei = [0x06, 0x0A, 0x00];
|
||||
assert!(parse_recovery_point(&sei).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_hevc_recovery_point_parses_its_se_coded_poc_count() {
|
||||
// recovery_poc_cnt se(0) = '1', exact = 0, broken = 0, payload alignment:
|
||||
// 0b1001_0000.
|
||||
let sei = [0x06, 0x01, 0x90, 0x80];
|
||||
assert_eq!(
|
||||
parse_recovery_point_hevc(&sei).unwrap(),
|
||||
Some(RecoveryPointHevc {
|
||||
recovery_poc_cnt: 0,
|
||||
exact_match: false,
|
||||
broken_link: false
|
||||
})
|
||||
);
|
||||
|
||||
// se(-1) = '011' (ue code point 2), exact = 1, broken = 0, alignment:
|
||||
// 0b0111_0100 — the negative range H.264's ue(v) syntax cannot express.
|
||||
let sei = [0x06, 0x01, 0x74, 0x80];
|
||||
assert_eq!(
|
||||
parse_recovery_point_hevc(&sei).unwrap(),
|
||||
Some(RecoveryPointHevc {
|
||||
recovery_poc_cnt: -1,
|
||||
exact_match: true,
|
||||
broken_link: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_hevc_parser_skips_earlier_messages_and_reports_absence_as_none() {
|
||||
// User-data message first, then the recovery point (poc_cnt se(3): ue code
|
||||
// point 5 = '00110', exact = 1, broken = 1, alignment: 0b0011_0111).
|
||||
let sei = [
|
||||
0x05, 0x02, 0xAA, 0xBB, // type 5
|
||||
0x06, 0x01, 0x37, // recovery point
|
||||
0x80,
|
||||
];
|
||||
assert_eq!(
|
||||
parse_recovery_point_hevc(&sei).unwrap(),
|
||||
Some(RecoveryPointHevc {
|
||||
recovery_poc_cnt: 3,
|
||||
exact_match: true,
|
||||
broken_link: true
|
||||
})
|
||||
);
|
||||
|
||||
let sei = [0x05, 0x01, 0x00, 0x80];
|
||||
assert_eq!(parse_recovery_point_hevc(&sei).unwrap(), None);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
//! Corpus replay: walk a captured real-host stream through the planners.
|
||||
//!
|
||||
//! The M0 capture hook (`PUNKTFUNK_DUMP_VIDEO=<dir>` on any desktop client) writes
|
||||
//! the exact decoder input of a live session — `au-<stamp>.<codec>` plus an `.idx`
|
||||
//! sidecar carrying `offset len flags complete` per AU. This harness feeds those AUs
|
||||
//! back through [`pf_bitstream::h264::H264Planner`] / [`pf_bitstream::h265::H265Planner`]
|
||||
//! and asserts the planner survives a REAL host stream: every AU plans (bar the
|
||||
//! deliberate skips), no panic, and the warnings are only the ones a clean capture may
|
||||
//! legitimately produce.
|
||||
//!
|
||||
//! Why this exists separately from the vendored conformance vectors: those prove we
|
||||
//! match the spec's own test streams, and the on-glass sessions prove the whole pipe —
|
||||
//! but between the two sits "does the planner handle what OUR five host encoder
|
||||
//! families actually emit", which is the question the corpus was captured to answer.
|
||||
//! For HEVC this is the ONLY pre-wiring validation against real host output (the
|
||||
//! client's HEVC rung is still being built), so it runs long before M3 finishes.
|
||||
//!
|
||||
//! Ignored by default: captures are hundreds of megabytes and live outside the repo.
|
||||
//! Run one explicitly —
|
||||
//!
|
||||
//! ```text
|
||||
//! PF_CORPUS=/path/to/au-1785970273.h265 \
|
||||
//! cargo test -p pf-bitstream --test corpus_replay -- --ignored --nocapture
|
||||
//! ```
|
||||
//!
|
||||
//! The `.idx` sidecar is found next to the data file (`<data>.idx`); the codec comes
|
||||
//! from the extension, matching the capture hook's own naming convention.
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// One captured access unit: its byte range in the data file, plus the wire bits the
|
||||
/// byte stream itself cannot carry.
|
||||
struct CapturedAu {
|
||||
offset: usize,
|
||||
len: usize,
|
||||
/// The wire `flags` byte (`USER_FLAG_*`) — kept for the RFI/intra-refresh legs,
|
||||
/// which discriminate on it.
|
||||
_flags: u32,
|
||||
complete: bool,
|
||||
}
|
||||
|
||||
/// Parse the `.idx` sidecar: one `offset len flags complete` line per AU, `#` comments
|
||||
/// and blank lines skipped (the hook writes none today, but a hand-trimmed corpus file
|
||||
/// is a thing a human will produce).
|
||||
///
|
||||
/// A malformed FINAL line is dropped with a note instead of failing: ending a capture
|
||||
/// means killing the client, so the last buffered line is routinely half-written (the
|
||||
/// hook's own docs call a truncated last AU acceptable). Anywhere else a malformed line
|
||||
/// means the sidecar is corrupt and the run must not quietly replay a subset.
|
||||
fn read_index(path: &Path) -> Vec<CapturedAu> {
|
||||
let text = std::fs::read_to_string(path)
|
||||
.unwrap_or_else(|e| panic!("cannot read the index sidecar {}: {e}", path.display()));
|
||||
let lines: Vec<&str> = text
|
||||
.lines()
|
||||
.filter(|line| !line.trim().is_empty() && !line.trim_start().starts_with('#'))
|
||||
.collect();
|
||||
let last = lines.len().saturating_sub(1);
|
||||
let mut out = Vec::with_capacity(lines.len());
|
||||
for (n, line) in lines.iter().enumerate() {
|
||||
match parse_index_line(line) {
|
||||
Some(au) => out.push(au),
|
||||
None if n == last => {
|
||||
println!("note: dropping a truncated final index line ({line:?})");
|
||||
}
|
||||
None => panic!("index line {n} is malformed: {line:?}"),
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// One `offset len flags complete` line, or `None` when it is not four parsable fields.
|
||||
fn parse_index_line(line: &str) -> Option<CapturedAu> {
|
||||
let mut it = line.split_whitespace();
|
||||
let num = |raw: &str| -> Option<u64> {
|
||||
match raw.strip_prefix("0x") {
|
||||
Some(hex) => u64::from_str_radix(hex, 16).ok(),
|
||||
None => raw.parse().ok(),
|
||||
}
|
||||
};
|
||||
let offset = num(it.next()?)?;
|
||||
let len = num(it.next()?)?;
|
||||
let flags = num(it.next()?)?;
|
||||
let complete = num(it.next()?)?;
|
||||
Some(CapturedAu {
|
||||
offset: offset as usize,
|
||||
len: len as usize,
|
||||
_flags: flags as u32,
|
||||
complete: complete != 0,
|
||||
})
|
||||
}
|
||||
|
||||
/// The capture named by `PF_CORPUS`, or `None` when the variable is unset.
|
||||
fn corpus_from_env() -> Option<(PathBuf, Vec<u8>, Vec<CapturedAu>)> {
|
||||
let path = PathBuf::from(std::env::var_os("PF_CORPUS")?);
|
||||
let data = std::fs::read(&path)
|
||||
.unwrap_or_else(|e| panic!("cannot read the capture {}: {e}", path.display()));
|
||||
let mut idx = path.clone().into_os_string();
|
||||
idx.push(".idx");
|
||||
let mut index = read_index(Path::new(&idx));
|
||||
// Same truncation story on the data side: the final AU's bytes may not all have
|
||||
// reached the file before the client died. Drop AUs the data cannot cover — but
|
||||
// only from the tail, so a short file can never silently hide a middle gap.
|
||||
let covered = index
|
||||
.iter()
|
||||
.take_while(|au| au.offset.saturating_add(au.len) <= data.len())
|
||||
.count();
|
||||
if covered < index.len() {
|
||||
println!(
|
||||
"note: dropping {} index entr{} past the end of the data file (truncated capture)",
|
||||
index.len() - covered,
|
||||
if index.len() - covered == 1 {
|
||||
"y"
|
||||
} else {
|
||||
"ies"
|
||||
},
|
||||
);
|
||||
index.truncate(covered);
|
||||
}
|
||||
assert!(!index.is_empty(), "the capture's index is empty");
|
||||
Some((path, data, index))
|
||||
}
|
||||
|
||||
/// Per-AU outcome tally — what the run reports and asserts on.
|
||||
#[derive(Default)]
|
||||
struct Tally {
|
||||
planned: usize,
|
||||
skipped: usize,
|
||||
errors: Vec<String>,
|
||||
warnings: Vec<String>,
|
||||
partial: usize,
|
||||
}
|
||||
|
||||
impl Tally {
|
||||
/// A clean capture of a healthy session must plan every complete AU. Errors are
|
||||
/// hard failures; warnings are printed and capped — `MissingReference` on a stream
|
||||
/// that never lost a packet would mean the planner invented a gap.
|
||||
fn assert_clean(&self, total: usize) {
|
||||
println!(
|
||||
"planned {} / skipped {} / partial-AUs-ignored {} / errors {} / warnings {} \
|
||||
(of {total} captured AUs)",
|
||||
self.planned,
|
||||
self.skipped,
|
||||
self.partial,
|
||||
self.errors.len(),
|
||||
self.warnings.len(),
|
||||
);
|
||||
for w in self.warnings.iter().take(20) {
|
||||
println!(" warning: {w}");
|
||||
}
|
||||
for e in self.errors.iter().take(20) {
|
||||
println!(" ERROR: {e}");
|
||||
}
|
||||
assert!(
|
||||
self.errors.is_empty(),
|
||||
"{} AUs failed to plan — first: {}",
|
||||
self.errors.len(),
|
||||
self.errors[0],
|
||||
);
|
||||
assert!(
|
||||
self.warnings.is_empty(),
|
||||
"{} planner warnings on a clean capture — first: {}",
|
||||
self.warnings.len(),
|
||||
self.warnings[0],
|
||||
);
|
||||
assert!(self.planned > 0, "no AU planned at all");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "needs a capture: PF_CORPUS=<au-file> (see the module docs)"]
|
||||
fn a_captured_host_stream_replays_through_the_planner() {
|
||||
let Some((path, data, index)) = corpus_from_env() else {
|
||||
panic!("PF_CORPUS is unset — see the module docs for the invocation");
|
||||
};
|
||||
let ext = path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.unwrap_or_default()
|
||||
.to_owned();
|
||||
println!(
|
||||
"replaying {} ({} bytes, {} AUs, codec {ext})",
|
||||
path.display(),
|
||||
data.len(),
|
||||
index.len(),
|
||||
);
|
||||
|
||||
let mut tally = Tally::default();
|
||||
// The planners take one COMPLETE AU. A partial AU (the wire's shard split) is the
|
||||
// pump's business, not the planner's — count and skip rather than feed a fragment.
|
||||
let complete: Vec<&CapturedAu> = index.iter().filter(|au| au.complete).collect();
|
||||
tally.partial = index.len() - complete.len();
|
||||
|
||||
match ext.as_str() {
|
||||
"h265" => {
|
||||
let mut planner = pf_bitstream::h265::H265Planner::new();
|
||||
for (i, au) in complete.iter().enumerate() {
|
||||
let bytes = &data[au.offset..au.offset + au.len];
|
||||
match planner.plan_au(bytes) {
|
||||
Ok(plan) => {
|
||||
tally.planned += 1;
|
||||
for w in &plan.warnings {
|
||||
tally.warnings.push(format!("AU {i}: {w:?}"));
|
||||
}
|
||||
}
|
||||
// The spec's own skip (8.1.3): decode nothing, show nothing, the
|
||||
// stream is healthy — never an error (the WP-2 contract note).
|
||||
Err(pf_bitstream::h265::PlanError::RaslSkipped { .. }) => tally.skipped += 1,
|
||||
Err(e) => tally.errors.push(format!("AU {i}: {e}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
"h264" => {
|
||||
let mut planner = pf_bitstream::h264::H264Planner::new();
|
||||
for (i, au) in complete.iter().enumerate() {
|
||||
let bytes = &data[au.offset..au.offset + au.len];
|
||||
match planner.plan_au(bytes) {
|
||||
Ok(plan) => {
|
||||
tally.planned += 1;
|
||||
for w in &plan.warnings {
|
||||
tally.warnings.push(format!("AU {i}: {w:?}"));
|
||||
}
|
||||
}
|
||||
Err(e) => tally.errors.push(format!("AU {i}: {e}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
other => panic!("no planner for a .{other} capture (h264/h265 only today)"),
|
||||
}
|
||||
|
||||
tally.assert_clean(index.len());
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Vendored snapshot — see PROVENANCE.md. Deliberately NOT opted into workspace lints
|
||||
# or workspace package inheritance: upstream code stays as close to pristine as the
|
||||
# trim allows, so re-syncing against the AOSP tree stays a diff, not an archaeology dig.
|
||||
[package]
|
||||
name = "cros-codecs"
|
||||
version = "0.0.5"
|
||||
license = "BSD-3-Clause"
|
||||
description = "Vendored cros-codecs parser layer (codec module only) for pf-bitstream"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
|
||||
# Upstream's in-tree unit tests (kept — they are the conformance goldens) want these.
|
||||
[dev-dependencies]
|
||||
env_logger = "0.11"
|
||||
serde_json = "1"
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
Copyright 2022 The ChromiumOS Authors
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Vendored: cros-codecs (parser layer only)
|
||||
|
||||
- **Upstream:** <https://android.googlesource.com/platform/system/cros-codecs/> (the
|
||||
authoritative AOSP tree). Snapshot taken from the read-only GitHub mirror
|
||||
<https://github.com/chromeos/cros-codecs>, branch `main`,
|
||||
commit **`5ff6d693ffae0b36935b8fc13092c733b4c2646f`**, fetched 2026-08-05.
|
||||
- **License:** BSD-3-Clause (`LICENSE`, copied verbatim). Attribution headers retained
|
||||
in every source file.
|
||||
- **Why vendored, not a crates.io dependency:** the GitHub repo is a read-only mirror
|
||||
and the crates.io release lags it; a pinned, reviewed snapshot is the supply-chain
|
||||
posture punktfunk already uses elsewhere (`clients/android/native/vendor/ndk`,
|
||||
`punktfunk-host/vendor/usbip-sim`). Decision of record:
|
||||
punktfunk-planning `design/client-native-decode.md` §8.1.
|
||||
|
||||
## What was taken
|
||||
|
||||
`src/codec/{h264,h265,av1,vp9}` (parsers, DPBs, picture types, NALU/OBU machinery,
|
||||
their `test_data` vectors — they double as punktfunk's conformance corpus),
|
||||
`src/bitstream_utils.rs`, `LICENSE`. Upstream designed the `codec` module for exactly
|
||||
this extraction — its module doc: "There shall be no dependencies from other modules of
|
||||
this crate to this module, so that it can be turned into a crate of its own if needed
|
||||
in the future."
|
||||
|
||||
## What was left behind
|
||||
|
||||
- `decoder/`, `encoder/`, `backend/`, `c2_wrapper/`, `video_frame`, `image_processing`,
|
||||
`utils` — the Linux-only halves (libva/v4l2/gbm/nix). punktfunk's `pf-bitstream` +
|
||||
`pf-vkdecode` occupy that layer.
|
||||
- `codec/vp8` — VP9 has no dependency on it (verified) and no punktfunk host will ever
|
||||
emit VP8.
|
||||
|
||||
## Deviations from pristine upstream
|
||||
|
||||
1. `src/lib.rs` — rewritten: keeps only the module decls and `Resolution` /
|
||||
`ResolutionRoundMode` (the sole root items `codec` references), both copied verbatim;
|
||||
adds crate-level `#![allow(clippy::all, mismatched_lifetime_syntaxes)]` — vendored
|
||||
code is not held to the workspace lint bar (CI's `-D warnings` legs would fail on
|
||||
upstream style otherwise).
|
||||
2. `src/codec.rs` — one line removed (`pub mod vp8;`).
|
||||
3. `Cargo.toml` — rewritten: `log` is the only dependency the vendored subset needs,
|
||||
plus `env_logger`/`serde_json` dev-dependencies for upstream's in-tree tests.
|
||||
4. `cargo fmt` normalization under the workspace's rustfmt config (mechanical only).
|
||||
5. **Zero-unsafe, enforced**: `#![forbid(unsafe_code)]` added to lib.rs. Upstream's codec
|
||||
module had exactly one production `unsafe` (h264/dpb.rs `build_ref_pic_lists`: ref→index
|
||||
via pointer `offset_from`) — replaced with a safe `position(ptr::eq)` over the ≤16-entry
|
||||
DPB — and three test-only `mem::zeroed()` asserts, replaced with `Default::default()`
|
||||
(`PredWeightTable` derives `Default`; all-integer struct, identical value). The layer
|
||||
facing untrusted bytes is now compiler-verified free of unsafe — the property that
|
||||
motivates replacing libavcodec's C parsers in the first place.
|
||||
6. `src/codec/h264/picture.rs` — `PictureData::new_from_slice`: `display_resolution`
|
||||
computed as `visible_rect.max` instead of `max - min`. `Sps::visible_rectangle()`
|
||||
returns the crop offset in `min` and the visible *size* in `max` (see its
|
||||
definition: `max.x = width - crop_left - crop_right`); upstream's subtraction
|
||||
double-counts the left/top crop and, worse, panics on u32 underflow for a
|
||||
large-but-parser-valid `frame_crop_left_offset` (e.g. 100 crop units on a 320-wide
|
||||
SPS). Found by pf-bitstream's conformance-window tests; upstream never hits it
|
||||
because real encoders crop right/bottom only. **Reported upstream 2026-08-06:
|
||||
<https://github.com/chromeos/cros-codecs/issues/99>.**
|
||||
|
||||
7. `src/codec/h265/parser.rs` — `parse_slice_header`: reject
|
||||
`num_long_term_sps + num_long_term_pics > 16` before the long-term RPS loop.
|
||||
Upstream bounds the pair only by `MAX_LONG_TERM_REF_PIC_SETS` (32) combined, while
|
||||
every long-term array in `SliceHeader` (`poc_lsb_lt`, `used_by_curr_pic_lt`,
|
||||
`delta_poc_msb_present_flag`, `delta_poc_msb_cycle_lt`, `lt_idx_sps`) is `[_; 16]`
|
||||
— a hostile slice header with 17+ entries panics the parser with an
|
||||
index-out-of-bounds (bounds checks stay on in release). Found by pf-bitstream's
|
||||
H.265 planner review; regression-tested there
|
||||
(`a_hostile_long_term_count_is_a_parse_error_not_a_panic`). **Reported upstream
|
||||
2026-08-06: <https://github.com/chromeos/cros-codecs/issues/100>.**
|
||||
|
||||
Re-sync procedure: fetch the AOSP tree, re-apply this trim, diff `codec/` +
|
||||
`bitstream_utils.rs` (expect near-zero conflicts), update the commit pin above.
|
||||
@@ -0,0 +1,788 @@
|
||||
// Copyright 2024 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::io::Cursor;
|
||||
use std::io::Read;
|
||||
use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
use std::io::Write;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::codec::h264::parser::Nalu as H264Nalu;
|
||||
use crate::codec::h265::parser::Nalu as H265Nalu;
|
||||
|
||||
/// A bit reader for codec bitstreams. It properly handles emulation-prevention
|
||||
/// bytes and stop bits for H264.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct BitReader<'a> {
|
||||
/// A reference into the next unread byte in the stream.
|
||||
data: Cursor<&'a [u8]>,
|
||||
/// Contents of the current byte. First unread bit starting at position 8 -
|
||||
/// num_remaining_bits_in_curr_bytes.
|
||||
curr_byte: u8,
|
||||
/// Number of bits remaining in `curr_byte`
|
||||
num_remaining_bits_in_curr_byte: usize,
|
||||
/// Used in emulation prevention byte detection.
|
||||
prev_two_bytes: u16,
|
||||
/// Number of emulation prevention bytes (i.e. 0x000003) we found.
|
||||
num_epb: usize,
|
||||
/// Whether or not we need emulation prevention logic.
|
||||
needs_epb: bool,
|
||||
/// How many bits have been read so far.
|
||||
position: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum GetByteError {
|
||||
OutOfBits,
|
||||
}
|
||||
|
||||
impl fmt::Display for GetByteError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "reader ran out of bits")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ReadBitsError {
|
||||
TooManyBitsRequested(usize),
|
||||
GetByte(GetByteError),
|
||||
ConversionFailed,
|
||||
}
|
||||
|
||||
impl fmt::Display for ReadBitsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ReadBitsError::TooManyBitsRequested(bits) => {
|
||||
write!(f, "more than 31 ({}) bits were requested", bits)
|
||||
}
|
||||
ReadBitsError::GetByte(_) => write!(f, "failed to advance the current byte"),
|
||||
ReadBitsError::ConversionFailed => {
|
||||
write!(f, "failed to convert read input to target type")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GetByteError> for ReadBitsError {
|
||||
fn from(err: GetByteError) -> Self {
|
||||
ReadBitsError::GetByte(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BitReader<'a> {
|
||||
pub fn new(data: &'a [u8], needs_epb: bool) -> Self {
|
||||
Self {
|
||||
data: Cursor::new(data),
|
||||
curr_byte: Default::default(),
|
||||
num_remaining_bits_in_curr_byte: Default::default(),
|
||||
prev_two_bytes: 0xffff,
|
||||
num_epb: Default::default(),
|
||||
needs_epb: needs_epb,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Read a single bit from the stream.
|
||||
pub fn read_bit(&mut self) -> Result<bool, String> {
|
||||
let bit = self.read_bits::<u32>(1)?;
|
||||
match bit {
|
||||
1 => Ok(true),
|
||||
0 => Ok(false),
|
||||
_ => panic!("Unexpected value {}", bit),
|
||||
}
|
||||
}
|
||||
|
||||
/// Read up to 31 bits from the stream. Note that we don't want to read 32
|
||||
/// bits even though we're returning a u32 because that would break the
|
||||
/// read_bits_signed() function. 31 bits should be overkill for compressed
|
||||
/// header parsing anyway.
|
||||
pub fn read_bits<U: TryFrom<u32>>(&mut self, num_bits: usize) -> Result<U, String> {
|
||||
if num_bits > 31 {
|
||||
return Err(ReadBitsError::TooManyBitsRequested(num_bits).to_string());
|
||||
}
|
||||
|
||||
let mut bits_left = num_bits;
|
||||
let mut out = 0u32;
|
||||
|
||||
while self.num_remaining_bits_in_curr_byte < bits_left {
|
||||
out |= (self.curr_byte as u32) << (bits_left - self.num_remaining_bits_in_curr_byte);
|
||||
bits_left -= self.num_remaining_bits_in_curr_byte;
|
||||
self.move_to_next_byte().map_err(|err| err.to_string())?;
|
||||
}
|
||||
|
||||
out |= (self.curr_byte >> (self.num_remaining_bits_in_curr_byte - bits_left)) as u32;
|
||||
out &= (1 << num_bits) - 1;
|
||||
self.num_remaining_bits_in_curr_byte -= bits_left;
|
||||
self.position += num_bits as u64;
|
||||
|
||||
U::try_from(out).map_err(|_| ReadBitsError::ConversionFailed.to_string())
|
||||
}
|
||||
|
||||
/// Reads a two's complement signed integer of length |num_bits|.
|
||||
pub fn read_bits_signed<U: TryFrom<i32>>(&mut self, num_bits: usize) -> Result<U, String> {
|
||||
let mut out: i32 = self
|
||||
.read_bits::<u32>(num_bits)?
|
||||
.try_into()
|
||||
.map_err(|_| ReadBitsError::ConversionFailed.to_string())?;
|
||||
if out >> (num_bits - 1) != 0 {
|
||||
out |= -1i32 ^ ((1 << num_bits) - 1);
|
||||
}
|
||||
|
||||
U::try_from(out).map_err(|_| ReadBitsError::ConversionFailed.to_string())
|
||||
}
|
||||
|
||||
/// Reads an unsigned integer from the stream and checks if the stream is byte aligned.
|
||||
pub fn read_bits_aligned<U: TryFrom<u32>>(&mut self, num_bits: usize) -> Result<U, String> {
|
||||
if self.num_remaining_bits_in_curr_byte % 8 != 0 {
|
||||
return Err("Attempted unaligned read_le()".into());
|
||||
}
|
||||
|
||||
Ok(self.read_bits(num_bits).map_err(|err| err.to_string())?)
|
||||
}
|
||||
|
||||
/// Skip `num_bits` bits from the stream.
|
||||
pub fn skip_bits(&mut self, mut num_bits: usize) -> Result<(), String> {
|
||||
while num_bits > 0 {
|
||||
let n = std::cmp::min(num_bits, 31);
|
||||
self.read_bits::<u32>(n)?;
|
||||
num_bits -= n;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the amount of bits left in the stream
|
||||
pub fn num_bits_left(&mut self) -> usize {
|
||||
let cur_pos = self.data.position();
|
||||
// This should always be safe to unwrap.
|
||||
let end_pos = self.data.seek(SeekFrom::End(0)).unwrap();
|
||||
let _ = self.data.seek(SeekFrom::Start(cur_pos));
|
||||
((end_pos - cur_pos) as usize) * 8 + self.num_remaining_bits_in_curr_byte
|
||||
}
|
||||
|
||||
/// Returns the number of emulation-prevention bytes read so far.
|
||||
pub fn num_epb(&self) -> usize {
|
||||
self.num_epb
|
||||
}
|
||||
|
||||
/// Whether the stream still has RBSP data. Implements more_rbsp_data(). See
|
||||
/// the spec for more details.
|
||||
pub fn has_more_rsbp_data(&mut self) -> bool {
|
||||
if self.num_remaining_bits_in_curr_byte == 0 && self.move_to_next_byte().is_err() {
|
||||
// no more data at all in the rbsp
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the next bit is the stop bit, then we should only see unset bits
|
||||
// until the end of the data.
|
||||
if (self.curr_byte & ((1 << (self.num_remaining_bits_in_curr_byte - 1)) - 1)) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut buf = [0u8; 1];
|
||||
let orig_pos = self.data.position();
|
||||
while let Ok(_) = self.data.read_exact(&mut buf) {
|
||||
if buf[0] != 0 {
|
||||
self.data.set_position(orig_pos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Reads an Unsigned Exponential golomb coding number from the next bytes in the
|
||||
/// bitstream. This may advance the state of position within the bitstream even if the
|
||||
/// read operation is unsuccessful. See H264 Annex B specification 9.1 for details.
|
||||
pub fn read_ue<U: TryFrom<u32>>(&mut self) -> Result<U, String> {
|
||||
let mut num_bits = 0;
|
||||
|
||||
while self.read_bits::<u32>(1)? == 0 {
|
||||
num_bits += 1;
|
||||
if num_bits > 31 {
|
||||
return Err("invalid stream".into());
|
||||
}
|
||||
}
|
||||
|
||||
let value = ((1u32 << num_bits) - 1)
|
||||
.checked_add(self.read_bits::<u32>(num_bits)?)
|
||||
.ok_or::<String>("read number cannot fit in 32 bits".into())?;
|
||||
|
||||
U::try_from(value).map_err(|_| "conversion error".into())
|
||||
}
|
||||
|
||||
pub fn read_ue_bounded<U: TryFrom<u32>>(&mut self, min: u32, max: u32) -> Result<U, String> {
|
||||
let ue = self.read_ue()?;
|
||||
if ue > max || ue < min {
|
||||
Err(format!(
|
||||
"Value out of bounds: expected {} - {}, got {}",
|
||||
min, max, ue
|
||||
))
|
||||
} else {
|
||||
Ok(U::try_from(ue).map_err(|_| String::from("Conversion error"))?)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_ue_max<U: TryFrom<u32>>(&mut self, max: u32) -> Result<U, String> {
|
||||
self.read_ue_bounded(0, max)
|
||||
}
|
||||
|
||||
/// Reads a signed exponential golomb coding number. Instead of using two's
|
||||
/// complement, this scheme maps even integers to positive numbers and odd
|
||||
/// integers to negative numbers. The least significant bit indicates the
|
||||
/// sign. See H264 Annex B specification 9.1.1 for details.
|
||||
pub fn read_se<U: TryFrom<i32>>(&mut self) -> Result<U, String> {
|
||||
let ue = self.read_ue::<u32>()? as i32;
|
||||
|
||||
if ue % 2 == 0 {
|
||||
Ok(U::try_from(-(ue / 2)).map_err(|_| String::from("Conversion error"))?)
|
||||
} else {
|
||||
Ok(U::try_from(ue / 2 + 1).map_err(|_| String::from("Conversion error"))?)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_se_bounded<U: TryFrom<i32>>(&mut self, min: i32, max: i32) -> Result<U, String> {
|
||||
let se = self.read_se()?;
|
||||
if se < min || se > max {
|
||||
Err(format!(
|
||||
"Value out of bounds, expected between {}-{}, got {}",
|
||||
min, max, se
|
||||
))
|
||||
} else {
|
||||
Ok(U::try_from(se).map_err(|_| String::from("Conversion error"))?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Read little endian multi-byte integer.
|
||||
pub fn read_le<U: TryFrom<u32>>(&mut self, num_bits: u8) -> Result<U, String> {
|
||||
let mut t = 0;
|
||||
|
||||
for i in 0..num_bits {
|
||||
let byte = self.read_bits_aligned::<u32>(8)?;
|
||||
t += byte << (i * 8)
|
||||
}
|
||||
|
||||
Ok(U::try_from(t).map_err(|_| String::from("Conversion error"))?)
|
||||
}
|
||||
|
||||
/// Return the position of this bitstream in bits.
|
||||
pub fn position(&self) -> u64 {
|
||||
self.position
|
||||
}
|
||||
|
||||
fn get_byte(&mut self) -> Result<u8, GetByteError> {
|
||||
let mut buf = [0u8; 1];
|
||||
self.data
|
||||
.read_exact(&mut buf)
|
||||
.map_err(|_| GetByteError::OutOfBits)?;
|
||||
Ok(buf[0])
|
||||
}
|
||||
|
||||
fn move_to_next_byte(&mut self) -> Result<(), GetByteError> {
|
||||
let mut byte = self.get_byte()?;
|
||||
|
||||
if self.needs_epb {
|
||||
if self.prev_two_bytes == 0 && byte == 0x03 {
|
||||
// We found an epb
|
||||
self.num_epb += 1;
|
||||
// Read another byte
|
||||
byte = self.get_byte()?;
|
||||
// We need another 3 bytes before another epb can happen.
|
||||
self.prev_two_bytes = 0xffff;
|
||||
}
|
||||
self.prev_two_bytes = (self.prev_two_bytes << 8) | u16::from(byte);
|
||||
}
|
||||
|
||||
self.num_remaining_bits_in_curr_byte = 8;
|
||||
self.curr_byte = byte;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over IVF packets.
|
||||
pub struct IvfIterator<'a> {
|
||||
cursor: Cursor<&'a [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> IvfIterator<'a> {
|
||||
pub fn new(data: &'a [u8]) -> Self {
|
||||
let mut cursor = Cursor::new(data);
|
||||
|
||||
// Skip the IVH header entirely.
|
||||
cursor.seek(std::io::SeekFrom::Start(32)).unwrap();
|
||||
|
||||
Self { cursor }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for IvfIterator<'a> {
|
||||
type Item = &'a [u8];
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Make sure we have a header.
|
||||
let mut len_buf = [0u8; 4];
|
||||
self.cursor.read_exact(&mut len_buf).ok()?;
|
||||
let len = ((len_buf[3] as usize) << 24)
|
||||
| ((len_buf[2] as usize) << 16)
|
||||
| ((len_buf[1] as usize) << 8)
|
||||
| (len_buf[0] as usize);
|
||||
|
||||
// Skip PTS.
|
||||
self.cursor.seek(std::io::SeekFrom::Current(8)).ok()?;
|
||||
|
||||
let start = self.cursor.position() as usize;
|
||||
let _ = self
|
||||
.cursor
|
||||
.seek(std::io::SeekFrom::Current(len as i64))
|
||||
.ok()?;
|
||||
let end = self.cursor.position() as usize;
|
||||
|
||||
Some(&self.cursor.get_ref()[start..end])
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper struct for synthesizing IVF file header
|
||||
pub struct IvfFileHeader {
|
||||
pub magic: [u8; 4],
|
||||
pub version: u16,
|
||||
pub header_size: u16,
|
||||
pub codec: [u8; 4],
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub framerate: u32,
|
||||
pub timescale: u32,
|
||||
pub frame_count: u32,
|
||||
pub unused: u32,
|
||||
}
|
||||
|
||||
impl Default for IvfFileHeader {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
magic: Self::MAGIC,
|
||||
version: 0,
|
||||
header_size: 32,
|
||||
codec: Self::CODEC_VP9,
|
||||
width: 320,
|
||||
height: 240,
|
||||
framerate: 1,
|
||||
timescale: 1000,
|
||||
frame_count: 1,
|
||||
unused: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IvfFileHeader {
|
||||
pub const MAGIC: [u8; 4] = *b"DKIF";
|
||||
pub const CODEC_VP8: [u8; 4] = *b"VP80";
|
||||
pub const CODEC_VP9: [u8; 4] = *b"VP90";
|
||||
pub const CODEC_AV1: [u8; 4] = *b"AV01";
|
||||
|
||||
pub fn new(codec: [u8; 4], width: u16, height: u16, framerate: u32, frame_count: u32) -> Self {
|
||||
let default = Self::default();
|
||||
|
||||
Self {
|
||||
codec,
|
||||
width,
|
||||
height,
|
||||
framerate: framerate * default.timescale,
|
||||
frame_count,
|
||||
..default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IvfFileHeader {
|
||||
/// Writes header into writer
|
||||
pub fn writo_into(&self, writer: &mut impl std::io::Write) -> std::io::Result<()> {
|
||||
writer.write_all(&self.magic)?;
|
||||
writer.write_all(&self.version.to_le_bytes())?;
|
||||
writer.write_all(&self.header_size.to_le_bytes())?;
|
||||
writer.write_all(&self.codec)?;
|
||||
writer.write_all(&self.width.to_le_bytes())?;
|
||||
writer.write_all(&self.height.to_le_bytes())?;
|
||||
writer.write_all(&self.framerate.to_le_bytes())?;
|
||||
writer.write_all(&self.timescale.to_le_bytes())?;
|
||||
writer.write_all(&self.frame_count.to_le_bytes())?;
|
||||
writer.write_all(&self.unused.to_le_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper struct for synthesizing IVF frame header
|
||||
pub struct IvfFrameHeader {
|
||||
pub frame_size: u32,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
impl IvfFrameHeader {
|
||||
/// Writes header into writer
|
||||
pub fn writo_into(&self, writer: &mut impl std::io::Write) -> std::io::Result<()> {
|
||||
writer.write_all(&self.frame_size.to_le_bytes())?;
|
||||
writer.write_all(&self.timestamp.to_le_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator NALUs in a bitstream.
|
||||
pub struct NalIterator<'a, Nalu>(Cursor<&'a [u8]>, PhantomData<Nalu>);
|
||||
|
||||
impl<'a, Nalu> NalIterator<'a, Nalu> {
|
||||
pub fn new(stream: &'a [u8]) -> Self {
|
||||
Self(Cursor::new(stream), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for NalIterator<'a, H264Nalu<'a>> {
|
||||
type Item = Cow<'a, [u8]>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
H264Nalu::next(&mut self.0).map(|n| n.data).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for NalIterator<'a, H265Nalu<'a>> {
|
||||
type Item = Cow<'a, [u8]>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
H265Nalu::next(&mut self.0).map(|n| n.data).ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BitWriterError {
|
||||
InvalidBitCount,
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for BitWriterError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
BitWriterError::InvalidBitCount => write!(f, "invalid bit count"),
|
||||
BitWriterError::Io(x) => write!(f, "{}", x.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for BitWriterError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
BitWriterError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub type BitWriterResult<T> = std::result::Result<T, BitWriterError>;
|
||||
|
||||
pub struct BitWriter<W: Write> {
|
||||
out: W,
|
||||
nth_bit: u8,
|
||||
curr_byte: u8,
|
||||
}
|
||||
|
||||
impl<W: Write> BitWriter<W> {
|
||||
pub fn new(writer: W) -> Self {
|
||||
Self {
|
||||
out: writer,
|
||||
curr_byte: 0,
|
||||
nth_bit: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes fixed bit size integer (up to 32 bit)
|
||||
pub fn write_f<T: Into<u32>>(&mut self, bits: usize, value: T) -> BitWriterResult<usize> {
|
||||
let value = value.into();
|
||||
|
||||
if bits > 32 {
|
||||
return Err(BitWriterError::InvalidBitCount);
|
||||
}
|
||||
|
||||
let mut written = 0;
|
||||
for bit in (0..bits).rev() {
|
||||
let bit = (1 << bit) as u32;
|
||||
|
||||
self.write_bit((value & bit) == bit)?;
|
||||
written += 1;
|
||||
}
|
||||
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
/// Takes a single bit that will be outputed to [`std::io::Write`]
|
||||
pub fn write_bit(&mut self, bit: bool) -> BitWriterResult<()> {
|
||||
self.curr_byte |= (bit as u8) << (7u8 - self.nth_bit);
|
||||
self.nth_bit += 1;
|
||||
|
||||
if self.nth_bit == 8 {
|
||||
self.out.write_all(&[self.curr_byte])?;
|
||||
self.nth_bit = 0;
|
||||
self.curr_byte = 0;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Immediately outputs any cached bits to [`std::io::Write`]
|
||||
pub fn flush(&mut self) -> BitWriterResult<()> {
|
||||
if self.nth_bit != 0 {
|
||||
self.out.write_all(&[self.curr_byte])?;
|
||||
self.nth_bit = 0;
|
||||
self.curr_byte = 0;
|
||||
}
|
||||
|
||||
self.out.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns `true` if ['Self`] hold data that wasn't written to [`std::io::Write`]
|
||||
pub fn has_data_pending(&self) -> bool {
|
||||
self.nth_bit != 0
|
||||
}
|
||||
|
||||
pub(crate) fn inner(&self) -> &W {
|
||||
&self.out
|
||||
}
|
||||
|
||||
pub(crate) fn inner_mut(&mut self) -> &mut W {
|
||||
&mut self.out
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> Drop for BitWriter<W> {
|
||||
fn drop(&mut self) {
|
||||
if let Err(e) = self.flush() {
|
||||
log::error!("Unable to flush bits {e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ivf_file_header() {
|
||||
let mut hdr = IvfFileHeader {
|
||||
version: 0,
|
||||
codec: IvfFileHeader::CODEC_VP9,
|
||||
width: 256,
|
||||
height: 256,
|
||||
framerate: 30_000,
|
||||
timescale: 1_000,
|
||||
frame_count: 1,
|
||||
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut buf = Vec::new();
|
||||
hdr.writo_into(&mut buf).unwrap();
|
||||
|
||||
const EXPECTED: [u8; 32] = [
|
||||
0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x39, 0x30, 0x00, 0x01,
|
||||
0x00, 0x01, 0x30, 0x75, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
assert_eq!(&buf, &EXPECTED);
|
||||
|
||||
hdr.width = 1920;
|
||||
hdr.height = 800;
|
||||
hdr.framerate = 24;
|
||||
hdr.timescale = 1;
|
||||
hdr.frame_count = 100;
|
||||
|
||||
buf.clear();
|
||||
hdr.writo_into(&mut buf).unwrap();
|
||||
|
||||
const EXPECTED2: [u8; 32] = [
|
||||
0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x39, 0x30, 0x80, 0x07,
|
||||
0x20, 0x03, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
assert_eq!(&buf, &EXPECTED2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ivf_frame_header() {
|
||||
let mut hdr = IvfFrameHeader {
|
||||
frame_size: 199249,
|
||||
timestamp: 0,
|
||||
};
|
||||
|
||||
let mut buf = Vec::new();
|
||||
hdr.writo_into(&mut buf).unwrap();
|
||||
|
||||
const EXPECTED: [u8; 12] = [
|
||||
0x51, 0x0a, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
assert_eq!(&buf, &EXPECTED);
|
||||
|
||||
hdr.timestamp = 1;
|
||||
hdr.frame_size = 52;
|
||||
|
||||
buf.clear();
|
||||
hdr.writo_into(&mut buf).unwrap();
|
||||
|
||||
const EXPECTED2: [u8; 12] = [
|
||||
0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
assert_eq!(&buf, &EXPECTED2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwriter_f1() {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = BitWriter::new(&mut buf);
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
}
|
||||
assert_eq!(buf, vec![0b10001111u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwriter_f3() {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = BitWriter::new(&mut buf);
|
||||
writer.write_f(3, 0b100u8).unwrap();
|
||||
writer.write_f(3, 0b101u8).unwrap();
|
||||
writer.write_f(3, 0b011u8).unwrap();
|
||||
}
|
||||
assert_eq!(buf, vec![0b10010101u8, 0b10000000u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwriter_f4() {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = BitWriter::new(&mut buf);
|
||||
writer.write_f(4, 0b1000u8).unwrap();
|
||||
writer.write_f(4, 0b1011u8).unwrap();
|
||||
}
|
||||
assert_eq!(buf, vec![0b10001011u8]);
|
||||
}
|
||||
|
||||
// These tests are adapted from the chromium tests at media/video/h264_bit_reader_unitttest.cc
|
||||
|
||||
#[test]
|
||||
fn read_stream_without_escape_and_trailing_zero_bytes() {
|
||||
const RBSP: [u8; 6] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xa0];
|
||||
|
||||
let mut reader = BitReader::new(&RBSP, true);
|
||||
assert_eq!(reader.read_bits::<u32>(1).unwrap(), 0);
|
||||
assert_eq!(reader.num_bits_left(), 47);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x02);
|
||||
assert_eq!(reader.num_bits_left(), 39);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
|
||||
assert_eq!(reader.read_bits::<u32>(31).unwrap(), 0x23456789);
|
||||
assert_eq!(reader.num_bits_left(), 8);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
|
||||
assert_eq!(reader.read_bits::<u32>(1).unwrap(), 1);
|
||||
assert_eq!(reader.num_bits_left(), 7);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
|
||||
assert_eq!(reader.read_bits::<u32>(1).unwrap(), 0);
|
||||
assert_eq!(reader.num_bits_left(), 6);
|
||||
assert!(!reader.has_more_rsbp_data());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_byte_stream() {
|
||||
const RBSP: [u8; 1] = [0x18];
|
||||
|
||||
let mut reader = BitReader::new(&RBSP, true);
|
||||
assert_eq!(reader.num_bits_left(), 8);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
assert_eq!(reader.read_bits::<u32>(4).unwrap(), 1);
|
||||
assert!(!reader.has_more_rsbp_data());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_bit_occupy_full_byte() {
|
||||
const RBSP: [u8; 2] = [0xab, 0x80];
|
||||
|
||||
let mut reader = BitReader::new(&RBSP, true);
|
||||
assert_eq!(reader.num_bits_left(), 16);
|
||||
assert!(reader.has_more_rsbp_data());
|
||||
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0xab);
|
||||
assert_eq!(reader.num_bits_left(), 8);
|
||||
|
||||
assert!(!reader.has_more_rsbp_data());
|
||||
}
|
||||
|
||||
// Check that read_ue behaves properly with input at the limits.
|
||||
#[test]
|
||||
fn read_ue() {
|
||||
// Regular value.
|
||||
let mut reader = BitReader::new(&[0b0001_1010], true);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 12);
|
||||
assert_eq!(reader.data.position(), 1);
|
||||
assert_eq!(reader.num_remaining_bits_in_curr_byte, 1);
|
||||
|
||||
// 0 value.
|
||||
let mut reader = BitReader::new(&[0b1000_0000], true);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 0);
|
||||
assert_eq!(reader.data.position(), 1);
|
||||
assert_eq!(reader.num_remaining_bits_in_curr_byte, 7);
|
||||
|
||||
// No prefix stop bit.
|
||||
let mut reader = BitReader::new(&[0b0000_0000], true);
|
||||
reader.read_ue::<u32>().unwrap_err();
|
||||
|
||||
// u32 max value: 31 0-bits, 1 bit marker, 31 bits 1-bits.
|
||||
let mut reader = BitReader::new(
|
||||
&[
|
||||
0b0000_0000,
|
||||
0b0000_0000,
|
||||
0b0000_0000,
|
||||
0b0000_0001,
|
||||
0b1111_1111,
|
||||
0b1111_1111,
|
||||
0b1111_1111,
|
||||
0b1111_1110,
|
||||
],
|
||||
true,
|
||||
);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 0xffff_fffe);
|
||||
assert_eq!(reader.data.position(), 8);
|
||||
assert_eq!(reader.num_remaining_bits_in_curr_byte, 1);
|
||||
}
|
||||
|
||||
// Check that emulation prevention is being handled correctly.
|
||||
#[test]
|
||||
fn skip_epb_when_enabled() {
|
||||
let mut reader = BitReader::new(&[0x00, 0x00, 0x03, 0x01], false);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x00);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x00);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x03);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x01);
|
||||
|
||||
let mut reader = BitReader::new(&[0x00, 0x00, 0x03, 0x01], true);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x00);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x00);
|
||||
assert_eq!(reader.read_bits::<u32>(8).unwrap(), 0x01);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_signed_bits() {
|
||||
let mut reader = BitReader::new(&[0b1111_0000], false);
|
||||
assert_eq!(reader.read_bits_signed::<i32>(4).unwrap(), -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
//! Parsers for various kinds of encoded streams.
|
||||
//!
|
||||
//! This module does not provide any actual decoding tools - that's the job of the
|
||||
//! [crate::decoder] module. However the parsers of this module are heavily used in order to
|
||||
//! implement stateless decoding.
|
||||
//!
|
||||
//! There shall be no dependencies from other modules of this crate to this module, so that it
|
||||
//! can be turned into a crate of its own if needed in the future.
|
||||
|
||||
pub mod av1;
|
||||
pub mod h264;
|
||||
pub mod h265;
|
||||
pub mod vp9;
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
mod helpers;
|
||||
pub mod parser;
|
||||
pub mod reader;
|
||||
pub mod synthesizer;
|
||||
pub mod writer;
|
||||
@@ -0,0 +1,186 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use crate::codec::av1::parser::NUM_REF_FRAMES;
|
||||
|
||||
const DIV_LUT: [i32; 257] = [
|
||||
16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768, 15709, 15650,
|
||||
15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142, 15087, 15033, 14980, 14926,
|
||||
14873, 14821, 14769, 14717, 14665, 14614, 14564, 14513, 14463, 14413, 14364, 14315, 14266,
|
||||
14218, 14170, 14122, 14075, 14028, 13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662,
|
||||
13618, 13574, 13530, 13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107,
|
||||
13066, 13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633, 12596,
|
||||
12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228, 12193, 12157, 12122,
|
||||
12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848, 11815, 11782, 11749, 11716, 11683,
|
||||
11651, 11619, 11586, 11555, 11523, 11491, 11460, 11429, 11398, 11367, 11336, 11305, 11275,
|
||||
11245, 11215, 11185, 11155, 11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894,
|
||||
10866, 10838, 10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538,
|
||||
10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255, 10230, 10205,
|
||||
10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986, 9963, 9939, 9916, 9892, 9869,
|
||||
9846, 9823, 9800, 9777, 9754, 9732, 9709, 9687, 9664, 9642, 9620, 9598, 9576, 9554, 9533, 9511,
|
||||
9489, 9468, 9447, 9425, 9404, 9383, 9362, 9341, 9321, 9300, 9279, 9259, 9239, 9218, 9198, 9178,
|
||||
9158, 9138, 9118, 9098, 9079, 9059, 9039, 9020, 9001, 8981, 8962, 8943, 8924, 8905, 8886, 8867,
|
||||
8849, 8830, 8812, 8793, 8775, 8756, 8738, 8720, 8702, 8684, 8666, 8648, 8630, 8613, 8595, 8577,
|
||||
8560, 8542, 8525, 8508, 8490, 8473, 8456, 8439, 8422, 8405, 8389, 8372, 8355, 8339, 8322, 8306,
|
||||
8289, 8273, 8257, 8240, 8224, 8208, 8192,
|
||||
];
|
||||
|
||||
const DIV_LUT_BITS: u32 = 8;
|
||||
const DIV_LUT_PREC_BITS: u32 = 14;
|
||||
|
||||
/// Implements FloorLog2(x), which is defined to be the floor of the base 2
|
||||
/// logarithm of the input x.
|
||||
///
|
||||
/// The input x will always be an integer, and will always be greater than or equal to 1.
|
||||
/// This function extracts the location of the most significant bit in x.
|
||||
pub fn floor_log2(mut x: u32) -> u32 {
|
||||
assert!(x > 0);
|
||||
let mut s = 0;
|
||||
|
||||
while x != 0 {
|
||||
x >>= 1;
|
||||
s += 1;
|
||||
}
|
||||
|
||||
s - 1
|
||||
}
|
||||
|
||||
/// Implements 5.9.3. Get relative distance function
|
||||
pub fn get_relative_dist(enable_order_hint: bool, order_hint_bits: i32, a: i32, b: i32) -> i32 {
|
||||
if !enable_order_hint {
|
||||
0
|
||||
} else {
|
||||
let diff = a - b;
|
||||
let m = 1 << (order_hint_bits - 1);
|
||||
(diff & (m - 1)) - (diff & m)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements find_latest_backward from section 7.8.
|
||||
pub fn find_latest_backward(
|
||||
shifted_order_hints: &[i32; NUM_REF_FRAMES],
|
||||
used_frame: &[bool; NUM_REF_FRAMES],
|
||||
cur_frame_hint: i32,
|
||||
latest_order_hint: &mut i32,
|
||||
) -> i32 {
|
||||
let mut _ref = -1;
|
||||
|
||||
for i in 0..NUM_REF_FRAMES {
|
||||
let hint = shifted_order_hints[i];
|
||||
if !used_frame[i] && hint >= cur_frame_hint && (_ref < 0 || hint >= *latest_order_hint) {
|
||||
_ref = i as i32;
|
||||
*latest_order_hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
_ref
|
||||
}
|
||||
|
||||
/// Implements find_earliest_backward from section 7.8.
|
||||
pub fn find_earliest_backward(
|
||||
shifted_order_hints: &[i32; NUM_REF_FRAMES],
|
||||
used_frame: &[bool; NUM_REF_FRAMES],
|
||||
cur_frame_hint: i32,
|
||||
earliest_order_hint: &mut i32,
|
||||
) -> i32 {
|
||||
let mut _ref = -1;
|
||||
|
||||
for i in 0..NUM_REF_FRAMES {
|
||||
let hint = shifted_order_hints[i];
|
||||
if !used_frame[i] && hint >= cur_frame_hint && (_ref < 0 || hint < *earliest_order_hint) {
|
||||
_ref = i as i32;
|
||||
*earliest_order_hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
_ref
|
||||
}
|
||||
|
||||
/// Implements find_latest_forward from section 7.8.
|
||||
pub fn find_latest_forward(
|
||||
shifted_order_hints: &[i32; NUM_REF_FRAMES],
|
||||
used_frame: &[bool; NUM_REF_FRAMES],
|
||||
cur_frame_hint: i32,
|
||||
latest_order_hint: &mut i32,
|
||||
) -> i32 {
|
||||
let mut _ref = -1;
|
||||
for i in 0..NUM_REF_FRAMES {
|
||||
let hint = shifted_order_hints[i];
|
||||
if !used_frame[i] && hint < cur_frame_hint && (_ref < 0 || hint >= *latest_order_hint) {
|
||||
_ref = i as i32;
|
||||
*latest_order_hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
_ref
|
||||
}
|
||||
|
||||
pub fn tile_log2(blk_size: u32, target: u32) -> u32 {
|
||||
let mut k = 0;
|
||||
|
||||
while (blk_size << k) < target {
|
||||
k += 1;
|
||||
}
|
||||
|
||||
k
|
||||
}
|
||||
|
||||
pub fn clip3(x: i32, y: i32, z: i32) -> i32 {
|
||||
if z < x {
|
||||
x
|
||||
} else if z > y {
|
||||
y
|
||||
} else {
|
||||
z
|
||||
}
|
||||
}
|
||||
|
||||
/// 5.9.29
|
||||
pub fn inverse_recenter(r: i32, v: i32) -> i32 {
|
||||
if v > 2 * r {
|
||||
v
|
||||
} else if v & 1 != 0 {
|
||||
r - ((v + 1) >> 1)
|
||||
} else {
|
||||
r + (v >> 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements Round2. See 4.7: mathematical functions.
|
||||
pub fn round2(x: u32, n: u32) -> u32 {
|
||||
(x + 2u32.pow(n - 1)) / 2u32.pow(n)
|
||||
}
|
||||
|
||||
/// Implements Round2Signed. See 4.7: mathematical functions.
|
||||
pub fn round2signed(x: i32, n: u32) -> Result<i32, String> {
|
||||
if x >= 0 {
|
||||
i32::try_from(round2(x as u32, n)).map_err(|e| e.to_string())
|
||||
} else {
|
||||
let x = x as i64;
|
||||
let val = i32::try_from(round2(-x as u32, n)).map_err(|e| e.to_string())?;
|
||||
Ok(-val)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements 7.11.3.7. Resolve divisor process
|
||||
pub fn resolve_divisor(d: i32) -> Result<(u32, i32), String> {
|
||||
let abs_d = u32::try_from(d.abs()).unwrap(); // abs cannot return a negative
|
||||
let n = floor_log2(abs_d);
|
||||
let e = abs_d - (1 << n);
|
||||
|
||||
let f = if n > DIV_LUT_BITS {
|
||||
round2(e, n - DIV_LUT_BITS)
|
||||
} else {
|
||||
e << (DIV_LUT_BITS - n)
|
||||
};
|
||||
|
||||
let div_shift = n + DIV_LUT_PREC_BITS;
|
||||
let div_factor = if d < 0 {
|
||||
-DIV_LUT[f as usize]
|
||||
} else {
|
||||
DIV_LUT[f as usize]
|
||||
};
|
||||
|
||||
Ok((div_shift, div_factor))
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,251 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use crate::bitstream_utils::BitReader;
|
||||
|
||||
use crate::codec::av1::helpers;
|
||||
|
||||
use super::parser::AnnexBState;
|
||||
|
||||
pub(crate) struct Reader<'a>(pub BitReader<'a>);
|
||||
|
||||
impl<'a> Reader<'a> {
|
||||
pub fn new(data: &'a [u8]) -> Self {
|
||||
Self(BitReader::new(data, false))
|
||||
}
|
||||
|
||||
/// Implements uvlc(): Variable length unsigned n-bit number appearing
|
||||
/// directly in the bitstream. See 4.10.3
|
||||
pub fn read_uvlc(&mut self) -> Result<u32, String> {
|
||||
let mut leading_zeroes = 0;
|
||||
loop {
|
||||
let done = self.0.read_bit()?;
|
||||
|
||||
if done {
|
||||
break;
|
||||
}
|
||||
|
||||
leading_zeroes += 1;
|
||||
}
|
||||
|
||||
if leading_zeroes >= 32 {
|
||||
return Ok(u32::MAX);
|
||||
}
|
||||
|
||||
let value = self.0.read_bits::<u32>(leading_zeroes)?;
|
||||
Ok(value + (1 << leading_zeroes) - 1)
|
||||
}
|
||||
|
||||
/// Implements leb128(): Unsigned integer represented by a variable number
|
||||
/// of little-endian bytes. See 4.10.5
|
||||
pub fn read_leb128(&mut self) -> Result<u32, String> {
|
||||
let mut value = 0u64;
|
||||
|
||||
for i in 0..8 {
|
||||
let byte = u64::from(self.0.read_bits_aligned::<u32>(8)?);
|
||||
value |= (byte & 0x7f) << (i * 7);
|
||||
|
||||
if byte & 0x80 == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(value as u32)
|
||||
}
|
||||
|
||||
/// Implements su(n): Signed integer converted from an n bits unsigned
|
||||
/// integer in the bitstream. (The unsigned integer corresponds to the
|
||||
/// bottom n bits of the signed integer.). See 4.10.6
|
||||
pub fn read_su(&mut self, num_bits: usize) -> Result<i32, String> {
|
||||
let mut value: i32 = self
|
||||
.0
|
||||
.read_bits::<u32>(num_bits)?
|
||||
.try_into()
|
||||
.map_err(|_| String::from("Read more than 31 signed bits!"))?;
|
||||
let sign_mask = 1 << (num_bits - 1);
|
||||
|
||||
if (value & sign_mask) != 0 {
|
||||
value -= 2 * sign_mask;
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// Implements ns(n): Unsigned encoded integer with maximum number of values
|
||||
/// n (i.e. output in range 0..n-1). See 4.10.7
|
||||
pub fn read_ns(&mut self, num_bits: usize) -> Result<u32, String> {
|
||||
let w = helpers::floor_log2(num_bits as u32) + 1;
|
||||
let m = (1 << w) - num_bits as u32;
|
||||
let v = self.0.read_bits::<u32>(
|
||||
usize::try_from(w).map_err(|_| String::from("Invalid num_bits"))? - 1,
|
||||
)?;
|
||||
|
||||
if v < m.into() {
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
let extra_bit = self.0.read_bit()?;
|
||||
Ok((v << 1) - u32::from(m) + u32::from(extra_bit))
|
||||
}
|
||||
|
||||
/// Implements 5.9.13: Delta quantizer syntax.
|
||||
pub fn read_delta_q(&mut self) -> Result<i32, String> {
|
||||
let delta_coded = self.0.read_bit()?;
|
||||
|
||||
if delta_coded {
|
||||
self.read_su(7)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn more_data_in_bitstream(&mut self) -> bool {
|
||||
self.0.num_bits_left() > 0
|
||||
}
|
||||
|
||||
pub(crate) fn consumed(&self, start_pos: u32) -> u32 {
|
||||
(self.0.position() / 8) as u32 - start_pos
|
||||
}
|
||||
|
||||
/// Get the length of the current OBU in AnnexB format.
|
||||
pub fn current_annexb_obu_length(
|
||||
&mut self,
|
||||
annexb_state: &mut AnnexBState,
|
||||
) -> Result<Option<usize>, String> {
|
||||
if !self.more_data_in_bitstream() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
#[allow(clippy::comparison_chain)]
|
||||
if annexb_state.temporal_unit_consumed == annexb_state.temporal_unit_size {
|
||||
annexb_state.temporal_unit_size = 0;
|
||||
} else if annexb_state.temporal_unit_consumed > annexb_state.temporal_unit_size {
|
||||
return Err(format!(
|
||||
"temporal_unit_size is {} but we consumed {} bytes",
|
||||
annexb_state.temporal_unit_size, annexb_state.temporal_unit_consumed,
|
||||
));
|
||||
}
|
||||
|
||||
if annexb_state.temporal_unit_size == 0 {
|
||||
annexb_state.temporal_unit_size = self.read_leb128()?;
|
||||
if annexb_state.temporal_unit_size == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
let start_pos = self.consumed(0);
|
||||
|
||||
#[allow(clippy::comparison_chain)]
|
||||
if annexb_state.frame_unit_consumed == annexb_state.frame_unit_size {
|
||||
annexb_state.frame_unit_size = 0;
|
||||
} else if annexb_state.frame_unit_consumed > annexb_state.frame_unit_size {
|
||||
return Err(format!(
|
||||
"frame_unit_size is {} but we consumed {} bytes",
|
||||
annexb_state.frame_unit_size, annexb_state.frame_unit_consumed,
|
||||
));
|
||||
}
|
||||
|
||||
if annexb_state.frame_unit_size == 0 {
|
||||
annexb_state.frame_unit_size = self.read_leb128()?;
|
||||
if annexb_state.frame_unit_size == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
annexb_state.temporal_unit_consumed += self.consumed(start_pos);
|
||||
}
|
||||
|
||||
let start_pos = self.consumed(0);
|
||||
let obu_length = self.read_leb128()?;
|
||||
let consumed = self.consumed(start_pos);
|
||||
|
||||
annexb_state.temporal_unit_consumed += consumed;
|
||||
annexb_state.frame_unit_consumed += consumed;
|
||||
|
||||
Ok(Some(obu_length.try_into().unwrap()))
|
||||
}
|
||||
|
||||
/// Implements 5.3.4.
|
||||
pub fn read_trailing_bits(&mut self, mut num_bits: u64) -> Result<(), String> {
|
||||
let trailing_one_bit = self.0.read_bit()?;
|
||||
num_bits -= 1;
|
||||
|
||||
if !trailing_one_bit {
|
||||
return Err("bad padding: trailing_one_bit is not set".into());
|
||||
}
|
||||
|
||||
while num_bits > 0 {
|
||||
let trailing_zero_bit = self.0.read_bit()?;
|
||||
if trailing_zero_bit {
|
||||
return Err("bad padding: trailing_zero_bit is set".into());
|
||||
}
|
||||
num_bits -= 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decode_subexp(&mut self, num_syms: i32) -> Result<u32, String> {
|
||||
let mut i = 0;
|
||||
let mut mk = 0;
|
||||
let k = 3;
|
||||
|
||||
loop {
|
||||
let b2 = if i != 0 { k + i - 1 } else { k };
|
||||
let a = 1 << b2;
|
||||
if num_syms <= mk + 3 * a {
|
||||
let num_bits = num_syms - mk;
|
||||
let subexp_final_bits = self.read_ns(num_bits as usize)?;
|
||||
return Ok(subexp_final_bits);
|
||||
} else {
|
||||
let subexp_more_bits = self.0.read_bit()?;
|
||||
if subexp_more_bits {
|
||||
i += 1;
|
||||
mk += a;
|
||||
} else {
|
||||
let num_bits = b2 as usize;
|
||||
let subexp_bits = self.0.read_bits::<u32>(num_bits)?;
|
||||
return Ok(subexp_bits + mk as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements 5.9.27.
|
||||
pub fn decode_unsigned_subexp_with_ref(&mut self, mx: i32, r: i32) -> Result<u32, String> {
|
||||
let v = self.decode_subexp(mx)?;
|
||||
if (r << 1) <= mx {
|
||||
Ok(helpers::inverse_recenter(r, v.try_into().unwrap())
|
||||
.try_into()
|
||||
.unwrap())
|
||||
} else {
|
||||
let res = mx - 1 - helpers::inverse_recenter(mx - 1 - r, v.try_into().unwrap());
|
||||
Ok(res.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements 5.9.26.
|
||||
pub fn decode_signed_subexp_with_ref(
|
||||
&mut self,
|
||||
low: i32,
|
||||
high: i32,
|
||||
r: i32,
|
||||
) -> Result<i32, String> {
|
||||
let x = self.decode_unsigned_subexp_with_ref(high - low, r - low)?;
|
||||
Ok(i32::try_from(x).unwrap() + low)
|
||||
}
|
||||
|
||||
/// Implements 5.3.5 Byte alignment syntax
|
||||
pub fn byte_alignment(&mut self) -> Result<(), String> {
|
||||
while (self.0.position() & 7) != 0 {
|
||||
self.0.read_bit()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Clone for Reader<'a> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generates the CRCs for all .av1 files in the current directory using ffmpeg.
|
||||
|
||||
for f in `ls *.av1`; do
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash crc32 - |grep -v '^#' |awk '{print $6}' >$f.crc
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash md5 - |grep -v '^#' |awk '{print $6}' >$f.md5
|
||||
done
|
||||
BIN
Binary file not shown.
+260
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"profile": "AV1PROFILE_PROFILE_MAIN",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
"frame_rate": 25,
|
||||
"num_frames": 250,
|
||||
"num_fragments": 250,
|
||||
"md5_checksums": [
|
||||
"83dab175e49c33a6e3ece5c3758d1bf6",
|
||||
"cedb4e25453dba430cb6ee830c1643f3",
|
||||
"ef14d142df162819eee800f3930a9e95",
|
||||
"11849ccb72cfdabc8f70e33271cd916f",
|
||||
"7c9856ed61566f399a1eda2243e199ca",
|
||||
"9394ed10354e986ecdfa2b753b921d2b",
|
||||
"573005df5ba8f982980c1f427dfb472e",
|
||||
"a96d9a913b1712f37f73b6c47b577cdf",
|
||||
"91fc52b076badd1e6cbddb9bca5c5cc3",
|
||||
"6253dde984bc5282f01005d7ebb55fe9",
|
||||
"ad88146fe374423e7c597a922049c76c",
|
||||
"ca7d1ddea7269e476b43a805bd5dd50b",
|
||||
"e3d1eeec3cbfa363a2222d274890be84",
|
||||
"fd7902a1b7352e04dc3940a010482a67",
|
||||
"cada3ee9e33c11c99f89c3f439e2723e",
|
||||
"1723ee290ae8be930f2904cb5aaf9de4",
|
||||
"bf48d536e70a6a0a6549e221a833ebe4",
|
||||
"f13b2e454420b1e0e5ab0adbbf2ce72f",
|
||||
"31c799b4bb0971b798970e23b906cd25",
|
||||
"3d925424bf645a225caf64757944a6e5",
|
||||
"ac55ba724f54dd068350fd2818064dd5",
|
||||
"a7125b8b0dc1e464e76ee64956897d22",
|
||||
"f2a00db38d83cc778fa9fbdb3f4515e3",
|
||||
"c804823f3401558a0283c4e77888af20",
|
||||
"662d71a06319faef70a0981b664481d2",
|
||||
"ad3a221a5f1f9d1a615733155a194385",
|
||||
"8b071335d6cee4b227782415b1cb8a13",
|
||||
"f3d98bfac8e5083233b88386b539b790",
|
||||
"739c73e71590e64db0629911039962b4",
|
||||
"0944990b0ada4012cc686b06833264ef",
|
||||
"77e306874ec1b0c91668f8df0953831b",
|
||||
"ca376820c5248cccb221ec8cb4b0eb9e",
|
||||
"86a72cec3aaf50e393880ac8d4139921",
|
||||
"b892ef1ff0c169b683b35cbaa9462ee3",
|
||||
"b5feafe6c294d29adb1b05138803be36",
|
||||
"3c3b150801f2dc48d300380c9a932890",
|
||||
"16b06dfb6e426a1b6d88e17de83f5e2c",
|
||||
"b1633b1c661a645bd1b04317b30fdbfa",
|
||||
"56d08d66ad8042ba295c3f86025d44cf",
|
||||
"78f6697fbb3af79dbd614f495c372031",
|
||||
"afb700399aacde4c8c895def06fd8594",
|
||||
"e7ae993d18af5c58047196d8369eee3e",
|
||||
"65d5d77181388229606972ea99f5191a",
|
||||
"bd336774b22d502d8fdca07d881d737e",
|
||||
"5cabd4479d94c040f86892fa41860ca9",
|
||||
"9ab949d5ede2f25889a9612b39f6f158",
|
||||
"bb54bb8d7782c4b2d63f201a8d338e7d",
|
||||
"9bf73fc10b4bb19021fd07586a0401d1",
|
||||
"a37621cda632ac5f58e03272d226e53b",
|
||||
"5c3ca20aa646d72b69f6e56592fd2f0b",
|
||||
"b8ff47ec622ce73e70cfc913a3f8116e",
|
||||
"1d020f74b9d3adf17b3f3da6992fcb52",
|
||||
"0236c4d4a9aa68ba59eeaeb6b010db26",
|
||||
"78a8e16aebbe5fc3d1e6051153031a51",
|
||||
"78a54c1182b8ce007a2c10d17915272d",
|
||||
"c7ac4f87168bbddd01155f54c79bc132",
|
||||
"e074be8ece629e08d6d93029b8d34ce2",
|
||||
"edfba91c624f4cdc558c693b33165542",
|
||||
"f3d005151909922bfed7a905693de7c0",
|
||||
"80118fa45af8b3e486928aae49d85b94",
|
||||
"e7663b97fc9b26348876d5fa64a54d5d",
|
||||
"69200a2a34bd4beccf4d473b4a4976f3",
|
||||
"82f6c63a1d87037c08fba3bf16ef9bf8",
|
||||
"6e3033f25eb56670a3c45c12822f340c",
|
||||
"6085ac2c582fd3048c240d3dc46e3455",
|
||||
"b4bbf1a7ae3f57b1d8f0ed65070e010b",
|
||||
"e7f0aad67af5c7719eb89e457cefe6b4",
|
||||
"6d5fdc1d68e136ce9095696be59b617b",
|
||||
"bf15759321de7b21ec3c1bd2cb98ca69",
|
||||
"fc4d67815a94c2e18e7d8b0b7d866641",
|
||||
"0d96425a800252d500fd25da7dccb94d",
|
||||
"5438c9e83cc90f030ee9b1876ec28bdc",
|
||||
"a88915fd11ad765299cef49c8e65e8ab",
|
||||
"4995a3442fa74849f3c45888037f9b42",
|
||||
"82693761e531127d2a98cdc5615cdb92",
|
||||
"07b9601bebc32dc33fd806f90cee586f",
|
||||
"d68df0d6b1dae0e4428a17717723dbe0",
|
||||
"2851422da5bcceebf57ae37a02a1fb57",
|
||||
"ae9ff5d20ea6ba6105fb5ed3e0109834",
|
||||
"a0f956663545e54acbaecf684d0841ff",
|
||||
"23589649e474e155583e6742fa79098c",
|
||||
"9031fbd94bd7a0508b48f8081018d447",
|
||||
"b72920bce007e8f0584d615529dda39f",
|
||||
"0638d4c62dbf43087b4831f2e39314fe",
|
||||
"7d34a23c9b78a61da7a60c520784e204",
|
||||
"0a3cf1af9095a7cb2787cf79ed257c59",
|
||||
"1c05ab5abe793c14ee53ea80e170d6cc",
|
||||
"02d0b03fe10b1b6675b86390fe317778",
|
||||
"7639df2f62c4f958a90337b19a591530",
|
||||
"6080ee3519bd5dd88fbb4050459c126b",
|
||||
"75ce7282839cda34f7ca6111d6353cdb",
|
||||
"2214093ad2bb512a223808ed78fe3369",
|
||||
"eb9bfad6ef08a5f28b531203db3fcb43",
|
||||
"cf4fd68dd57df907f35cc55fe5930fb8",
|
||||
"0aaf799fc8509acd1168cd667f789c9c",
|
||||
"e36ebe2332eb5a9a0ddd03469493d3cb",
|
||||
"49ec5c818b0fcc02fbe3f5636417a2da",
|
||||
"8430b81f1a90c325d116cec424d3c32c",
|
||||
"c67e1e1f7fec9f9ab688f1d54cf2f4d4",
|
||||
"fd98fabb3db5dc2d841dc50af7395130",
|
||||
"8af0c8f486057cbae86939fa248c8238",
|
||||
"e1888b1f32d2991682261f28f860cb27",
|
||||
"9c0455744df622675a6d5232d790f5b1",
|
||||
"acc73e6665f54bdaa98acead49be5f65",
|
||||
"5c6e6167e6c05411a22c348a2c807fc5",
|
||||
"89d09cb95dc2e212efed266b4b687b35",
|
||||
"9d35702693b699ac0ccb4bffc559e2e8",
|
||||
"afbeb04e4e00a1b0a4407b4a34815a63",
|
||||
"6f3515d4331d83abfd1dbdfb2de78189",
|
||||
"be6cb0da9149ad5d68269d0ed657cd38",
|
||||
"9e9f498bc71df3097caa266089a77fba",
|
||||
"40d9198beea17a254ee6b74544317a7a",
|
||||
"e2f04358338ae115635e621cf229df56",
|
||||
"5da22d2d7c5c304fc6198f809206de1d",
|
||||
"4951c1ad5ea945a098c6a4d7fad163fa",
|
||||
"5a25300d1ef28b60f9e137b47b2e4364",
|
||||
"5954dd49f459ea4c0984dba30076db89",
|
||||
"820a838b57e43271a55f2f17c3e0676f",
|
||||
"b486477fe004ed8ee213afe8ecdb35c6",
|
||||
"0715a96ada76fe2d713cdfc2b9abf11d",
|
||||
"c30544fc39df1c7876043115ceed355f",
|
||||
"1f7ce18debf0e339db20c68c1f0bf8b8",
|
||||
"e10229f1f8a95d2e59a086e5d6ac4faa",
|
||||
"8ad6c73b38d32fd1712a1fd67750d364",
|
||||
"30fdf5b06ae3fd2c0df9e631ea1e1048",
|
||||
"0026b1e7db5e25651ecaaf19685b2dc2",
|
||||
"0b53f3f2ca17d00138b4678580d63ab6",
|
||||
"cb08de2030a42826ef573082188d3614",
|
||||
"e14242c776b3a32da936d1f6484e29ba",
|
||||
"41a43d3ee9021bcda09efa1b218cc65a",
|
||||
"9b884d243e8b330edb8f569e416960f1",
|
||||
"5737c4f611cdc9871df094ba51a6a6d5",
|
||||
"9d47768c1a15c0b20d28545ad5e6ca53",
|
||||
"8c981af4e6c3432a330b6d8e330bc03a",
|
||||
"195910783821f51cb3dad54f651c1a75",
|
||||
"659833dc03dc5f929eb140e188f2b1f6",
|
||||
"f2f30eaa72c5a093d67cebfda15fac73",
|
||||
"3c521e3025340933cf826027a994114b",
|
||||
"469b72a8db2ac77c70a792c8035b0288",
|
||||
"e2cf1d7930d44341c5c363b0ceaa6c84",
|
||||
"469d4283cca04e78ac2cb9407531db67",
|
||||
"02416a6c77174796ecbd61adab5177b9",
|
||||
"f89077b3dfb54119157e04dff24b79bd",
|
||||
"2d1a8fc14b649e343288b5972abe1fdf",
|
||||
"3d059186dab49cd8d13584dc365862db",
|
||||
"765ef42f457dee16234df6992ec74cd2",
|
||||
"957589c357d82631477177e6250c713c",
|
||||
"2473af8395d08e9396216c082f854d6f",
|
||||
"6a117d16f8e8ffe87aebec05844d6a0a",
|
||||
"8e467cfcbd66ed80fca648248af56b3f",
|
||||
"71e39c4304e09688750aa85e9d040f4a",
|
||||
"3071ee85d87ef8029619d4777c799c2b",
|
||||
"cc86f09e3f228001e806fd3afe5e1271",
|
||||
"3828673cf67828240005f7bf9fe37412",
|
||||
"12700b04cc22fba7688ae1709e48b886",
|
||||
"a1045aa13b0007d23f22ad8e83c4bdb0",
|
||||
"a12e6c2d2805336c407417b7503670fe",
|
||||
"11dd1907c6785eccbedeba6a5708c516",
|
||||
"3fb8be1276b83db1ccd8206cc69ec736",
|
||||
"980ce03ae4e6f2eceb314f37290e0dd2",
|
||||
"c39395d9b6108f1bd4ab1f004c44a5f0",
|
||||
"a7244c89efd3b00611c92ebaf98793e8",
|
||||
"fbede5a2957c023216e79cc31ab32946",
|
||||
"bb40544a3adfe992e07a8eb3e5bf6966",
|
||||
"0f71f57100699e95fff51dabde86cb42",
|
||||
"6ba085efefacf385728423ca99bd4629",
|
||||
"4df2d956234cb2129ebefdd90f28185a",
|
||||
"d0a0d4263ef4f32d59b004752a5b94af",
|
||||
"a9deed8bf550f4ee370730e1d993d4dc",
|
||||
"eca65ba94930bf78854ce991c05e3d9c",
|
||||
"4eef9fa5bca7ee74e97a0ac6e12e5f53",
|
||||
"84e97d688ba1922f9ed71d72cea67259",
|
||||
"407dc974664f93be14c53a2b291cc422",
|
||||
"31eb9e589470cfbe4e72e1c441d56e3f",
|
||||
"ea4f696ad2ae150a1f0e622874f67fca",
|
||||
"7552fea18e053b4771c0490015488291",
|
||||
"6863cd478581244fff72f6a0021a9fb8",
|
||||
"9118deacdd49db27c317eeec868cd870",
|
||||
"50290c87c5ee1c558bd304fc0f4a15ea",
|
||||
"5aef6d78538151648450fd391c9deaec",
|
||||
"a7e3feb23e01e0b4556446e01b2d81eb",
|
||||
"6918645d2b0bd511247c6ed372bf213e",
|
||||
"2f9661df4d114ab9f3a98a255a8177f2",
|
||||
"baaea6f9f05a7a2bc10721f1afe6f57b",
|
||||
"366ab99c236a8e84e658bad69d82a1ba",
|
||||
"f950a6508c051ef32e4c04be56fcc719",
|
||||
"9e586c73c3b9daebc608600efbee33b0",
|
||||
"e9fb7690077e8cbac15d5564130a8d7c",
|
||||
"ef3c8d2b5376753c26a795bf403cdcc1",
|
||||
"be46eec37b67dfc8077705ce89588a7c",
|
||||
"dba1b08cfeddbcf4e8d79621ee343bd4",
|
||||
"a4a612bcb6c33c7799433c998c5f12d1",
|
||||
"5f45fa214bc860825510d034f1ff26de",
|
||||
"1766dd6fe6080c408a4baca135609f1c",
|
||||
"34dc16d50d7afeb93a874563f1f5e4fd",
|
||||
"0a5314f217972a9271c4792921f61153",
|
||||
"7c228f1f5ccc6f7307526531f79a307d",
|
||||
"188544479f5a44b6a90b6be62e33611a",
|
||||
"9cb9be5574c6a2c06862a3ed605c68b5",
|
||||
"845b033cc82472d8e647f2a3bb3eb653",
|
||||
"2c6b66c68107fd13395a1ed5f0639355",
|
||||
"0436424e24e562c52ab7e7063b04c129",
|
||||
"21248608746bb252faa347028f5343d7",
|
||||
"81607476ae05bbf7386dea9d8eac352b",
|
||||
"fadc83171e49e779ebe5d81769049cef",
|
||||
"e768c96238a8cf14caf8d03420981265",
|
||||
"c57aa4d8e2f7c9101868246de4de1c13",
|
||||
"b405a01f8eb1d4ffade0e49f593e5a8f",
|
||||
"76f02bab5b932bf4bcf4ce06bdf0e42c",
|
||||
"51b09ce7117e15cf654ad76e13263f0c",
|
||||
"45f650b845e31b87b522574cc7afde80",
|
||||
"858605e70124ef7130742b713b079ad9",
|
||||
"5d955329a007742ecab7153d2e69b262",
|
||||
"c4139450cb6ffcac62b764d62083bc31",
|
||||
"8b13de43cffa8d12dd17b8e749a375b2",
|
||||
"b000fbdb48be876302bc336aeb6deba1",
|
||||
"88e2b7abbc33f70231889113582f8f8c",
|
||||
"d9f31d4cfeee31da719b3567d5d11a19",
|
||||
"7c2a6cc9be9ce8cb96b5a1616909941b",
|
||||
"954c2be78496f0235ab137a98a5ae11a",
|
||||
"9efd13fe15e8900f67a6c76103c9ce78",
|
||||
"b04aedbee4993ff955ebba1dcb8a04e1",
|
||||
"83b045a2a43445f97d82c1faaf33b332",
|
||||
"1cf416bf7bf4a2124932d4b1bb0aca94",
|
||||
"ac17d329b587b065512269fa3def8279",
|
||||
"fcf2b7ab8b7d53741c737f75c3587a6f",
|
||||
"0aaaaca0aa165a6786e2161043aa1e72",
|
||||
"8d19a0848fad7b32a15522cc0b24b4d1",
|
||||
"be0a1be3f90ff47b80be31be021c28f1",
|
||||
"c9e423c59186d93100c56ad8f14c0fb4",
|
||||
"052dbb80693750c716acce06f3ad7266",
|
||||
"6a2c8002df49d3832b7e1abd70af542f",
|
||||
"92bec3aa91edfd2cc5dee7d1f66ac189",
|
||||
"579d29110e7a7a71152aedb9a462c79f",
|
||||
"b0bb435df9dd211dd5da3c547c8887b8",
|
||||
"fb7a3cf05afd06668287f5dcc9c20a55",
|
||||
"bbd27b9b555f361478f9516e839077a5",
|
||||
"a74dc95fe982709b25434bcc53a91973",
|
||||
"27f82418568440caea8df7bcdf56eae7",
|
||||
"d5ff54f75c8fa6d60428816945ee5e89",
|
||||
"4b6677c4cc9866f477ecda5618411c8d",
|
||||
"d56046f25113a82b090bf9a91291587c",
|
||||
"cb56aa0f4343c7da821c04e55e8af21a",
|
||||
"c633ea8a4c20ea4d70c8c241d0293e9b",
|
||||
"dd2b157ce8a010a61908170ecb3e31b0",
|
||||
"3c3509c92b03a702ac1f4a28b5abd3d5",
|
||||
"d1400e54b8b61241cabad5291d6e3a43",
|
||||
"c29470cd6afb0aee4ae4a8d0622a468d",
|
||||
"e35764f7bd48746d37478b2d6f3f2755",
|
||||
"3dcf1fd38fbcc1d45f98574b17ac5710"
|
||||
]
|
||||
}
|
||||
BIN
Binary file not shown.
+250
@@ -0,0 +1,250 @@
|
||||
6aea6152
|
||||
cb4a90b3
|
||||
fd83e35f
|
||||
074bd081
|
||||
216fcc04
|
||||
c73ca1e4
|
||||
fbfb2a30
|
||||
cd587935
|
||||
e8bc2912
|
||||
051517b7
|
||||
f3e9831d
|
||||
812e7bba
|
||||
3e2054e6
|
||||
7446385e
|
||||
8b75d043
|
||||
f930d9a7
|
||||
7bf6b591
|
||||
253c5389
|
||||
11a25f1f
|
||||
c5101d08
|
||||
ee1c0aae
|
||||
ce055a9f
|
||||
0ed4a046
|
||||
aa0a72c3
|
||||
87f7a598
|
||||
aa3a422e
|
||||
0ee0e533
|
||||
5ce3d683
|
||||
cc7e88e5
|
||||
3e1c7774
|
||||
bd6708d3
|
||||
0ba6a0ee
|
||||
ac00d2da
|
||||
f1222e65
|
||||
3c6aadc8
|
||||
a28e7327
|
||||
fd2d0d8c
|
||||
e0a791bf
|
||||
90a33d7e
|
||||
63ae28ce
|
||||
26230e31
|
||||
215e9021
|
||||
6ca1295b
|
||||
01604116
|
||||
15f8d3c9
|
||||
6f28a1d4
|
||||
8d54633d
|
||||
08cccd41
|
||||
0b082923
|
||||
0aaae5a1
|
||||
98310e98
|
||||
33f12578
|
||||
9fd072e0
|
||||
36a1220e
|
||||
a278c894
|
||||
828dcf3f
|
||||
3573505c
|
||||
861874b7
|
||||
dd78b1fd
|
||||
310ca9a0
|
||||
74d670f3
|
||||
93c48c50
|
||||
814991b1
|
||||
fca836a7
|
||||
9299e121
|
||||
a8d3b267
|
||||
661a1c05
|
||||
50038462
|
||||
bc866fe1
|
||||
46e2d826
|
||||
7035f78c
|
||||
00c2ed17
|
||||
6b64a0c6
|
||||
315f4761
|
||||
df4c3ef7
|
||||
7ad4996a
|
||||
3185972f
|
||||
19af5f17
|
||||
01c4e3a3
|
||||
3728bd7e
|
||||
16adc384
|
||||
5798878c
|
||||
d0ac34ee
|
||||
56f76f8a
|
||||
2b6f3f47
|
||||
4a5ec1a9
|
||||
75f0027c
|
||||
7a1dd1f6
|
||||
50c0f14f
|
||||
978d00e7
|
||||
a1c430b8
|
||||
7c67432a
|
||||
4615b4cb
|
||||
c53c7308
|
||||
876d9f98
|
||||
b0015dd1
|
||||
73288a1e
|
||||
d843f40a
|
||||
4127f309
|
||||
3adbe013
|
||||
9e84104c
|
||||
9f98680d
|
||||
380a36e2
|
||||
2202f414
|
||||
ca931e02
|
||||
182b20e1
|
||||
815a6be2
|
||||
59cc5d53
|
||||
0a05d420
|
||||
d53b5f2d
|
||||
98c613aa
|
||||
e4de4fc1
|
||||
2b8f6d29
|
||||
48ce9586
|
||||
d6e822dd
|
||||
c8674577
|
||||
75dfa0e9
|
||||
7ad6ed39
|
||||
f7725767
|
||||
a44e0f11
|
||||
bcd743cd
|
||||
1ccf1835
|
||||
8ceb6153
|
||||
0a43af09
|
||||
79bab263
|
||||
855dd65a
|
||||
a37d34fe
|
||||
be063b4d
|
||||
aec5df0c
|
||||
7b12399b
|
||||
c5ad7294
|
||||
2f609050
|
||||
8bb2dcba
|
||||
c19aa763
|
||||
700eb99b
|
||||
11bf5174
|
||||
e74d5eda
|
||||
f54e54ef
|
||||
0173e328
|
||||
162372d6
|
||||
3c8f18a3
|
||||
ce8579c7
|
||||
91bdbf86
|
||||
745edb27
|
||||
df783664
|
||||
e7462cfd
|
||||
30d8d761
|
||||
f15474e6
|
||||
4c5bb874
|
||||
27c36dd2
|
||||
c40981c0
|
||||
1cc4b7c0
|
||||
ebd96a40
|
||||
a5f4d31e
|
||||
cd1a957a
|
||||
0b0d8e1d
|
||||
c5d30b99
|
||||
d7d6b75e
|
||||
0ea512b8
|
||||
dd12fced
|
||||
29eab68d
|
||||
e4bb47d1
|
||||
e3060770
|
||||
0483e6ca
|
||||
296b084f
|
||||
d11abff6
|
||||
c7589394
|
||||
b187d62e
|
||||
2e217b3c
|
||||
b516603b
|
||||
287c8b71
|
||||
2f24a994
|
||||
7ea617d0
|
||||
7ba0024e
|
||||
7067ae3e
|
||||
95650cbd
|
||||
7b2e7deb
|
||||
d1b6da6d
|
||||
76f22a5a
|
||||
9ce6fac7
|
||||
1e5cf6c7
|
||||
bbe20b47
|
||||
2f2cc450
|
||||
3f0297f3
|
||||
a2084503
|
||||
06487daa
|
||||
5d06ae48
|
||||
02cbba1b
|
||||
b386b4f4
|
||||
47623370
|
||||
1acb6e9d
|
||||
5b55fd00
|
||||
70d43ae3
|
||||
8a0703c0
|
||||
4d62a79b
|
||||
e358a27d
|
||||
b89fcec0
|
||||
59508160
|
||||
f2c9f57d
|
||||
2b57ec09
|
||||
9427c163
|
||||
91169e76
|
||||
eda7cda1
|
||||
289c7bc0
|
||||
821dc9d5
|
||||
b003d6ce
|
||||
3d8dbc53
|
||||
d6c3324a
|
||||
76a7b9c9
|
||||
a4d4b21b
|
||||
51ce1f2c
|
||||
49cc8861
|
||||
b4fc2309
|
||||
c435862e
|
||||
3bceba0f
|
||||
7ee0c219
|
||||
cb04facd
|
||||
b2fad23b
|
||||
2b8cf4f1
|
||||
fcdcbad2
|
||||
f3c038c6
|
||||
71e639e9
|
||||
282325bf
|
||||
52c64dc8
|
||||
9ebe8705
|
||||
f8679dc3
|
||||
906116a2
|
||||
9f740960
|
||||
3cad2af8
|
||||
c7765bb4
|
||||
c8f38650
|
||||
1e5d7d36
|
||||
3374dc4c
|
||||
e83476e5
|
||||
6a9c0d00
|
||||
08b8cb58
|
||||
bd74ea9e
|
||||
399bce4c
|
||||
1577335d
|
||||
cdbbea48
|
||||
d1373c35
|
||||
cc62212a
|
||||
8a5e59e2
|
||||
75f5f297
|
||||
8c5f3776
|
||||
fce09105
|
||||
92b2d17e
|
||||
416e8530
|
||||
968d1450
|
||||
d20688a8
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
ce5386b1beaa89f73a668d3720717fb4
|
||||
8f5d21bf3d78d9c242609bdd8df6cfd6
|
||||
7d75a95c82171c8cf4b09d694d4cbef9
|
||||
20d4bebdc51702ee7f40e187747696c7
|
||||
9c55dc575db2a189c5576537afca2c54
|
||||
68a15a8cdbc0aeaf10dff65db4d1a810
|
||||
dfd03584b10852eb16901d52578d8f8e
|
||||
a9a0cffed57bba344c9366ce91408e26
|
||||
9fdf7ac0fc07f2391da56462faf3e2e0
|
||||
b83d2da8f82e1a06d26bbb514b471f4b
|
||||
17c92a58fb68d0b3b02cb5b9105dbb37
|
||||
1e5bd3c05fb67f2aefc01611ed43d117
|
||||
eb287667a027f3e5325bfb27652021a6
|
||||
67e388816af98b99e4b9134516205c52
|
||||
35cba13cd8a6f23d6dfd95803af0886b
|
||||
45966e4a1b83dce6a2b0c259fea10cae
|
||||
416a95236e46a7bb0f11cf1147631979
|
||||
f23ab59d3c4efbb8eb2d80d67a2e5136
|
||||
ab7bce374a3468c03483418ccffb52de
|
||||
bdaaf22c6c4e58d393d7c051d4d0ae8a
|
||||
6f7de2de3e8d79c726f0f2c2fe52ee58
|
||||
d2fc7067797bbffe3765a238ff803b85
|
||||
769dbc781b43759287da0b2888e8338b
|
||||
2abd608af57978290e24c4cd62e4904f
|
||||
4fb54d7b0a71a4d3ca95b56d7b3d9a81
|
||||
262ba91321a0edac67c01e6ddcc2e4f7
|
||||
4c9c2d967fb853ecdc6042f223a7d138
|
||||
f21ccd6a4eb5f561b0a0eff9cb1956ec
|
||||
3c206ed277864249e7eaade75e71c815
|
||||
7167fed00621472662b19a0215dd00c8
|
||||
76e6f142e710ff5d7f6797d3fc1b8dfd
|
||||
4d814bb1fec0a2bca9d92140d5734ae0
|
||||
65b576bf469b182c8954591fd15dd21c
|
||||
abb7e8f11617aa0c9bf6870e537b008d
|
||||
02b86ea6b2f8699097d6899ab1f073c4
|
||||
610786c84b9fc118679afb09404c15ae
|
||||
7feb8fae65767f848ebbefa730f15d68
|
||||
12677768a4266571e85b750b51ef9fc8
|
||||
5b6541b178f6a885d0439b381e501967
|
||||
352cc90ecc1f3e26c19970f106c475fa
|
||||
9c5215a9fce00f0ec30615649171f8e4
|
||||
27e593a4b30c0b64939c62e5e0488e5a
|
||||
d8a5fd54958527ecefc642f6730e4164
|
||||
754dfeb4337108e534ba70bab429777a
|
||||
821ad11c37ffda3ad5438b57a9523e9f
|
||||
add12a889a5e08a5358e2e0e086fe522
|
||||
fa100278f49cbb7f9c9d7dc5e12fc0e1
|
||||
ef46a151df454084d0f0bc644adeb47d
|
||||
c02f8023a4be8a3249bcf6e1b223dffa
|
||||
41a11da85806e85fa86a9de41e1cd93f
|
||||
e792d89b5df357d1b03b1812a762832c
|
||||
90f72aead8124bc6ce51495b4b99da75
|
||||
af25c00b1990b778b50f529ae81efa30
|
||||
900f66f0e222a8d253153711a23a5ee9
|
||||
0850cad30d59e1b5e5e2943e6b916d0a
|
||||
03ca961e9876ee96b14711c44a9f2a69
|
||||
fa6bf9c30dd8618fdab499e9dd217582
|
||||
4e09e08e1f99bf210d4757281ab4c836
|
||||
dbf2bc5355a6846a028a7b3140fdef34
|
||||
b38e1973cabab58f8137cf66fc7fa3aa
|
||||
0ee4998cda155ca2823f5c9336a62cc2
|
||||
4f9918b4782a59a0361619389bd22d54
|
||||
c5c82a59505a9888b95e012a068b3254
|
||||
5eabc71dca6f57407ba306db416c5031
|
||||
41b8b1155bf6144aeb822acbff051e1a
|
||||
12e7d40ccd4298400cf3b5577370bff8
|
||||
2f22b7979183c9c3b26838c7e84a49a8
|
||||
68af2e17a487001d9374f6b38ed950af
|
||||
3a55bc482844ecc366e10544c38cc890
|
||||
6a08d19bbecb554837c9922b9818455a
|
||||
b2f95f48c1214a5dfb8f4528afcbf901
|
||||
c3c4fc391a1a040c71cb65a8c654a5b1
|
||||
86786c55d138bb9a4a4165522cd15253
|
||||
b329ece66a9dab6bebab9e3687629e7c
|
||||
7d6d818e7fe9a9b335c72ee6aedf9980
|
||||
317956c14cb119eda584de03dbf089cc
|
||||
d095660e8dd16899be9e916e0ff7946c
|
||||
12571880bd56bed1bbbd034094fabbaa
|
||||
7f702375e8c43036e36ddc07b543afb2
|
||||
e254d4c9854b28db694fb5477144551e
|
||||
24a4b250bc0461ad4894334838fbb645
|
||||
16b3dca0bfcad463498a62bf8a3f06a8
|
||||
77dbe27a373d87a6fc1012caa166a0a5
|
||||
1b304ea04baf90e1bf11d6296f64f933
|
||||
42c94efb8ab8ceb6ff98497ef0981c66
|
||||
1074398b6c210e833b4135c7d2caeb91
|
||||
3bce8712a7ba7b037a2cc85e4f72aea4
|
||||
42c1bc84350e82cbead374b41732d8d5
|
||||
76f8fc8e26d1b64e8afb8f263ec3f795
|
||||
ef9f8b042eb888f5408ccb500c9a157f
|
||||
d46505a331887bf49e157f8de4c17a98
|
||||
0be7df49394337bb277b63a6b9147520
|
||||
deb977415048b0b7fa1fd02878c1b10e
|
||||
a0395e32b4cc279f8545b791cee5d394
|
||||
c7dcd8741840799886a1f3b5208c0b36
|
||||
02b1297f58b9e699f232b9ed7e8bbcd0
|
||||
48852b209e405d7aaab50c5810448579
|
||||
d8a5598b2e7183d72cd3a81e54f301ce
|
||||
dfe2e4af7518f0d1f04fd825069d575b
|
||||
e1a70679c95173e6a1504b7c52dd0d3c
|
||||
16ae515dfb1268052bfe330a1cbbbffa
|
||||
f17c090f2140cfd3060558ceefe4d1bd
|
||||
58b1ba1fbbd76670c9218a846a8f6baf
|
||||
f543d8380c2d095f9b62d4ffaaee7467
|
||||
1b16d3e1d688a5a905ff22680ad803cb
|
||||
12e16d58422d5a5899379f11c6ca5b9a
|
||||
f1986c3e4a4545356656f76c27db0ae7
|
||||
324a3d45f631aed6c758888254ae07ad
|
||||
49532c06798f685e2a41dc683b081f79
|
||||
95934c5a6e2cc8de08c8b8342936cf38
|
||||
67d89790392f18908c24cc36bbe50362
|
||||
c4f963cd490f9241f4959cca6a6d35ce
|
||||
b21db693ba10898ec3205cb0cb343a02
|
||||
72e63227e74f2473a44da365fa9bc02f
|
||||
220d247b6c0f9512256dfcdf95582148
|
||||
86c290279ffa61ca615f1f8f8877e807
|
||||
6651d56c548fd4c5e8b2c86354c28ca3
|
||||
d863321ec53cd582d34a8ee5e88a5576
|
||||
f262bda775cf67026d8d226620c9d4aa
|
||||
15816d939647890021ac31aa1c3b2f75
|
||||
229b295a4bc44d8522580dd4383812d0
|
||||
833afe87641e34e60f2d127f44a7cbeb
|
||||
62cc76ec3a853878ebfff04ebbc8addc
|
||||
40fca93e2d6a976de641cdbfb56257b5
|
||||
65d654e9145527f8fcd24608d64f68f1
|
||||
1b2b0c68b6d9305f46642109b92a234b
|
||||
85aa859b29f2caeb60343cf53718e451
|
||||
3aa590c6c8a4dee128f1e7fcb2b82a2a
|
||||
699cb26687934746b722e2dfbc1d2c82
|
||||
9cc9b7f51cbdbaf15bc8eec9c1a1cf7c
|
||||
b1be900fe6a6eb21a563754420c5f38e
|
||||
47976686aff65b42661ae0fb2685f462
|
||||
6b3f96a1be97c4c2a371d5935672096a
|
||||
ac9b60c754c95ccbaf56f68544712dd6
|
||||
7dab91b68788d2ed61cd40d3073091a8
|
||||
35b367c591e71f11ddcd9dcc75be79e7
|
||||
d3321d793265630e81e6d52b20e58f44
|
||||
9d97047182efd2ba0594a569f6f2ce04
|
||||
14c772a342a28bd6785bb722e67fc767
|
||||
288802e107c373c9d28eeb3f8726214e
|
||||
1c9d8ff04c346a59ea4f3a349dc4b891
|
||||
2c857a65df4619d06f424ddcccbd2221
|
||||
10a0b3e4e7825d21fc22bcff34a3b26c
|
||||
78c8a5ee6e6880a3af222bfc27de62a1
|
||||
9e16c4346a69ff9127bb6c9287d98859
|
||||
1f1d95fa30c9c3a58f41d9657aa0e6ec
|
||||
5e8c6b3b4690da7f4175abe288d0c509
|
||||
0bf315da2ec1e135963cc4c9cf73ea1a
|
||||
2992fdf295438ec9f8dc7979b6d4e5ff
|
||||
a3d43afab0119aa3b6e38a81d244c388
|
||||
889d049dc64457637ad089e18e718a23
|
||||
46016c611b9323fe8f4206bd393a6741
|
||||
f555b79be75ba2a1a741f467192b693e
|
||||
242d4b4c323c7c1e9648de52ec8d7c2c
|
||||
383d2ee4d28919f193f28448ba28ddc6
|
||||
2c7cd221bd1025547fc654ca6717553d
|
||||
e16de72e05b548758832102ffb39d242
|
||||
5cecf3fc2823225f0f1748a1fedadf35
|
||||
4e709cb904317a43ffd94739281d32bc
|
||||
b6dfd4657668ed2c1ebaff9fa92702ab
|
||||
3c618cd95706cc25a0565fc0ed00e352
|
||||
dca8dbc91708a94525f16c064454a2ce
|
||||
fe3fbff45e30dcc3fa4f57ae78114f7f
|
||||
0f7bc1eab5cf9faeaa127c0243675253
|
||||
19b6fca6e3f0d039074753265436d2c5
|
||||
fce950fc2ec2526c0b29b6869ff58dee
|
||||
4c9c0b19668dc20a9fac84e13c590deb
|
||||
8fe06eb38ee870ffd7cb9f065476ac78
|
||||
515ce9eaa9a6970f809475e416325123
|
||||
6d58868e827dd9dca698c5b24380fea7
|
||||
072951a0e1d06aa829d716a86ae498fe
|
||||
07f23add152c44f754eac930093e6b59
|
||||
e98798eb29c162ddfff7ec72aa7b65dc
|
||||
62f4e1ca0294a3944224fb4a4280ed56
|
||||
28fc910d3b7a926f63e7bfaf18878cc1
|
||||
40065fe5c0e32a16622988bc1485a038
|
||||
b2623ec75309e28c6c0a4b179e4acd6d
|
||||
3ea6b991014bde2185be7a6c92745c28
|
||||
5fde25c7fe79a9c0e2b86eb1878de02c
|
||||
5bf42dc3006f4c601d01ee4820e44d38
|
||||
44500b37f18b2eb499894bc1ff1efdcc
|
||||
f5bfe3352c4281083083e51ef1fe0a72
|
||||
abf9c6ba639f68d9b8f8c0d9d97a19d3
|
||||
75f6dc9ccbc6a1381785bf9440a95744
|
||||
4db0fd27cac20f59718fe00c5dc13202
|
||||
9e0d611017698f2d1716f8d9d81a8bf7
|
||||
13c7015f10b37b3dbe1618cde5edc2ee
|
||||
70e2a0182471290a46961a0d62611053
|
||||
47ba942fc3396104b3731ea40eb97339
|
||||
bf10238458969233c0062b09a68f22a7
|
||||
115b7375a9aa156b8203dd88acdc5672
|
||||
1b39aa22702c993aa1e7606e9afad9c5
|
||||
c85e67c08e02538f151c6276662ba69b
|
||||
89dcf41c5adb944bcd46ca3f67666a75
|
||||
90fd81f9b572ede873313f4faa58da4b
|
||||
00badd56e7d5b2dddb10ef7de05be515
|
||||
a13c3404ac033c9fce8a6435f2a4a416
|
||||
af83e8f7af9785c96ff61c354417aab4
|
||||
5176b27945cc7686520b1425144dc4d3
|
||||
e5f248be2c0e83ad0a6bfd2eff759f6e
|
||||
cd693cce87898dafa5c68dbaeeb151fa
|
||||
2a47245fc3da1229e3dc288f216c4e20
|
||||
c6f8e88fbf5566000f8f86b0d4bf9020
|
||||
3e88c5f7b571a292c998cac33b41215b
|
||||
2a2e8271ecba2cec040ef343317e2ae9
|
||||
8e693282602bde3452061affde3ce514
|
||||
992acab07cf4d6aa5b95b4c4cc33cf0c
|
||||
6db1ad3494be9c3c9758b00d956bd2cb
|
||||
824d130a16d7bc2c6d6b26c31c2a0e05
|
||||
d286bd8f5cdfd65b695815ff68bb191f
|
||||
4c5bbeecda37bf4fb6dd79f266aac3d6
|
||||
c4f64e991e13dfc3913246f730c31e87
|
||||
459d8fd53975479aa977c61dc3ef1b9e
|
||||
ece59558539b52684433b54bf2c7e214
|
||||
4362122d7ed40dd5ad0886cdf901539e
|
||||
66ffe4fb31a5e4fa9462a3aa57224476
|
||||
86586a04e75ebde21903f407e6037e50
|
||||
93b2e3af91cb24ffafa6418c76cc1ce7
|
||||
41ca4598aac764fa944d8f578b2ab5ab
|
||||
6ef7ce05836d63520925817c220a5274
|
||||
c4e902503f3d5602ba2454907d7809f7
|
||||
8f3cb447682bebd3a230740e11d35dff
|
||||
4340ec4c3e62118b2749264393fc78ee
|
||||
8178fbeab83126f2111ab74c23d241c9
|
||||
db298bcb2a999b7ac2037991ef078d32
|
||||
f586895d6dca606e2d62dfdc92cc2021
|
||||
b5aaf4b91dd7b6cda3a2635c603c4500
|
||||
0f024b59afa957b59f5ebb9b63ff1b1a
|
||||
41acc378b08b5d9b7da2f644b79aebdf
|
||||
cd173062829e6e86eb094b8d40d16579
|
||||
ef55ddf0fa94dcb4f275033bb55e8466
|
||||
48a3efa1f9d8291d99ce434fc5474fb6
|
||||
731a649c764fa964d6e2ce640b34c25a
|
||||
5f9ac7b1dca56c8dab9ce1f92341094b
|
||||
e9b0ee7355299aaf55cce1e240050125
|
||||
8a285fc7c728cdfa1f4b651c64eab7e5
|
||||
05823b86e463ad514a4cd7eacd9c01bb
|
||||
0ce34318119eb0e8921b5e798789bea0
|
||||
e46f4c793b42136b1eefbece7b867052
|
||||
1331c7fcae627f290299b978299a9b48
|
||||
285c5783029a7b23374e91cce19df0de
|
||||
670fba4fad181308c15778f38e619646
|
||||
46a3350a39c21f45bafed75d339ed101
|
||||
b1d6f3230e58d2647d1aa4a5446061ed
|
||||
f6eb5936ec9bb3212b14716da8329839
|
||||
1ecb00343900a550ad33ba10777df23d
|
||||
4b9f70244adda8e0a42f4da7341b8d84
|
||||
6caafeb26793a011ebef352ef1d1aa34
|
||||
723ab0797281e7ee36109b53140a324d
|
||||
7a5e9be8c7c8307aa22c8b48708424a2
|
||||
@@ -0,0 +1,203 @@
|
||||
// Copyright 2024 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::bitstream_utils::BitWriter;
|
||||
use crate::bitstream_utils::BitWriterError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ObuWriterError {
|
||||
BitWriterError(BitWriterError),
|
||||
UnalignedLeb128,
|
||||
}
|
||||
|
||||
impl fmt::Display for ObuWriterError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ObuWriterError::BitWriterError(x) => write!(f, "{}", x.to_string()),
|
||||
ObuWriterError::UnalignedLeb128 => {
|
||||
write!(f, "attempted to write leb128 on unaligned position")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BitWriterError> for ObuWriterError {
|
||||
fn from(err: BitWriterError) -> Self {
|
||||
ObuWriterError::BitWriterError(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub type ObuWriterResult<T> = std::result::Result<T, ObuWriterError>;
|
||||
|
||||
pub struct ObuWriter<W: Write>(BitWriter<W>);
|
||||
|
||||
impl<W: Write> ObuWriter<W> {
|
||||
pub fn new(writer: W) -> Self {
|
||||
Self(BitWriter::new(writer))
|
||||
}
|
||||
|
||||
/// Writes fixed bit size integer. Corresponds to `f(n)` in AV1 spec defined in 4.10.2.
|
||||
pub fn write_f<T: Into<u32>>(&mut self, bits: usize, value: T) -> ObuWriterResult<usize> {
|
||||
self.0
|
||||
.write_f(bits, value)
|
||||
.map_err(ObuWriterError::BitWriterError)
|
||||
}
|
||||
|
||||
/// Writes variable length unsigned n-bit number. Corresponds to `uvlc()` in AV1 spec
|
||||
/// defined in 4.10.3.
|
||||
pub fn write_uvlc<T: Into<u32>>(&mut self, value: T) -> ObuWriterResult<usize> {
|
||||
let value: u32 = value.into();
|
||||
if value == u32::MAX {
|
||||
return self.write_f(32, 0u32);
|
||||
}
|
||||
|
||||
let value = value + 1;
|
||||
let leading_zeros = (32 - value.leading_zeros()) as usize;
|
||||
|
||||
Ok(self.write_f(leading_zeros - 1, 0u32)? + self.write_f(leading_zeros, value)?)
|
||||
}
|
||||
|
||||
/// Writes unsigned little-endian n-byte integer. Corresponds to `le(n)` in AV1 spec
|
||||
/// defined in 4.10.4.
|
||||
pub fn write_le<T: Into<u32>>(&mut self, n: usize, value: T) -> ObuWriterResult<usize> {
|
||||
let value: u32 = value.into();
|
||||
let mut value = value.to_le();
|
||||
|
||||
for _ in 0..n {
|
||||
self.write_f(4, value & 0xff)?;
|
||||
value >>= 8;
|
||||
}
|
||||
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
/// Writes unsigned integer represented by a variable number of little-endian bytes.
|
||||
/// Corresponds to `leb128()` in AV1 spec defined in 4.10.4.
|
||||
///
|
||||
/// Note: Despite the name, the AV1 4.10.4 limits the value to [`u32::MAX`] = (1 << 32) - 1.
|
||||
pub fn write_leb128<T: Into<u32>>(
|
||||
&mut self,
|
||||
value: T,
|
||||
min_bytes: usize,
|
||||
) -> ObuWriterResult<usize> {
|
||||
if !self.aligned() {
|
||||
return Err(ObuWriterError::UnalignedLeb128);
|
||||
}
|
||||
|
||||
let value: u32 = value.into();
|
||||
let mut value: u32 = value.to_le();
|
||||
let mut bytes = 0;
|
||||
|
||||
for _ in 0..8 {
|
||||
bytes += 1;
|
||||
|
||||
if value >= 0x7f || bytes < min_bytes {
|
||||
self.write_f(8, 0x80 | (value & 0x7f))?;
|
||||
value >>= 7;
|
||||
} else {
|
||||
self.write_f(8, value & 0x7f)?;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(value < 0x7f);
|
||||
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
pub fn write_su<T: Into<i32>>(&mut self, bits: usize, value: T) -> ObuWriterResult<usize> {
|
||||
let mut value: i32 = value.into();
|
||||
if value < 0 {
|
||||
value += 1 << bits;
|
||||
}
|
||||
|
||||
assert!(value >= 0);
|
||||
self.write_f(bits, value.unsigned_abs())
|
||||
}
|
||||
|
||||
pub fn aligned(&self) -> bool {
|
||||
!self.0.has_data_pending()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::codec::av1::reader::Reader;
|
||||
|
||||
const TEST_VECTOR: &[u32] = &[
|
||||
// some random test values
|
||||
u32::MAX,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
10,
|
||||
20,
|
||||
7312,
|
||||
8832,
|
||||
10123,
|
||||
47457,
|
||||
21390213,
|
||||
u32::MIN,
|
||||
u32::MAX - 1,
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_uvlc() {
|
||||
for &value in TEST_VECTOR {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
|
||||
ObuWriter::new(&mut buf).write_uvlc(value).unwrap();
|
||||
|
||||
if value == u32::MAX {
|
||||
// force stop uvlc
|
||||
buf.push(0x80);
|
||||
}
|
||||
|
||||
let read = Reader::new(&buf).read_uvlc().unwrap();
|
||||
|
||||
assert_eq!(read, value, "failed testing {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_leb128() {
|
||||
for &value in TEST_VECTOR {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
|
||||
ObuWriter::new(&mut buf).write_leb128(value, 0).unwrap();
|
||||
let read = Reader::new(&buf).read_leb128().unwrap();
|
||||
|
||||
assert_eq!(read, value, "failed testing {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_su() {
|
||||
let vector = TEST_VECTOR
|
||||
.iter()
|
||||
.map(|e| *e as i32)
|
||||
.chain(TEST_VECTOR.iter().map(|e| -(*e as i32)));
|
||||
|
||||
for value in vector {
|
||||
let bits = 32 - value.abs().leading_zeros() as usize + 1; // For sign
|
||||
if bits >= 32 {
|
||||
// Skip too big nubmers
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
|
||||
ObuWriter::new(&mut buf).write_su(bits, value).unwrap();
|
||||
|
||||
let read = Reader::new(&buf).read_su(bits as usize).unwrap();
|
||||
|
||||
assert_eq!(read, value, "failed testing {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
pub mod dpb;
|
||||
pub mod nalu;
|
||||
pub mod nalu_writer;
|
||||
pub mod parser;
|
||||
pub mod picture;
|
||||
pub mod synthesizer;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use std::io::Cursor;
|
||||
use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
|
||||
#[allow(clippy::len_without_is_empty)]
|
||||
pub trait Header: Sized {
|
||||
/// Parse the NALU header, returning it.
|
||||
fn parse<T: AsRef<[u8]>>(cursor: &mut Cursor<T>) -> Result<Self, String>;
|
||||
/// Whether this header type indicates EOS.
|
||||
fn is_end(&self) -> bool;
|
||||
/// The length of the header.
|
||||
fn len(&self) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Nalu<'a, U> {
|
||||
pub header: U,
|
||||
/// The mapping that backs this NALU. Possibly shared with the other NALUs
|
||||
/// in the Access Unit.
|
||||
pub data: Cow<'a, [u8]>,
|
||||
|
||||
pub size: usize,
|
||||
pub offset: usize,
|
||||
}
|
||||
|
||||
impl<'a, U> Nalu<'a, U>
|
||||
where
|
||||
U: Debug + Header,
|
||||
{
|
||||
/// Find the next Annex B encoded NAL unit.
|
||||
pub fn next(cursor: &mut Cursor<&'a [u8]>) -> Result<Nalu<'a, U>, String> {
|
||||
let bitstream = cursor.clone().into_inner();
|
||||
let pos = usize::try_from(cursor.position()).map_err(|err| err.to_string())?;
|
||||
|
||||
// Find the start code for this NALU
|
||||
let current_nalu_offset = match Nalu::<'a, U>::find_start_code(cursor, pos) {
|
||||
Some(offset) => offset,
|
||||
None => return Err("No NAL found".into()),
|
||||
};
|
||||
|
||||
let mut start_code_offset = pos + current_nalu_offset;
|
||||
|
||||
// If the preceding byte is 00, then we actually have a four byte SC,
|
||||
// i.e. 00 00 00 01 Where the first 00 is the "zero_byte()"
|
||||
if start_code_offset > 0 && cursor.get_ref()[start_code_offset - 1] == 00 {
|
||||
start_code_offset -= 1;
|
||||
}
|
||||
|
||||
// The NALU offset is its offset + 3 bytes to skip the start code.
|
||||
let nalu_offset = pos + current_nalu_offset + 3;
|
||||
|
||||
// Set the bitstream position to the start of the current NALU
|
||||
cursor.set_position(u64::try_from(nalu_offset).map_err(|err| err.to_string())?);
|
||||
|
||||
let hdr = U::parse(cursor)?;
|
||||
|
||||
// Find the start of the subsequent NALU.
|
||||
let mut next_nalu_offset = match Nalu::<'a, U>::find_start_code(cursor, nalu_offset) {
|
||||
Some(offset) => offset,
|
||||
None => {
|
||||
let cur_pos = cursor.position();
|
||||
let end_pos = cursor
|
||||
.seek(SeekFrom::End(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let _ = cursor
|
||||
.seek(SeekFrom::Start(cur_pos))
|
||||
.map_err(|err| err.to_string())?;
|
||||
(end_pos - cur_pos) as usize
|
||||
} // Whatever data is left must be part of the current NALU
|
||||
};
|
||||
|
||||
while next_nalu_offset > 0 && cursor.get_ref()[nalu_offset + next_nalu_offset - 1] == 00 {
|
||||
// Discard trailing_zero_8bits
|
||||
next_nalu_offset -= 1;
|
||||
}
|
||||
|
||||
let nal_size = if hdr.is_end() {
|
||||
// the NALU is comprised of only the header
|
||||
hdr.len()
|
||||
} else {
|
||||
next_nalu_offset
|
||||
};
|
||||
|
||||
Ok(Nalu {
|
||||
header: hdr,
|
||||
data: Cow::from(&bitstream[start_code_offset..nalu_offset + nal_size]),
|
||||
size: nal_size,
|
||||
offset: nalu_offset - start_code_offset,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, U> Nalu<'a, U>
|
||||
where
|
||||
U: Debug,
|
||||
{
|
||||
fn find_start_code(data: &mut Cursor<&'a [u8]>, offset: usize) -> Option<usize> {
|
||||
// discard all zeroes until the start code pattern is found
|
||||
data.get_ref()[offset..]
|
||||
.windows(3)
|
||||
.position(|window| window == [0x00, 0x00, 0x01])
|
||||
}
|
||||
|
||||
pub fn into_owned(self) -> Nalu<'static, U> {
|
||||
Nalu {
|
||||
header: self.header,
|
||||
size: self.size,
|
||||
offset: self.offset,
|
||||
data: Cow::Owned(self.data.into_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, U> AsRef<[u8]> for Nalu<'a, U> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.data[self.offset..self.offset + self.size]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
// Copyright 2024 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::bitstream_utils::BitWriter;
|
||||
use crate::bitstream_utils::BitWriterError;
|
||||
|
||||
/// Internal wrapper over [`std::io::Write`] for possible emulation prevention
|
||||
struct EmulationPrevention<W: Write> {
|
||||
out: W,
|
||||
prev_bytes: [Option<u8>; 2],
|
||||
|
||||
/// Emulation prevention enabled.
|
||||
ep_enabled: bool,
|
||||
}
|
||||
|
||||
impl<W: Write> EmulationPrevention<W> {
|
||||
fn new(writer: W, ep_enabled: bool) -> Self {
|
||||
Self {
|
||||
out: writer,
|
||||
prev_bytes: [None; 2],
|
||||
ep_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
fn write_byte(&mut self, curr_byte: u8) -> std::io::Result<()> {
|
||||
if self.prev_bytes[1] == Some(0x00) && self.prev_bytes[0] == Some(0x00) && curr_byte <= 0x03
|
||||
{
|
||||
self.out.write_all(&[0x00, 0x00, 0x03, curr_byte])?;
|
||||
self.prev_bytes = [None; 2];
|
||||
} else {
|
||||
if let Some(byte) = self.prev_bytes[1] {
|
||||
self.out.write_all(&[byte])?;
|
||||
}
|
||||
|
||||
self.prev_bytes[1] = self.prev_bytes[0];
|
||||
self.prev_bytes[0] = Some(curr_byte);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes a H.264 NALU header.
|
||||
fn write_header(&mut self, idc: u8, type_: u8) -> NaluWriterResult<()> {
|
||||
self.out.write_all(&[
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
(idc & 0b11) << 5 | (type_ & 0b11111),
|
||||
])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_data_pending(&self) -> bool {
|
||||
self.prev_bytes[0].is_some() || self.prev_bytes[1].is_some()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> Write for EmulationPrevention<W> {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
if !self.ep_enabled {
|
||||
self.out.write_all(buf)?;
|
||||
return Ok(buf.len());
|
||||
}
|
||||
|
||||
for byte in buf {
|
||||
self.write_byte(*byte)?;
|
||||
}
|
||||
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
if let Some(byte) = self.prev_bytes[1].take() {
|
||||
self.out.write_all(&[byte])?;
|
||||
}
|
||||
|
||||
if let Some(byte) = self.prev_bytes[0].take() {
|
||||
self.out.write_all(&[byte])?;
|
||||
}
|
||||
|
||||
self.out.flush()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> Drop for EmulationPrevention<W> {
|
||||
fn drop(&mut self) {
|
||||
if let Err(e) = self.flush() {
|
||||
log::error!("Unable to flush pending bytes {e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum NaluWriterError {
|
||||
Overflow,
|
||||
Io(std::io::Error),
|
||||
BitWriterError(BitWriterError),
|
||||
}
|
||||
|
||||
impl fmt::Display for NaluWriterError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
NaluWriterError::Overflow => write!(f, "value increment caused value overflow"),
|
||||
NaluWriterError::Io(x) => write!(f, "{}", x.to_string()),
|
||||
NaluWriterError::BitWriterError(x) => write!(f, "{}", x.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for NaluWriterError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
NaluWriterError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BitWriterError> for NaluWriterError {
|
||||
fn from(err: BitWriterError) -> Self {
|
||||
NaluWriterError::BitWriterError(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub type NaluWriterResult<T> = std::result::Result<T, NaluWriterError>;
|
||||
|
||||
/// A writer for H.264 bitstream. It is capable of outputing bitstream with
|
||||
/// emulation-prevention.
|
||||
pub struct NaluWriter<W: Write>(BitWriter<EmulationPrevention<W>>);
|
||||
|
||||
impl<W: Write> NaluWriter<W> {
|
||||
pub fn new(writer: W, ep_enabled: bool) -> Self {
|
||||
Self(BitWriter::new(EmulationPrevention::new(writer, ep_enabled)))
|
||||
}
|
||||
|
||||
/// Writes fixed bit size integer (up to 32 bit) output with emulation
|
||||
/// prevention if enabled. Corresponds to `f(n)` in H.264 spec.
|
||||
pub fn write_f<T: Into<u32>>(&mut self, bits: usize, value: T) -> NaluWriterResult<usize> {
|
||||
self.0
|
||||
.write_f(bits, value)
|
||||
.map_err(NaluWriterError::BitWriterError)
|
||||
}
|
||||
|
||||
/// An alias to [`Self::write_f`] Corresponds to `n(n)` in H.264 spec.
|
||||
pub fn write_u<T: Into<u32>>(&mut self, bits: usize, value: T) -> NaluWriterResult<usize> {
|
||||
self.write_f(bits, value)
|
||||
}
|
||||
|
||||
/// Writes a number in exponential golumb format.
|
||||
pub fn write_exp_golumb(&mut self, value: u32) -> NaluWriterResult<()> {
|
||||
let value = value.checked_add(1).ok_or(NaluWriterError::Overflow)?;
|
||||
let bits = 32 - value.leading_zeros() as usize;
|
||||
let zeros = bits - 1;
|
||||
|
||||
self.write_f(zeros, 0u32)?;
|
||||
self.write_f(bits, value)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes a unsigned integer in exponential golumb format.
|
||||
/// Coresponds to `ue(v)` in H.264 spec.
|
||||
pub fn write_ue<T: Into<u32>>(&mut self, value: T) -> NaluWriterResult<()> {
|
||||
let value = value.into();
|
||||
|
||||
self.write_exp_golumb(value)
|
||||
}
|
||||
|
||||
/// Writes a signed integer in exponential golumb format.
|
||||
/// Coresponds to `se(v)` in H.264 spec.
|
||||
pub fn write_se<T: Into<i32>>(&mut self, value: T) -> NaluWriterResult<()> {
|
||||
let value: i32 = value.into();
|
||||
let abs_value: u32 = value.unsigned_abs();
|
||||
|
||||
if value <= 0 {
|
||||
self.write_ue(2 * abs_value)
|
||||
} else {
|
||||
self.write_ue(2 * abs_value - 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if ['Self`] hold data that wasn't written to [`std::io::Write`]
|
||||
pub fn has_data_pending(&self) -> bool {
|
||||
self.0.has_data_pending() || self.0.inner().has_data_pending()
|
||||
}
|
||||
|
||||
/// Writes a H.264 NALU header.
|
||||
pub fn write_header(&mut self, idc: u8, _type: u8) -> NaluWriterResult<()> {
|
||||
self.0.flush()?;
|
||||
self.0.inner_mut().write_header(idc, _type)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns `true` if next bits will be aligned to 8
|
||||
pub fn aligned(&self) -> bool {
|
||||
!self.0.has_data_pending()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bitstream_utils::BitReader;
|
||||
|
||||
#[test]
|
||||
fn simple_bits() {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = NaluWriter::new(&mut buf, false);
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, false).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
writer.write_f(1, true).unwrap();
|
||||
}
|
||||
assert_eq!(buf, vec![0b10001111u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_first_few_ue() {
|
||||
fn single_ue(value: u32) -> Vec<u8> {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = NaluWriter::new(&mut buf, false);
|
||||
writer.write_ue(value).unwrap();
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
||||
assert_eq!(single_ue(0), vec![0b10000000u8]);
|
||||
assert_eq!(single_ue(1), vec![0b01000000u8]);
|
||||
assert_eq!(single_ue(2), vec![0b01100000u8]);
|
||||
assert_eq!(single_ue(3), vec![0b00100000u8]);
|
||||
assert_eq!(single_ue(4), vec![0b00101000u8]);
|
||||
assert_eq!(single_ue(5), vec![0b00110000u8]);
|
||||
assert_eq!(single_ue(6), vec![0b00111000u8]);
|
||||
assert_eq!(single_ue(7), vec![0b00010000u8]);
|
||||
assert_eq!(single_ue(8), vec![0b00010010u8]);
|
||||
assert_eq!(single_ue(9), vec![0b00010100u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writer_reader() {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = NaluWriter::new(&mut buf, false);
|
||||
writer.write_ue(10u32).unwrap();
|
||||
writer.write_se(-42).unwrap();
|
||||
writer.write_se(3).unwrap();
|
||||
writer.write_ue(5u32).unwrap();
|
||||
}
|
||||
|
||||
let mut reader = BitReader::new(&buf, true);
|
||||
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 10);
|
||||
assert_eq!(reader.read_se::<i32>().unwrap(), -42);
|
||||
assert_eq!(reader.read_se::<i32>().unwrap(), 3);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 5);
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = NaluWriter::new(&mut buf, false);
|
||||
writer.write_se(30).unwrap();
|
||||
writer.write_ue(100u32).unwrap();
|
||||
writer.write_se(-402).unwrap();
|
||||
writer.write_ue(50u32).unwrap();
|
||||
}
|
||||
|
||||
let mut reader = BitReader::new(&buf, true);
|
||||
|
||||
assert_eq!(reader.read_se::<i32>().unwrap(), 30);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 100);
|
||||
assert_eq!(reader.read_se::<i32>().unwrap(), -402);
|
||||
assert_eq!(reader.read_ue::<u32>().unwrap(), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writer_emulation_prevention() {
|
||||
fn test(input: &[u8], bitstream: &[u8]) {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
{
|
||||
let mut writer = NaluWriter::new(&mut buf, true);
|
||||
for byte in input {
|
||||
writer.write_f(8, *byte).unwrap();
|
||||
}
|
||||
}
|
||||
assert_eq!(buf, bitstream);
|
||||
{
|
||||
let mut reader = BitReader::new(&buf, true);
|
||||
for byte in input {
|
||||
assert_eq!(*byte, reader.read_bits::<u8>(8).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test(&[0x00, 0x00, 0x00], &[0x00, 0x00, 0x03, 0x00]);
|
||||
test(&[0x00, 0x00, 0x01], &[0x00, 0x00, 0x03, 0x01]);
|
||||
test(&[0x00, 0x00, 0x02], &[0x00, 0x00, 0x03, 0x02]);
|
||||
test(&[0x00, 0x00, 0x03], &[0x00, 0x00, 0x03, 0x03]);
|
||||
|
||||
test(&[0x00, 0x00, 0x00, 0x00], &[0x00, 0x00, 0x03, 0x00, 0x00]);
|
||||
test(&[0x00, 0x00, 0x00, 0x01], &[0x00, 0x00, 0x03, 0x00, 0x01]);
|
||||
test(&[0x00, 0x00, 0x00, 0x02], &[0x00, 0x00, 0x03, 0x00, 0x02]);
|
||||
test(&[0x00, 0x00, 0x00, 0x03], &[0x00, 0x00, 0x03, 0x00, 0x03]);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,443 @@
|
||||
// Copyright 2022 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::rc::Weak;
|
||||
|
||||
use log::debug;
|
||||
|
||||
use crate::codec::h264::parser::MaxLongTermFrameIdx;
|
||||
use crate::codec::h264::parser::RefPicMarking;
|
||||
use crate::codec::h264::parser::Slice;
|
||||
use crate::codec::h264::parser::SliceType;
|
||||
use crate::codec::h264::parser::Sps;
|
||||
use crate::Resolution;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum Field {
|
||||
#[default]
|
||||
Frame,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
impl Field {
|
||||
/// Returns the field of opposite parity.
|
||||
pub fn opposite(&self) -> Self {
|
||||
match *self {
|
||||
Field::Frame => Field::Frame,
|
||||
Field::Top => Field::Bottom,
|
||||
Field::Bottom => Field::Top,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum Reference {
|
||||
#[default]
|
||||
None,
|
||||
ShortTerm,
|
||||
LongTerm,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum IsIdr {
|
||||
#[default]
|
||||
No,
|
||||
Yes {
|
||||
idr_pic_id: u16,
|
||||
},
|
||||
}
|
||||
|
||||
/// The rank of a field, i.e. whether it is the first or second one to be parsed from the stream.
|
||||
/// This is unrelated to the `Field` type, as the first field can be either `Top` or `Bottom`.
|
||||
#[derive(Default, Debug)]
|
||||
pub enum FieldRank {
|
||||
/// Frame has a single field.
|
||||
#[default]
|
||||
Single,
|
||||
/// Frame is interlaced, and this is the first field (with a reference to the second one).
|
||||
First(Weak<RefCell<PictureData>>),
|
||||
/// Frame is interlaced, and this is the second field (with a reference to the first one).
|
||||
Second(Rc<RefCell<PictureData>>),
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PictureData {
|
||||
pub pic_order_cnt_type: u8,
|
||||
pub top_field_order_cnt: i32,
|
||||
pub bottom_field_order_cnt: i32,
|
||||
pub pic_order_cnt: i32,
|
||||
pub pic_order_cnt_msb: i32,
|
||||
pub pic_order_cnt_lsb: i32,
|
||||
pub delta_pic_order_cnt_bottom: i32,
|
||||
pub delta_pic_order_cnt0: i32,
|
||||
pub delta_pic_order_cnt1: i32,
|
||||
|
||||
pub pic_num: i32,
|
||||
pub long_term_pic_num: u32,
|
||||
pub frame_num: u32,
|
||||
pub frame_num_offset: u32,
|
||||
pub frame_num_wrap: i32,
|
||||
pub long_term_frame_idx: u32,
|
||||
|
||||
pub coded_resolution: Resolution,
|
||||
pub display_resolution: Resolution,
|
||||
|
||||
pub type_: SliceType,
|
||||
pub nal_ref_idc: u8,
|
||||
pub is_idr: IsIdr,
|
||||
reference: Reference,
|
||||
pub ref_pic_list_modification_flag_l0: i32,
|
||||
pub abs_diff_pic_num_minus1: i32,
|
||||
|
||||
// Does memory management op 5 needs to be executed after this
|
||||
// picture has finished decoding?
|
||||
pub has_mmco_5: bool,
|
||||
|
||||
// Created by the decoding process for gaps in frame_num.
|
||||
// Not for decode or output.
|
||||
pub nonexisting: bool,
|
||||
|
||||
pub field: Field,
|
||||
|
||||
// Values from slice_hdr to be used during reference marking and
|
||||
// memory management after finishing this picture.
|
||||
pub ref_pic_marking: RefPicMarking,
|
||||
|
||||
field_rank: FieldRank,
|
||||
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
/// A `PictureData` within a `Rc<RefCell>` which field rank is guaranteed to be correct.
|
||||
///
|
||||
/// The field rank of `PictureData` is only final after both fields have been constructed - namely,
|
||||
/// the first field can only point to the second one after the latter is available as a Rc. Methods
|
||||
/// [`PictureData::into_rc`] and [`PictureData::split_frame`] take care of this, and is this only
|
||||
/// producer of this type, ensuring all instances are correct.
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct RcPictureData {
|
||||
pic: Rc<RefCell<PictureData>>,
|
||||
}
|
||||
|
||||
impl Deref for RcPictureData {
|
||||
type Target = Rc<RefCell<PictureData>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.pic
|
||||
}
|
||||
}
|
||||
|
||||
impl PictureData {
|
||||
pub fn new_non_existing(frame_num: u32, timestamp: u64) -> Self {
|
||||
PictureData {
|
||||
frame_num,
|
||||
nonexisting: true,
|
||||
nal_ref_idc: 1,
|
||||
field: Field::Frame,
|
||||
pic_num: frame_num as i32,
|
||||
reference: Reference::ShortTerm,
|
||||
timestamp,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new picture from a `slice`, `sps`, and `timestamp`.
|
||||
///
|
||||
/// `first_field` is set if this picture is the second field of a frame.
|
||||
pub fn new_from_slice(
|
||||
slice: &Slice,
|
||||
sps: &Sps,
|
||||
timestamp: u64,
|
||||
first_field: Option<&RcPictureData>,
|
||||
) -> Self {
|
||||
let hdr = &slice.header;
|
||||
let nalu_hdr = &slice.nalu.header;
|
||||
|
||||
let is_idr = if nalu_hdr.idr_pic_flag {
|
||||
IsIdr::Yes {
|
||||
idr_pic_id: hdr.idr_pic_id,
|
||||
}
|
||||
} else {
|
||||
IsIdr::No
|
||||
};
|
||||
|
||||
let field = if hdr.field_pic_flag {
|
||||
if hdr.bottom_field_flag {
|
||||
Field::Bottom
|
||||
} else {
|
||||
Field::Top
|
||||
}
|
||||
} else {
|
||||
Field::Frame
|
||||
};
|
||||
|
||||
let reference = if nalu_hdr.ref_idc != 0 {
|
||||
Reference::ShortTerm
|
||||
} else {
|
||||
Reference::None
|
||||
};
|
||||
|
||||
let pic_num = if !hdr.field_pic_flag {
|
||||
hdr.frame_num
|
||||
} else {
|
||||
2 * hdr.frame_num + 1
|
||||
};
|
||||
|
||||
let (
|
||||
pic_order_cnt_lsb,
|
||||
delta_pic_order_cnt_bottom,
|
||||
delta_pic_order_cnt0,
|
||||
delta_pic_order_cnt1,
|
||||
) = match sps.pic_order_cnt_type {
|
||||
0 => (
|
||||
hdr.pic_order_cnt_lsb,
|
||||
hdr.delta_pic_order_cnt_bottom,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
),
|
||||
1 => (
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
hdr.delta_pic_order_cnt[0],
|
||||
hdr.delta_pic_order_cnt[1],
|
||||
),
|
||||
_ => (
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
),
|
||||
};
|
||||
|
||||
let coded_resolution = Resolution::from((sps.width(), sps.height()));
|
||||
|
||||
let visible_rect = sps.visible_rectangle();
|
||||
|
||||
// punktfunk deviation (PROVENANCE.md #6): `Sps::visible_rectangle()` returns
|
||||
// the crop offset in `min` and the visible SIZE in `max` (not a corner);
|
||||
// upstream's `max - min` double-counts the left/top crop and panics on a u32
|
||||
// underflow for large-but-parser-valid left/top offsets.
|
||||
let display_resolution = Resolution {
|
||||
width: visible_rect.max.x,
|
||||
height: visible_rect.max.y,
|
||||
};
|
||||
|
||||
let mut pic = PictureData {
|
||||
pic_order_cnt_type: sps.pic_order_cnt_type,
|
||||
pic_order_cnt_lsb: i32::from(pic_order_cnt_lsb),
|
||||
delta_pic_order_cnt_bottom,
|
||||
delta_pic_order_cnt0,
|
||||
delta_pic_order_cnt1,
|
||||
pic_num: i32::from(pic_num),
|
||||
frame_num: u32::from(hdr.frame_num),
|
||||
nal_ref_idc: nalu_hdr.ref_idc,
|
||||
is_idr,
|
||||
reference,
|
||||
field,
|
||||
ref_pic_marking: hdr.dec_ref_pic_marking.clone(),
|
||||
coded_resolution,
|
||||
display_resolution,
|
||||
timestamp,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(first_field) = first_field {
|
||||
pic.set_first_field_to(first_field);
|
||||
}
|
||||
|
||||
pic
|
||||
}
|
||||
|
||||
/// Whether the current picture is a reference, either ShortTerm or LongTerm.
|
||||
pub fn is_ref(&self) -> bool {
|
||||
!matches!(self.reference, Reference::None)
|
||||
}
|
||||
|
||||
/// Whether this picture is a second field.
|
||||
pub fn is_second_field(&self) -> bool {
|
||||
matches!(self.field_rank, FieldRank::Second(..))
|
||||
}
|
||||
|
||||
/// Returns the field rank of this picture, including a reference to its other field.
|
||||
pub fn field_rank(&self) -> &FieldRank {
|
||||
&self.field_rank
|
||||
}
|
||||
|
||||
/// Returns a reference to the picture's Reference
|
||||
pub fn reference(&self) -> &Reference {
|
||||
&self.reference
|
||||
}
|
||||
|
||||
/// Mark the picture as a reference picture.
|
||||
pub fn set_reference(&mut self, reference: Reference, apply_to_other_field: bool) {
|
||||
log::debug!("Set reference of {:#?} to {:?}", self, reference);
|
||||
self.reference = reference;
|
||||
|
||||
if apply_to_other_field {
|
||||
if let Some(other_field) = self.other_field() {
|
||||
log::debug!(
|
||||
"other_field: Set reference of {:#?} to {:?}",
|
||||
&other_field.borrow(),
|
||||
reference
|
||||
);
|
||||
other_field.borrow_mut().reference = reference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the picture's other field, if there is any
|
||||
/// and its reference is still valid.
|
||||
pub fn other_field(&self) -> Option<Rc<RefCell<PictureData>>> {
|
||||
match &self.field_rank {
|
||||
FieldRank::Single => None,
|
||||
FieldRank::First(other_field) => other_field.upgrade(),
|
||||
FieldRank::Second(other_field) => Some(other_field.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set this picture's second field.
|
||||
fn set_second_field_to(&mut self, other_field: &Rc<RefCell<Self>>) {
|
||||
self.field_rank = FieldRank::First(Rc::downgrade(other_field));
|
||||
}
|
||||
|
||||
/// Whether the current picture is the second field of a complementary ref pair.
|
||||
pub fn is_second_field_of_complementary_ref_pair(&self) -> bool {
|
||||
self.is_ref()
|
||||
&& matches!(self.field_rank(), FieldRank::Second(first_field) if first_field.borrow().is_ref())
|
||||
}
|
||||
|
||||
/// Set this picture's first field.
|
||||
fn set_first_field_to(&mut self, other_field: &Rc<RefCell<Self>>) {
|
||||
self.field_rank = FieldRank::Second(other_field.clone());
|
||||
}
|
||||
|
||||
pub fn pic_num_f(&self, max_pic_num: i32) -> i32 {
|
||||
if !matches!(self.reference(), Reference::LongTerm) {
|
||||
self.pic_num
|
||||
} else {
|
||||
max_pic_num
|
||||
}
|
||||
}
|
||||
|
||||
pub fn long_term_pic_num_f(&self, max_long_term_frame_idx: MaxLongTermFrameIdx) -> u32 {
|
||||
if matches!(self.reference(), Reference::LongTerm) {
|
||||
self.long_term_pic_num
|
||||
} else {
|
||||
2 * max_long_term_frame_idx.to_value_plus1()
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume this picture and return a Rc'd version.
|
||||
///
|
||||
/// If the picture was a second field, adjust the field of the first field to point to this
|
||||
/// one.
|
||||
pub fn into_rc(self) -> RcPictureData {
|
||||
let self_rc = Rc::new(RefCell::new(self));
|
||||
|
||||
if let FieldRank::Second(first_field) = self_rc.borrow().field_rank() {
|
||||
first_field.borrow_mut().set_second_field_to(&self_rc);
|
||||
}
|
||||
|
||||
RcPictureData { pic: self_rc }
|
||||
}
|
||||
|
||||
/// Split a frame into two complementary fields that reference one another.
|
||||
pub fn split_frame(mut self) -> (RcPictureData, RcPictureData) {
|
||||
assert!(matches!(self.field, Field::Frame));
|
||||
assert!(matches!(self.field_rank, FieldRank::Single));
|
||||
|
||||
debug!(
|
||||
"Splitting picture (frame_num, POC) ({:?}, {:?})",
|
||||
self.frame_num, self.pic_order_cnt
|
||||
);
|
||||
|
||||
let second_pic_order_cnt = if self.top_field_order_cnt < self.bottom_field_order_cnt {
|
||||
self.field = Field::Top;
|
||||
self.pic_order_cnt = self.top_field_order_cnt;
|
||||
|
||||
self.bottom_field_order_cnt
|
||||
} else {
|
||||
self.field = Field::Bottom;
|
||||
self.pic_order_cnt = self.bottom_field_order_cnt;
|
||||
|
||||
self.top_field_order_cnt
|
||||
};
|
||||
|
||||
let second_field = PictureData {
|
||||
top_field_order_cnt: self.top_field_order_cnt,
|
||||
bottom_field_order_cnt: self.bottom_field_order_cnt,
|
||||
frame_num: self.frame_num,
|
||||
reference: self.reference,
|
||||
nonexisting: self.nonexisting,
|
||||
pic_order_cnt: second_pic_order_cnt,
|
||||
field: self.field.opposite(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Split into picture (frame_num, POC) ({:?}, {:?}), field: {:?}",
|
||||
self.frame_num, self.pic_order_cnt, self.field
|
||||
);
|
||||
debug!(
|
||||
"Split into picture (frame_num, POC) ({:?}, {:?}), field {:?}",
|
||||
second_field.frame_num, second_field.pic_order_cnt, second_field.field
|
||||
);
|
||||
|
||||
let first_field = Rc::new(RefCell::new(self));
|
||||
let second_field = Rc::new(RefCell::new(second_field));
|
||||
|
||||
first_field.borrow_mut().set_second_field_to(&second_field);
|
||||
second_field.borrow_mut().set_first_field_to(&first_field);
|
||||
|
||||
(
|
||||
RcPictureData { pic: first_field },
|
||||
RcPictureData { pic: second_field },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PictureData {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PictureData")
|
||||
.field("pic_order_cnt_type", &self.pic_order_cnt_type)
|
||||
.field("top_field_order_cnt", &self.top_field_order_cnt)
|
||||
.field("bottom_field_order_cnt", &self.bottom_field_order_cnt)
|
||||
.field("pic_order_cnt", &self.pic_order_cnt)
|
||||
.field("pic_order_cnt_msb", &self.pic_order_cnt_msb)
|
||||
.field("pic_order_cnt_lsb", &self.pic_order_cnt_lsb)
|
||||
.field(
|
||||
"delta_pic_order_cnt_bottom",
|
||||
&self.delta_pic_order_cnt_bottom,
|
||||
)
|
||||
.field("delta_pic_order_cnt0", &self.delta_pic_order_cnt0)
|
||||
.field("delta_pic_order_cnt1", &self.delta_pic_order_cnt1)
|
||||
.field("pic_num", &self.pic_num)
|
||||
.field("long_term_pic_num", &self.long_term_pic_num)
|
||||
.field("frame_num", &self.frame_num)
|
||||
.field("frame_num_offset", &self.frame_num_offset)
|
||||
.field("frame_num_wrap", &self.frame_num_wrap)
|
||||
.field("long_term_frame_idx", &self.long_term_frame_idx)
|
||||
.field("coded_resolution", &self.coded_resolution)
|
||||
.field("display_resolution", &self.display_resolution)
|
||||
.field("type_", &self.type_)
|
||||
.field("nal_ref_idc", &self.nal_ref_idc)
|
||||
.field("is_idr", &self.is_idr)
|
||||
.field("reference", &self.reference)
|
||||
.field(
|
||||
"ref_pic_list_modification_flag_l0",
|
||||
&self.ref_pic_list_modification_flag_l0,
|
||||
)
|
||||
.field("abs_diff_pic_num_minus1", &self.abs_diff_pic_num_minus1)
|
||||
.field("has_mmco_5", &self.has_mmco_5)
|
||||
.field("nonexisting", &self.nonexisting)
|
||||
.field("field", &self.field)
|
||||
.field("ref_pic_marking", &self.ref_pic_marking)
|
||||
.field("field_rank", &self.field_rank)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,593 @@
|
||||
// Copyright 2024 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::codec::h264::nalu_writer::NaluWriter;
|
||||
use crate::codec::h264::nalu_writer::NaluWriterError;
|
||||
use crate::codec::h264::parser::HrdParams;
|
||||
use crate::codec::h264::parser::NaluType;
|
||||
use crate::codec::h264::parser::Pps;
|
||||
use crate::codec::h264::parser::Sps;
|
||||
use crate::codec::h264::parser::DEFAULT_4X4_INTER;
|
||||
use crate::codec::h264::parser::DEFAULT_4X4_INTRA;
|
||||
use crate::codec::h264::parser::DEFAULT_8X8_INTER;
|
||||
use crate::codec::h264::parser::DEFAULT_8X8_INTRA;
|
||||
|
||||
mod private {
|
||||
pub trait NaluStruct {}
|
||||
}
|
||||
|
||||
impl private::NaluStruct for Sps {}
|
||||
|
||||
impl private::NaluStruct for Pps {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SynthesizerError {
|
||||
Unsupported,
|
||||
NaluWriter(NaluWriterError),
|
||||
}
|
||||
|
||||
impl fmt::Display for SynthesizerError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
SynthesizerError::Unsupported => write!(f, "tried to synthesize unsupported settings"),
|
||||
SynthesizerError::NaluWriter(x) => write!(f, "{}", x.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NaluWriterError> for SynthesizerError {
|
||||
fn from(err: NaluWriterError) -> Self {
|
||||
SynthesizerError::NaluWriter(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub type SynthesizerResult<T> = Result<T, SynthesizerError>;
|
||||
|
||||
/// A helper to output typed NALUs to [`std::io::Write`] using [`NaluWriter`].
|
||||
pub struct Synthesizer<'n, N: private::NaluStruct, W: Write> {
|
||||
writer: NaluWriter<W>,
|
||||
nalu: &'n N,
|
||||
}
|
||||
|
||||
/// Extended Sample Aspect Ratio - H.264 Table E-1
|
||||
const EXTENDED_SAR: u8 = 255;
|
||||
|
||||
impl<N: private::NaluStruct, W: Write> Synthesizer<'_, N, W> {
|
||||
fn u<T: Into<u32>>(&mut self, bits: usize, value: T) -> SynthesizerResult<()> {
|
||||
self.writer.write_u(bits, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn f<T: Into<u32>>(&mut self, bits: usize, value: T) -> SynthesizerResult<()> {
|
||||
self.writer.write_f(bits, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ue<T: Into<u32>>(&mut self, value: T) -> SynthesizerResult<()> {
|
||||
self.writer.write_ue(value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn se<T: Into<i32>>(&mut self, value: T) -> SynthesizerResult<()> {
|
||||
self.writer.write_se(value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn scaling_list(&mut self, list: &[u8], default: &[u8]) -> SynthesizerResult<()> {
|
||||
// H.264 7.3.2.1.1.1
|
||||
if list == default {
|
||||
self.se(-8)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// The number of list values we want to encode.
|
||||
let mut run = list.len();
|
||||
|
||||
// Check how many values at the end of the matrix are the same,
|
||||
// so we can save on encoding those.
|
||||
for j in (1..list.len()).rev() {
|
||||
if list[j - 1] != list[j] {
|
||||
break;
|
||||
}
|
||||
run -= 1;
|
||||
}
|
||||
|
||||
// Encode deltas.
|
||||
let mut last_scale = 8;
|
||||
for scale in &list[0..run] {
|
||||
let delta_scale = *scale as i32 - last_scale;
|
||||
self.se(delta_scale)?;
|
||||
last_scale = *scale as i32;
|
||||
}
|
||||
|
||||
// Didn't encode all values, encode -|last_scale| to set decoder's
|
||||
// |next_scale| (H.264 7.3.2.1.1.1) to zero, i.e. decoder should repeat
|
||||
// last values in matrix.
|
||||
if run < list.len() {
|
||||
self.se(-last_scale)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn default_scaling_list(i: usize) -> &'static [u8] {
|
||||
// H.264 Table 7-2
|
||||
match i {
|
||||
0 => &DEFAULT_4X4_INTRA[..],
|
||||
1 => &DEFAULT_4X4_INTRA[..],
|
||||
2 => &DEFAULT_4X4_INTRA[..],
|
||||
3 => &DEFAULT_4X4_INTER[..],
|
||||
4 => &DEFAULT_4X4_INTER[..],
|
||||
5 => &DEFAULT_4X4_INTER[..],
|
||||
6 => &DEFAULT_8X8_INTRA[..],
|
||||
7 => &DEFAULT_8X8_INTER[..],
|
||||
8 => &DEFAULT_8X8_INTRA[..],
|
||||
9 => &DEFAULT_8X8_INTER[..],
|
||||
10 => &DEFAULT_8X8_INTRA[..],
|
||||
11 => &DEFAULT_8X8_INTER[..],
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn rbsp_trailing_bits(&mut self) -> SynthesizerResult<()> {
|
||||
self.f(1, 1u32)?;
|
||||
|
||||
while !self.writer.aligned() {
|
||||
self.f(1, 0u32)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, W: Write> Synthesizer<'n, Sps, W> {
|
||||
pub fn synthesize(
|
||||
ref_idc: u8,
|
||||
sps: &'n Sps,
|
||||
writer: W,
|
||||
ep_enabled: bool,
|
||||
) -> SynthesizerResult<()> {
|
||||
let mut s = Self {
|
||||
writer: NaluWriter::<W>::new(writer, ep_enabled),
|
||||
nalu: sps,
|
||||
};
|
||||
|
||||
s.writer.write_header(ref_idc, NaluType::Sps as u8)?;
|
||||
s.seq_parameter_set_data()?;
|
||||
s.rbsp_trailing_bits()
|
||||
}
|
||||
|
||||
fn hrd_parameters(&mut self, hrd_params: &HrdParams) -> SynthesizerResult<()> {
|
||||
self.ue(hrd_params.cpb_cnt_minus1)?;
|
||||
self.u(4, hrd_params.bit_rate_scale)?;
|
||||
self.u(4, hrd_params.cpb_size_scale)?;
|
||||
|
||||
for i in 0..=(hrd_params.cpb_cnt_minus1 as usize) {
|
||||
self.ue(hrd_params.bit_rate_value_minus1[i])?;
|
||||
self.ue(hrd_params.cpb_size_value_minus1[i])?;
|
||||
self.u(1, hrd_params.cbr_flag[i])?;
|
||||
}
|
||||
|
||||
self.u(5, hrd_params.initial_cpb_removal_delay_length_minus1)?;
|
||||
self.u(5, hrd_params.cpb_removal_delay_length_minus1)?;
|
||||
self.u(5, hrd_params.dpb_output_delay_length_minus1)?;
|
||||
self.u(5, hrd_params.time_offset_length)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn vui_parameters(&mut self) -> SynthesizerResult<()> {
|
||||
// H.264 E.1.1
|
||||
let vui_params = &self.nalu.vui_parameters;
|
||||
|
||||
self.u(1, vui_params.aspect_ratio_info_present_flag)?;
|
||||
if vui_params.aspect_ratio_info_present_flag {
|
||||
self.u(8, vui_params.aspect_ratio_idc)?;
|
||||
if vui_params.aspect_ratio_idc == EXTENDED_SAR {
|
||||
self.u(16, vui_params.sar_width)?;
|
||||
self.u(16, vui_params.sar_height)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.u(1, vui_params.overscan_info_present_flag)?;
|
||||
if vui_params.overscan_info_present_flag {
|
||||
self.u(1, vui_params.overscan_appropriate_flag)?;
|
||||
}
|
||||
|
||||
self.u(1, vui_params.video_signal_type_present_flag)?;
|
||||
if vui_params.video_signal_type_present_flag {
|
||||
self.u(3, vui_params.video_format)?;
|
||||
self.u(1, vui_params.video_full_range_flag)?;
|
||||
|
||||
self.u(1, vui_params.colour_description_present_flag)?;
|
||||
if vui_params.colour_description_present_flag {
|
||||
self.u(8, vui_params.colour_primaries)?;
|
||||
self.u(8, vui_params.transfer_characteristics)?;
|
||||
self.u(8, vui_params.matrix_coefficients)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.u(1, vui_params.chroma_loc_info_present_flag)?;
|
||||
if vui_params.chroma_loc_info_present_flag {
|
||||
self.ue(vui_params.chroma_sample_loc_type_top_field)?;
|
||||
self.ue(self.nalu.vui_parameters.chroma_sample_loc_type_bottom_field)?;
|
||||
}
|
||||
|
||||
self.u(1, vui_params.timing_info_present_flag)?;
|
||||
if vui_params.timing_info_present_flag {
|
||||
self.u(32, vui_params.num_units_in_tick)?;
|
||||
self.u(32, vui_params.time_scale)?;
|
||||
self.u(1, vui_params.fixed_frame_rate_flag)?;
|
||||
}
|
||||
|
||||
self.u(1, vui_params.nal_hrd_parameters_present_flag)?;
|
||||
if vui_params.nal_hrd_parameters_present_flag {
|
||||
self.hrd_parameters(&vui_params.nal_hrd_parameters)?;
|
||||
}
|
||||
self.u(1, vui_params.vcl_hrd_parameters_present_flag)?;
|
||||
if vui_params.vcl_hrd_parameters_present_flag {
|
||||
self.hrd_parameters(&vui_params.vcl_hrd_parameters)?;
|
||||
}
|
||||
|
||||
if vui_params.nal_hrd_parameters_present_flag || vui_params.vcl_hrd_parameters_present_flag
|
||||
{
|
||||
self.u(1, vui_params.low_delay_hrd_flag)?;
|
||||
}
|
||||
|
||||
self.u(1, vui_params.pic_struct_present_flag)?;
|
||||
|
||||
self.u(1, vui_params.bitstream_restriction_flag)?;
|
||||
if vui_params.bitstream_restriction_flag {
|
||||
self.u(1, vui_params.motion_vectors_over_pic_boundaries_flag)?;
|
||||
self.ue(vui_params.max_bytes_per_pic_denom)?;
|
||||
self.ue(vui_params.max_bits_per_mb_denom)?;
|
||||
self.ue(vui_params.log2_max_mv_length_horizontal)?;
|
||||
self.ue(vui_params.log2_max_mv_length_vertical)?;
|
||||
self.ue(vui_params.max_num_reorder_frames)?;
|
||||
self.ue(vui_params.max_dec_frame_buffering)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn seq_parameter_set_data(&mut self) -> SynthesizerResult<()> {
|
||||
// H.264 7.3.2.1.1
|
||||
self.u(8, self.nalu.profile_idc)?;
|
||||
self.u(1, self.nalu.constraint_set0_flag)?;
|
||||
self.u(1, self.nalu.constraint_set1_flag)?;
|
||||
self.u(1, self.nalu.constraint_set2_flag)?;
|
||||
self.u(1, self.nalu.constraint_set3_flag)?;
|
||||
self.u(1, self.nalu.constraint_set4_flag)?;
|
||||
self.u(1, self.nalu.constraint_set5_flag)?;
|
||||
self.u(2, /* reserved_zero_2bits */ 0u32)?;
|
||||
self.u(8, self.nalu.level_idc as u32)?;
|
||||
self.ue(self.nalu.seq_parameter_set_id)?;
|
||||
|
||||
if self.nalu.profile_idc == 100
|
||||
|| self.nalu.profile_idc == 110
|
||||
|| self.nalu.profile_idc == 122
|
||||
|| self.nalu.profile_idc == 244
|
||||
|| self.nalu.profile_idc == 44
|
||||
|| self.nalu.profile_idc == 83
|
||||
|| self.nalu.profile_idc == 86
|
||||
|| self.nalu.profile_idc == 118
|
||||
|| self.nalu.profile_idc == 128
|
||||
|| self.nalu.profile_idc == 138
|
||||
|| self.nalu.profile_idc == 139
|
||||
|| self.nalu.profile_idc == 134
|
||||
|| self.nalu.profile_idc == 135
|
||||
{
|
||||
self.ue(self.nalu.chroma_format_idc)?;
|
||||
|
||||
if self.nalu.chroma_format_idc == 3 {
|
||||
self.u(1, self.nalu.separate_colour_plane_flag)?;
|
||||
}
|
||||
|
||||
self.ue(self.nalu.bit_depth_luma_minus8)?;
|
||||
self.ue(self.nalu.bit_depth_chroma_minus8)?;
|
||||
self.u(1, self.nalu.qpprime_y_zero_transform_bypass_flag)?;
|
||||
self.u(1, self.nalu.seq_scaling_matrix_present_flag)?;
|
||||
|
||||
if self.nalu.seq_scaling_matrix_present_flag {
|
||||
let scaling_list_count = if self.nalu.chroma_format_idc != 3 {
|
||||
8
|
||||
} else {
|
||||
12
|
||||
};
|
||||
|
||||
for i in 0..scaling_list_count {
|
||||
// Assume if scaling lists are zeroed that they are not present.
|
||||
if i < 6 {
|
||||
if self.nalu.scaling_lists_4x4[i] == [0; 16] {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ false)?;
|
||||
} else {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ true)?;
|
||||
self.scaling_list(
|
||||
&self.nalu.scaling_lists_4x4[i],
|
||||
Self::default_scaling_list(i),
|
||||
)?;
|
||||
}
|
||||
} else if self.nalu.scaling_lists_8x8[i - 6] == [0; 64] {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ false)?;
|
||||
} else {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ true)?;
|
||||
self.scaling_list(
|
||||
&self.nalu.scaling_lists_8x8[i - 6],
|
||||
Self::default_scaling_list(i),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.ue(self.nalu.log2_max_frame_num_minus4)?;
|
||||
self.ue(self.nalu.pic_order_cnt_type)?;
|
||||
|
||||
if self.nalu.pic_order_cnt_type == 0 {
|
||||
self.ue(self.nalu.log2_max_pic_order_cnt_lsb_minus4)?;
|
||||
} else if self.nalu.pic_order_cnt_type == 1 {
|
||||
self.u(1, self.nalu.delta_pic_order_always_zero_flag)?;
|
||||
self.se(self.nalu.offset_for_non_ref_pic)?;
|
||||
self.se(self.nalu.offset_for_top_to_bottom_field)?;
|
||||
self.ue(self.nalu.num_ref_frames_in_pic_order_cnt_cycle)?;
|
||||
|
||||
for offset_for_ref_frame in &self.nalu.offset_for_ref_frame {
|
||||
self.se(*offset_for_ref_frame)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.ue(self.nalu.max_num_ref_frames)?;
|
||||
self.u(1, self.nalu.gaps_in_frame_num_value_allowed_flag)?;
|
||||
self.ue(self.nalu.pic_width_in_mbs_minus1)?;
|
||||
self.ue(self.nalu.pic_height_in_map_units_minus1)?;
|
||||
self.u(1, self.nalu.frame_mbs_only_flag)?;
|
||||
if !self.nalu.frame_mbs_only_flag {
|
||||
self.u(1, self.nalu.mb_adaptive_frame_field_flag)?;
|
||||
}
|
||||
self.u(1, self.nalu.direct_8x8_inference_flag)?;
|
||||
|
||||
self.u(1, self.nalu.frame_cropping_flag)?;
|
||||
if self.nalu.frame_cropping_flag {
|
||||
self.ue(self.nalu.frame_crop_left_offset)?;
|
||||
self.ue(self.nalu.frame_crop_right_offset)?;
|
||||
self.ue(self.nalu.frame_crop_top_offset)?;
|
||||
self.ue(self.nalu.frame_crop_bottom_offset)?;
|
||||
}
|
||||
|
||||
self.u(1, self.nalu.vui_parameters_present_flag)?;
|
||||
if self.nalu.vui_parameters_present_flag {
|
||||
self.vui_parameters()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, W: Write> Synthesizer<'n, Pps, W> {
|
||||
pub fn synthesize(
|
||||
ref_idc: u8,
|
||||
pps: &'n Pps,
|
||||
writer: W,
|
||||
ep_enabled: bool,
|
||||
) -> SynthesizerResult<()> {
|
||||
let mut s = Self {
|
||||
writer: NaluWriter::<W>::new(writer, ep_enabled),
|
||||
nalu: pps,
|
||||
};
|
||||
|
||||
s.writer.write_header(ref_idc, NaluType::Pps as u8)?;
|
||||
s.pic_parameter_set_rbsp()?;
|
||||
s.rbsp_trailing_bits()
|
||||
}
|
||||
|
||||
fn pic_parameter_set_rbsp(&mut self) -> SynthesizerResult<()> {
|
||||
self.ue(self.nalu.pic_parameter_set_id)?;
|
||||
self.ue(self.nalu.seq_parameter_set_id)?;
|
||||
self.u(1, self.nalu.entropy_coding_mode_flag)?;
|
||||
self.u(1, self.nalu.bottom_field_pic_order_in_frame_present_flag)?;
|
||||
|
||||
self.ue(self.nalu.num_slice_groups_minus1)?;
|
||||
if self.nalu.num_slice_groups_minus1 > 0 {
|
||||
return Err(SynthesizerError::Unsupported);
|
||||
}
|
||||
|
||||
self.ue(self.nalu.num_ref_idx_l0_default_active_minus1)?;
|
||||
self.ue(self.nalu.num_ref_idx_l1_default_active_minus1)?;
|
||||
self.u(1, self.nalu.weighted_pred_flag)?;
|
||||
self.u(2, self.nalu.weighted_bipred_idc)?;
|
||||
self.se(self.nalu.pic_init_qp_minus26)?;
|
||||
self.se(self.nalu.pic_init_qs_minus26)?;
|
||||
self.se(self.nalu.chroma_qp_index_offset)?;
|
||||
self.u(1, self.nalu.deblocking_filter_control_present_flag)?;
|
||||
self.u(1, self.nalu.constrained_intra_pred_flag)?;
|
||||
self.u(1, self.nalu.redundant_pic_cnt_present_flag)?;
|
||||
|
||||
if !(self.nalu.transform_8x8_mode_flag
|
||||
|| self.nalu.pic_scaling_matrix_present_flag
|
||||
|| self.nalu.second_chroma_qp_index_offset != 0)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.u(1, self.nalu.transform_8x8_mode_flag)?;
|
||||
self.u(1, self.nalu.pic_scaling_matrix_present_flag)?;
|
||||
|
||||
if self.nalu.pic_scaling_matrix_present_flag {
|
||||
let mut scaling_list_count = 6;
|
||||
if self.nalu.transform_8x8_mode_flag {
|
||||
if self.nalu.sps.chroma_format_idc != 3 {
|
||||
scaling_list_count += 2;
|
||||
} else {
|
||||
scaling_list_count += 6;
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..scaling_list_count {
|
||||
// Assume if scaling lists are zeroed that they are not present.
|
||||
if i < 6 {
|
||||
if self.nalu.scaling_lists_4x4[i] == [0; 16] {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ false)?;
|
||||
} else {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ true)?;
|
||||
self.scaling_list(
|
||||
&self.nalu.scaling_lists_4x4[i],
|
||||
Self::default_scaling_list(i),
|
||||
)?;
|
||||
}
|
||||
} else if self.nalu.scaling_lists_8x8[i - 6] == [0; 64] {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ false)?;
|
||||
} else {
|
||||
self.u(1, /* seq_scaling_list_present_flag */ true)?;
|
||||
self.scaling_list(
|
||||
&self.nalu.scaling_lists_8x8[i - 6],
|
||||
Self::default_scaling_list(i),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.se(self.nalu.second_chroma_qp_index_offset)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::io::Cursor;
|
||||
|
||||
use super::*;
|
||||
use crate::codec::h264::parser::Nalu;
|
||||
use crate::codec::h264::parser::NaluType;
|
||||
use crate::codec::h264::parser::Parser;
|
||||
use crate::codec::h264::parser::Profile;
|
||||
|
||||
#[test]
|
||||
fn synthesize_sps() {
|
||||
let raw_sps_buf = [0x00, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x0a, 0xfb, 0x88];
|
||||
let mut raw_sps = Cursor::new(&raw_sps_buf[..]);
|
||||
|
||||
let nalu = Nalu::next(&mut raw_sps).unwrap();
|
||||
assert_eq!(nalu.header.type_, NaluType::Sps);
|
||||
|
||||
let mut parser = Parser::default();
|
||||
let sps = parser.parse_sps(&nalu).unwrap();
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
Synthesizer::<'_, Sps, _>::synthesize(0, sps, &mut buf, false).unwrap();
|
||||
|
||||
assert_eq!(buf, raw_sps_buf);
|
||||
|
||||
let write_to_file = std::option_env!("CROS_CODECS_TEST_WRITE_TO_FILE") == Some("true");
|
||||
if write_to_file {
|
||||
let mut out = std::fs::File::create("sps.h264").unwrap();
|
||||
out.write_all(&buf).unwrap();
|
||||
out.flush().unwrap();
|
||||
}
|
||||
|
||||
let mut cursor = Cursor::new(&buf[..]);
|
||||
let nalu = Nalu::next(&mut cursor).unwrap();
|
||||
|
||||
let mut parser = Parser::default();
|
||||
|
||||
let sps2 = parser.parse_sps(&nalu).unwrap();
|
||||
|
||||
assert_eq!(sps, sps2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn synthesize_sps_scaling_lists() {
|
||||
let sps = Sps {
|
||||
profile_idc: Profile::High as u8,
|
||||
seq_scaling_matrix_present_flag: true,
|
||||
scaling_lists_4x4: [[
|
||||
11, 20, 10, 20, 10, 22, 10, 20, 10, 20, 13, 20, 10, 20, 10, 24,
|
||||
]; 6],
|
||||
scaling_lists_8x8: [
|
||||
[
|
||||
33, 20, 10, 21, 33, 20, 12, 20, 33, 23, 10, 20, 33, 20, 10, 20, 33, 24, 10, 20,
|
||||
33, 20, 15, 20, 33, 20, 10, 26, 33, 20, 17, 20, 33, 28, 10, 20, 33, 20, 10, 20,
|
||||
33, 29, 10, 20, 33, 20, 11, 20, 33, 20, 10, 20, 33, 20, 10, 20, 33, 20, 10, 20,
|
||||
33, 20, 10, 20,
|
||||
],
|
||||
[
|
||||
10, 77, 11, 20, 10, 77, 12, 20, 10, 77, 13, 20, 10, 77, 14, 20, 10, 77, 15, 20,
|
||||
10, 77, 16, 20, 10, 77, 17, 20, 10, 77, 18, 20, 10, 77, 19, 20, 10, 77, 10, 20,
|
||||
10, 77, 10, 21, 10, 77, 10, 22, 10, 77, 10, 23, 10, 77, 10, 24, 10, 77, 10, 26,
|
||||
10, 77, 10, 28,
|
||||
],
|
||||
[0; 64],
|
||||
[0; 64],
|
||||
[0; 64],
|
||||
[0; 64],
|
||||
],
|
||||
frame_mbs_only_flag: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
Synthesizer::<'_, Sps, _>::synthesize(0, &sps, &mut buf, false).unwrap();
|
||||
|
||||
let write_to_file = std::option_env!("CROS_CODECS_TEST_WRITE_TO_FILE") == Some("true");
|
||||
if write_to_file {
|
||||
let mut out = std::fs::File::create("sps.h264").unwrap();
|
||||
out.write_all(&buf).unwrap();
|
||||
out.flush().unwrap();
|
||||
}
|
||||
|
||||
let mut cursor = Cursor::new(&buf[..]);
|
||||
let nalu = Nalu::next(&mut cursor).unwrap();
|
||||
|
||||
let mut parser = Parser::default();
|
||||
|
||||
let sps2 = parser.parse_sps(&nalu).unwrap();
|
||||
|
||||
assert_eq!(sps.scaling_lists_4x4, sps2.scaling_lists_4x4);
|
||||
assert_eq!(sps.scaling_lists_8x8, sps2.scaling_lists_8x8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn synthesize_pps() {
|
||||
let raw_sps_pps = [
|
||||
0x00, 0x00, 0x00, 0x01, 0x07, 0x4d, 0x40, 0x0d, 0xa9, 0x18, 0x28, 0x3e, 0x60, 0x0d,
|
||||
0x41, 0x80, 0x41, 0xad, 0xb0, 0xad, 0x7b, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08,
|
||||
0xde, 0x09, 0x88,
|
||||
];
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
let mut out = Cursor::new(&mut buf);
|
||||
|
||||
let mut cursor = Cursor::new(&raw_sps_pps[..]);
|
||||
let mut parser: Parser = Default::default();
|
||||
|
||||
while let Ok(nalu) = Nalu::next(&mut cursor) {
|
||||
match nalu.header.type_ {
|
||||
NaluType::Sps => {
|
||||
let sps = parser.parse_sps(&nalu).unwrap();
|
||||
Synthesizer::<'_, Sps, _>::synthesize(0, sps, &mut out, false).unwrap();
|
||||
}
|
||||
NaluType::Pps => {
|
||||
let pps = parser.parse_pps(&nalu).unwrap();
|
||||
Synthesizer::<'_, Pps, _>::synthesize(0, pps, &mut out, false).unwrap();
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
let write_to_file = std::option_env!("CROS_CODECS_TEST_WRITE_TO_FILE") == Some("true");
|
||||
if write_to_file {
|
||||
let mut out = std::fs::File::create("sps_pps.h264").unwrap();
|
||||
out.write_all(&buf).unwrap();
|
||||
out.flush().unwrap();
|
||||
|
||||
let mut out = std::fs::File::create("sps_pps_ref.h264").unwrap();
|
||||
out.write_all(&raw_sps_pps).unwrap();
|
||||
out.flush().unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(buf, raw_sps_pps);
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
43656b2f
|
||||
c9dd1361
|
||||
62d34555
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
45ba0c1a27d0ff82fd7a969631adffe6
|
||||
cee875ded4998c9810a14f9497a11f72
|
||||
d1e0b9347134ba7a07cbcf249066f022
|
||||
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
||||
ee936370
|
||||
0e5e577c
|
||||
bfe430af
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fe6701d54768bc37c76e630435e8fe02
|
||||
3298d47365ac1f9dc0942ece9e104246
|
||||
7cb9209603f53ba995f7eee20b2bbf4b
|
||||
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
9fc67012
|
||||
7f0b441e
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
115a8e6899b71c04e32a0254ba62b30a
|
||||
1fa3f5a930e08943e6d6bfbd5d43004e
|
||||
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
7dd66ef1
|
||||
+1
@@ -0,0 +1 @@
|
||||
d2304abbf0349ec63324741bf723960d
|
||||
@@ -0,0 +1,70 @@
|
||||
# H.264 Test Data
|
||||
|
||||
This document lists the test data used by the H.264 decoder.
|
||||
|
||||
Unless otherwise noted, the CRCs were computed using GStreamer's VA-API decoder in
|
||||
`gst-plugins-bad`.
|
||||
|
||||
## 16x16-I.h264
|
||||
|
||||
A 16x16 progressive byte-stream encoded I-frame to make it easier to spot errors on the libva trace.
|
||||
Encoded with the following GStreamer pipeline:
|
||||
|
||||
```
|
||||
gst-launch-1.0 videotestsrc num-buffers=1 ! video/x-raw,format=I420,width=16,height=16 ! \
|
||||
x264enc ! video/x-h264,profile=constrained-baseline,stream-format=byte-stream ! \
|
||||
filesink location="/tmp/16x16-I.h264"
|
||||
```
|
||||
|
||||
## 16x16-I-P.h264
|
||||
|
||||
A 16x16 progressive byte-stream encoded I-frame and P-frame to make it easier to spot errors on the
|
||||
libva trace. Encoded with the following GStreamer pipeline:
|
||||
|
||||
```
|
||||
gst-launch-1.0 videotestsrc num-buffers=2 ! video/x-raw,format=I420,width=16,height=16 ! \
|
||||
x264enc b-adapt=false ! video/x-h264,profile=constrained-baseline,stream-format=byte-stream ! \
|
||||
filesink location="/tmp/16x16-I-P.h264"
|
||||
```
|
||||
|
||||
## 16x16-I-P-B-P.h264
|
||||
|
||||
A 16x16 progressive byte-stream encoded I-P-B-P sequence to make it easier to it easier to spot
|
||||
errors on the libva trace. Encoded with the following GStreamer pipeline:
|
||||
|
||||
```
|
||||
gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw,format=I420,width=16,height=16 ! \
|
||||
x264enc b-adapt=false bframes=1 ! video/x-h264,profile=constrained-baseline,stream-format=byte-stream ! \
|
||||
filesink location="/tmp/16x16-I-B-P.h264"
|
||||
```
|
||||
|
||||
## 16x16-I-P-B-P-high.h264
|
||||
|
||||
A 16x16 progressive byte-stream encoded I-P-B-P sequence to make it easier to it easier to spot
|
||||
errors on the libva trace. Also tests whether the decoder supports the high profile. Encoded with
|
||||
the following GStreamer pipeline:
|
||||
|
||||
```
|
||||
gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw,format=I420,width=16,height=16 ! \
|
||||
x264enc b-adapt=false bframes=1 ! video/x-h264,profile=high,stream-format=byte-stream ! \
|
||||
filesink location="/tmp/16x16-I-B-P-high.h264"
|
||||
```
|
||||
|
||||
## test-25fps.h264
|
||||
|
||||
Same as Chromium's `test-25fps.h264`. The slice data in `test-25fps-h264-slice-data-*.bin` was
|
||||
manually extracted from GStreamer using GDB.
|
||||
|
||||
## test-25fps-interlaced.h264
|
||||
|
||||
Adapted from Chromium's `test-25fps.h264`. Same file as above, but encoded as interlaced instead
|
||||
using the following ffmpeg command:
|
||||
|
||||
```
|
||||
ffmpeg -i \
|
||||
src/third_party/blink/web_tests/media/content/test-25fps.mp4 \
|
||||
-flags +ilme+ildct -vbsf h264_mp4toannexb -an test-25fps.h264
|
||||
```
|
||||
|
||||
This test makes sure that the interlaced logic in the decoder actually works, specially that "frame
|
||||
splitting" works, as the fields here were encoded as frames.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generates the CRCs for all .h264 files in the current directory using ffmpeg.
|
||||
|
||||
for f in `ls *.h264`; do
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash crc32 - |grep -v '^#' |awk '{print $6}' >$f.crc
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash md5 - |grep -v '^#' |awk '{print $6}' >$f.md5
|
||||
done
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+1
@@ -0,0 +1 @@
|
||||
ЁЃ`_яяяяяяяяя_щЏ°`Џ}Ў��ЇяяяѓЌ%ђ\jЭaБfїЪwц”[bњѓћУJAПяь1ъШ?‹'ю4€Т_®3Iџ?Р`Wqaц– �6ЙFzzZшХ+ЯяГ0шI`‡Э–2рЛЄ}†-“~‘ґшн‚_яьC 88lи5фУг¶в0ЬшkЋЂ
|
||||
BIN
Binary file not shown.
Vendored
+250
@@ -0,0 +1,250 @@
|
||||
8e0a948b
|
||||
0d25f469
|
||||
612a0a5c
|
||||
0a452520
|
||||
6c83e97b
|
||||
d1598a6e
|
||||
26892325
|
||||
e7eb5f61
|
||||
e527446a
|
||||
f85a9d52
|
||||
16bfd3c5
|
||||
e837620a
|
||||
38484895
|
||||
050d070f
|
||||
b30cfcd9
|
||||
bec9e023
|
||||
9b272332
|
||||
f6a542ba
|
||||
bf978015
|
||||
1767b90a
|
||||
f3755595
|
||||
5ae99ff9
|
||||
5b8b86a6
|
||||
44cd3b51
|
||||
d99e1fab
|
||||
17761096
|
||||
271806c4
|
||||
b0d17f38
|
||||
01f033d7
|
||||
6ae775c1
|
||||
42933e3b
|
||||
11f61f13
|
||||
4ecab452
|
||||
8e50b509
|
||||
dfde6c00
|
||||
06703f5c
|
||||
92a02866
|
||||
c6f3a13b
|
||||
4371bed0
|
||||
5dd9e344
|
||||
cfd668a3
|
||||
abfc6c45
|
||||
ffbc45ac
|
||||
be1cbdf9
|
||||
a6dd2c68
|
||||
fc838af2
|
||||
d8f88c05
|
||||
e377a83d
|
||||
8acea967
|
||||
cfcae361
|
||||
47ec0343
|
||||
c5af87e3
|
||||
a4c1d94e
|
||||
080ca745
|
||||
74f48838
|
||||
00480284
|
||||
f2da9c1d
|
||||
8bb000aa
|
||||
32857438
|
||||
e7fcb9ae
|
||||
9bbb834f
|
||||
3889cf50
|
||||
a3ec330c
|
||||
6963e8b3
|
||||
8de3e2f3
|
||||
8e1d1dc1
|
||||
242fd47d
|
||||
e11cc789
|
||||
9e558667
|
||||
2ff16820
|
||||
d75fad55
|
||||
5f4a5907
|
||||
83182bc7
|
||||
450343a5
|
||||
dad31a6d
|
||||
bb365f64
|
||||
cdd2d57b
|
||||
99c0e687
|
||||
52eecf8a
|
||||
951cd566
|
||||
f29f0fef
|
||||
d1165eae
|
||||
0df626f8
|
||||
6fbdfc15
|
||||
7f5180af
|
||||
c1f6a321
|
||||
7d9b9418
|
||||
a0f25570
|
||||
c5af5562
|
||||
acc18caa
|
||||
0d3d93a1
|
||||
cce8f670
|
||||
7804b84a
|
||||
ed7999c0
|
||||
38dbf871
|
||||
09143151
|
||||
866c7c00
|
||||
c782f291
|
||||
65605fc3
|
||||
8f37e317
|
||||
aaf653bf
|
||||
2894b605
|
||||
7eeba8f6
|
||||
cad6e5a6
|
||||
bce25e79
|
||||
cffbc84e
|
||||
c29dc1b4
|
||||
99ac23e8
|
||||
7805efed
|
||||
78623121
|
||||
88767543
|
||||
a5e2df6f
|
||||
555355b0
|
||||
4e646cd0
|
||||
1fa3064f
|
||||
dc4f65f4
|
||||
77c52338
|
||||
41287dca
|
||||
0ea69260
|
||||
2fb243a8
|
||||
3de20c11
|
||||
ad7fd2c0
|
||||
79f73884
|
||||
cf89a598
|
||||
301e0a62
|
||||
3e26fed7
|
||||
8e8dacbe
|
||||
628cfc2b
|
||||
5c7fe45f
|
||||
06892492
|
||||
fb7d8b50
|
||||
ddf98de9
|
||||
5fb4c485
|
||||
501ccf38
|
||||
e5f40baf
|
||||
07ab7574
|
||||
8596934d
|
||||
f7066878
|
||||
27e166e6
|
||||
10a37320
|
||||
39dc9664
|
||||
ca9e1642
|
||||
5d23f171
|
||||
dafd915b
|
||||
ddcbc72c
|
||||
56b4b83d
|
||||
3bbde005
|
||||
41ed4060
|
||||
68caa834
|
||||
957b84b9
|
||||
5f6bbbfc
|
||||
98e64dae
|
||||
ebd05871
|
||||
c851d8e9
|
||||
f73fbbe4
|
||||
7451ac0b
|
||||
cbfd7a78
|
||||
901fe589
|
||||
9ed86bd9
|
||||
1e9fef87
|
||||
faca6981
|
||||
98b7bd7a
|
||||
e1d4bdf1
|
||||
b6a95dee
|
||||
3955fb57
|
||||
90d28016
|
||||
64472746
|
||||
5f2b76df
|
||||
478197b2
|
||||
c59fda8c
|
||||
169c2bfe
|
||||
74210735
|
||||
94662d44
|
||||
f16e4ef6
|
||||
f2134ee3
|
||||
f881db32
|
||||
0d927db1
|
||||
ab77556a
|
||||
12a65d29
|
||||
632965b4
|
||||
807d10f7
|
||||
339e5f7e
|
||||
be2c9336
|
||||
bc593f8b
|
||||
c9dfe52d
|
||||
fc738a40
|
||||
17699e28
|
||||
e8be4231
|
||||
b4264279
|
||||
895a00b1
|
||||
41eb9726
|
||||
e804873a
|
||||
c6a4b014
|
||||
bdc91323
|
||||
14b6934d
|
||||
dd31a422
|
||||
0d379528
|
||||
4e4b45cd
|
||||
9f6773f8
|
||||
326f3f46
|
||||
6180b23d
|
||||
61329916
|
||||
01a1ecf3
|
||||
8b77abcf
|
||||
4508213e
|
||||
dfc43ab1
|
||||
0937305a
|
||||
a9d22bba
|
||||
541a1ba4
|
||||
5eb3490a
|
||||
4702020a
|
||||
190299ca
|
||||
202ef749
|
||||
911daf20
|
||||
b7b63628
|
||||
3bbb965c
|
||||
25971699
|
||||
3cf16f5f
|
||||
1e95278a
|
||||
273193c1
|
||||
48794404
|
||||
a5a25d98
|
||||
7c85b782
|
||||
d17a5be3
|
||||
c218d70a
|
||||
8ce5be9b
|
||||
eed76688
|
||||
7fdd906e
|
||||
136a9e51
|
||||
87674a67
|
||||
0c1f44d8
|
||||
6e09307d
|
||||
f4f2d7f0
|
||||
855c52e4
|
||||
e63633cc
|
||||
8baecd74
|
||||
08371d8b
|
||||
18949a47
|
||||
c253b241
|
||||
c94aa045
|
||||
e272c69c
|
||||
f2b73158
|
||||
6b6d3a84
|
||||
76e9bf4d
|
||||
4c05b45e
|
||||
1a774816
|
||||
47e007d1
|
||||
37e715a7
|
||||
8d8bd4f6
|
||||
733862ca
|
||||
Vendored
+250
@@ -0,0 +1,250 @@
|
||||
b318f483b819b982a9756e53d7e15648
|
||||
f0257b3a3e42c43334b5114f7af458c2
|
||||
7e53dcfd409361c9747f2e15498bffec
|
||||
d149b038ca22572e33a1f395e5ecee08
|
||||
eb27dd6ebe6c63da3383569c0775a831
|
||||
2cbbf7c8d7519b6f5e8ac14363b4bfa5
|
||||
ca1a19e2110b2129f11e8b49127bdd85
|
||||
286936def7ad4df160b360d65ac9b46e
|
||||
b33f9984878150925a7967072e99d49b
|
||||
075757bf9b1875431fff1fef1f8d757b
|
||||
68d3706a9b387f97e6ddbfd4abc57ad0
|
||||
bdde980b77c72c36b4f090c9b5da5344
|
||||
2574458dd66165304420f6ea813d63e5
|
||||
35fcaf6785eb36fc903eb5279b6c29aa
|
||||
ec4f4e19d7e54e26d3dfcc30e46f8a57
|
||||
bffdfe52242097b034c1716a4f3c2c28
|
||||
5fb0282d92050c9a5c7b3c12dd5ced0f
|
||||
6167bc48f2e77dad220a3a6aa67b05bc
|
||||
d3cffb696153090eb014e6a88802bd4e
|
||||
9d175a5550156b1e8bca6099b4c09f61
|
||||
7fbd2aaeedd6f3d6cb9603910c7cf2c2
|
||||
56e21b1c18fff15a62e9933e442fe8ff
|
||||
546312d22a42fc9b67b08e18d6b82852
|
||||
2509014b171245b4a3b692527c2781f3
|
||||
fb31a14a29920145563197157f60b0cf
|
||||
64985fa4c405b139aa60202819bee68c
|
||||
7886fd15be015e09715906507fd7ee6b
|
||||
f86709eedd0ea8413c30e5417dab459a
|
||||
0d3b8df30ef8188a889dc7cdeb02b21f
|
||||
255db4b53038918896afe70d26f7a52c
|
||||
c35945881b96b536573f7eb5a35d9bd3
|
||||
809a7dcc7966d196b61e0645025e959b
|
||||
fe2130868d0026602d29492cfb77365b
|
||||
1f341d6cb526c6cb2b18a4919d13dd3f
|
||||
14a9658c25c52651b75b009cf505c268
|
||||
f1b76a3abadb11253729430c7f333fa8
|
||||
cd204999e6f7912ba9caa4f625314a7d
|
||||
3701e818d60637dfc56407d88b79feda
|
||||
819907f586f4c7515106b4083ddbad47
|
||||
c43789f2fcd506cd7ac5116c9ef4d15d
|
||||
19ae171488b106301ee54078b6f5b5df
|
||||
21ca7fe9e1ab4f13ef5a7f8a041d471d
|
||||
6d23d3b81f1c4c787e0ee9f62f5a9849
|
||||
3c9ea82d2bd157595b69138c327133a6
|
||||
506a237ea2ec916734d9511fbe79be10
|
||||
5001323d2e1b5410def30db2f59e4261
|
||||
f4e315814b0812511fbe50d5c061e324
|
||||
a687ca61e888fe0e36db694a870a62f5
|
||||
9f6f17e40f587c27ba7a24227f279285
|
||||
1e09cb2dcafb86be51648f2a4e14dc24
|
||||
db5fff370bd822000ca204fd64bac350
|
||||
0ad486dd80931116e0eedc3c2938a201
|
||||
c2a0ee00978debffcbd633efe9299d97
|
||||
21fe48e7b1666fedfeb8a6e7b67ed7e9
|
||||
bd2f4438022e4007207af7db7e488674
|
||||
f4c6654ae5325c06d7248b423d2dfff0
|
||||
f24ccbfb2bb7856c3a6a03570b01d1df
|
||||
253e90c855cb01f47c98b86c02ab5038
|
||||
9b1dc8a79e1d93d8756ed0cfcbfe5137
|
||||
aea93cf9423bc3dfc384faaca064397c
|
||||
fb030c4f06693f3610802851ceb11232
|
||||
9307c5df0bef220e2dac16807f7f237e
|
||||
1934c1a1a72b0646d0e9e71c15dc4987
|
||||
5ddc040a414fc5a141ff949e4b127d4a
|
||||
a1d5f1d432006062b5d6b9443c717ad2
|
||||
0589d0ebf3c8d2364237e80d41a2b475
|
||||
ddcebf0cefb4f874243424fac2e3b6de
|
||||
cdf1dfcfc39fa58d1f9092bf38ba7e7f
|
||||
167ce118cb7d087ea441c56fe4d35fb1
|
||||
20dc2343a99d4f973832173523c2f5b1
|
||||
3c54348b7b75234d86ee3dcf298b00dc
|
||||
187f13356155b3966596693b3ba7f6fc
|
||||
e64ec5b7d6554e8976f9d55620ae8411
|
||||
8e4d7d9d357d5146b824655e99284939
|
||||
221da170942678c1bb96f106bdacca65
|
||||
10397b2182e00d3c2f3521adb1125b1e
|
||||
820a2cbffd802eb8444d7d321903855d
|
||||
fb6543d46d8733d2fe8505f058b14e4b
|
||||
088bb42d269720bc1d023537f7b57213
|
||||
5d34e835cf4fe44f26e6ea7df3699323
|
||||
7525e57a778a4b298ab8a1f529dea231
|
||||
f6611d41cae1236372a61794515f3286
|
||||
fa807ac173b70892aa9fbbfe5cf097bf
|
||||
b30a12a5c07b96c5d2a7ef716a40e214
|
||||
b699c6d2b59396338c025cf72e28235e
|
||||
567c19149bb2089eae35fb58e6d3ca9f
|
||||
d3d47ec2f02bc7d564192a98fad66e34
|
||||
bd8293548cf345333c892503bc02762e
|
||||
84c3e877420d17c1536836f1b4b0cf42
|
||||
55c15bb8eb4cd81545314e0ab6535c73
|
||||
e47f3fd5c096033b0d1d3e9de8e05dfe
|
||||
63e69377f86e999221ce62dd101fb530
|
||||
8ca70fbe70b840ffc159f2ba5890b472
|
||||
e5da1d908351429ba3875de6e541a294
|
||||
0cd2b4b3d9dc052d4f3d82235a469809
|
||||
8c47d7a5e67175912811cf24ce1be9df
|
||||
b3a7c2128d325519e6e788ffa19b867b
|
||||
bf803115b52d1452e2f46355deba01a4
|
||||
5db69b7973fd9e6da6aaf7836219d495
|
||||
4466c1bf9d8cb075799e7259b06c3dfd
|
||||
0df28c89649a7ada81ed6b73995dacd3
|
||||
60adb4f96fdf22479e7d1edc583d532f
|
||||
af2802fee9230f40f7662f6eb6318518
|
||||
f1a5beadc8a5ba88b74d31e211b3da2b
|
||||
407d4028cf27cfe3cb265d932dd01ad8
|
||||
837ef722923ce9df10ead5332e2ad1b4
|
||||
d468d3075b95985c692d1182cf45c1f0
|
||||
cf750f31df41c4fd0f64797d7e776243
|
||||
bd0881cfb36014d96dbbd8d1872b449a
|
||||
b3fdd5a0235590e0606eb8223425c206
|
||||
c2130fcb9907554280a2f1024bf5b58e
|
||||
0b4cc296d9d7354718341a0b241d5417
|
||||
09be4cf122c20e92a8460571af96236d
|
||||
2c8763ee3dffb8a2ab123a0b98909531
|
||||
bc07e96aa9fd80daee6b6747f3eb10d9
|
||||
5191f574d1aed73c2fea26ba696ecd73
|
||||
cd863713a5588c5df97f1272bbbc8537
|
||||
1ed61be740e1c0dbca9e803537e913fe
|
||||
6ff899d76a0599bf67b4898078d10c8d
|
||||
ee1f3a668c150ed6dfae060e97dc46cc
|
||||
d73c55aa581d36c4f7f534f1e03c9418
|
||||
d9689cd24ae9b08375530f7ec41a574a
|
||||
08846be9ad2afa27ed851634d9cab4e5
|
||||
1668585e3d72b2bc736fd5b582b17ee8
|
||||
5d2d6df2d6c40044086e8faf5e20fa76
|
||||
53e50b205ac2de14ac79d2a658ef4327
|
||||
e73d59cfc81ec50e7aa5ca9087aaeae4
|
||||
2ca1fe1fc342c4c3dcb28089e82604a3
|
||||
b1cce1a87a2486705b59517c895e817f
|
||||
86143d602317e1302c8d1825bfb201d2
|
||||
7c962811ce295e6ab9c4650cae19319e
|
||||
be87fbaa40ac8989649700e9a82d0ce9
|
||||
d3fd645e47efd43950972463ffd74e3d
|
||||
6ed763a90aca846393467bd37bf6ecc2
|
||||
f888abbf25d47985669b2ecbbda04063
|
||||
1c64db945e018359d80762d0f1e82f85
|
||||
a5c8ff3c974ebbb722e9d6ef92de4c3e
|
||||
7611866a4cb7d346752bc4700621779e
|
||||
075ddd7b4bf5bcc6d308065b94c9e4e6
|
||||
0a59ab9ec9d8228b1b3d554bcbdafa26
|
||||
af6014ace2c40bada1bac0da4ca1855b
|
||||
86955b7f88078d167b381366229f8a42
|
||||
f8c66e921bf190453f6c64ba9dbeb3d5
|
||||
c353624e039f8f5a6ea83196d7559886
|
||||
bb418dee4a5aab8c9c1e5f4d32a4bc8a
|
||||
b56240f383319fc8ceddf6864f715a5b
|
||||
544ab0aebf0e6b5bac10f5c27329ef52
|
||||
dde30afce82bbb95752b39662d79648e
|
||||
ffe0f8f122b0b575c17a745d98af418a
|
||||
ba476f1704cc103f303dc88d6aa5fd31
|
||||
ddfc7326b1e137d4338da33585c94fc4
|
||||
32a313e1553677d00ac43cb8610186bc
|
||||
4fed1c0a1959a9dca55c1d126c704ce7
|
||||
cc073c0fcb57c2a0ac7785d3e36289cb
|
||||
7e91a82a927a14d0be7a4ccdce702222
|
||||
85a1e2124c2acb27c2eae947e371332d
|
||||
b8dad5132989583791ea3180ede734e3
|
||||
b749f5cfa51035c2c901c8f51fdae26f
|
||||
63c8d810da89f6d93895744cf6bc6092
|
||||
c4c32e4c185cf04da9e6f6cb4b228c52
|
||||
6d48d28f00b6cbd78b4ddfa056c4b24f
|
||||
a56ec3b1d282706257e9539d97708745
|
||||
3487a2b855eef272eca5c04ee2b826dd
|
||||
5d35907998c38c521a0bb08dd114900b
|
||||
f01a320fef7ed3cfa74fd5e7b7214491
|
||||
3655861d44a93225eab5a6f6aa4dbd9f
|
||||
adc67f4388f9e4aa42232f19db02690c
|
||||
096cebe6b60bc924def53b2d9413febb
|
||||
8200dc7f73ae39a7fbeaf6b7fdf11e2e
|
||||
ccc47ba3d01aaeb9859cd998d3472efe
|
||||
727e467f3789d4b3805318dd600e8d41
|
||||
ab74f71926d8e1b5d0fb89904c4f0e56
|
||||
2ef13831a4100e211309658d5c02a177
|
||||
796c34d7ccc6790fccabc9be3e42db9c
|
||||
b1fb2e39582d47ab8172702288b2fcbc
|
||||
ac5d037d7457af598c9b7fca0eadb384
|
||||
7a82d0ec070abcbb2d1ef16bc8af47e7
|
||||
ed68a5b6911d53f073b778294192e44f
|
||||
55b14258fc94575ccea51bc4bcf6cb61
|
||||
2502f7cd3fd06ad7994acd5ac8995508
|
||||
afbfe5035e3cdede39a1250b1d91eff4
|
||||
c7bd0e18288966e3fc902e401a1cf92a
|
||||
a3243a3f3ed1f32bf4e2d5ee06cf69ab
|
||||
3538beb96dff67a1d7b81a317950d038
|
||||
ff24aa585a23d93671add56e45ffdca3
|
||||
912bcec63bdabb5a4b472df4b4f557e1
|
||||
d59ad48f9b4378ce89b4bfffec9b916e
|
||||
ea4e4951dc51b56e07bf01c0d4171549
|
||||
7197584855f20ff4903c247939967dca
|
||||
9f7482cc0d499ab79f2eb5480807ec6e
|
||||
eaadda1f5ff577d617e6c4c479b5f563
|
||||
a4c9e70aebeaf8b4f986fbf8bd8aa902
|
||||
10f3080e8374ba0397f1e296fbb60350
|
||||
b021caa467751d617842f66bb4e62b47
|
||||
444ce58ff856af0ee2ba0e99ae37950b
|
||||
b61d88b82f582f32723ee5dfdb1d34de
|
||||
55f921778031bd848ebddb7dc0d63db7
|
||||
bb9ad6dd7d13d4e412bdfec31783992d
|
||||
a4d4f8ce07d3496017024897233b09dc
|
||||
ffd49b1bb1ebb2afa89ac73305762656
|
||||
69d843e05f072e3616e9fbeefe1feb9a
|
||||
4758c49357c312d6187a3cc7322d40a9
|
||||
0200eae7e77a5f7eb0ab6a52b5934c43
|
||||
6f6de279c5b1bf22064d6173e0f4c659
|
||||
dd1f5fc9e67d0f2375e72bfaefa72590
|
||||
bffd8a460d7ee4746ced0abd2e108562
|
||||
2d638249a3d755b2c778f6b384b862e8
|
||||
1e5322f8df0406fdbd2c99d5eeed0a68
|
||||
41e1a633a6adfaa70198f5872272013c
|
||||
9900e6ccab80f965f0f42f5f466e51f6
|
||||
0da72ec72eb2eae9f410267cee90d1b7
|
||||
c808dd41b542e64db7ee2b6770eb99b3
|
||||
2d8b514f3e2257521b2ab872ea7d4ea4
|
||||
be6a7befa9d91157e6a70bee2cdb9516
|
||||
ccc15622babeb66a984b81d80a713966
|
||||
caa22e1262b249b7e0dbac4bdd59e391
|
||||
d759cf8e65cb2b805a7101b32bfe64d2
|
||||
43da07daa63a0ad6c39e5d3b468b7df9
|
||||
2cf45923c9b52de4b23a34ae07616bfa
|
||||
1c5dd7b336a9cfcfa7772e4df2f62075
|
||||
8261e8791fc1d8a5097af6ed2c1487b8
|
||||
e97b262b8f2056851ba19b6b1b23a378
|
||||
567442abf4ee97d491572bd868d50daa
|
||||
cf25196079d433cdd802e87d4211ad3e
|
||||
e7295385f1842ede9e7e5e48602fac00
|
||||
6e44cb843be327f938e1558fd22d9aee
|
||||
e8efa873da70fb0c55e95ccb3b98dd0c
|
||||
1f520e477d527dfee845187c8bba3433
|
||||
da789f8b71e7618b6b614e7f38c6eb06
|
||||
4e9f640a8f317b0da5d3f24e87708866
|
||||
922134326b2d0223cbd3a679adc908e4
|
||||
272aa55d0137df113bee04f8c06e4d46
|
||||
6e5f5d3f6d2c88fdc80f26c3af4baf39
|
||||
2fec6a2b1154841837b77a456627de14
|
||||
71c562a6801157465fd5df54b87504b9
|
||||
eec76ebe71275d86b69a1ca42a8da947
|
||||
42e10d7a5b99affc5d9ed41006e701f2
|
||||
ae0aa8ce889e3ff30b7840b7a2b74737
|
||||
06bebb86bff1e08d071adf6284bbe3b1
|
||||
0fbe06a9de9f8195b03364748b6455e3
|
||||
46f2d55d237687a1b9d3b326c56da6c3
|
||||
3ffbbb180f1c3bf8303967a0840297af
|
||||
19cd3d6d0641fe34da63c78cfc94cb72
|
||||
953d1514d529804060f71d1430fdcf7e
|
||||
961279642b7ca4f0ddc329c2c0d7a819
|
||||
cc4ffd1fe4dab49b3a5ad06948fd3875
|
||||
32f0f8ff923031ac246925020c11868c
|
||||
ab56616053efde4cc28e379d689d380c
|
||||
253c3fa01be26ad95522f95bb3927132
|
||||
0b137261e168b892d7b6b2255198d545
|
||||
BIN
Binary file not shown.
+250
@@ -0,0 +1,250 @@
|
||||
3eae0fa4
|
||||
671432fb
|
||||
36f2633d
|
||||
0d4c5ed0
|
||||
5401b3b1
|
||||
132ea2eb
|
||||
638474a8
|
||||
ddaac73d
|
||||
55d506dd
|
||||
a895940a
|
||||
552aa819
|
||||
3df1c8cb
|
||||
4570f1a7
|
||||
e355e911
|
||||
29220d98
|
||||
e1d6c064
|
||||
44b2001e
|
||||
264b8f82
|
||||
d13e3c00
|
||||
36b2feb1
|
||||
dcee531a
|
||||
f8a44834
|
||||
a913018c
|
||||
90f486e7
|
||||
9a1101d0
|
||||
15332185
|
||||
842e0474
|
||||
bff7bbf9
|
||||
dc8cd701
|
||||
835bd3cd
|
||||
2a3ea506
|
||||
67e8e53b
|
||||
ef5b8038
|
||||
97c89f86
|
||||
ef8a9d7c
|
||||
792b083e
|
||||
388e20b0
|
||||
c9b83d6c
|
||||
868e8252
|
||||
d77091cc
|
||||
33a41580
|
||||
67912531
|
||||
d3a7e0cc
|
||||
fd5ac6f7
|
||||
ed96bee7
|
||||
8b4a495c
|
||||
1219c05f
|
||||
b8050ff4
|
||||
c9c27101
|
||||
465b4659
|
||||
01fb0b1e
|
||||
7a01e4d9
|
||||
1a6333b7
|
||||
bd4e9d8e
|
||||
fe812caa
|
||||
4bb09d4d
|
||||
64b15b3d
|
||||
cba3b242
|
||||
720daf5f
|
||||
44efaa8c
|
||||
14ae7ec5
|
||||
6c6c8c3d
|
||||
3bbaa125
|
||||
7b4872f6
|
||||
a59dd7f2
|
||||
83925660
|
||||
b0679228
|
||||
f52ef9fb
|
||||
2850560d
|
||||
01dfd505
|
||||
94a48963
|
||||
7fcc0cca
|
||||
47528c61
|
||||
032dc2f3
|
||||
bb8e0fb1
|
||||
63914082
|
||||
b9b4c36c
|
||||
c69f899d
|
||||
49a9c94e
|
||||
77af09d5
|
||||
07cdcc3d
|
||||
eabc68d5
|
||||
62421f8d
|
||||
2811bd16
|
||||
e3d5a2e5
|
||||
17d95adb
|
||||
55bcd9cb
|
||||
d785f280
|
||||
45e97423
|
||||
c7457a9c
|
||||
3e2b380f
|
||||
57b67280
|
||||
d02339e4
|
||||
065e3598
|
||||
d5977df8
|
||||
8ae372e3
|
||||
54e17f4c
|
||||
ba6e24c1
|
||||
a8a11da8
|
||||
ed23d1fd
|
||||
c1f3ed84
|
||||
4a46e699
|
||||
fea03186
|
||||
8bf1c40d
|
||||
7ee9d985
|
||||
fd3fafcc
|
||||
f2b62184
|
||||
aceda460
|
||||
97d31d6c
|
||||
54aa313e
|
||||
d95b8ea8
|
||||
70c3792a
|
||||
677ee6ad
|
||||
ca53aba4
|
||||
1351a9f5
|
||||
99a1bb43
|
||||
c01cff4c
|
||||
b1cb013c
|
||||
ef543a58
|
||||
f5c2ae90
|
||||
ca5387ad
|
||||
7b5ca533
|
||||
78d125a3
|
||||
5e04f1b8
|
||||
8f620bd6
|
||||
24ffe5c1
|
||||
5fda8ca9
|
||||
ae38f186
|
||||
2d86f080
|
||||
2b94cc5d
|
||||
697a09f7
|
||||
a6187634
|
||||
dae9cce8
|
||||
74bb20a4
|
||||
18a41fd8
|
||||
a4d92f33
|
||||
e902181c
|
||||
18b9f932
|
||||
e5ee4cda
|
||||
1ccb55bb
|
||||
6ae0fe2e
|
||||
05129a95
|
||||
66d634d7
|
||||
0dceffae
|
||||
00814ab6
|
||||
6370890a
|
||||
c6d35660
|
||||
8eb21a54
|
||||
9ccd4c7e
|
||||
b3a01706
|
||||
79d5382b
|
||||
d56f2dda
|
||||
b6bd04c6
|
||||
becb8b5d
|
||||
0860f480
|
||||
1febbb26
|
||||
c45e567d
|
||||
9b12f235
|
||||
916e5b2b
|
||||
7a0c2458
|
||||
cdfd327b
|
||||
666d700e
|
||||
d5743e0e
|
||||
a8ead497
|
||||
2de13dfe
|
||||
1ef94a75
|
||||
8a05fd88
|
||||
e8498198
|
||||
b3f388bf
|
||||
3ad2a8ed
|
||||
9a871a37
|
||||
1e994a52
|
||||
3c9c0f61
|
||||
9e67b705
|
||||
b37baee1
|
||||
c57c176a
|
||||
8cd83bd6
|
||||
ed5d5bef
|
||||
d933b481
|
||||
75882924
|
||||
662a5466
|
||||
956e24ed
|
||||
f55aa48e
|
||||
16273797
|
||||
1dbffc93
|
||||
dadd656e
|
||||
7bec0c75
|
||||
aabdd998
|
||||
136aa991
|
||||
72abfe71
|
||||
b2be52f9
|
||||
df04bac8
|
||||
fc14d7f9
|
||||
f34ae6f1
|
||||
1ea238aa
|
||||
d77bd8f7
|
||||
821bb618
|
||||
4c543487
|
||||
81bc3b15
|
||||
afd3f64e
|
||||
843d503a
|
||||
54bf670f
|
||||
f447048a
|
||||
51221d02
|
||||
f20efc3b
|
||||
e492c81f
|
||||
a2cff836
|
||||
41ffd6d6
|
||||
8e1877af
|
||||
a866b3ba
|
||||
c7751eaf
|
||||
6d80911d
|
||||
a8701556
|
||||
0185616d
|
||||
ce91cb8b
|
||||
a8b341b7
|
||||
49c4f47d
|
||||
d3001a6b
|
||||
6410d282
|
||||
ee71f778
|
||||
190d2d8f
|
||||
05c09706
|
||||
e25514d3
|
||||
7a8e74df
|
||||
543ac711
|
||||
4477777e
|
||||
40803303
|
||||
3cfae743
|
||||
bf691cc7
|
||||
c94b4dc2
|
||||
7127479d
|
||||
2aaaa442
|
||||
a36b21a2
|
||||
f8fcf82a
|
||||
e024d413
|
||||
7e080f9d
|
||||
937d6382
|
||||
3e0a998f
|
||||
f2af5462
|
||||
64df59a0
|
||||
9a9d533f
|
||||
9e2bd916
|
||||
58084d1b
|
||||
d638f9c7
|
||||
04d186be
|
||||
1b3b2b54
|
||||
48a8fa7d
|
||||
d20ab14c
|
||||
c4b87b7e
|
||||
0ec6efbf
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"profile": "H264PROFILE_MAIN",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
"frame_rate": 25,
|
||||
"num_frames": 250,
|
||||
"num_fragments": 258,
|
||||
"md5_checksums": [
|
||||
"a5dad6170eb13fc5cbc6fe3511d44053",
|
||||
"e056362baaf13dd0f888e67a681ab381",
|
||||
"ee0c33d2b92e0443ca5770bd0c56911f",
|
||||
"0c8f0226fd484358b69e9fce6294a888",
|
||||
"a0809d811b6273bb63ecfdb74097e0df",
|
||||
"0cada76917c6dbca2093352b3beaa2e9",
|
||||
"63a5dae178cfa9e10fc6fdae7957f38d",
|
||||
"7e473898faa27f0372c30ccf7c1702e3",
|
||||
"6d3e896e1748f259207b2be30d24a0ad",
|
||||
"7a8a94778f723b6a4da79be367577dd0",
|
||||
"abbcff2c3d72fe2ccf8205c0e47142cb",
|
||||
"4790caa46b6c5998d627d53cf8a45ed0",
|
||||
"6d183cdb8d57e3c5cb5e5340c71214e0",
|
||||
"2594ab487dcd844860fe120e92e9513b",
|
||||
"1b365becbe416007e1fb269dfe2bf0d5",
|
||||
"ae6953f149e85d1170a27e22cf8fea89",
|
||||
"b6e8a55010fdd0a2a2f9b5aa26f24994",
|
||||
"0ea165fcde3b1a71bbb2e16c615c9e5a",
|
||||
"0dd539e2735c216bce229ada7e0e7722",
|
||||
"9d6b6e80b820a773a16060cd73d0b047",
|
||||
"f9375adb2bebacaed22305ba32af4583",
|
||||
"9185b111100dd0431b23ed799ca02b70",
|
||||
"bdbc5de6197178cc0ef70cdc07b5c34a",
|
||||
"505517fa76a772b8af27670302b5bb80",
|
||||
"df7a95b296257c8ec2c9fed399376631",
|
||||
"8d8d754f34f3118fb0d9ca69da2bf6b0",
|
||||
"f5d0ef57ef80fb4efffc2d4530f0d60e",
|
||||
"262eee5c2f052fcff8d330c5aa62353a",
|
||||
"90ff465117bfc3cc8b6363b204326a0d",
|
||||
"dc2445266fec9498194b185f4dd41fb2",
|
||||
"878f7dcb0df9ddeaa8470f73bbf0d1e6",
|
||||
"848d8910f7c95fbe27bf00d26ce3fc97",
|
||||
"e01547b08bd83922ccd677733ea21472",
|
||||
"fdc049f772de5fb88493d8ec58bf808e",
|
||||
"9f74486171798cbd0d4da6c6bf0ff00f",
|
||||
"557ff971fa63589cd4ae687abb778e15",
|
||||
"0fec7b663d136fcdab088178c7c240a2",
|
||||
"65b1f1ae4a015b9da106ba97baa929f1",
|
||||
"5e495f76502f2010c30c08d0ea7b6371",
|
||||
"96067b4e79207c0430f68ab0a4be612b",
|
||||
"5a5ff39ae498ba16009071e2b19a1047",
|
||||
"cdf81c7f4c94d199cb252cb0f880ba0f",
|
||||
"3e482b016234911fda0acb5a2b31b1e8",
|
||||
"0eba802cbbab73ab3ea6c1713bf38249",
|
||||
"4e3c939c00b2f439b9bb0e4f748cd693",
|
||||
"7da28a3926f11c1ad21ada44919326b7",
|
||||
"bb6ddd70a7c21190a9896deb89f0393f",
|
||||
"3bbc5a5d4855fdef5cff6a72e080db59",
|
||||
"8809185828397c4f188225a3a261319e",
|
||||
"0e6763c0673aad271cd13fc5c6c5b05f",
|
||||
"7dd4aa0e1a6ac5d308ca8437d3b33420",
|
||||
"4b38d5173b9e9f03df4c7d02ae380f7c",
|
||||
"a252d94720017908735d566322be9e25",
|
||||
"a547bf19701974e914d556b55e5cc876",
|
||||
"d9f65e78870600cd4b53cb19ecbde3e0",
|
||||
"22d740be86b5ae270b34a6a05f306169",
|
||||
"c7d9428660fdffccc6cff0a038a65c8f",
|
||||
"50dcb76ce04decbc97e17897a03120f5",
|
||||
"b39d19ae0f6a8dba61eb15f3a27512cf",
|
||||
"bd1dbca640bef318da29f3d6de5bafc4",
|
||||
"5eafb79ab0af0235020931cb2b411e97",
|
||||
"050393b1311b31b5d711cb3a84fa0398",
|
||||
"f8827e35815f52022a340129bc005860",
|
||||
"5c6f844ab5b0fab77e98ea3e5a2c6d30",
|
||||
"f29317ec99a14eeea363fa70d55dfe7a",
|
||||
"9fe58ebd66d22be9a7a443baa2733f83",
|
||||
"f7cdb42ccf66afa9cfe598fdd6243869",
|
||||
"ec68961bf9e81cedb36269a0bf94c851",
|
||||
"16b64cdafde9e955bf5930c4dbeb2f8e",
|
||||
"0c412adf668372e1676957e58e876518",
|
||||
"fb0179693e77dfa0e4873552f81415e0",
|
||||
"9d31a15e3fe050695d0a7a77387dc7b6",
|
||||
"737fa9ddc16c371672ab7c43645b69e5",
|
||||
"3c0723cf264055cdade0834c1fd0c503",
|
||||
"53b4f854484bab3f7fa8043729e14bf0",
|
||||
"6fa2c2fd8930dfc46e37ea8a2a153ea5",
|
||||
"a2d85585fa27d9f000aeed5da5d1722a",
|
||||
"7da150a3fbfad35c7c7e233147f97927",
|
||||
"f33db156c0c29a6125904477c7a52e0c",
|
||||
"8a4b651ac53d128e8bd530f947ecc393",
|
||||
"0ac0408a68e2fee3f359941c3c7664c4",
|
||||
"0af391a381b14b44c61e67baf5716869",
|
||||
"626d9be039035d65f3e6e40f3a1849b7",
|
||||
"388532467f13b64b84280fc2df75157c",
|
||||
"79ac74b267d1e31a9760e4797f3bd9af",
|
||||
"3cb436415cc056b2d2e0b56c5ec99b14",
|
||||
"66b2a9581b65a9f8381dab9b4e3cb107",
|
||||
"13f8261ab7bcc21ab46848b861cab446",
|
||||
"9fd2eb5e88ce9137ba774b8e5743f842",
|
||||
"531d9b50624f55446efe0ce2eb168cbc",
|
||||
"be08a1e2b214db9d3b8a7995bdf8c401",
|
||||
"fbb6f7ff4a4fec07e4609e6292846873",
|
||||
"70924eb573abb590615100d48f54ef92",
|
||||
"7dc5a37f2365231da2145dfbcbcf4a1b",
|
||||
"ca1ef1e6859945533b4afc4bf1a12ab3",
|
||||
"289ee446a3b431865d539ca2d3a50d59",
|
||||
"bc1d07902b4572ea615b6653c01f9b52",
|
||||
"fae9de5e08b65986e9e43df1e5e474e3",
|
||||
"ea4bb6045444a9c3085dcf546eb71016",
|
||||
"162392f165140997cf35e436c03366dd",
|
||||
"1a39e8d92602106ed428487c1e543541",
|
||||
"383cb9b29e98c471ff4de80a3abfe0cb",
|
||||
"cc70ac50536aa7b063375423dad34096",
|
||||
"e2e11c7ade1b414be1e51f626b9939a6",
|
||||
"2eb1b386c45d627ec119abbc84ea8dd9",
|
||||
"e788b25c134e1a0f258af9a88b1e1e2f",
|
||||
"10fb71dee1a7653cb6cc2d19e58b04cb",
|
||||
"8d20c4bbf93fe920a470f4dfb7f2d130",
|
||||
"9ff22a54b4589962f1d475a4d308f96f",
|
||||
"b5f27d12234ab57a97fd8d8595738aac",
|
||||
"6673fddc74d578fdf5e716218211b7ad",
|
||||
"e1cc1721e9c048e480214a8cb1369f08",
|
||||
"cc0d3ce9313fbc02005f4eacf08246f0",
|
||||
"7e275f2e832e8b4518e2aec5925323e6",
|
||||
"747af41fea71a7c443b58632ee06b6b7",
|
||||
"fe8a0cc71b908e241692e36284c9e2a6",
|
||||
"cdba33dbf114170b84ce01177b1eaa7d",
|
||||
"0eb286cac90b1e17f4e02c8625df85b9",
|
||||
"620252c40523dee3f0d3ed75d2d2bfb2",
|
||||
"ab8165d3282c27f4166c44a3f947154f",
|
||||
"25cb402b0681d921c819e00e5b8f77ad",
|
||||
"8ff4db1bb234ca8f2f6f8f4e45dc5088",
|
||||
"f30db0bbdee5bb63bdf04f5d944352a2",
|
||||
"985a0d075da06266437d3257e85e6d0f",
|
||||
"c53c0d7258484d806b908d2c69376688",
|
||||
"9390be2306908ee719ed6135ae3e0661",
|
||||
"3f74122552fa39da806b039fdcafe885",
|
||||
"2c7650ec0a56db5dce916508157d282f",
|
||||
"44f7fa9c7a71d3968830b2dc97005ed2",
|
||||
"0e5a240b5b64b1f86db4f603248d2d48",
|
||||
"dcc1268f74789b61f0120445d86dc3a7",
|
||||
"1df397a99a63248fe2a283d9398e3bf1",
|
||||
"72da4e7b2d0b9327bfc198ea86f259ff",
|
||||
"7152dd7b90eaf1699d5d03a29f41fa96",
|
||||
"ba8f38171542fd2de0e63fc4dd5ca4d1",
|
||||
"452e1a61ecef97d95eedbda97f27626d",
|
||||
"b5163a55f4d3da0cc563f2d8308aa8ea",
|
||||
"0594c34726be28517ff0180cc826031a",
|
||||
"0da52fffcf3ab88f9f1e9a0c5b6c277a",
|
||||
"787b744b305354ac0127af6f7ab6e5b4",
|
||||
"682d202d5b4b154c1e1d87fea635bfe9",
|
||||
"b2dbacace18349a8c4bc4af6d0109caf",
|
||||
"25fbe415ae8031b5f4260222520618f3",
|
||||
"bab2de7762b7e0db9c8b1583b2ca2fe6",
|
||||
"1d8b3418ff6170f7492f8b8098dfbe3c",
|
||||
"89cf144aac4e2932d2b30683ceb8a5df",
|
||||
"b952fe86a6275745f461e2f0243a8f2f",
|
||||
"1c5e35bb8d3f117ad22b80c3208ab36b",
|
||||
"8cba5bec1dbe1e9045cfc458fc3be807",
|
||||
"e3eb152d091b689b142fb52fde68acfe",
|
||||
"a90e523e20ef52a9708c27dd32a32e51",
|
||||
"276c2cb2e4dc2dee97014b913d20ceef",
|
||||
"bb1c76cafaed84030fbdf88cbd38bd10",
|
||||
"dd7155ad9cdb7914394f376585716ce4",
|
||||
"fd088933a0743c3f014c5cde815f8c0d",
|
||||
"cb41f67f3730d052129aa534e4cae33b",
|
||||
"349d01c4e208ae68fa5fbfa5c0b259c2",
|
||||
"44571e3c02368efe154dc942a86db41d",
|
||||
"9d50ad1788986f0e71aaeed49bfde214",
|
||||
"9e102fe1eb1cbfd67370cfe2ec676c42",
|
||||
"16eeab863b12b958d9da04ec16b76049",
|
||||
"697873e7878031ba7e5fb57fcf8bb3ba",
|
||||
"7d1c52765bd7dc87b01b96963085eca5",
|
||||
"dbc235422231280b8b314ac38bf03943",
|
||||
"bad7ce4deaf3ba172e30ee67770d5495",
|
||||
"6c7b0cf1bcb5da8ac7805d722d4c8e52",
|
||||
"92a923806b59470f83a1121c0a2b1282",
|
||||
"790f8f46429044540879beec078c2b9e",
|
||||
"fee37fef18b74dfc5fac61dd343297a4",
|
||||
"adeb2bf5bddd3ee4c3977570f7957eb2",
|
||||
"42da9b4d6561a9faa4646c1938665d8d",
|
||||
"96ef3aa375d97217ac52921f11f53393",
|
||||
"b4b9c2e6dccb82477037b237bc29beb7",
|
||||
"78f5063f7255796d6b954ffa63f171bc",
|
||||
"c48f05d7bd5865ba64bb670ff950528c",
|
||||
"737413a29e706d1ce3cb47476881d72b",
|
||||
"69da9015e20f16edccf22676850577b8",
|
||||
"9b76caf25e9566b9a507d2bc9d381d54",
|
||||
"c7820c8373e48a8219421ce9f01ab923",
|
||||
"1482abead594e3f5dcc4bc73e5cb3ccd",
|
||||
"ae8504362f1612eaf12fd4c99fb09849",
|
||||
"de613970f131a752cceef714c8cee331",
|
||||
"22a358e5278844f125e72d277397fc91",
|
||||
"a57f9588335e6afe9b346a674b8c4b02",
|
||||
"85e88cea5a43e5c7984df07a0b5bed61",
|
||||
"28ef730a1eade5e972beba4e46273451",
|
||||
"238dc0244e981538ef2c57c4667164a5",
|
||||
"7dbead8203f5037fd4ccaf9e662995dc",
|
||||
"a15b6b70fd457142da0841378b31b9e0",
|
||||
"e0e51fa5868886349846a60b105721f0",
|
||||
"afe444099e5c600d3ccaa8711c9099c0",
|
||||
"67eca422c9f2301e0f9f00674392ff31",
|
||||
"d21bc2ee616b28d5501334a56570b229",
|
||||
"93d9d78079d426c690b6c3f707fcc7ab",
|
||||
"50cc4faf4fa623f78f47865cfd638093",
|
||||
"89457f854433da6e28fe3e7d921d632a",
|
||||
"028a95319145051732f732422ad75473",
|
||||
"ef7124eb0ad577d2fb7d4fbd67146242",
|
||||
"d5f82be488a5bb797cbfe4449c96b13e",
|
||||
"06e79dfe8b046868ef7b80eeca6f213c",
|
||||
"52ecabe5b54e0bcdd9e61855b07403d9",
|
||||
"ad0f3e305e4c98d31a7aa7b38bd23feb",
|
||||
"fc8177e47267379c6d86cb66c70a9ecb",
|
||||
"78f8589a7a57c08808c16bf976e97eb7",
|
||||
"f32ef46b3a6364450a4c84dc59a3fdb1",
|
||||
"6dbda2170360e7f601c76ab2d8054ef1",
|
||||
"d7447d04d50b84be9fb685de827fb799",
|
||||
"bd678e5ecd23870c85f0d3ac3b304548",
|
||||
"caa25dceb0de2d4918b62bf290641b36",
|
||||
"5e231beb0c3c7f29770db53fa311efae",
|
||||
"dd68639cb5083b06a1ea1c850028cd6f",
|
||||
"fa1c9525569aba0ef23804b5f586e78b",
|
||||
"d75607ea7fe696715bf898aa537dc1b2",
|
||||
"bb0d9294e588699ce1cf9a3e6a477340",
|
||||
"ef2787371909de8fa59c9f45c41eca96",
|
||||
"7835e9094edcddfb16b147525cd8792e",
|
||||
"42dbe4b5aadf06ffca6f24b465b5ba3c",
|
||||
"36f6aa385cd30d73424113c1a6ff0aad",
|
||||
"cf2ac7f34a03a9e086858debebafb447",
|
||||
"9816f6620aafc8cad3a17e089c0bb3e8",
|
||||
"72db245f772dfcbd40489b96c8f2dd81",
|
||||
"555b6cb91b77a820359dc17e3a85c7c9",
|
||||
"88044cb9b0719ef254908df5694daf16",
|
||||
"82d5c83ae707acc6a24c5e6ea8369a53",
|
||||
"d6ab871f03fb9c3ebd2c16f7b1cd7778",
|
||||
"7eb6daaedc6863c8ca86605862cf55fc",
|
||||
"473e3dc83b70a0639735c211c6fa0fc1",
|
||||
"3b249d9a5747aaae5d21b54cea85f9f4",
|
||||
"1e270e073d634b47675716d555a285fc",
|
||||
"7b2123f7dba790ee1fa3c2f9de87fc19",
|
||||
"5e331a4678035837e9ed06957d13e05d",
|
||||
"fc79c2f6c81d68ea24b5f66373ba1b6f",
|
||||
"a29698a51f90cdeebe78133e9cbb741a",
|
||||
"e4b88aad03803aa0e4432545b2f4d851",
|
||||
"c214f459aa112b1d78bc37a599208891",
|
||||
"b429e6cc68732d804d94929f89c31158",
|
||||
"bb31ded86e464207d3b0b28b544806ad",
|
||||
"92bdd6f9949b8ce7e610345551fcfeec",
|
||||
"a0eccd9dd12fa381f36d0d877c9efa69",
|
||||
"f205c3e0255e4ff75bd86d3fd4ff0fbb",
|
||||
"950096d65b623715914809acf4c0a557",
|
||||
"b87ef8d2938e34894ed1bbf609fb99a2",
|
||||
"0a303937d3043c39e8904cc0ad181555",
|
||||
"05458b392f6555d1343949122653d6af",
|
||||
"d3dd90431ded20aae2f5ff0b65802fa9",
|
||||
"34df02751bd5cc9efe159cb85d0e22a2",
|
||||
"b32744532a99fc2657cdfbc85fd87be7",
|
||||
"160a29e8413328fde6623493a4da522f",
|
||||
"a2029dbf4304d50965dc2aad44b930c4",
|
||||
"1c082bc656c7752f21118f10b8677a6c"
|
||||
]
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
776f98580836e9d1f6de6cd5eaa26541
|
||||
b99c6281ace0eeaf0e5718808a568c2b
|
||||
133d598e8d3bc1ad6dad666799ef3b8c
|
||||
a0a05e3c48e4351dcf08934e55a53147
|
||||
79ecb0b46cf15db887390ee78403c27d
|
||||
b8ad982874240fee89b026eab547af09
|
||||
fb7de18f21faa1480d0f1c50b643b8a5
|
||||
a750adaf7e7a955744c377f3ba9bd99e
|
||||
3b5effc41ded56870353e19aeca14793
|
||||
adacf75ba5386d3442d30c8092fb4384
|
||||
0fb60fb5707a4b34c4a54f156c532423
|
||||
bcafabeb810e85570de61e4bd1b83466
|
||||
096823e6e69b2240cfc5f1c08a23d145
|
||||
d182e6428b339c9ec59081c4c196c4b5
|
||||
0c7edf230a9ca3112cf4895f2af7a835
|
||||
f6aca8639f2d838dba473658547a2928
|
||||
8eb680b4878e0c9e0bcf089b760b2267
|
||||
478b442172760bf7c3c7fe003ad73f21
|
||||
10e0f6e66e9739c36caae0cc2eaa97d3
|
||||
046a852108fc096d1d553a6583590d4a
|
||||
45d7284eafcbc5cccc618c12bc6af4c1
|
||||
8b5426beaac95a80df290220654c1dbf
|
||||
226d2eeae31131078f6d257e5ee89285
|
||||
2e1774cd1b8776a772b6dcb69773c5eb
|
||||
f31ec82bece107ec42c68a53b808e949
|
||||
8a9ba366d610b45d268848d3176ea179
|
||||
17a5556be0efb4a31949857a46cee27e
|
||||
f2077c849aebec971fa1cbc99d1ee8ee
|
||||
a067dd84f656e0367c4b3bad1862c533
|
||||
8be7cef3ee5b1edca2902e0afb28a116
|
||||
5adae2c59438976603e9b4d7da49e210
|
||||
44390208c61cda26906a26c85264ed6e
|
||||
222501ba177acc3aeda64927b0646d4e
|
||||
0d5fdc758b4632fd7792ce22bcfe717c
|
||||
144f01c1f347bb9f4dc27df962d37b4f
|
||||
c88762634ecfa06f1d12a4ce8a025af5
|
||||
2f5304392f987f4522e1ed7519475321
|
||||
1cbef99d860f038da6b8b2769d6c8e22
|
||||
8b5209b0fd0c84b96b9707c77778fe4c
|
||||
d78469cd4fba6d81b440d1fcb6ed1a71
|
||||
11d869672accf917e3f4f706f8f4a9d4
|
||||
ef985cbc882bac5bf8639f8d82680e8f
|
||||
96e113dc4f4d7526b49fb5ea0f8e901d
|
||||
ce418516be51f76d27509e2fd550f986
|
||||
7bd8928c90578e0d2fd8c9c1989946f9
|
||||
5a09fc3b51daba42beef52fce8e15881
|
||||
ab0430d72c7fd2288830fb99aae787e3
|
||||
7a5b68603fd986c7f6027f82fce47cdf
|
||||
305ec7419408437f8daeff01e3aad6cc
|
||||
0038fd9154185e9f0a5fded4e8dca4dd
|
||||
375019f32ed04e8484864f9fc51afd21
|
||||
6d8fb78c18042b55884d0a9e8c7ed7ea
|
||||
f83931a19f8de74dfb93082c228a73bb
|
||||
04a585694299a82dc862b108f1691dbf
|
||||
fbc073e705710480225f17d16ccd6527
|
||||
1d9e07daeb879c11029397f80513aec9
|
||||
3a1ba3f2da5307b17c68803bea449df1
|
||||
8d2f9d9a9d1188dbb90b987b321b9cb6
|
||||
57c52b47a13cc8aeab3ab005cceb45fd
|
||||
c52eee2498f6d567bd48e5a7a4046b51
|
||||
a401da6fb4349055cf343cd44a974497
|
||||
2def25c6377a6c1b069003f838f6ec31
|
||||
67331ed57c8a7f189727f84e9a5469ec
|
||||
8d279d4327fe50f2ff21ee53eb6cf015
|
||||
9e5e8223bdc1abbfba3cb65700452b70
|
||||
eb211e3d53c1fe49e89aa6ad729fc13c
|
||||
fc5a3e258868dfb2aedde494f8f475cd
|
||||
1fe91a15c43a4ad8f7007234de8ac222
|
||||
9d43fdbd942765778da18fa223f43cc6
|
||||
733b6b775a4a0421fc091216705ef652
|
||||
9ab696e0d1dac6105f84ea8ca9465756
|
||||
d5686e35b935d8990e5dee6d1bcf4723
|
||||
706aba57f814480fa8a17e078b6352f8
|
||||
0e5f8befc07ff3317ca174fd587e25bc
|
||||
f95f242b2e2eafea3f5a20cdf0c34d89
|
||||
0f1a8078ce533787c9cb30c9429dd450
|
||||
a226c15cc7e0c0b7e1c4de8c620c07b7
|
||||
36edee26f6f02c1576019034648cd4c8
|
||||
c79dea598375f06c3a24d75f5b77e8cb
|
||||
eb6fd06a0916ba6d60be7f4ad8561c0b
|
||||
d022fdb8aa0e7cdc1fd83680b9b8a0fd
|
||||
b5bb9c5a4cb36aa9c6b4b58076268d3d
|
||||
38416e5de6f0092bbf61efe8ed7f76cb
|
||||
a2ce2bf815fffc1fca8d99a4c97afb50
|
||||
6beb9dbfdc0edb74498a49c2d81106b3
|
||||
7b13ce77fc66031f036a8667076790f2
|
||||
569dcc3536bb44110d6b3a54bf0dee88
|
||||
6e08f74630a07154df6461ae25a955c9
|
||||
af8235bf965e972834a181f9210b9e09
|
||||
f9e4b7b0ffbbb24431e2ec6b6b337436
|
||||
d87cfba6630357b213316c6608583be5
|
||||
ec3382387784e715ea321fc05ce95372
|
||||
bc0fef2061b2e64ab5a40e0174a49ea7
|
||||
91d25f646606b2f9992688ef4edf4abb
|
||||
008e89f1070b0d8e2477d7e9fb9a86c9
|
||||
69bf6be50b0c1f9305f2522a1b01deef
|
||||
11db65d54b6c6b6c39062a3beaf82427
|
||||
efe6a4e563d48c7c86341a0f30e8fefe
|
||||
8df7408615732649f592c7830cb0f00e
|
||||
2fe4ec387ce34336dd8b968dac027b62
|
||||
0ae9182a07b24f27298e8eff4a74b541
|
||||
c0215167505dc21651dbef4565d0ae9c
|
||||
4453511aab349d4e9444949ce7b5c138
|
||||
29921ddff3b0ba42de2b36249f06a70a
|
||||
9e8fb2d42c7c90f64c346023186c1d46
|
||||
76e252269587a07138b016f57d09d5d4
|
||||
a3d3e21942d46be6f98cac225bac9fa1
|
||||
47ebd96106eb758c2ab1d7f6325a46ae
|
||||
fea2c0b6ff517b07aec90c975d3e929f
|
||||
a58220f49b95e399365f5a9c083923d6
|
||||
0ba65b271d8d95d5b1c4ba96a6281e48
|
||||
980589673748a3e2cfd37920e330d1e2
|
||||
5c800089bdd1626fb2d3b9b51520b2a1
|
||||
5aea26dea4436520f9643ed92409daae
|
||||
48499bbd0c06d1873249ddd2a5dc76a0
|
||||
6905e3dc0ee6930b3678d56898bfc5ef
|
||||
76c17247950a478a67b6adc5e4baa195
|
||||
18c123fbb6833207b27e7a400529a607
|
||||
9a41b6d8f3c52ebd3a1517fb822d09e1
|
||||
10cb9cde61fe48ed38bbe9d50755eaaf
|
||||
1899fe52ca9524948a641acba633c087
|
||||
03b254591b13d993575b960b8a5e5bfe
|
||||
2cbcffec5b410eb6ecdd05c48e7f0526
|
||||
69fd3b0f432bb70404a2a8deddd33856
|
||||
f0a8ad93606ae12b229aff1ec0e2c3ee
|
||||
580ae926ff57ac9ae54f35b000012b97
|
||||
87e3e0f6204e2ad502eb5153c65b2632
|
||||
d129b9408e42287088d7613d3bfbcd12
|
||||
dbc5c280fb9001496ed8b45602b4de1b
|
||||
f9c1efcff8549db819571d9a6cd55480
|
||||
9d0a444c988a2027cbc41c2163be63db
|
||||
1070020a0a6afb6c597d61b8524381ba
|
||||
a21ab68bc243e08536feb2624647f7db
|
||||
2e718c27e0d3266618907e40cc4a28a6
|
||||
4669c75778da3184aba250b6310b6d1b
|
||||
4e841515c3647e65a00b63dee84e67eb
|
||||
f867fae5ebf1ed714c5a70f3fe10adbc
|
||||
90cacccf6932ba8660e08b586f7597f7
|
||||
cb0774848fc16d1536418ab7e5ada88a
|
||||
c3e74fbbd564f993828e8cbeb876f31e
|
||||
90fe0f8363b9a3fb33b9b2bb4db254a4
|
||||
d38e11dcb17af7dd7e700355aa92e003
|
||||
9bb3f94f84033c4937adf84586e2be95
|
||||
4b4aedbc5dfa015b897b765e566feb96
|
||||
acd1ceb766b0a4e15f25870f0244f549
|
||||
32119d41be592c1f669ffd0b3a7888eb
|
||||
7e7775b06fa9b72f771ec6b8d481a6d0
|
||||
4415957d5a0d1526db1c19bc17b5d395
|
||||
334f9ae780437dca2a5fc3377d46f6e5
|
||||
35c3b43d748aad62f7410306ea3c3f99
|
||||
1ab4c3340132c3f5fa6ef55ba7b08127
|
||||
a61818d54edda2029762e87b9b431c34
|
||||
1af968ff49189f25e28b9d8afcd46a92
|
||||
80a8b78662dcd2aa4b1615b1325757a2
|
||||
10ad96ed6e46f5b054603f66ed6bf29b
|
||||
362457c91a605e04d3334b03b349ec78
|
||||
7704dc866db3238023317a0eac5b8249
|
||||
4231732950cb318403a45f38a46ad46b
|
||||
a8482c9229879f410b309fc77983e3d1
|
||||
45063084d5e5dfab462adaf5fcb43795
|
||||
5028d5d62a02bf9c6843602c9843f54d
|
||||
bc0d1e086e96d1347cb800a1d1aae611
|
||||
343d41fca235543df80e8ecee45f2248
|
||||
e68ed7bc5e4f4d5b92202011cdcda940
|
||||
d8735dcc4a5b6f28f8724616e256b759
|
||||
c261e7a13a9b507af279ed948acbe386
|
||||
4d5af215399a10792b02e6a372aadb02
|
||||
381abc836088178c39cc7da9b588b5a3
|
||||
406e3372afbd23924539b43f6fb9dc63
|
||||
032c29160e0529defc053d863b543926
|
||||
eb4b9c324770d1f900191833ccc4c603
|
||||
7540374c617d048db93719f2f74869e0
|
||||
8d851c4ee3ed3b42a8f8abc37dc037d9
|
||||
0cc60cb97509cd32f8de9a33248ec2a5
|
||||
bcb5a48c5816ecf1c701c1887fd72531
|
||||
2d0681c5f0c5daa293ac07c83ef0c852
|
||||
936265a67adf4d3bc271d0ef0513c4bf
|
||||
58e976105d9eb6e0715927143ddfad37
|
||||
b6a82350ee6b0f00fb5323b32e8b8dd4
|
||||
5cbc1b4da91aed315f7988ee9b4f6ae7
|
||||
446945e9f46db22cc480474572957f43
|
||||
8cdbbe21312c86754be28c1af186c85f
|
||||
c696ac596e16de134f9026c2fc89fcb9
|
||||
ac368b1a10748d0e18452527fdb67cd9
|
||||
f1eb8157957c7a2a84b5310c2825c5fd
|
||||
7fd5969b27e06110ee5eb52c0b7f895f
|
||||
93a4c8093abe3a4e37cb317584adec57
|
||||
3495c733a5c07428d7014799147f903b
|
||||
5fb650661b0891f52cc9d908e3425033
|
||||
399e846bf54ea08b854adc57b33bb940
|
||||
5377988dae4eb18ac1d50e0add7938a1
|
||||
f6f14c9520459a1bde9378e1faa59ca0
|
||||
93cce870e1a92b6ab841ccf2a27b2770
|
||||
7f79cd2127ac7c289414e993005828a6
|
||||
ed4d0faa60421d65cbefcc8ea9a83f00
|
||||
8c6b723120855441c69ef4ddd7e5194b
|
||||
9d675f33810dcac032f38e224e4bb65d
|
||||
a99ad6ea3c77cfb3dd94f8b39a909a34
|
||||
9d2f4e964ba17ef2c7d0496231b1c47b
|
||||
a6f1e6419f610d1f33888bcc7b16c6d1
|
||||
f7e92cd6ee5c8aa99f7be89fd4b9f79f
|
||||
9f95bf8beae3f90eeaa45f8a6003f0aa
|
||||
361311a47b6cefc08b8e8af37fd68038
|
||||
afc33b5877411da4349e013560a15e17
|
||||
3811debaef6b08f2e9338e9d04f6f02c
|
||||
7fd97c64677f845e98a4a0dc97a7711c
|
||||
7a7392b1f2525842393dba40e92077cb
|
||||
24ec025a0d2e7c2a57ff336f0a9baba1
|
||||
72f4ad6e07a788cd9356f01c92d94c8a
|
||||
3a801f8e16b8fc40b03be96b9db43e08
|
||||
c89e78f74a7dd4c649413129534b9367
|
||||
026609682e9ef750ea8e3f196c017c56
|
||||
2cc76327407153e015d1ae69f14f643f
|
||||
9aa38da2abb78d2b237f89ccf3fd052d
|
||||
e6f44e4485cef73ffa5a649aaeb92293
|
||||
ed8a7d1abce5a3f45d771ded4b8d0ddf
|
||||
b477e09272a812756950266e6d9d21a3
|
||||
7f7822c20694075ba7f74a1cc58ed326
|
||||
da4bd23e36c0cd2683ad3a08ccb92381
|
||||
a9e2a88720bfa413e5e3b2fd4c1306bc
|
||||
3e91bbfe96a7462186151f6e76e36233
|
||||
8fb00375e1d7595fa4544359f349eaed
|
||||
106d0cc1aad3fa1014b8a34ebe7a4a3c
|
||||
1692448922564e97d70d04cc12d55e81
|
||||
3537b9b91dcae2df5d3a09805a7ffc4d
|
||||
111ddd889dc595e18f97a93e36f7d3f2
|
||||
8e8875c00cfc5394e731e8c2d4846f07
|
||||
3f728c9ea9954a093405040047271fb4
|
||||
f93ef278c1c3dff430da16ee3596a83f
|
||||
51c0bd2ac650dd07df5b3630aee3705e
|
||||
f33a19dd85ef67cdf5a0d92f3f1fbecf
|
||||
0a6a7457190fa0fa9989dc71fee2152b
|
||||
f4b157a6ef24d5d2a1027120fc419a91
|
||||
dd69ac1443293ea2f753eda6e94101bc
|
||||
0f431525cb6ac56aa05484cf2a067303
|
||||
4aa02c74b3054a4ae3b13a5fbdeccd1f
|
||||
4f7c553a7830426c493b59685b371223
|
||||
738fc54e143b460de42f6279a9ef1672
|
||||
a437cbbd9abf89d9e8b1e69b4ef48b86
|
||||
afe6cb281c9ce601a1f4ab4d673f734f
|
||||
4756e9d1ebb100cdf77ff9e6f9d182f6
|
||||
a65853ac0ade5103a5840542e6e16c32
|
||||
f5abe519e7bf7078d4c581ed477b80bc
|
||||
d75c1f88e47baeef857fc43e8ad25ba0
|
||||
7200f686415f52d0d3ac0684eca69fb2
|
||||
31674be1dabca7c3fabef1c7481d6538
|
||||
4aa521f1811346604b61a29c658ab020
|
||||
fd049c4f80a58b6e2f4aea4d02b941d7
|
||||
ef6b331ba064b6637de7e821d5d6d935
|
||||
f23fa47c8cc237fa2f878b0bfc508986
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
pub mod dpb;
|
||||
pub mod parser;
|
||||
pub mod picture;
|
||||
@@ -0,0 +1,297 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::cell::Ref;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::RefMut;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::codec::h265::parser::Sps;
|
||||
use crate::codec::h265::picture::PictureData;
|
||||
use crate::codec::h265::picture::Reference;
|
||||
|
||||
// Shortcut to refer to a DPB entry.
|
||||
//
|
||||
// The first member of the tuple is the `PictureData` for the frame.
|
||||
//
|
||||
// The second member is the backend handle of the frame.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DpbEntry<T>(pub Rc<RefCell<PictureData>>, pub T);
|
||||
|
||||
pub struct Dpb<T> {
|
||||
/// List of `PictureData` and backend handles to decoded pictures.
|
||||
entries: Vec<DpbEntry<T>>,
|
||||
/// The maximum number of pictures that can be stored.
|
||||
max_num_pics: usize,
|
||||
}
|
||||
|
||||
impl<T: Clone> Dpb<T> {
|
||||
/// Returns an iterator over the underlying H265 pictures stored in the
|
||||
/// DPB.
|
||||
pub fn pictures(&self) -> impl Iterator<Item = Ref<'_, PictureData>> {
|
||||
self.entries.iter().map(|h| h.0.borrow())
|
||||
}
|
||||
|
||||
/// Returns a mutable iterator over the underlying H265 pictures stored in
|
||||
/// the DPB.
|
||||
pub fn pictures_mut(&mut self) -> impl Iterator<Item = RefMut<'_, PictureData>> {
|
||||
self.entries.iter().map(|h| h.0.borrow_mut())
|
||||
}
|
||||
|
||||
/// Returns the length of the DPB.
|
||||
pub fn len(&self) -> usize {
|
||||
self.entries.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Get a reference to the whole DPB entries.
|
||||
pub fn entries(&self) -> &Vec<DpbEntry<T>> {
|
||||
&self.entries
|
||||
}
|
||||
|
||||
/// Set the dpb's max num pics.
|
||||
pub fn set_max_num_pics(&mut self, max_num_pics: usize) {
|
||||
self.max_num_pics = max_num_pics;
|
||||
}
|
||||
|
||||
/// Get a reference to the dpb's max num pics.
|
||||
pub fn max_num_pics(&self) -> usize {
|
||||
self.max_num_pics
|
||||
}
|
||||
|
||||
/// Mark all pictures in the DPB as unused for reference.
|
||||
pub fn mark_all_as_unused_for_ref(&mut self) {
|
||||
for mut picture in self.pictures_mut() {
|
||||
picture.set_reference(Reference::None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the position of `needle` in the DPB, if any.
|
||||
fn get_position(&self, needle: &Rc<RefCell<PictureData>>) -> Option<usize> {
|
||||
self.entries
|
||||
.iter()
|
||||
.position(|handle| Rc::ptr_eq(&handle.0, needle))
|
||||
}
|
||||
|
||||
/// Finds a reference picture in the DPB using `poc`.
|
||||
pub fn find_ref_by_poc(&self, poc: i32) -> Option<DpbEntry<T>> {
|
||||
let position = self
|
||||
.pictures()
|
||||
.position(|p| p.is_ref() && p.pic_order_cnt_val == poc);
|
||||
|
||||
log::debug!("find_ref_by_poc: {}, found position {:?}", poc, position);
|
||||
Some(self.entries[position?].clone())
|
||||
}
|
||||
|
||||
/// Finds a reference picture in the DPB using `poc` and `mask`.
|
||||
pub fn find_ref_by_poc_masked(&self, poc: i32, mask: i32) -> Option<DpbEntry<T>> {
|
||||
let position = self
|
||||
.pictures()
|
||||
.position(|p| p.is_ref() && p.pic_order_cnt_val & mask == poc);
|
||||
|
||||
log::debug!("find_ref_by_poc: {}, found position {:?}", poc, position);
|
||||
Some(self.entries[position?].clone())
|
||||
}
|
||||
|
||||
/// Finds a short term reference picture in the DPB using `poc`.
|
||||
pub fn find_short_term_ref_by_poc(&self, poc: i32) -> Option<DpbEntry<T>> {
|
||||
let position = self.pictures().position(|p| {
|
||||
matches!(p.reference(), Reference::ShortTerm) && p.pic_order_cnt_val == poc
|
||||
});
|
||||
|
||||
log::debug!(
|
||||
"find_short_term_ref_by_poc: {}, found position {:?}",
|
||||
poc,
|
||||
position
|
||||
);
|
||||
Some(self.entries[position?].clone())
|
||||
}
|
||||
|
||||
/// Drains the DPB by continuously invoking the bumping process.
|
||||
pub fn drain(&mut self) -> Vec<DpbEntry<T>> {
|
||||
log::debug!("Draining the DPB.");
|
||||
|
||||
let mut pics = vec![];
|
||||
while let Some(pic) = self.bump(true) {
|
||||
pics.push(pic);
|
||||
}
|
||||
|
||||
pics
|
||||
}
|
||||
|
||||
/// Whether the DPB needs bumping. See C.5.2.2.
|
||||
pub fn needs_bumping(&mut self, sps: &Sps) -> bool {
|
||||
let num_needed_for_output = self.pictures().filter(|pic| pic.needed_for_output).count();
|
||||
|
||||
let highest_tid = sps.max_sub_layers_minus1;
|
||||
let max_num_reorder_pics = sps.max_num_reorder_pics[usize::from(highest_tid)];
|
||||
let max_latency_increase_plus1 = sps.max_latency_increase_plus1[usize::from(highest_tid)];
|
||||
let pic_over_max_latency = self.pictures().find(|pic| {
|
||||
pic.needed_for_output && pic.pic_latency_cnt >= i32::from(max_latency_increase_plus1)
|
||||
});
|
||||
let max_dec_pic_buffering =
|
||||
usize::from(sps.max_dec_pic_buffering_minus1[usize::from(highest_tid)]) + 1;
|
||||
|
||||
num_needed_for_output > max_num_reorder_pics.into()
|
||||
|| (max_latency_increase_plus1 != 0 && pic_over_max_latency.is_some())
|
||||
|| self.entries().len() >= max_dec_pic_buffering
|
||||
}
|
||||
|
||||
/// Find the lowest POC in the DPB that can be bumped.
|
||||
fn find_lowest_poc_for_bumping(&self) -> Option<DpbEntry<T>> {
|
||||
let lowest = self
|
||||
.pictures()
|
||||
.filter(|pic| pic.needed_for_output)
|
||||
.min_by_key(|pic| pic.pic_order_cnt_val)?;
|
||||
|
||||
let position = self
|
||||
.entries
|
||||
.iter()
|
||||
.position(|handle| handle.0.borrow().pic_order_cnt_val == lowest.pic_order_cnt_val)
|
||||
.unwrap();
|
||||
|
||||
Some(self.entries[position].clone())
|
||||
}
|
||||
|
||||
/// See C.5.2.4 "Bumping process".
|
||||
pub fn bump(&mut self, flush: bool) -> Option<DpbEntry<T>> {
|
||||
let handle = self.find_lowest_poc_for_bumping()?;
|
||||
let mut pic = handle.0.borrow_mut();
|
||||
|
||||
pic.needed_for_output = false;
|
||||
log::debug!("Bumping POC {} from the dpb", pic.pic_order_cnt_val);
|
||||
log::trace!("{:#?}", pic);
|
||||
|
||||
if !pic.is_ref() || flush {
|
||||
let index = self.get_position(&handle.0).unwrap();
|
||||
|
||||
log::debug!(
|
||||
"Removed POC {} from the dpb: reference: {}, flush: {}",
|
||||
pic.pic_order_cnt_val,
|
||||
pic.is_ref(),
|
||||
flush
|
||||
);
|
||||
log::trace!("{:#?}", pic);
|
||||
|
||||
self.entries.remove(index);
|
||||
}
|
||||
|
||||
Some(handle.clone())
|
||||
}
|
||||
|
||||
/// See C.5.2.3. Happens when we are done decoding the picture.
|
||||
pub fn needs_additional_bumping(&mut self, sps: &Sps) -> bool {
|
||||
let num_needed_for_output = self.pictures().filter(|pic| pic.needed_for_output).count();
|
||||
let highest_tid = sps.max_sub_layers_minus1;
|
||||
|
||||
let max_num_reorder_pics = sps.max_num_reorder_pics[usize::from(highest_tid)];
|
||||
let max_latency_increase_plus1 = sps.max_latency_increase_plus1[usize::from(highest_tid)];
|
||||
|
||||
let pic_over_max_latency = self.pictures().find(|pic| {
|
||||
pic.needed_for_output && pic.pic_latency_cnt >= i32::from(max_latency_increase_plus1)
|
||||
});
|
||||
|
||||
num_needed_for_output > max_num_reorder_pics.into()
|
||||
|| (max_latency_increase_plus1 != 0 && pic_over_max_latency.is_some())
|
||||
}
|
||||
|
||||
/// Clears the DPB, dropping all the pictures.
|
||||
pub fn clear(&mut self) {
|
||||
log::debug!("Clearing the DPB");
|
||||
|
||||
let max_num_pics = self.max_num_pics;
|
||||
|
||||
*self = Default::default();
|
||||
self.max_num_pics = max_num_pics;
|
||||
}
|
||||
|
||||
/// Removes all pictures which are marked as "not needed for output" and
|
||||
/// "unused for reference". See C.5.2.2
|
||||
pub fn remove_unused(&mut self) {
|
||||
log::debug!("Removing unused pictures from DPB.");
|
||||
self.entries.retain(|e| {
|
||||
let pic = e.0.borrow();
|
||||
let retain = pic.needed_for_output || pic.is_ref();
|
||||
log::debug!("Retaining pic POC: {}: {}", pic.pic_order_cnt_val, retain);
|
||||
retain
|
||||
})
|
||||
}
|
||||
|
||||
/// Store a picture and its backend handle in the DPB.
|
||||
pub fn store_picture(
|
||||
&mut self,
|
||||
picture: Rc<RefCell<PictureData>>,
|
||||
handle: T,
|
||||
) -> Result<(), String> {
|
||||
if self.entries.len() >= self.max_num_pics {
|
||||
return Err("Can't add a picture to the DPB: DPB is full.".into());
|
||||
}
|
||||
|
||||
let mut pic = picture.borrow_mut();
|
||||
log::debug!(
|
||||
"Stored picture POC {:?}, the DPB length is {:?}",
|
||||
pic.pic_order_cnt_val,
|
||||
self.entries.len()
|
||||
);
|
||||
|
||||
if pic.pic_output_flag {
|
||||
pic.needed_for_output = true;
|
||||
pic.pic_latency_cnt = 0;
|
||||
} else {
|
||||
pic.needed_for_output = false;
|
||||
}
|
||||
|
||||
// C.3.4.
|
||||
// After all the slices of the current picture have been decoded, this
|
||||
// picture is marked as "used for short-term reference".
|
||||
pic.set_reference(Reference::ShortTerm);
|
||||
drop(pic);
|
||||
|
||||
for mut pic in self.pictures_mut() {
|
||||
pic.pic_latency_cnt += 1;
|
||||
}
|
||||
|
||||
self.entries.push(DpbEntry(picture, handle));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns all the references in the DPB.
|
||||
pub fn get_all_references(&self) -> Vec<DpbEntry<T>> {
|
||||
self.entries
|
||||
.iter()
|
||||
.filter(|e| e.0.borrow().is_ref())
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Default for Dpb<T> {
|
||||
fn default() -> Self {
|
||||
// See https://github.com/rust-lang/rust/issues/26925 on why this can't
|
||||
// be derived.
|
||||
Self {
|
||||
entries: Default::default(),
|
||||
max_num_pics: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> std::fmt::Debug for Dpb<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let pics = self
|
||||
.entries
|
||||
.iter()
|
||||
.map(|h| &h.0)
|
||||
.enumerate()
|
||||
.collect::<Vec<_>>();
|
||||
f.debug_struct("Dpb")
|
||||
.field("pictures", &pics)
|
||||
.field("max_num_pics", &self.max_num_pics)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use crate::codec::h265::parser::NaluType;
|
||||
use crate::codec::h265::parser::Slice;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum Reference {
|
||||
#[default]
|
||||
None,
|
||||
ShortTerm,
|
||||
LongTerm,
|
||||
}
|
||||
|
||||
/// Data associated with an h.265 picture. Most fields are extracted from the
|
||||
/// slice header and kept for future processing.
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub struct PictureData {
|
||||
// Fields extracted from the slice header. These are the CamelCase
|
||||
// variables, unless noted otherwise.
|
||||
pub nalu_type: NaluType,
|
||||
pub no_rasl_output_flag: bool,
|
||||
pub pic_output_flag: bool,
|
||||
pub valid_for_prev_tid0_pic: bool,
|
||||
pub slice_pic_order_cnt_lsb: i32,
|
||||
pub pic_order_cnt_msb: i32,
|
||||
pub pic_order_cnt_val: i32,
|
||||
pub no_output_of_prior_pics_flag: bool,
|
||||
|
||||
// Internal state.
|
||||
pub first_picture_after_eos: bool,
|
||||
reference: Reference,
|
||||
pub pic_latency_cnt: i32,
|
||||
pub needed_for_output: bool,
|
||||
pub short_term_ref_pic_set_size_bits: u32,
|
||||
}
|
||||
|
||||
impl PictureData {
|
||||
/// Instantiates a new `PictureData` from a slice.
|
||||
///
|
||||
/// See 8.1.3 Decoding process for a coded picture with nuh_layer_id equal
|
||||
/// to 0.
|
||||
///
|
||||
/// This will also call the picture order count process (clause 8.3.1) to
|
||||
/// correctly initialize the POC values.
|
||||
pub fn new_from_slice(
|
||||
slice: &Slice,
|
||||
first_picture_in_bitstream: bool,
|
||||
first_picture_after_eos: bool,
|
||||
prev_tid0_pic: Option<&PictureData>,
|
||||
max_pic_order_cnt_lsb: i32,
|
||||
) -> Self {
|
||||
let hdr = &slice.header;
|
||||
let nalu_type = slice.nalu.header.type_;
|
||||
|
||||
// We assume HandleCraAsBlafFLag == 0, as it is only set through
|
||||
// external means, which we do not provide.
|
||||
|
||||
let mut pic_order_cnt_msb = 0;
|
||||
let slice_pic_order_cnt_lsb: i32 = hdr.pic_order_cnt_lsb.into();
|
||||
|
||||
// Compute the output flags:
|
||||
// The value of NoRaslOutputFlag is equal to 1 for each IDR access
|
||||
// unit, each BLA access unit, and each CRA access unit that is the
|
||||
// first access unit in the bitstream in decoding order, is the first
|
||||
// access unit that follows an end of sequence NAL unit in decoding
|
||||
// order, or has HandleCraAsBlaFlag equal to 1.
|
||||
let no_rasl_output_flag = nalu_type.is_idr()
|
||||
|| nalu_type.is_bla()
|
||||
|| (nalu_type.is_cra() && first_picture_in_bitstream)
|
||||
|| first_picture_after_eos;
|
||||
|
||||
let pic_output_flag = if slice.nalu.header.type_.is_rasl() && no_rasl_output_flag {
|
||||
false
|
||||
} else {
|
||||
hdr.pic_output_flag
|
||||
};
|
||||
|
||||
// Compute the Picture Order Count. See 8.3.1 Decoding Process for
|
||||
// Picture Order Count
|
||||
if !(nalu_type.is_irap() && no_rasl_output_flag) {
|
||||
if let Some(prev_tid0_pic) = prev_tid0_pic {
|
||||
// Equation (8-1)
|
||||
let prev_pic_order_cnt_lsb = prev_tid0_pic.slice_pic_order_cnt_lsb;
|
||||
let prev_pic_order_cnt_msb = prev_tid0_pic.pic_order_cnt_msb;
|
||||
if (slice_pic_order_cnt_lsb < prev_pic_order_cnt_lsb)
|
||||
&& (prev_pic_order_cnt_lsb - slice_pic_order_cnt_lsb)
|
||||
>= (max_pic_order_cnt_lsb / 2)
|
||||
{
|
||||
pic_order_cnt_msb = prev_pic_order_cnt_msb + max_pic_order_cnt_lsb;
|
||||
} else if (slice_pic_order_cnt_lsb > prev_pic_order_cnt_lsb)
|
||||
&& (slice_pic_order_cnt_lsb - prev_pic_order_cnt_lsb)
|
||||
> (max_pic_order_cnt_lsb / 2)
|
||||
{
|
||||
pic_order_cnt_msb = prev_pic_order_cnt_msb - max_pic_order_cnt_lsb;
|
||||
} else {
|
||||
pic_order_cnt_msb = prev_pic_order_cnt_msb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute whether this picture will be a valid prevTid0Pic, i.e.:
|
||||
//
|
||||
// Let prevTid0Pic be the previous picture in decoding order that has
|
||||
// TemporalId equal to 0 and that is not a RASL, RADL or SLNR picture.
|
||||
//
|
||||
// Use this flag to correctly set up the field in the decoder during
|
||||
// `finish_picture`.
|
||||
let valid_for_prev_tid0_pic = slice.nalu.header.nuh_temporal_id() == 0
|
||||
&& !nalu_type.is_radl()
|
||||
&& !nalu_type.is_rasl()
|
||||
&& !nalu_type.is_slnr();
|
||||
|
||||
let no_output_of_prior_pics_flag =
|
||||
if nalu_type.is_irap() && no_rasl_output_flag && !first_picture_in_bitstream {
|
||||
nalu_type.is_cra() || hdr.no_output_of_prior_pics_flag
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Self {
|
||||
nalu_type,
|
||||
no_rasl_output_flag,
|
||||
no_output_of_prior_pics_flag,
|
||||
pic_output_flag,
|
||||
valid_for_prev_tid0_pic,
|
||||
slice_pic_order_cnt_lsb,
|
||||
pic_order_cnt_msb,
|
||||
// Equation (8-2)
|
||||
pic_order_cnt_val: pic_order_cnt_msb + slice_pic_order_cnt_lsb,
|
||||
first_picture_after_eos,
|
||||
reference: Default::default(),
|
||||
pic_latency_cnt: 0,
|
||||
needed_for_output: false,
|
||||
short_term_ref_pic_set_size_bits: hdr.st_rps_bits,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the current picture is a reference, either ShortTerm or LongTerm.
|
||||
pub fn is_ref(&self) -> bool {
|
||||
!matches!(self.reference, Reference::None)
|
||||
}
|
||||
|
||||
pub fn set_reference(&mut self, reference: Reference) {
|
||||
log::debug!(
|
||||
"Set reference of POC {} to {:?}",
|
||||
self.pic_order_cnt_val,
|
||||
reference
|
||||
);
|
||||
|
||||
self.reference = reference;
|
||||
}
|
||||
|
||||
pub fn reference(&self) -> &Reference {
|
||||
&self.reference
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
+3
@@ -0,0 +1,3 @@
|
||||
2904d4d2
|
||||
d8e11777
|
||||
a1108fed
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
c45648e1d3dd68913e998bd6ddb0f633
|
||||
8a44f604b2518c6caa7bb422907c8d17
|
||||
fe6ac1f24e248f3dba54087245380dd8
|
||||
BIN
Binary file not shown.
+2
@@ -0,0 +1,2 @@
|
||||
2407c115
|
||||
396fe8d4
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
afcabbf0be007e76b1f496e199eb07fa
|
||||
cebc9437bfc8501523c432d3fee3621d
|
||||
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
a5a83a48
|
||||
+1
@@ -0,0 +1 @@
|
||||
15caee73c93560200b9e240c6f5d7d0f
|
||||
@@ -0,0 +1,17 @@
|
||||
# H.265 Test Data
|
||||
|
||||
This document lists the test data used by the H.265 parser.
|
||||
|
||||
## bear.hevc
|
||||
|
||||
Same as Chromium's `bbb.hevc`.
|
||||
|
||||
## bear.hevc
|
||||
|
||||
Same as Chromium's `bear.hevc`.
|
||||
|
||||
## test-25fps.hevc
|
||||
|
||||
Same as Chromium's `test-25fps.hevc`.
|
||||
|
||||
The slice data for the first two slices in this stream was extracted manually from GStreamer using GDB.
|
||||
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
97255112
|
||||
c317718d
|
||||
bd113d45
|
||||
186209fe
|
||||
75726ee3
|
||||
e4a90dbd
|
||||
1da8aec0
|
||||
f537bcee
|
||||
bdcead02
|
||||
edd12fd6
|
||||
9814391e
|
||||
ea813192
|
||||
8e3f606c
|
||||
7298a718
|
||||
c25ed8f9
|
||||
54585aa5
|
||||
c5d6811c
|
||||
83ffc178
|
||||
ad9b6189
|
||||
20e3b289
|
||||
ea852c44
|
||||
38af63d3
|
||||
222e116b
|
||||
cbf5b144
|
||||
5cc11d3f
|
||||
561aba19
|
||||
c1b0021e
|
||||
97465654
|
||||
3f69533a
|
||||
95724dac
|
||||
4fd1865b
|
||||
00fc6666
|
||||
262e9ecc
|
||||
753e21c5
|
||||
73820a63
|
||||
6023ad07
|
||||
6baf0154
|
||||
6b658956
|
||||
c7f3d4d0
|
||||
b7fe7729
|
||||
652e5667
|
||||
76b64fad
|
||||
98f934ef
|
||||
64a737be
|
||||
e561fe00
|
||||
2bd0799f
|
||||
53d86edb
|
||||
07cad162
|
||||
c4857692
|
||||
9ab13929
|
||||
c445eb2a
|
||||
f0e890de
|
||||
1db971fc
|
||||
d03cc3fa
|
||||
69d2cdba
|
||||
172562d2
|
||||
356c55d0
|
||||
515bfbd6
|
||||
5d8dfbc2
|
||||
ec0874fb
|
||||
@@ -0,0 +1,60 @@
|
||||
e4519fce4b5a50a8ae38d2b42864e550
|
||||
c7f6707ea7b2aaa3a9c027e00bf2064b
|
||||
21c016eb7a57804d8637b03bc7910b31
|
||||
f744d8b67d4836629beac1ca4efdad9b
|
||||
8e593571ad75b9b19c3b14b44033bc03
|
||||
3f76c8397f7829d948ddb50c7050b4bb
|
||||
d91e343dbdb64dfd15f09abc4c460b06
|
||||
62d5c1de7a7ff8b4cdfb51cb33746bcd
|
||||
01a4c4d5f770d3cdc5429264f6a1a742
|
||||
760de93c5a25439a89378fbe50c26f3d
|
||||
d56f52f9252745321c723121824e5d21
|
||||
be626892c70d6fd412d7bff504852529
|
||||
ae49266f3b90dd1238f7ad83ae86886e
|
||||
7a9fe15547cbcb51557bfd0b8370e0ee
|
||||
a5b81f4e52fe54f67d109caa200486ec
|
||||
34395343b832af13dbe37ebe745506e0
|
||||
36d6e24c8a000b4f8d5c1aabba85c185
|
||||
9be3b6e5b0b77c136b5abe8a22bded59
|
||||
5122057efd33ed5634b755a7b0581382
|
||||
abaf35e215001a6abe0dbc63f5b4ace1
|
||||
62ba3a52072f80993c24cf9a3abda06f
|
||||
21b225675443d0142e104ec88f7e9569
|
||||
b561e6555b65ba6cebf0d73eefe4f319
|
||||
ab2b1a568bed6f9bafe79cf15dfd85b5
|
||||
e8c3645830f80e082e8b02e3cc599cc2
|
||||
82d655fb233fea3fc3377b4d3dfc11ff
|
||||
4a7c2a51149c1939cffc8cfc87fdb953
|
||||
32295652a5ff998c90fa18fbfc066fdc
|
||||
ce8974e2519a2babc43fb29106459cd2
|
||||
589fa92d80565556776c2108f676c439
|
||||
2bc1878534bf66caa6d686d0dad5a936
|
||||
b3d81309bb62ed349bed2c0fb17a5593
|
||||
c941ae94ab205aa1c27b9b06df4b57de
|
||||
e782fa5f5a7302b8246c29880e9c2f9d
|
||||
eeabb3a6c5fa1ea0f17a9fb911f5b612
|
||||
26f27eafea985de929a48287162fc641
|
||||
da4f4da7a16a4326c0c458f3dba12ef6
|
||||
7697150fa654713af6a6ecc07ad7d3dc
|
||||
67696b8c27169cbdbc18d093f794b328
|
||||
96ba8f5d17e7b35e78f5ac78a816a364
|
||||
1ab2c0d535d26c72d730e101600f42af
|
||||
f8b9d8fc231ccd64c551c829ef25089a
|
||||
eb004174e79dc8dbb533922639a725e2
|
||||
fd519318eb8c47e5fac6fc767246bfed
|
||||
471dbd17c2a374ab7dcaf64c345c1884
|
||||
fc28a8f484573893f6f501a4ade8ac37
|
||||
1e2dd38a14d5c13ef76e89d142f73951
|
||||
0fd6a338f4ecb3df053d105bc95e6ee1
|
||||
a42fd1e8bb069ab5c501fbfd655fc1b0
|
||||
f252d07215ddd6687fb3019f2710c939
|
||||
c8df7b9cbc16a26d782494b8cd312be4
|
||||
966a2f3fcb066179feef80e68f13e212
|
||||
b99b1100b6950144e70fa47310451340
|
||||
9b3502c7dc1a4ca2579a29f6b17af84d
|
||||
9a81be9720c64ce3b343fd20bc17bb14
|
||||
e5a67048a9c1ae74b8a97c5a27d6d2b2
|
||||
1527a719633c75b67ae6c36ebe550812
|
||||
86b1329ec84332fec1a75330e7d7a174
|
||||
6fa5b5faf93d70e96ffa215e4628ad9a
|
||||
ed6279f7b90727abc8a193745170a318
|
||||
Binary file not shown.
+30
@@ -0,0 +1,30 @@
|
||||
0a6ac0dd
|
||||
350b4669
|
||||
61a8b9ad
|
||||
f566d7c6
|
||||
8d8ab332
|
||||
52468dae
|
||||
44bdbf5f
|
||||
935e3db3
|
||||
814109bc
|
||||
68dc2234
|
||||
d5b47d8b
|
||||
852f3e1f
|
||||
3f54c08b
|
||||
9e33e4ae
|
||||
047c4f0d
|
||||
10cebb43
|
||||
87774650
|
||||
08adc4be
|
||||
837797a6
|
||||
17f80256
|
||||
221e943f
|
||||
e06ff206
|
||||
7fb43061
|
||||
e5dc2425
|
||||
37928778
|
||||
3a787cf0
|
||||
14ea1afd
|
||||
0331b84f
|
||||
bdfa1606
|
||||
28216ab7
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
037e7ff0ab754f16dc254edbecaf5bc0
|
||||
47d9c4d6427726b74dd8586aeea147e4
|
||||
1fae73f309640f704f8358fc0bae4c39
|
||||
579c2fe2b1fa83ab3082e30daebba728
|
||||
a4e01659d6bc12626d445a02fa5f977e
|
||||
3bcadc5d9985e44338edca617fd84541
|
||||
ac92b5ee1f79b5bda8f662eefab40085
|
||||
03d24eba6675f51496b9338d97c39308
|
||||
77f9d5f1e2e5bd40164336d9fe7970ef
|
||||
355f2e0f8e8c4702ad45c790415004df
|
||||
1d9563a8ccdf00b2116edb508b665e7e
|
||||
44eb70aeba2c5eba6b0ce931d6fff3e5
|
||||
c5fab1da55bd8177342d4e174bdc1474
|
||||
30f0d9a37231141722ba65c61bd59d09
|
||||
a1e8fdc8b33af447e4486c17d028b706
|
||||
11cd37f438399a595745dff608965aa2
|
||||
8025ff7ac2d9c9cda4039900834c1182
|
||||
e934c10259100457b44bd13a8630a3e0
|
||||
9f745c40aae4b6c31d57a0a43b39a4d2
|
||||
041ea32d187a011baafda69c1f079b2e
|
||||
d8a172fed23b9f0b4213bc7f8f1375a9
|
||||
22e9e048f8e04410307068b6bc2e79d7
|
||||
3c9d59aa49756060f8e78a5d608db8e6
|
||||
5482d7c76a6ff60c9c32fffc27c39873
|
||||
44a4d11b3ecdc827cc21ff732e1c7c7d
|
||||
aeaaff7c5b23b4f03d939de6c12e5006
|
||||
afa6ece7a21db66eece97e2e0713f29c
|
||||
d84b7794f4a4968ea7fadf5cba7333d0
|
||||
f9644eca3981a123b917938c7a4963fb
|
||||
e02c049b9e516e10c05ce4469856e37d
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generates the CRCs for all .h265 files in the current directory using ffmpeg.
|
||||
|
||||
for f in `ls *.h265`; do
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash crc32 - |grep -v '^#' |awk '{print $6}' >$f.crc
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash md5 - |grep -v '^#' |awk '{print $6}' >$f.md5
|
||||
done
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
+250
@@ -0,0 +1,250 @@
|
||||
97f807e6
|
||||
ee7f1354
|
||||
6fa0cec6
|
||||
9285fe16
|
||||
b291ad06
|
||||
155fee7a
|
||||
01427b08
|
||||
37610d09
|
||||
404fa256
|
||||
2935ba29
|
||||
fe05c389
|
||||
f4330069
|
||||
549eff98
|
||||
5150e3fb
|
||||
10a15359
|
||||
0673d70d
|
||||
6041a014
|
||||
104cba40
|
||||
47a31b16
|
||||
b5bc8a04
|
||||
3a16605a
|
||||
da5384bc
|
||||
156479bd
|
||||
dc555188
|
||||
458bffed
|
||||
2cc6fc99
|
||||
15abaa1b
|
||||
bdddda11
|
||||
fffa939a
|
||||
54a83ce1
|
||||
82ba8102
|
||||
0ac14f5a
|
||||
49e4c2c8
|
||||
4ba7c6e5
|
||||
44f0bcb2
|
||||
c370a456
|
||||
6361c839
|
||||
5c0fdfc5
|
||||
dcd0b111
|
||||
adad6054
|
||||
67b38f70
|
||||
8decebb8
|
||||
d64dacb4
|
||||
4025f908
|
||||
d7154e44
|
||||
93fbddde
|
||||
be5cf4ed
|
||||
d4492e49
|
||||
44d25551
|
||||
fcfbdbcf
|
||||
8698aa50
|
||||
00025a9a
|
||||
45f6d961
|
||||
507fa2e0
|
||||
bda2b113
|
||||
d735c28e
|
||||
13d54b15
|
||||
2b0e2c70
|
||||
fd1938c9
|
||||
e7b016c9
|
||||
511bbb25
|
||||
52754511
|
||||
f4c71342
|
||||
9572d1c1
|
||||
279aa775
|
||||
bee7e9aa
|
||||
0e916552
|
||||
6bd17554
|
||||
0616896f
|
||||
f2fbed3a
|
||||
f2c2f64e
|
||||
b34fea4e
|
||||
fb9f27d0
|
||||
7bf93797
|
||||
58fe6b72
|
||||
d6dbb367
|
||||
a4351497
|
||||
6001755c
|
||||
54e3ef07
|
||||
04bdff16
|
||||
f50bb46e
|
||||
619d9976
|
||||
c7438682
|
||||
71186e2d
|
||||
9f90810b
|
||||
26fa0f46
|
||||
e276d45f
|
||||
de8947eb
|
||||
98c35c3e
|
||||
5cd09c8d
|
||||
6ffcf799
|
||||
d0af871b
|
||||
b6f20a85
|
||||
b6064e3d
|
||||
f8af1a1d
|
||||
6d749e92
|
||||
484768ab
|
||||
779f6743
|
||||
f98c027a
|
||||
1579feb1
|
||||
8efcd176
|
||||
b7ab75fd
|
||||
e7911455
|
||||
1878ec1f
|
||||
db6c2d82
|
||||
8ad48e21
|
||||
9757e7ab
|
||||
fd22cb3b
|
||||
e441e63e
|
||||
12bcd5e3
|
||||
f76a42e8
|
||||
261856b7
|
||||
ab00bc6f
|
||||
03c25d9f
|
||||
65ef13d7
|
||||
b66512c9
|
||||
415b3d05
|
||||
0dff93cb
|
||||
cb541aaa
|
||||
0ee6c61b
|
||||
d6276a2c
|
||||
900d44ad
|
||||
0c408967
|
||||
2d539b08
|
||||
5479da37
|
||||
298f03dd
|
||||
bac454b8
|
||||
81b81c33
|
||||
a99b8c77
|
||||
2cc2e8af
|
||||
4053184a
|
||||
24be8904
|
||||
5c46ee1c
|
||||
30f2825f
|
||||
311a5956
|
||||
8379cadc
|
||||
16b91eea
|
||||
9e765763
|
||||
c1115845
|
||||
8bf28db3
|
||||
40b89f88
|
||||
c785befb
|
||||
b863d8a7
|
||||
d65c8552
|
||||
1571d9c1
|
||||
38c47640
|
||||
a04a8084
|
||||
d0881cc9
|
||||
e76534e9
|
||||
1b7b3ec0
|
||||
fa89a1e6
|
||||
91a77797
|
||||
50eabb2b
|
||||
1ffea9fd
|
||||
36da14d7
|
||||
4d21ead9
|
||||
0e9f3a19
|
||||
5c3bc82b
|
||||
e408152c
|
||||
aff45223
|
||||
4016bb65
|
||||
9055be73
|
||||
966f4f40
|
||||
1b232cde
|
||||
19d409a7
|
||||
9cf5ada9
|
||||
b983a480
|
||||
4329c339
|
||||
1b8c3818
|
||||
0a7e1997
|
||||
cebc35c9
|
||||
a5483e3c
|
||||
aa1ff50f
|
||||
ad76567f
|
||||
c1b9bd1a
|
||||
8340988a
|
||||
ecd60321
|
||||
8c12fdcf
|
||||
e3744c63
|
||||
99c0fa4c
|
||||
e1bdfb1f
|
||||
a047f435
|
||||
7e3b8ebb
|
||||
106e6518
|
||||
fb09be12
|
||||
d535a54d
|
||||
23e91694
|
||||
1e68c0cb
|
||||
53844c1a
|
||||
c8180fa6
|
||||
a58b3a20
|
||||
bf8a3c82
|
||||
fbd86177
|
||||
27041f33
|
||||
88fe20d5
|
||||
c0dbae26
|
||||
1677f210
|
||||
1d40f687
|
||||
e37f402a
|
||||
35d23b41
|
||||
8d0bd70e
|
||||
1439b309
|
||||
bbe21347
|
||||
e03ae4c5
|
||||
13b745d7
|
||||
e5116c4e
|
||||
70569ef4
|
||||
c85f4731
|
||||
b5b6de1f
|
||||
9dc8c6ba
|
||||
d7e7ec20
|
||||
fd5fdeb9
|
||||
1de6cf05
|
||||
968fe4ea
|
||||
c658ebd9
|
||||
a3427991
|
||||
1d5aa7ef
|
||||
6ae06a27
|
||||
41abbdb5
|
||||
a9104c0c
|
||||
db2726a1
|
||||
d7f4ce5c
|
||||
9ce1a83d
|
||||
70252457
|
||||
6744fda6
|
||||
a5b475f8
|
||||
5718ff91
|
||||
d40f157d
|
||||
50e7af4c
|
||||
a49ec566
|
||||
1eda24b9
|
||||
b77eda17
|
||||
aac39c22
|
||||
2352e08d
|
||||
a701b790
|
||||
cd916c2e
|
||||
5ef244e6
|
||||
b9ee5202
|
||||
4a8b8eec
|
||||
60a8976e
|
||||
f98cbcb1
|
||||
d5a8094f
|
||||
7b7c1585
|
||||
c679bf1d
|
||||
e6bb3547
|
||||
4f05e0eb
|
||||
d63111c5
|
||||
b8b260c0
|
||||
a18d9b72
|
||||
a7c1ca74
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"profile": "HEVCPROFILE_MAIN",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
"frame_rate": 25,
|
||||
"num_frames": 250,
|
||||
"num_fragments": 254,
|
||||
"md5_checksums": [
|
||||
"9d45302f59628259021c0d580f38e577",
|
||||
"cfafb8cdd693af7b24292d98e28d6966",
|
||||
"a9e93b65a59b752063f259c40e7d9fe7",
|
||||
"8b2445ed2bde8128fe090ebf112299b3",
|
||||
"af2fb4344c89078811eea7979ea87be8",
|
||||
"031f754980442cb3d8c59e83f637f16b",
|
||||
"3d579a05e18b85c5bf8e1079ebdb76d5",
|
||||
"9414c26b10b707ce582bea5e067be2b4",
|
||||
"18599153c70945dfde292dae24b81521",
|
||||
"7a324a7822e3a94df8b5a767f42ae5b9",
|
||||
"83ff81efb040a2d247abd639a66b76b7",
|
||||
"0e5b73811f510ac2ed2b976b27d4a3d9",
|
||||
"787e4f184a285d5c3071c14085ca528d",
|
||||
"8f9d7714962d32e211ca88e3f1c7f46d",
|
||||
"a40888217689af118a13d33ba1acee02",
|
||||
"0dc38b3c25ef2e35a1a5d000f24066bd",
|
||||
"f8bfaca952ef6158cac2b4139079ff3c",
|
||||
"04dd4c10c44fe65111eec52cef42b79e",
|
||||
"52e07c85f11add8e08473228c97d9e96",
|
||||
"5d2d01028f9549b67452343e1a37159a",
|
||||
"3e86b75a1c9cd4fc82371091dc9270ef",
|
||||
"091c1d95044708b1699a704f7fe00e97",
|
||||
"566eabd3b2112b1e60687c2646a03d7d",
|
||||
"7febb218fcfcd622e78cadc575e00d74",
|
||||
"c661462a644194e0e3f48cb76180f991",
|
||||
"8a98f0f76e624e718ab7ee1f8b3d06d7",
|
||||
"a74cee3ff950de4dfa7c049e72372d8a",
|
||||
"2003bb8048e0778cd7b684d3d290e238",
|
||||
"9583a569bef2a181e4b14ef9d7515965",
|
||||
"28fc9c431f8895224ee76a7a6a069644",
|
||||
"1f86380ff7e1ce3a549ec193f5442915",
|
||||
"8ce13d9e3659b928c7b768c470863673",
|
||||
"3e842fddf70acc3989b99a784d2d3a64",
|
||||
"2161a6b08f354b9213673af0f10595a4",
|
||||
"706ae034f4622cb729016b5efbf71761",
|
||||
"9ab6c4ec2708fc446bd6e57c0943f9ce",
|
||||
"77905702a6b7b1ad3a364914115ae1c1",
|
||||
"f35817cdbb7fd60cd39363f8116474a5",
|
||||
"ae41c4d453cf07939f652f79c6f2cc23",
|
||||
"938bd9a612612c55a018f6a746eee14e",
|
||||
"72b4d96412d20cdecce2861eacdf7e85",
|
||||
"f392537536b52626f5bc338f8d5f6261",
|
||||
"e7efe9c3e54ee42cfb1552c512844283",
|
||||
"2560af598073488d3c49ef8c59d6010d",
|
||||
"8a78183c164f50e206a7f376264103ab",
|
||||
"3f4235a1536c838c0bdc273314ded61e",
|
||||
"5887551fbb1436f5bc9fa6e63b9d9da0",
|
||||
"77fb5a36e251287e8b93e8c12279f54f",
|
||||
"36c1d5aef11aa43bff133907478abc07",
|
||||
"7988ba44232599cc54acaa71bfcac8ee",
|
||||
"a420156487134f7fd8b2bffc86c2c466",
|
||||
"a27f4e7c47212d83dce57ba52e4bf728",
|
||||
"651da9f2f35798255fa618affc9d5140",
|
||||
"736f41a6fc11267e14d865a44a5024d5",
|
||||
"5a0c9f520021a5e027287905443326c0",
|
||||
"838c3ef02a0d419f79b0a5cb96100712",
|
||||
"5d135fae4da8f33e842fe1d56b771baa",
|
||||
"9f5b762f5d0a9e6b4373aca87c04f872",
|
||||
"6a28827f8b5217636a003eba52bff2ab",
|
||||
"117254f82ee37acee64c1695da6efa61",
|
||||
"b9c023f5a72cbf120872794f94025c55",
|
||||
"70ed7dfa85fa637e446a4aa941f2b9fe",
|
||||
"7dcfc63d25fe08bc05c0c1b919148b57",
|
||||
"830c4e8958e84338f7b0a2ae8ecac5b7",
|
||||
"518e7456c889f30d1a4afdf2d0618f4b",
|
||||
"8a5aa2e84a77756adf020b9b5570a47e",
|
||||
"906878b088da07f0b5b61e2975aed09f",
|
||||
"6f8a49de618fceee2c2284037ccb4181",
|
||||
"f0f751f49e75b38373c2a5a4f2a8d9b8",
|
||||
"a4ae82030d893596129f19c51158e595",
|
||||
"35d0a14a2c4086c4ca4f010d2e9f0adb",
|
||||
"9c39936e95c658ada88bb6e8885f4639",
|
||||
"11bac53610bf107cfa9a80cc7d40d7ef",
|
||||
"3b1377f3a2bbc03be2a04ccce3f26d02",
|
||||
"520e6cb06673ece706cc96db877bd606",
|
||||
"8ab7f21cf1de8ce902f15ce812bdbdbe",
|
||||
"f140e1564aac1f71728922702083f9e9",
|
||||
"51828833d2bcb377fa0be61b7cb82579",
|
||||
"426f15aa7c01101d16237eb33995e4bf",
|
||||
"8f00d6311bb2ce1d290433126e480114",
|
||||
"1feaca010259e859bd3363b5c1d04f35",
|
||||
"2bb0e4dd7b3a115bc0f445497e35dc08",
|
||||
"fc640243683109158e0dff5dcea50842",
|
||||
"867f0ecd82aae7740bd9b251b9179350",
|
||||
"85111785a9ed8b2b8b70b09e12154428",
|
||||
"40ab1b731a9bf8f8e441c70ccc19b1dd",
|
||||
"3100c669e824c8aec2b2d67561db1349",
|
||||
"d05552052cd675c02caf5e1c671be35b",
|
||||
"47fc5cd75aca27be5d6dadde030fa3d5",
|
||||
"da2cc8eafa37e9a057e9a569ee541637",
|
||||
"d2b4a325071110060e847fd3e8ef1f52",
|
||||
"1dcccb0cf3a74b3153cb9b7c09a7f377",
|
||||
"8c91eb6aa2594899c0101d537505a121",
|
||||
"13abb158d7c22362ef1b73b5f15bfecf",
|
||||
"35ad01fb07169fc0050cdb996de53d9e",
|
||||
"d25ce524d14d95fd99607d42e13b7937",
|
||||
"c2ff502083b013873ab203d2af83337e",
|
||||
"68567f7ce7b9b19e5f85872442c54f79",
|
||||
"5ae94fee674131ecfd45a6775854ec96",
|
||||
"1c9f092f1e02caca84086b9873e1af89",
|
||||
"6510b165141b38e47d7cdc23e44cf39c",
|
||||
"913b03bbb72f8ccba56440632377b342",
|
||||
"3cf908dcf12bd787901571e601af20d7",
|
||||
"25518a7a40234f05661aaefea13518b2",
|
||||
"6d3512a84091b9a8934da296e8dfc5c4",
|
||||
"8ca79a3ace49c1126687674fffaaa5a2",
|
||||
"e644740d09c3e2f3598fce3839497dab",
|
||||
"8342af1710d8fec8f10a64da2ca9ea01",
|
||||
"7dc733dc534e2cca2422027db2a3e34a",
|
||||
"50fd7033960cf1d08bb558f7f7b7743d",
|
||||
"0cab05f4bc4f716df0c741a34a128f3f",
|
||||
"ff12d8589ee2ba883462db3496625218",
|
||||
"cfb4baf656a92ffad4f8e29e086a22ed",
|
||||
"6276eaef79a25eeb77e15c26121b522e",
|
||||
"5af976088fc10e9b263bf12d27af2131",
|
||||
"27510f90e0599ab31df00771f712cfe7",
|
||||
"5e120f23d16415907b3bca93c61a7798",
|
||||
"f0822f6593be64c890a73b5e19fa0aba",
|
||||
"6f00bf23a01f93f6cdea4c5ec9d429ba",
|
||||
"acf06eafb385d75956ac11b4394d8a96",
|
||||
"99f22f1087710da1e13fa51638b1cd1b",
|
||||
"206d93afe06167faf8560300ae7d9e02",
|
||||
"f0ac45f756a2ea398aa8c5cc6557048f",
|
||||
"314169ee8e31d3d654e6b60b63ea6b94",
|
||||
"b709914ad6a828552323fd7814aa3a69",
|
||||
"16eedf463a872c4e4f9645e2e7f731c2",
|
||||
"9ecaeec7815eda54aeb7ac937df6688e",
|
||||
"d3f880557ed0e69595d2887a879c46bf",
|
||||
"79afbc938ea2f2e0968b9cf31c7d653c",
|
||||
"4e76d541aa8796cfe4409da6f2d2afbc",
|
||||
"5a9b81dee85caeaeb1e5eccb8a5017cf",
|
||||
"977e990539d1cf3088ffe511f7346953",
|
||||
"2e0e69b8c37d91453b95cd3e4635ab4f",
|
||||
"3768fcaea9f36b873b054d02e7386a44",
|
||||
"600c3f478e859e5114fca6188e0832c3",
|
||||
"7a02082f7f1f104c3f01be9707be6978",
|
||||
"b5ba5c7504bdee1e10d74c3ebdd6d6b8",
|
||||
"baecb5bc56ac7ff840164b35bdf555c4",
|
||||
"33584ab96f9c3b6d7808e3e117b5b8a2",
|
||||
"3cfbd17bcdec301728b833feb9f3c7fa",
|
||||
"74daa5525ff24e90e6a1772a8e3055cf",
|
||||
"a37c2933e7445a765c8f3f18f3384c93",
|
||||
"e2b7199fcef9de93d4296cb3667bceae",
|
||||
"adc2b4e150ece651e7bc1174a78f79c2",
|
||||
"8568addcb675d4086158303460594703",
|
||||
"81a2b4bf06a0bbcc851779890cd73756",
|
||||
"c3f3f15b6ab9e47ce9242e32ff4951a6",
|
||||
"0495b5f57f93e37a3cfe3eff9f52319e",
|
||||
"36ffcdf358c7a42c427a6c827117a428",
|
||||
"9bc6ade4706bcd242b6b9b4a50fab72c",
|
||||
"584b7f4b14d531f8c8ac045a505da5d2",
|
||||
"393180967f07275e834e21127cf40ff6",
|
||||
"5dc3b033f2f26a4c0f113c60fe2d30bb",
|
||||
"157e3c22f8f6a319bd77a7c7e9689d96",
|
||||
"24395b2b073cb0d7448a7eec6ecb5edb",
|
||||
"6fc1d9efc86af03f5939f3aa1a1f9dfd",
|
||||
"ded02a863d25e29f9d1a78e8953cca16",
|
||||
"275c63d4d60e0bcb63613bec7d3ebba3",
|
||||
"042a6db4563ec75d5ff675a1e0e06647",
|
||||
"872755f0743242d0b8fdc42ac5b81d4d",
|
||||
"0aee140a64076aa43c8f9fb74d18796b",
|
||||
"ba738328a5377253b7067843fe48cbe4",
|
||||
"ba4fcdd5085f5bb3b33420c0eb97b5ab",
|
||||
"c393ac063ba4ee7370595f1528b00e98",
|
||||
"39ef16ba57122f6dd3bbec8aa83c596f",
|
||||
"ce7baa5845683d115d17e2822238ea56",
|
||||
"afd200eb4ed02c2ff93a8e04503490ac",
|
||||
"df783cda0056926ae9687bcdff01d6cd",
|
||||
"24129bf695474e4944cbf79c27dc49d5",
|
||||
"bb62851ee3852094c3722b71c469764d",
|
||||
"04a64b8e4f5a26bb03eeed2d6e63e7ad",
|
||||
"54732dc13d72d9f57580ebf69943d927",
|
||||
"b88ad31f39b05cf5f305be2ddb073f6f",
|
||||
"9cd5b43a79eb5ee177c8bba8ac15d168",
|
||||
"950909eefb9170dee1d45b3969e00427",
|
||||
"23e208e28a0bde09a3f046aa167bed38",
|
||||
"ed2706a02ba04c9b4a1c1b8cfffb04a3",
|
||||
"588a2708e07d0b338a2ed07cbea6af80",
|
||||
"23059a68238c316e7822233ed2f6eb7a",
|
||||
"e7cebf9ac14981339822d58b36cd4167",
|
||||
"3428cef2bda3072f21dcc48bb54d3042",
|
||||
"2110db4e61e860db243e6ddfd48e84d0",
|
||||
"0f2ea09489ff2b0b7202ece325580741",
|
||||
"ab6aad6bcb8fb77126ee5a2ebb039d23",
|
||||
"36882f3914929a863054d0a216dc570d",
|
||||
"e6b9a67f2314c460d0e8dadc84e979d8",
|
||||
"582bdd8b90609e15502a5c9f70ca9baa",
|
||||
"9fa97542b318a264b496d49c73bb2d19",
|
||||
"8da8a03cf4017c330226f4718ed449f7",
|
||||
"b7f15e01dca2d411491444b724ffbd68",
|
||||
"0c336bd2a32f5fb269803611d3e623a4",
|
||||
"c1b129d76a277373c6748927436794a1",
|
||||
"f303f6cb6a53b5998b3df6d273e502fb",
|
||||
"99b90cdc84ff584deff8b85be4de29f2",
|
||||
"3beb71970b6ad6d42ad08ac2b077bb23",
|
||||
"f4952ee5cf74f1a1c65ca51c1dcac9b4",
|
||||
"1636578dcfcfb9fc7dbabe14e3f85322",
|
||||
"20242c41b958e6fcaf16ce3c5e5ac2df",
|
||||
"1f5398fde49a13097929bb51ee4c6c5c",
|
||||
"6b426035d763bbfd14b24ccea8e7bfd1",
|
||||
"66123deb830f5d697ffdfb48e8310ed6",
|
||||
"189ba318c114f516bb9c7598319facb6",
|
||||
"a41c4331dd165fed91a4520efefa60c9",
|
||||
"96e3507c43dd3966884ba5f841673dc4",
|
||||
"a4308628349e5b94d6151d128d62f8f9",
|
||||
"24b9cb3b410c8bff36af293af5f1f6c4",
|
||||
"c5f17e29d80e18551fa11edc9c533e3d",
|
||||
"ca89232bbc3b590a12c21e4392437a92",
|
||||
"150542ffea542c14a0ec1ca46add7d83",
|
||||
"f0074cb65b559bc01f92ee0b2b2d851c",
|
||||
"c20e6eaa9005a856a1295c5c43b849b5",
|
||||
"61c579376b7d08d44982cd58efd2f2f3",
|
||||
"cd7c18087349de540dc8c7ee53bca62e",
|
||||
"545dda07c02e9ef635d10da90129712e",
|
||||
"af193247eb37e7e2b237bec00a68fea5",
|
||||
"a1a1368be1b97d9eb671dc59d2529e72",
|
||||
"e51153a36891bc8c22edae72954af0af",
|
||||
"82a2a2e229ee457b2a50e747fc05db45",
|
||||
"6988aa461cb3dc59fb5b04aaff4af962",
|
||||
"7617af042cf22ef700c27e3893878474",
|
||||
"d84e5115883391ae8b4136de46eeb056",
|
||||
"0674289ea495ed353988d4a2a39b1622",
|
||||
"bbf870e8ff3e047fe87b37895ccb30a8",
|
||||
"c62e8b15d60c0f45522c9607dcaef52c",
|
||||
"6a2535d22f6c34f09868be21ada6063d",
|
||||
"b54d58f9772149b9e40ba765a6f0c7a0",
|
||||
"7a2bb00940c3ea825a5994fc6e1a5862",
|
||||
"daccd8eb96035f7427c2ac984ef2669b",
|
||||
"e93b78e2adbf25f11a13e4476cb5eb56",
|
||||
"4621a7e39895cc326486e84f4000438a",
|
||||
"f6cfda926b4214d72983d1abb8d7f0bf",
|
||||
"15222df4f32a096b2178364382bb02b5",
|
||||
"5825ed69a82645fda8a6e86b4c48aeaa",
|
||||
"690fbef93df5dbc0316eff2a04e30244",
|
||||
"0eeee51628e3a3d6943266a0a95bf4ff",
|
||||
"7204f8130ec97d750287c03a613bdf23",
|
||||
"fade1a84465a00a62c91325ecfdb788e",
|
||||
"e061571ce0382db61922852144786a27",
|
||||
"e369e19a152688b1dcc910784d41739d",
|
||||
"bdc6190b3e945bea34219fc4a1849926",
|
||||
"c0dd752a1b1143e6b41d411fd423ae17",
|
||||
"08fe1c3af42005990a61685a2f35383c",
|
||||
"029de50a465d0f816070c3d5f17bde37",
|
||||
"bc75689a45409bffc566ff7f099030c2",
|
||||
"2e577e6c6a15e33a7b3f26b01ab1497a",
|
||||
"08038a3f13e60ba8bdde60a09ae429a3",
|
||||
"1f6e4ac664308335b10cb31da28f03c3",
|
||||
"e7c9e3c8ff869ffba99c64385dd58db5",
|
||||
"855c9cc4f404f747d2af60dff6b3db3a",
|
||||
"b6ae874fc675a3fd0f69cf36515cf8e5"
|
||||
]
|
||||
}
|
||||
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
3aa1404b3c67f08effee1b22a1edfe35
|
||||
126904a814874104c62aaf430100013e
|
||||
57a22d9cefafaf079f065bfb4c30153a
|
||||
5e03e8591340813fe3f84b0f02a31570
|
||||
6ead9483dd1cb7e15c325525081aec55
|
||||
379af5d20d2745f7ef89ee902651d159
|
||||
d3ad92e815413ac0df5a152dff1513ef
|
||||
a5a2774087b82062477b966c956ee507
|
||||
6372aea236df163e92abf32a23955586
|
||||
99f10be97458407433c6bc7e76e453c0
|
||||
699aa7d9609dde914f7a315da43b85a4
|
||||
b29a0c1424632d002dd6fc65a85ae702
|
||||
fbb0bbe60d3574300c4324350dd9cf94
|
||||
abd49b7181e7533e32d582cb89f4a890
|
||||
ece092ba9c23de4fd597d1d590b2fd5c
|
||||
71fbd2135bcb03651fa3fce07fe212c2
|
||||
ab2f4e90aa360da6a67eb0b4b94d89a5
|
||||
c3ebfa439f56a5d4a1274642ccf5fe88
|
||||
e3646565b25d19be356d725c9ccdf571
|
||||
10ad345a9199940edc4cf259fd740d67
|
||||
b25f027b25711e949ca188e9b7c071b7
|
||||
79f38a78fa14b251c3d13b25829be484
|
||||
2f471f7f9e841bf8d0a71fec8c99edab
|
||||
4386d538763d73d5f7ca8727aa0a1d0d
|
||||
be88a7beb8bfd95c5eb03493f0a3d5ad
|
||||
0beaeb365979f8355db831d8a39805c2
|
||||
c854fb790d5189b93bae7f5a8ee3c634
|
||||
557d551050575b0d7c36c103e587ed51
|
||||
bf1c245bf54695757f00d9a04defe688
|
||||
9f21b22a7e887e382b83a5fc070212e1
|
||||
97f63b86fb8dcdd3eb4e80be92672475
|
||||
9f6df014df10bd5983c15aebc5d9b0ae
|
||||
9c8437e809cf388325101c45720d2965
|
||||
caf27527cf3cdef68449a8515bc271ab
|
||||
1d2ffaed9291656e526ba9f33cc6edba
|
||||
85a827b0a35ed63bf1ccd33aa8fa2fbb
|
||||
c8d67d86ea8b4ff56591288f3b354881
|
||||
a690a754d9a51ae87a000f41d6157324
|
||||
cb31f37e307feeaeff6aa0df28ec4a63
|
||||
0ae07bc4b807aa17d831312ac7f8be00
|
||||
4a73a078bab877b40f4230d905b2c657
|
||||
4f99a4b8b320f540ac2ce76ee08a5131
|
||||
0e8043071109eaa1f983fa9f89c9893d
|
||||
9827495323c5df10b900bed10caac240
|
||||
cf1e190b0cbe8a395630d9dbb8926f3e
|
||||
aa8511fa4ddfcfb9c68d7cafb8dea11c
|
||||
a49a2fc1c52f716d1fdb4eb75a148658
|
||||
5f25b4f699445d8af438b77a58554eb6
|
||||
734344be019030baf3801a2c238a3b81
|
||||
9d82b03748e1f39e795ed2e7c8048233
|
||||
26656158f2dc3e44b8ecfc302b6ba50d
|
||||
2bdc0637fb6f1834bca11ed7a884d3d5
|
||||
a4c41fb0b47337bec3f98732bc2d72d6
|
||||
21b8fec70f82c45281e86651f3c10b4a
|
||||
4bd700ca4c31f0b67c85a11d57013310
|
||||
d3c6545314d53d68ba842d5f65784230
|
||||
2f1826430cdc477c82bbf48c7178d4d0
|
||||
11cb5dcc7932047eff832efca8dabff9
|
||||
0d00bd23075c075240df89baf1533931
|
||||
7b2e8f4c9ce1edd3d88613bd38e1347a
|
||||
224d1d502dfe17e65280afdb0944a768
|
||||
55f5e305c52979a4280310e91eb99c3e
|
||||
7b021942409264048613a0bac9f261fa
|
||||
98962ca6ee07c708b1cebf93d92ec706
|
||||
5901a19c4a240037bb1b1efe7ee0afb5
|
||||
6f49b4efe4155cf2e209c17d9e4bed3a
|
||||
5fb93030e6f55756004b5abf3e5a9f47
|
||||
b6f1473717ef4ef16cff8721a51f53ce
|
||||
e66e2f9382528cbbf4041dc1b315e8b3
|
||||
5104df3dd59e8f8c029ceb1da0dbe170
|
||||
aac0cd3df566a3b7d5a72bc5202c7752
|
||||
b97493d2bd5da6a25462f09dbe86a8a6
|
||||
c9dc6f8e721de915864d6a39be93171d
|
||||
c67a196f47a9d8aca36d33dabd1c60c6
|
||||
f98dca89ac1d9da1e4ecd2f00748f8ca
|
||||
4b223546c3f83f24c50ef023bdcfe096
|
||||
4a8d486fb79d01706cd51a2c7d446afb
|
||||
a25a13b07a66c230edd3ac6aa97f2d70
|
||||
a478b43a9b2f7cb8086056ff981f3d82
|
||||
3a86ca51898cb11bfbf47f32c4e1948e
|
||||
d48f1ec0f0740d506553472b5038001c
|
||||
1e0597118f13b08c78fcb8d3e445e89d
|
||||
0d3a037c2ea82a7adf739987eb77a4b3
|
||||
70cf1159356ad666fbff7eb33a4e220b
|
||||
49aca942deb5340e899ec93a70c467bb
|
||||
a4d8a4fe1963990af2167ddd193d2a2e
|
||||
7da7b5197dcb138788d66742913d7238
|
||||
a806177db926b0c4b469b52329c32bc2
|
||||
3b0da86ca6b69266628b474ba4c6dbf5
|
||||
7547a5b2c8b5d4613e81ee3b6d7003f2
|
||||
80afa451394825bf9f61b000bd001857
|
||||
40807c933935dd92abb61e2b2da1fcc8
|
||||
508fdefd102f9e1f7804d39eae916655
|
||||
91d9ee56f07f46d1ec191e662bd935f8
|
||||
807c81583b0073a2746d752a4b1f42df
|
||||
30734e3d8a710b269f5a29ce589b8a57
|
||||
4cdde1ffffc3dabe5b7e8f5c0ff8f084
|
||||
be6c0266091a2f3363dae1df8f724c9c
|
||||
8858b0f16fb5babda61c4a6beb0523ca
|
||||
16ffb13b8ff3aec78e8066cef06913f6
|
||||
3aed790a2749291489b12520da443dad
|
||||
c57ba43539016f901db55073386d5cd9
|
||||
0f8f41751bd1fdc06b72c4d82d350d84
|
||||
aef1772f3fdcef057f6924a40da7c2d8
|
||||
f5f8b1460650b41f06cf8391bc18e426
|
||||
a729195174db4ceea1973eb6165a9d6e
|
||||
e5022f7d2feaf57faa1e38ff1fc5bf68
|
||||
c694bf08869619a1bcc289127a408ed0
|
||||
0caaeabd4abbcc6d3bbca0b8b5d7cdb1
|
||||
971bdb6165a17e75773adeff5cf65fba
|
||||
5bcba13d46fd61c73341d2d362962872
|
||||
95bc9f0f82248551d9b41d799beb08ac
|
||||
7495973421c51dd51958d54b542ecc29
|
||||
7205d43bd4aeb3675aafb0b257d43136
|
||||
0720c6b6c9936f8457aeb9172c030a53
|
||||
6560c536d9c02d726f2f1d3737087ece
|
||||
83dbde13fa583e0e6444dd6efb011b34
|
||||
23080ac9e24b9698a2abf602ccfd2d09
|
||||
ff9c9e733f7e8ba1d74fcc40b7f89762
|
||||
65a541bfb561ec6cd945283e00175039
|
||||
4c57d75ca3f96e852f24f11b5b9944f8
|
||||
1e42dc0503db109faa0ce0a4c2d1eb5b
|
||||
284fc104d59d56c359631879d4ca5ae4
|
||||
a433eeff0d24300f106528ff3ee97dd9
|
||||
8b3cc99a2ba8b51ab37ff8e43ec39d88
|
||||
c883537d57780448f19b1fa22b731ddc
|
||||
34ebc05648788fa25e14aecc00c941b0
|
||||
2a522bbb0f652b825f4546bd483b002a
|
||||
1cd101eecab9fa491786310326aa02aa
|
||||
c34b70539d2cf79ba8c4814ca0b2b2f4
|
||||
6a445c83d65f30a519d6f1257de3a5d8
|
||||
7d006c2ced504c486d09fbb5c70d8f48
|
||||
1ecaaf8b8b79c0134d224408feb4b12e
|
||||
4f6fc08223fa794700c7fe2e13552aef
|
||||
89c50b145e15de68a635acdc56118fdf
|
||||
cf7d298515c15f7b969998211ed76d5c
|
||||
22007d9a686417c64151ce79d890f1f6
|
||||
091caca7499775a91fba09b45d0efeba
|
||||
6141cbf235f3d5f9ee7921795ac12948
|
||||
b5f9f13c06aaba11aba62edd8680a619
|
||||
cb81aeb1845c13741d7306e05ec620b5
|
||||
9e38b9005b5f87093069b0733186f92a
|
||||
2cb31fe3452d1e1b188ac8071bbd2145
|
||||
38e1dc763e76422f652b4791ab0d00a0
|
||||
491418db6354101d9e9221f9a366ef4e
|
||||
9dd1f141bac7936ce04b31d0d0e80db7
|
||||
f53ea317e8e16c5c556454b5139c6a3f
|
||||
e4b632d8bd400354cf8d03bfac61987f
|
||||
61195150e317268a4d8809db46344c01
|
||||
ff66c261ab7e00745d5f6dbd696dc4de
|
||||
5e090a50613045d8f71460a9de77547e
|
||||
83b8182ba7a6b77117eeb729f9d6fd53
|
||||
941a4dfa7c33d3a84993505f406e58aa
|
||||
5b2dab7f75283b9d05a1baeb465afb8f
|
||||
ccccd7a54b1b162b47267ad3c633588b
|
||||
b649cc2512d02ded5f8fb1a5e6c4e468
|
||||
36d2229b2a85ca5eb5e627d4fefe5d0e
|
||||
58f856aabbd3bb8df15d226c2c86f53a
|
||||
6218b94752b4936b2a9332ad78ed3c78
|
||||
46317cf4bccec620087f52c7da5af936
|
||||
6f1d6769eafa76baa638f5eacd68bea8
|
||||
240996e0719b183d04808ed92b36ec02
|
||||
24cb70c1de6c09acb298836f591ccf60
|
||||
62abeb55d923017366c3c0b5913b290c
|
||||
2074b8a3aaed5d41493578617834f865
|
||||
9bab5c6da1b475040a1ef3ad96039f16
|
||||
61a3914b0a1c2b563cc6be02f7c52c39
|
||||
9214566cdf649774366168904ba5a631
|
||||
b29a21da4b59070f8938175cf982610e
|
||||
712b8106393fa454db36d409829fd446
|
||||
7303c34c4ee40273c96d97aa193254d1
|
||||
34aac7ac642a02409cea8ddc0e79ca5a
|
||||
c905bb704eb57a5803b5f628a1885e65
|
||||
cfaeb64926d2cc463d2b039e25796e2c
|
||||
631aa39682688ca2a9fa1b5ac046c84b
|
||||
35e029947bb6ca6436f2287e56194910
|
||||
9559137575c4bdf3e4e32794c30d566e
|
||||
b26eb2e52cd85d5c62d02ceef8beca5e
|
||||
eda954629e3db49ce785db968dfd7435
|
||||
0c4db062f0a361a085e02a82c62ae623
|
||||
25505fb97d5a024c6a8c756b94417c85
|
||||
7145b53631fcdaf67d46f578dc061709
|
||||
86196a74f056323957abe0db608e063b
|
||||
4a2cec3448951953c76676511ce24068
|
||||
34b6f3e81afd9002411772b291d376f9
|
||||
0a889a8d77a4f7d001734e5590a1143d
|
||||
b2dd18c9a76ff8df04202b70a08e8480
|
||||
4966084a71252407273f57638148c878
|
||||
a9a0c3cd10496210ad5f423c67fd388c
|
||||
c7cf572ff8d7d859e255a1865012af47
|
||||
2d3fad5c6403435842002f02012c23ed
|
||||
e45d5b0fa1f296600bd8f6bdb91d59ff
|
||||
b308537943d50f9cf6afb9289826f21f
|
||||
1a6eacecb41a9984e8324900b7eafe43
|
||||
cee6bc8991e350ff29b2002d47e473c6
|
||||
fcb9de16c63bb0504dc97c3936f01479
|
||||
20ba7f47ea85ec2c1ede90415f69f96c
|
||||
edfc01d0213d0da38817b95c7f2090fd
|
||||
e89dd0d6f9982683375fd43fc10f8d33
|
||||
3937797142661006c3287488b3218b12
|
||||
33f13996becd2161301afdc6397c0582
|
||||
d8df3b5bbfd905c12c244c0252e49760
|
||||
fbd6b8d0fe1da3e6fe5464720212b94f
|
||||
b48262d193c09a00ba217cf056832696
|
||||
ca7bb0ae9e2baca1669dee5b4181cba3
|
||||
556adb32715d449d18032f2b1b0d5bb8
|
||||
2cda45ece79f91c91d97dbecbfdb77ff
|
||||
02be10a3e8fcef9ddaf31ec127117346
|
||||
a1bd20b8e168dca0743acee02e266bb8
|
||||
37959f49652a6a63c78700852ec32f99
|
||||
612cbca363753f225e4236e4ef7cbf08
|
||||
3593229c535f68e9285c13b91d2a84d0
|
||||
76dfdfdcae9abe98b65b0183f56d81b0
|
||||
b01c94b49b38b5f1b3cefcb0bb5baf4e
|
||||
aa41e02d44472fc5bf4b7d70eedf6317
|
||||
1f08d61e6780d63803337b2ee8120ac3
|
||||
d96c5b0c7616a32308a3873a93055940
|
||||
fbedfad1f84c85373ed740fa7d9faee9
|
||||
8900bc3aea596ba8957fc57edd2590d5
|
||||
660524d84aa663b32198423942525e2a
|
||||
ce749f243fdaa7ddbf79ef3ee145f8bb
|
||||
bb22ba1c54cb0c1535d64a1b947ffcff
|
||||
fe1af0925d781c8e733d0bbb93234d6a
|
||||
6d29a1bdb45482834fc37adbfa4de834
|
||||
77f09e7535a1745cfde19b7e262b4a6f
|
||||
cb6d2d2d5e94ab426166ccc46b8df0ad
|
||||
a49a9e733db88096180a27411c66d211
|
||||
3d7caaddb5f71b238fb2c253ab835396
|
||||
7feab55c011e16389d52ee203187f55b
|
||||
c06bc6b54bad2330d11c7ad711c8ee9a
|
||||
49569cc2cd80e956e0bd0ee178abee42
|
||||
392eadde235ec3f44c16e347040e7dc3
|
||||
d358513ffb159bbe5d93f3cebf24f4e7
|
||||
b2b6c35f846328ffe100c2d6bcff2091
|
||||
868971765ea4221a6f8854847c65b2b3
|
||||
3b0d0a5b426029b3ccc7eba61e4a8fdb
|
||||
0230e17adf575c13decdd0d225fed9a8
|
||||
24ccb608f3f4ee193f9553709ac112c0
|
||||
8da1c9cddc689c17b6a40df060769c6f
|
||||
52c6bd707266df417b6ca83e83befe49
|
||||
95fea0bccde2991e6fe7476444517c3b
|
||||
bd0cd099fa62bc0db33593e28c2b140c
|
||||
04c8032d5f34150d4f011c6322fdc5c6
|
||||
71735c0de711d3e34f053927e25c1e26
|
||||
98853c3c86949059572bd5d711b91b26
|
||||
cc9a35cb0bde5916476212203f7af380
|
||||
5346c2a8f3fee6ff9a3068b52bcf590f
|
||||
b13980ab3982fb964f80606acdf0dfb4
|
||||
d3137b6453aa267bc67be303db77630e
|
||||
e71431bb7d535ddad95ed24bcea40451
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2023 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#![warn(clippy::missing_panics_doc)]
|
||||
#![warn(clippy::panic)]
|
||||
#![warn(clippy::unwrap_used)]
|
||||
|
||||
pub mod lookups;
|
||||
pub mod parser;
|
||||
@@ -0,0 +1,116 @@
|
||||
// Copyright 2022 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/// The DC Quantization lookup table for bit_depth = 8, as per "8.6.1 Dequantization functions"
|
||||
pub const DC_QLOOKUP: [i16; 256] = [
|
||||
4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27,
|
||||
28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
|
||||
48, 49, 50, 51, 52, 53, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 66, 67,
|
||||
68, 69, 70, 70, 71, 72, 73, 74, 74, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87,
|
||||
88, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117,
|
||||
118, 120, 121, 123, 125, 127, 129, 131, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154,
|
||||
156, 158, 161, 164, 166, 169, 172, 174, 177, 180, 182, 185, 187, 190, 192, 195, 199, 202, 205,
|
||||
208, 211, 214, 217, 220, 223, 226, 230, 233, 237, 240, 243, 247, 250, 253, 257, 261, 265, 269,
|
||||
272, 276, 280, 284, 288, 292, 296, 300, 304, 309, 313, 317, 322, 326, 330, 335, 340, 344, 349,
|
||||
354, 359, 364, 369, 374, 379, 384, 389, 395, 400, 406, 411, 417, 423, 429, 435, 441, 447, 454,
|
||||
461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549, 559, 569, 579, 590, 602, 614, 626,
|
||||
640, 654, 668, 684, 700, 717, 736, 755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022,
|
||||
1058, 1098, 1139, 1184, 1232, 1282, 1336,
|
||||
];
|
||||
|
||||
/// The DC Quantization lookup table for bit_depth = 10, as per "8.6.1 Dequantization functions"
|
||||
pub const DC_QLOOKUP_10: [i16; 256] = [
|
||||
4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37, 40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75,
|
||||
78, 82, 86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132, 136, 140, 143, 147, 151,
|
||||
155, 159, 163, 166, 170, 174, 178, 182, 185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223,
|
||||
226, 230, 233, 237, 241, 244, 248, 251, 255, 259, 262, 266, 269, 273, 276, 280, 283, 287, 290,
|
||||
293, 297, 300, 304, 307, 310, 314, 317, 321, 324, 327, 331, 334, 337, 343, 350, 356, 362, 369,
|
||||
375, 381, 387, 394, 400, 406, 412, 418, 424, 430, 436, 442, 448, 454, 460, 466, 472, 478, 484,
|
||||
490, 499, 507, 516, 525, 533, 542, 550, 559, 567, 576, 584, 592, 601, 609, 617, 625, 634, 644,
|
||||
655, 666, 676, 687, 698, 708, 718, 729, 739, 749, 759, 770, 782, 795, 807, 819, 831, 844, 856,
|
||||
868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001, 1015, 1030, 1045, 1061, 1076, 1090,
|
||||
1105, 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, 1253, 1271, 1288, 1306, 1323, 1342, 1361,
|
||||
1379, 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670, 1692,
|
||||
1717, 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088, 2123, 2159,
|
||||
2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675, 2737, 2802, 2871, 2944, 3020,
|
||||
3102, 3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130,
|
||||
5347,
|
||||
];
|
||||
|
||||
/// The DC Quantization lookup table for bit_depth = 12, as per "8.6.1 Dequantization functions"
|
||||
pub const DC_QLOOKUP_12: [i16; 256] = [
|
||||
4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91, 103, 115, 127, 140, 153, 166, 180, 194, 208, 222,
|
||||
237, 251, 266, 281, 296, 312, 327, 343, 358, 374, 390, 405, 421, 437, 453, 469, 484, 500, 516,
|
||||
532, 548, 564, 580, 596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752, 768, 783, 798, 814,
|
||||
829, 844, 859, 874, 889, 904, 919, 934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080,
|
||||
1094, 1108, 1122, 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, 1248, 1261, 1275, 1288, 1302,
|
||||
1315, 1329, 1342, 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668,
|
||||
1692, 1717, 1741, 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, 1957, 1992, 2027, 2061, 2096,
|
||||
2130, 2165, 2199, 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, 2499, 2532, 2575, 2618, 2661,
|
||||
2704, 2746, 2788, 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, 3177, 3226, 3275, 3324, 3373,
|
||||
3421, 3469, 3517, 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, 4005, 4058, 4119, 4181, 4241,
|
||||
4301, 4361, 4420, 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013, 5083, 5153, 5222, 5291,
|
||||
5367, 5442, 5517, 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, 6234, 6319, 6404, 6495, 6587,
|
||||
6678, 6769, 6867, 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085, 8214, 8352,
|
||||
8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, 10465, 10702, 10946, 11210,
|
||||
11482, 11776, 12081, 12409, 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, 16356,
|
||||
16943, 17575, 18237, 18949, 19718, 20521, 21387,
|
||||
];
|
||||
|
||||
/// The AC Quantization lookup table for bit_depth = 8, as per "8.6.1 Dequantization functions"
|
||||
pub const AC_QLOOKUP: [i16; 256] = [
|
||||
4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
|
||||
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
|
||||
102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138,
|
||||
140, 142, 144, 146, 148, 150, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 188,
|
||||
191, 194, 197, 200, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, 260,
|
||||
265, 270, 275, 280, 285, 290, 295, 300, 305, 311, 317, 323, 329, 335, 341, 347, 353, 359, 366,
|
||||
373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448, 456, 465, 474, 483, 492, 501, 510, 520,
|
||||
530, 540, 550, 560, 571, 582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715, 729, 743,
|
||||
757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933, 951, 969, 988, 1007, 1026, 1046,
|
||||
1066, 1087, 1108, 1129, 1151, 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423,
|
||||
1451, 1479, 1508, 1537, 1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
|
||||
];
|
||||
|
||||
/// The AC Quantization lookup table for bit_depth = 10, as per "8.6.1 Dequantization functions"
|
||||
pub const AC_QLOOKUP_10: [i16; 256] = [
|
||||
4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40, 44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83,
|
||||
88, 92, 96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149, 154, 158, 163, 168,
|
||||
172, 177, 181, 186, 190, 195, 199, 204, 208, 213, 217, 222, 226, 231, 235, 240, 244, 249, 253,
|
||||
258, 262, 267, 271, 275, 280, 284, 289, 293, 297, 302, 306, 311, 315, 319, 324, 328, 332, 337,
|
||||
341, 345, 349, 354, 358, 362, 367, 371, 375, 379, 384, 388, 392, 396, 401, 409, 417, 425, 433,
|
||||
441, 449, 458, 466, 474, 482, 490, 498, 506, 514, 523, 531, 539, 547, 555, 563, 571, 579, 588,
|
||||
596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713, 725, 737, 749, 761, 773, 785, 797, 809,
|
||||
825, 841, 857, 873, 889, 905, 922, 938, 954, 970, 986, 1002, 1018, 1038, 1058, 1078, 1098,
|
||||
1118, 1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, 1411, 1435, 1463,
|
||||
1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, 1895, 1931, 1967,
|
||||
2003, 2039, 2079, 2119, 2159, 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, 2555, 2603, 2651,
|
||||
2703, 2755, 2807, 2859, 2915, 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591,
|
||||
3659, 3731, 3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784, 4876,
|
||||
4972, 5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, 6388, 6512, 6640,
|
||||
6768, 6900, 7036, 7172, 7312,
|
||||
];
|
||||
|
||||
/// The AC Quantization lookup table for bit_depth = 12, as per "8.6.1 Dequantization functions"
|
||||
pub const AC_QLOOKUP_12: [i16; 256] = [
|
||||
4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99, 112, 126, 139, 154, 168, 183, 199, 214, 230, 247,
|
||||
263, 280, 297, 314, 331, 349, 366, 384, 402, 420, 438, 456, 475, 493, 511, 530, 548, 567, 586,
|
||||
604, 623, 642, 660, 679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865, 884, 902, 920, 939,
|
||||
957, 976, 994, 1012, 1030, 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229,
|
||||
1246, 1264, 1282, 1299, 1317, 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, 1474, 1491, 1509,
|
||||
1526, 1543, 1560, 1577, 1595, 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954,
|
||||
1987, 2020, 2052, 2085, 2118, 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, 2411, 2459, 2508,
|
||||
2556, 2605, 2653, 2701, 2750, 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, 3185, 3234, 3298,
|
||||
3362, 3426, 3491, 3555, 3619, 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, 4230, 4310, 4390,
|
||||
4470, 4550, 4631, 4711, 4791, 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, 5641, 5737, 5849,
|
||||
5961, 6073, 6185, 6297, 6410, 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, 7579, 7723, 7867,
|
||||
8011, 8155, 8315, 8475, 8635, 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, 10220, 10412,
|
||||
10604, 10812, 11020, 11228, 11437, 11661, 11885, 12109, 12333, 12573, 12813, 13053, 13309,
|
||||
13565, 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054,
|
||||
17390, 17726, 18062, 18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902,
|
||||
22334, 22766, 23214, 23662, 24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599, 28143,
|
||||
28687, 29247,
|
||||
];
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
# VP9 Test Data
|
||||
|
||||
This document lists the test data used by the VP9 decoder.
|
||||
|
||||
Unless otherwise noted, the CRCs were computed using GStreamer's VA-API decoder in
|
||||
`gst-plugins-bad`.
|
||||
|
||||
## test-25fps.vp9
|
||||
|
||||
Same as Chromium's `test-25fps.vp9`.
|
||||
|
||||
## vp90_2_10_show_existing_frame2_vp9
|
||||
|
||||
Test taken from `libvpx` official test suite.
|
||||
|
||||
## vp90_2_10_show_existing_frame_vp9
|
||||
|
||||
Test taken from `libvpx` official test suite.
|
||||
|
||||
## resolution_change_500frames_vp9
|
||||
|
||||
Same as Chromium's `test_resolution_change_500frames_vp9`.
|
||||
|
||||
More information can be gathered from the Chromium documentation:
|
||||
|
||||
```
|
||||
Dumped compressed stream of videos on
|
||||
[http://crosvideo.appspot.com](http://crosvideo.appspot.com) manually
|
||||
changing resolutions at random. Those contain 144p, 240p, 360p, 480p, 720p, and
|
||||
1080p frames. Those frame sizes can be found by
|
||||
|
||||
ffprobe -show_frames resolution_change_500frames.vp9
|
||||
```
|
||||
|
||||
## vp9-superframe.bin
|
||||
|
||||
Raw dump of a VP9 superframe. Extracted from GStreamer. Available at
|
||||
|
||||
```
|
||||
gst-plugins-bad/tests/check/libs/vp9parser.c
|
||||
```
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Generates the CRCs for all .vp9 and .ivf files in the current directory using ffmpeg.
|
||||
|
||||
for f in `ls *.vp9 *.ivf`; do
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash crc32 - |grep -v '^#' |awk '{print $6}' >$f.crc
|
||||
ffmpeg -i $f -pix_fmt nv12 -f framehash -hash md5 - |grep -v '^#' |awk '{print $6}' >$f.md5
|
||||
done
|
||||
Vendored
BIN
Binary file not shown.
+500
@@ -0,0 +1,500 @@
|
||||
30434565
|
||||
3f479427
|
||||
1a3815b4
|
||||
003efaf8
|
||||
a326e30b
|
||||
5e48c696
|
||||
4a95cdff
|
||||
d094e6b9
|
||||
f88fb600
|
||||
3166c8fe
|
||||
0631ba57
|
||||
0f994c4b
|
||||
fcfd01d4
|
||||
0d6085ca
|
||||
83f02696
|
||||
9a6281b1
|
||||
e477c455
|
||||
83fb3e76
|
||||
0dab98b1
|
||||
2704ae4a
|
||||
4c735dae
|
||||
665987f7
|
||||
fd3a4848
|
||||
89ab7ede
|
||||
99abfab3
|
||||
c602e1de
|
||||
22b58401
|
||||
3cf8420e
|
||||
5a33eecf
|
||||
847e256e
|
||||
acdcec41
|
||||
ae5c98ac
|
||||
cb7b8f57
|
||||
5f58e096
|
||||
8f5cf9eb
|
||||
c2bb56a9
|
||||
72708cd9
|
||||
d60f26e0
|
||||
ac56d0e5
|
||||
56fae066
|
||||
c8f77144
|
||||
957ea038
|
||||
75a28a96
|
||||
602ba7b8
|
||||
8dfa67dc
|
||||
145d0c16
|
||||
07d84b15
|
||||
d5ff745b
|
||||
89b9c4fd
|
||||
476ddf3b
|
||||
73e3833f
|
||||
eb946288
|
||||
39916706
|
||||
a62f2ffa
|
||||
b62fce6f
|
||||
cec06605
|
||||
d139ea59
|
||||
5250ceb5
|
||||
b75ccc92
|
||||
c79f5e51
|
||||
8bf78f86
|
||||
2f55a022
|
||||
0b4d2c33
|
||||
ee21ac93
|
||||
e5880dfb
|
||||
98ebd835
|
||||
d2bd50b7
|
||||
e63409b9
|
||||
c7f17438
|
||||
b4671d62
|
||||
6e012ab2
|
||||
1d71249b
|
||||
1cc7e30c
|
||||
8ad0ebf3
|
||||
b3bf9734
|
||||
8f45ae14
|
||||
185495d4
|
||||
edcd3b82
|
||||
b7b7bc38
|
||||
e62517e2
|
||||
3e5767dd
|
||||
a0b59888
|
||||
1517dc9b
|
||||
213303bb
|
||||
1c0e1d69
|
||||
48849645
|
||||
c41fe238
|
||||
3423ddb4
|
||||
e8e9bcb9
|
||||
aca22302
|
||||
85142fc3
|
||||
034b1fa8
|
||||
4fecedcb
|
||||
6317d541
|
||||
b098f009
|
||||
7d13c5cf
|
||||
b6b6127a
|
||||
1ee289ad
|
||||
3a3f70bc
|
||||
a6b8e785
|
||||
185c7dea
|
||||
08025f9e
|
||||
a6647fdc
|
||||
1916ab72
|
||||
d2906114
|
||||
2c833567
|
||||
86374614
|
||||
7dc4ad6c
|
||||
aa9e4b12
|
||||
9a7e5485
|
||||
4e89084c
|
||||
b0e7e971
|
||||
1c7d3e11
|
||||
6f1f48ef
|
||||
d2eb406d
|
||||
4952e5ce
|
||||
8ad0dee8
|
||||
5581a685
|
||||
f430f28c
|
||||
18adef19
|
||||
f81c45a5
|
||||
66ecef00
|
||||
6b8023cf
|
||||
58d96699
|
||||
5db8ddfc
|
||||
2f8d6d4c
|
||||
150426dc
|
||||
9d14824a
|
||||
69879063
|
||||
465d1e5a
|
||||
f4d03906
|
||||
3bbb4545
|
||||
74e922a6
|
||||
be20217a
|
||||
dca8cce3
|
||||
7d1e9b5b
|
||||
edcc5564
|
||||
5d6611d8
|
||||
0698b853
|
||||
a62b3ecb
|
||||
b34c5938
|
||||
e26c121e
|
||||
39cc64a8
|
||||
cc34cef7
|
||||
81cf2401
|
||||
d575fff6
|
||||
1a7f0bdc
|
||||
f0c6d006
|
||||
5b106cfe
|
||||
9f2888e0
|
||||
6f2a63ce
|
||||
c1155ec4
|
||||
12da69bf
|
||||
c1dbed84
|
||||
671c4163
|
||||
5dad13b0
|
||||
d2017cee
|
||||
496bb413
|
||||
30434565
|
||||
3f479427
|
||||
1a3815b4
|
||||
003efaf8
|
||||
a326e30b
|
||||
5e48c696
|
||||
4a95cdff
|
||||
d094e6b9
|
||||
f88fb600
|
||||
3166c8fe
|
||||
0631ba57
|
||||
0f994c4b
|
||||
fcfd01d4
|
||||
0d6085ca
|
||||
83f02696
|
||||
9a6281b1
|
||||
e477c455
|
||||
83fb3e76
|
||||
0dab98b1
|
||||
2704ae4a
|
||||
4c735dae
|
||||
665987f7
|
||||
fd3a4848
|
||||
89ab7ede
|
||||
99abfab3
|
||||
c602e1de
|
||||
22b58401
|
||||
3cf8420e
|
||||
5a33eecf
|
||||
847e256e
|
||||
acdcec41
|
||||
ae5c98ac
|
||||
cb7b8f57
|
||||
5f58e096
|
||||
8f5cf9eb
|
||||
c2bb56a9
|
||||
72708cd9
|
||||
d60f26e0
|
||||
ac56d0e5
|
||||
56fae066
|
||||
c8f77144
|
||||
957ea038
|
||||
75a28a96
|
||||
602ba7b8
|
||||
8dfa67dc
|
||||
145d0c16
|
||||
07d84b15
|
||||
d5ff745b
|
||||
89b9c4fd
|
||||
476ddf3b
|
||||
7aebabfc
|
||||
5098261a
|
||||
6be66915
|
||||
2c0dac16
|
||||
46e4498a
|
||||
4bb011a9
|
||||
1db45608
|
||||
51d4b563
|
||||
0c70020d
|
||||
5fe5a5d3
|
||||
9fd0b920
|
||||
db24b6fd
|
||||
2900f825
|
||||
ae09ecfa
|
||||
7c220368
|
||||
58cb372f
|
||||
b4da90fe
|
||||
c62f659c
|
||||
b6b990bf
|
||||
665a5990
|
||||
aad5e55c
|
||||
aff234d3
|
||||
c6850001
|
||||
366cb3ab
|
||||
b95a04db
|
||||
f34882e5
|
||||
93d19d35
|
||||
37834afb
|
||||
998b8b4b
|
||||
ab26528d
|
||||
4f39e702
|
||||
5bd3b3fd
|
||||
ecb5a096
|
||||
d434b006
|
||||
d44a715e
|
||||
37f1c963
|
||||
367b4f79
|
||||
154ef078
|
||||
8a909d4e
|
||||
7cd512da
|
||||
2bb88121
|
||||
e2bfd733
|
||||
dba85108
|
||||
eb49fd76
|
||||
e2c9f19f
|
||||
25a38992
|
||||
742619f3
|
||||
e9a279b4
|
||||
90c4de29
|
||||
4ff923d4
|
||||
e4b56000
|
||||
1a6b4200
|
||||
839fedd8
|
||||
87650ead
|
||||
0345d74c
|
||||
691fa48c
|
||||
cedb2e03
|
||||
0b3e2577
|
||||
5f5b60b5
|
||||
95b19c13
|
||||
633d49e3
|
||||
2da01d07
|
||||
a114b659
|
||||
8080d857
|
||||
f52eab8e
|
||||
b5348da2
|
||||
12453318
|
||||
a6589d2b
|
||||
189c908d
|
||||
eb83c448
|
||||
4e09feba
|
||||
506361d6
|
||||
72de5e28
|
||||
49644af2
|
||||
ec508bb2
|
||||
efcd9e22
|
||||
947abf26
|
||||
47d491a9
|
||||
f3819b93
|
||||
19bf5692
|
||||
a1a6ff76
|
||||
ed33d700
|
||||
c4def3ad
|
||||
ef10c624
|
||||
fdabd9d9
|
||||
6ad10a8e
|
||||
d719e93a
|
||||
593c7aae
|
||||
1e3ccd7a
|
||||
bf625826
|
||||
3f174d5c
|
||||
222db35e
|
||||
0884b2e8
|
||||
f3b5be46
|
||||
07794925
|
||||
21c9233f
|
||||
35041427
|
||||
10d883a8
|
||||
765d6db0
|
||||
54dfccc9
|
||||
4801da6f
|
||||
06c7e866
|
||||
69208a52
|
||||
3381d557
|
||||
c3f91b72
|
||||
1dece653
|
||||
0828a727
|
||||
6b808625
|
||||
4db6f222
|
||||
64982c8e
|
||||
5782aad6
|
||||
dc1ab775
|
||||
51ab86b2
|
||||
c9f02103
|
||||
4ebe8270
|
||||
85d90d4f
|
||||
62194ea7
|
||||
9c4d98db
|
||||
15e04acf
|
||||
955f3ec1
|
||||
6a9205c9
|
||||
6a915ccc
|
||||
013d43c2
|
||||
4a7e4926
|
||||
bce87d78
|
||||
8db1db9b
|
||||
f0e7eba1
|
||||
cec75219
|
||||
1cb9aa20
|
||||
37163dab
|
||||
b619ad9a
|
||||
c3348021
|
||||
ac44a4df
|
||||
5ef80c45
|
||||
cf3238b6
|
||||
db148947
|
||||
cfebcfeb
|
||||
68c2ba8d
|
||||
97bd3333
|
||||
38b9a39e
|
||||
88239b6e
|
||||
21dada0c
|
||||
3a3240ee
|
||||
309c773d
|
||||
782b8c8c
|
||||
a18fa947
|
||||
d96adf14
|
||||
d130b2bf
|
||||
13ca5914
|
||||
5d0252f8
|
||||
94482817
|
||||
f859fd3b
|
||||
454ca588
|
||||
bacf1f63
|
||||
9685ff99
|
||||
12bfbea9
|
||||
758d0396
|
||||
d1dc7f1a
|
||||
f332a5dd
|
||||
95ed5526
|
||||
320373cf
|
||||
66ae44d0
|
||||
d7f60521
|
||||
174e8778
|
||||
d8f1cb9a
|
||||
505edb44
|
||||
e218879d
|
||||
8ee171c8
|
||||
7f0d1f7d
|
||||
00a0f4a2
|
||||
b77fcb6e
|
||||
9d9e118b
|
||||
3ef2a6ba
|
||||
bc3ec3cb
|
||||
ab1f4821
|
||||
dcb9c237
|
||||
aedf52c5
|
||||
5191f352
|
||||
e58687bd
|
||||
74584d91
|
||||
42310f91
|
||||
c1276911
|
||||
c81f69ec
|
||||
ffe3479f
|
||||
0dcd9a22
|
||||
00c1d7cf
|
||||
6308e6dc
|
||||
0a7a9866
|
||||
032125a4
|
||||
68f91bf4
|
||||
e488c252
|
||||
a7534dcf
|
||||
24d336a9
|
||||
98a8bbb9
|
||||
caad1bf4
|
||||
64f2157e
|
||||
52a304ac
|
||||
f15eb12c
|
||||
c6dbedca
|
||||
da11a1f8
|
||||
be321a1f
|
||||
ae891efa
|
||||
0ec7ace0
|
||||
ce45b0d5
|
||||
77137631
|
||||
5a0b7286
|
||||
19498745
|
||||
e1ba1f6a
|
||||
9f76aa6c
|
||||
c409dd1b
|
||||
92536c65
|
||||
bb9ef77a
|
||||
2240c34a
|
||||
4b698459
|
||||
52bf0ddf
|
||||
2b357e41
|
||||
b821dd12
|
||||
9c428cc4
|
||||
f58cb68b
|
||||
3f1adb2c
|
||||
ebbfd9c5
|
||||
f47f62d8
|
||||
7305e1be
|
||||
79ef7a93
|
||||
a83ac98c
|
||||
ee9fdddc
|
||||
b2a237fb
|
||||
22dab010
|
||||
fc03b4c2
|
||||
90cd6a71
|
||||
7cfac9af
|
||||
50472042
|
||||
8d46b423
|
||||
34ca61f2
|
||||
01cc9d54
|
||||
b191f0a7
|
||||
64330c48
|
||||
25c84ef5
|
||||
e3d608b4
|
||||
1faf320a
|
||||
dc42008e
|
||||
a4478667
|
||||
54cc09fd
|
||||
cbf1e2b5
|
||||
82c03181
|
||||
76a575cb
|
||||
c88fe2a9
|
||||
92f328a2
|
||||
d792a66b
|
||||
ae89fbd0
|
||||
742429d3
|
||||
1045723d
|
||||
084976fc
|
||||
ea999295
|
||||
2c79adc2
|
||||
ca4fb5c6
|
||||
0ae9e41d
|
||||
e3d52ad3
|
||||
d453b8fc
|
||||
eb24dbb1
|
||||
1220c85f
|
||||
5b631b96
|
||||
eaab2c2a
|
||||
c10c82b3
|
||||
01cf2040
|
||||
381ac249
|
||||
431bc361
|
||||
57df9be3
|
||||
2010ccd8
|
||||
6e5d770b
|
||||
7934dea1
|
||||
37a6d295
|
||||
69b537b1
|
||||
1c5b6117
|
||||
5aef90c9
|
||||
22c21587
|
||||
f45a95f0
|
||||
46ff5fdd
|
||||
a2c00527
|
||||
bf2c3a89
|
||||
ca3def6f
|
||||
40e4600e
|
||||
12255f84
|
||||
6439fa9e
|
||||
89f0b37d
|
||||
13f60bfb
|
||||
6ede3385
|
||||
e2eb309f
|
||||
c1dd01a5
|
||||
cecc9d99
|
||||
d1845fd9
|
||||
dd87d2b0
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
d5a38844026bf51029f97b815fb04b19
|
||||
401c6bf17f34a1185d5381009e58ba65
|
||||
BIN
Binary file not shown.
+250
@@ -0,0 +1,250 @@
|
||||
1abf0870
|
||||
32ab9360
|
||||
fd2a8755
|
||||
795c3488
|
||||
05605011
|
||||
c836c6f6
|
||||
9811bd68
|
||||
2ea553c0
|
||||
2cc69486
|
||||
9784cc5d
|
||||
dc95c93c
|
||||
9abb41bc
|
||||
fbc1180f
|
||||
a4f5e378
|
||||
0ba301f7
|
||||
49af5c91
|
||||
1a33dc74
|
||||
c3841cc4
|
||||
3d22678d
|
||||
9ba82c05
|
||||
acd3f53e
|
||||
5e147078
|
||||
3710613c
|
||||
55c0edc8
|
||||
c4a734bc
|
||||
ee06bb4f
|
||||
57ffbd97
|
||||
4e3b52e4
|
||||
9848ca34
|
||||
a5f6a263
|
||||
7bf13fc1
|
||||
d7cf6fcb
|
||||
a49569c9
|
||||
5b9b87a3
|
||||
e1732f37
|
||||
fec42824
|
||||
1e8514df
|
||||
7580ba76
|
||||
e07ae78f
|
||||
065a11ed
|
||||
e254d9f5
|
||||
67ca9179
|
||||
b74ad987
|
||||
8f0151b8
|
||||
c9d5220f
|
||||
34788052
|
||||
c8269a62
|
||||
98108c54
|
||||
43db9efa
|
||||
1d6e8a25
|
||||
790b24cf
|
||||
93badd6b
|
||||
43276faa
|
||||
ba4561aa
|
||||
78d7e0cd
|
||||
aa11db2f
|
||||
98c23282
|
||||
0d27f401
|
||||
4450596e
|
||||
a511b3fd
|
||||
45aaf3f4
|
||||
8b6afa2e
|
||||
798ddc36
|
||||
c16d2441
|
||||
90096480
|
||||
32d5f72e
|
||||
ba19403e
|
||||
e2d0ad1b
|
||||
f5306855
|
||||
184309d4
|
||||
f1134993
|
||||
49a1ae44
|
||||
e724a782
|
||||
76ecef33
|
||||
7b48a1c8
|
||||
80e678a4
|
||||
14217558
|
||||
21d6bf24
|
||||
907ca9e4
|
||||
71bdf4b9
|
||||
be9b2301
|
||||
bf953977
|
||||
a5c17a0a
|
||||
b7c27ba3
|
||||
dd13bf91
|
||||
600d03eb
|
||||
fd2d8874
|
||||
a2d8af0e
|
||||
4c21a3db
|
||||
48353f6e
|
||||
e3e6b60c
|
||||
ef3b9c28
|
||||
1a4df0bd
|
||||
af18c549
|
||||
4e2da67b
|
||||
77a51623
|
||||
86b999df
|
||||
f5b45a41
|
||||
b0d5b913
|
||||
46b5ed49
|
||||
f64a266d
|
||||
ff157d94
|
||||
67b1e678
|
||||
705a8536
|
||||
0a7f2695
|
||||
02c328d4
|
||||
ddbee2a6
|
||||
259fe83b
|
||||
9164f5e4
|
||||
f7b740e2
|
||||
07026fdc
|
||||
8887118e
|
||||
ee734407
|
||||
7544e6a0
|
||||
d1cd9b46
|
||||
ed639972
|
||||
1c791217
|
||||
52ca157e
|
||||
b3ac782e
|
||||
3592f784
|
||||
ec3a0a53
|
||||
ba29434f
|
||||
0c9dafcb
|
||||
4659b0c9
|
||||
c645af06
|
||||
5b9c4202
|
||||
5a89bde5
|
||||
c7e3498e
|
||||
c202031f
|
||||
51b8e7d9
|
||||
bec84a33
|
||||
163fe7a8
|
||||
4e05e423
|
||||
d1e3f398
|
||||
dce754c5
|
||||
795ccbdb
|
||||
5d1e3e29
|
||||
737f110a
|
||||
20d97337
|
||||
f112e2db
|
||||
cf7148ee
|
||||
c305f875
|
||||
f18e07aa
|
||||
bfdf8135
|
||||
6a216daf
|
||||
8fbe0aaf
|
||||
639343a0
|
||||
0e2152b1
|
||||
695c3d1f
|
||||
22065e7b
|
||||
98acf61d
|
||||
7a3fcb35
|
||||
dcf38665
|
||||
b7a69707
|
||||
03066f3d
|
||||
1ed4cf65
|
||||
193be090
|
||||
6f3ada5e
|
||||
018ce957
|
||||
0eddb953
|
||||
9348cf1f
|
||||
6e6d4172
|
||||
28ec3fe9
|
||||
529bfd00
|
||||
084d2315
|
||||
f3556816
|
||||
cab6043d
|
||||
0262486d
|
||||
7d3c4498
|
||||
61a96b90
|
||||
1cfe545a
|
||||
e92f9e8a
|
||||
57d3eca4
|
||||
45051fcc
|
||||
c73e5a15
|
||||
6bf04540
|
||||
3e5cbfe6
|
||||
e9315867
|
||||
c59ffd57
|
||||
a7eae6b6
|
||||
ee526a3e
|
||||
978aebb2
|
||||
adcf6a3c
|
||||
979a7dc1
|
||||
fc3f7b6e
|
||||
2e716a71
|
||||
878e3d42
|
||||
3144b8d5
|
||||
84224d07
|
||||
408a0c1d
|
||||
af9a7070
|
||||
c86e81e7
|
||||
7e04a9fa
|
||||
b190255a
|
||||
5ce924bd
|
||||
8799f259
|
||||
29e5e7da
|
||||
be77bd1c
|
||||
8e001635
|
||||
75f47834
|
||||
fdde4db9
|
||||
264b2528
|
||||
5586fe04
|
||||
c2a06cc1
|
||||
4a3fb4a2
|
||||
45f4f1fc
|
||||
0fee683a
|
||||
987dea92
|
||||
83b24331
|
||||
b4acfdcc
|
||||
03679bf5
|
||||
8f9ae6f4
|
||||
5cef71dd
|
||||
947f45b6
|
||||
2aac1e37
|
||||
028426d1
|
||||
2dad1dde
|
||||
14a9c696
|
||||
c59d9bac
|
||||
54de7644
|
||||
094a7b74
|
||||
ae7e70be
|
||||
43d26c10
|
||||
6232d8c9
|
||||
cc65bf7d
|
||||
59ee8a5a
|
||||
807addde
|
||||
e7d82793
|
||||
7fe92022
|
||||
4283f764
|
||||
d9a91c0c
|
||||
a77f54b3
|
||||
02aea8de
|
||||
b44fb9ce
|
||||
1a116375
|
||||
46304da0
|
||||
247c2899
|
||||
a9d9cb2f
|
||||
88bcfc60
|
||||
b2ba9844
|
||||
333d1188
|
||||
4c2f12ac
|
||||
a4d54033
|
||||
be8e652e
|
||||
1a37abc4
|
||||
2ca65b02
|
||||
95d7a371
|
||||
55840fec
|
||||
ed610cf4
|
||||
c0809111
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"profile": "VP9PROFILE_PROFILE0",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
"frame_rate": 25,
|
||||
"num_frames": 250,
|
||||
"num_fragments": 250,
|
||||
"md5_checksums": [
|
||||
"a6ddd21f5f4e7424b6e7a1f2925fb33b",
|
||||
"41c77adcfd29abfaad62a057855adeaa",
|
||||
"afdb44531614034e4a4a90c805a5d3b1",
|
||||
"1fb247507d6e076feefb7281846d4938",
|
||||
"597957a1bb001769a675d5be58db3271",
|
||||
"c023f0ad8c3051e536ac9c9bb1d5eab2",
|
||||
"64fd982393c290d092e1cda39cd429c7",
|
||||
"915e863eaba1a7957f554b5cce006e1e",
|
||||
"ace4ad6c26023dbf12f4c5e897e996f8",
|
||||
"166ba862f99f7e0145f0b3a8a46c53a4",
|
||||
"bf401e2e9084c80cb3c22d2d05dcc627",
|
||||
"94dfc278df94cc355b6019096133befd",
|
||||
"c88a98cb020b5cb9372b528ea876e3e3",
|
||||
"7c05949db143606204b3ede34fbc0472",
|
||||
"ebb8798f465fbe8083bd0255a41e17da",
|
||||
"59e6ad68fb6e7c78383426c2dcb768df",
|
||||
"57f2f71ab176f78b815182c107649b56",
|
||||
"0713b3db71e138b41e1c64d5f76292e2",
|
||||
"913558ea3033285c2ef414c29cd9e36d",
|
||||
"f66bcbf90aad3f2973d7210ba221c5ac",
|
||||
"02371beb715f84b4cc366ac78c9597ed",
|
||||
"332355fc07a4eadc59ff5b5f0514347a",
|
||||
"5bc08aa98cb182e58bab48967c26c938",
|
||||
"cf1a6f1bc177d45bbbd06a21417973ef",
|
||||
"c69f55a8cce9b1af971f96989c2ed50e",
|
||||
"51b067bd3faf4b624e265dbf3bba6e43",
|
||||
"9323f02a491fa931645c5add54109890",
|
||||
"2fe699e08540e1a211e259909248f91e",
|
||||
"e4bb4daddbdbc8c9c1b7398adfd2664c",
|
||||
"9356a0ac6701f2231c6a12d6d3eccfed",
|
||||
"597e71f32915badf51be8ffc255aab74",
|
||||
"08a0dcd28bcaa495e95d15d2645d9c03",
|
||||
"48742951820e0b22038c17f715f55027",
|
||||
"df8b6480a30359d33f0fc5ff5f22cbb2",
|
||||
"25d9f7a3dfc3bd6f7e581af20daa749f",
|
||||
"fcb79ce3d922d1478e34399f29fd69a4",
|
||||
"6de189116760547566fa6e3885a9b2d5",
|
||||
"29da43f8a80e83a54db3c83016578bf5",
|
||||
"b327993a3a9782630e8f38830b99f1eb",
|
||||
"6a25c1b232dff00e78565f2886bfa728",
|
||||
"fad26a4f6912ca0527c5cea767eca873",
|
||||
"9d05717db2bdb502179161b9be1d4604",
|
||||
"47f91eb36e06b5c7fff2c538f3026c39",
|
||||
"a5611dd903d184a7ad3b3c5a02027694",
|
||||
"9b977c83aafc80e375655d81406fb3d1",
|
||||
"6eb2923e12b36b91b1d38a50c0a477d7",
|
||||
"14acfd2a71f163186da78c84b34ce0b9",
|
||||
"9f5395258aaff37e8c87b6c07df978b5",
|
||||
"d5a22ec4e0ef752d3877afa7ca1db26c",
|
||||
"005415db7bb57768a6ba92d4a43afab1",
|
||||
"40cb57177361e07b523c95a206f20be8",
|
||||
"e645c544fe2c8426bbe9ff1b24c6be8b",
|
||||
"94a976505f27a90649f553dc7a193fe9",
|
||||
"3b435d0e9e6af6ecf3676cb7299ef6d3",
|
||||
"c169aebf19b7c6f3717ee0e097036507",
|
||||
"c970f90040212ca7a392ca5cb7c8708e",
|
||||
"243932bc414d8de7fb3c1bdfb4fcfa91",
|
||||
"3ff138cd7f150eebf63a2f16a0ddc3f7",
|
||||
"03ad4bcd723e5f2a3e96de33effac6cb",
|
||||
"5416a2155944c3c23167d5a00e8e12b2",
|
||||
"0620389d338d9fea5c6867f261f35452",
|
||||
"377b5550cccafcd5e3142da159791add",
|
||||
"68b1733c716380a04d0dbf21fc1f30d4",
|
||||
"c9b872ed955bb13dc0819661f2b96692",
|
||||
"fcc79ce029edff15bb7c2c5130d421a7",
|
||||
"933967daa7eb201accf440799113547e",
|
||||
"b64df022a685c95ca39c6c860e1f5ab9",
|
||||
"8cb58810932a51ab29b10c691dcd50f8",
|
||||
"5dfd36a6f1d476780724792b7a33b45b",
|
||||
"25580f9904ff6397ddbf57dd93623aaa",
|
||||
"77d61f46a7421182f43385fb7de3ad28",
|
||||
"1e7adc2c2f99538d5c629cf906e82a65",
|
||||
"60336a4c5b6dffcac7f3d42cd8c8d8cf",
|
||||
"7ed47daa771ef93fc2eb05cf123184ed",
|
||||
"bc03e5d85743ecb2b9f408c4814ccc03",
|
||||
"5096b7c2eee1d8d7bf7fc825db35fc6b",
|
||||
"38c7db4fb6532a9c827a6d2c0ca15640",
|
||||
"93188336537ca3b189075b83afcb4304",
|
||||
"4b0a2f9d16710b28e1b5b4f2a6757101",
|
||||
"c14cfb8c07018c8926d849d0d6910d1c",
|
||||
"d0d67b916206b75134f4b254d41a5747",
|
||||
"2390a0cfa71bced2b9fb3637cff30921",
|
||||
"3ab325d11b4014ef6f70734127fd4d31",
|
||||
"9964596397e69118de09fb1e44fe01ef",
|
||||
"89522f41b2b45984a1a27d54c59b41c0",
|
||||
"b3270c89e1278984d133f4c2b7fc0a70",
|
||||
"fdd6bb9f2b4b89584294221de8291107",
|
||||
"79e5d6ec50f8d136e8a01bd0f150416a",
|
||||
"1066212964911081dd41a8c184716589",
|
||||
"5aff5ab98073ca06b2cd02b044ed2bac",
|
||||
"52fa9f744f083400fa1013a9a296783a",
|
||||
"ed586b59b27f1f3147d0c33cf94618e9",
|
||||
"ebe31226ad166d53db606dfd46f65c4e",
|
||||
"9208a53c77d7a69273cbbd386bdaf38b",
|
||||
"5cbc9121a9decf62cdf538fc3b6ac6ff",
|
||||
"de33f01b71d0b84bd6641864e5e03c1d",
|
||||
"68459b19450133bebfe87e8658840d84",
|
||||
"f93988c89aff87855e8a46a388231ea0",
|
||||
"02a92e92e273e30d11c65a9c17afbdc0",
|
||||
"194ee974b89f3c7ed85efc0b3067bcf8",
|
||||
"111c441b0ce29b52370d79a7c040a319",
|
||||
"c5c668728b0a0def951aabb873747c64",
|
||||
"9fc4ce859ad1060df8583f11650e5e69",
|
||||
"ac7ea5ac33d992834e18d5a80f7865bb",
|
||||
"ede582c26d225a3cb903504a2817685c",
|
||||
"4d491df588bdebd988d8d89e1f3aeae0",
|
||||
"3d24041ab9920d06219f02b762d1ea92",
|
||||
"5bd75a66e942a73ae09bb24936335869",
|
||||
"5d335e05b9b578f104306a3577acbfdf",
|
||||
"866816a72e249b6cf0f9f6e33b65ac78",
|
||||
"afaaa9d734c02fedb83ebf6524e9bab6",
|
||||
"d7d1b2774ef4ddcb191fc9fe6bf28c29",
|
||||
"482908be24d0988e8e6b40df91c1bb1c",
|
||||
"1752814ee8e6d3097cca487d503edb0a",
|
||||
"128c52fa88a9e3df2b928519812fd3f2",
|
||||
"cb41c09b32c25ad921c87538b62f70f6",
|
||||
"a1be95f5d67cf17a1540557605398b5e",
|
||||
"28fcc49f81a46bfb2fa1e39b7ddbef2c",
|
||||
"1e6fe0400d792d432c03a6fbb7a346da",
|
||||
"fd357048fef2312acd9bd1a84f08dd0d",
|
||||
"2f4925cb7f740454ca31ecad6da072fa",
|
||||
"721c71f2297e2cde48d23e2d14209b70",
|
||||
"eb39d3512e79c54299a2f2360d001523",
|
||||
"d3b3c4661b95a8102a091dadb3f61a8f",
|
||||
"abed47e70a4fcea8b5905e27bc4d91d2",
|
||||
"33144b402f5b60a0d7109727d678367f",
|
||||
"347710490553e286bb41635a87d51440",
|
||||
"e5d90bfd73c660c136f18708cf691902",
|
||||
"2ccb92441cacb6fdc449092df990f7c1",
|
||||
"cd457fae93314e50d5c2b7f1f3cec91a",
|
||||
"d00e8d32b7b8e03211ec61f8329944c0",
|
||||
"7481f50fca5fb8758a12932b40eea3f8",
|
||||
"24cda7a1abbbd3f90286e529ad0ee446",
|
||||
"fe49c757004f028382165c8ea24208e7",
|
||||
"d903372b98ebe31896a591a1a6cabe0e",
|
||||
"28f937e819685a1b5e73cd404e998fb0",
|
||||
"5bd6d6f0037891cad42864acc85b9824",
|
||||
"c5c6a4e219aebda78e3e9d2c91a48564",
|
||||
"0a367f3982856c5bd984c2f866b255db",
|
||||
"8d62ebc501823bce65b840cfedf2e75d",
|
||||
"49b0c80de766ff81ab183cd611d1d118",
|
||||
"da984ebe368315c820f2a1caaafd2534",
|
||||
"710b15893183f93f2497c2e98ba56e0b",
|
||||
"3ec5a99fcf6f43eedff8dd9995aa4704",
|
||||
"67b9d9e89fb300ae3ebb03b396fee273",
|
||||
"6194ca3c338f64f144326486d118e793",
|
||||
"e85a130d9149590919e72a2f8ecc5f1b",
|
||||
"62fbf66d14bc819353086e442c581616",
|
||||
"bbc6b58d27c1623bc87dd81793dd72a9",
|
||||
"5804683f0f89bdb8e43508e93ed2d17a",
|
||||
"72fb2bd71150381878acc658ea547020",
|
||||
"351e4493573d81f4b8cdbf4a94fa2dd5",
|
||||
"573f6ebdef825cc73a6aefa219518add",
|
||||
"f671a8002c56f70623b1d36f6d1ccce9",
|
||||
"bc8f0deb204095ec70effde543c4f087",
|
||||
"a0e79d0c3e9c3734c90471e17cfaa402",
|
||||
"1e85a120057917174101240f66fbe12c",
|
||||
"bde29019b9d44035c78ae593d882c0df",
|
||||
"f1036a0a0190b198558aeae5c8539100",
|
||||
"7d50b367eeac4a7ea9d0f797f3f286b8",
|
||||
"133a4ed3fb42fe986117df1fe34f07d9",
|
||||
"1e899dad271bb94f8d768c2025d527d3",
|
||||
"258bcce7005861b2a6c2e547c81d66a3",
|
||||
"30723accdb0788aea00ff42610c0dd99",
|
||||
"a60ab6066b2b8258194cb10d8e10c206",
|
||||
"321b86641c6e978e98b36ac367982397",
|
||||
"be2b37e04fde984631e06ee04c8749f8",
|
||||
"af1de1b1e1b4104aa99b563527828c68",
|
||||
"c10f648540156e7379ed764ad424e233",
|
||||
"716f1d5d894f0caeb6e060c365b1c68e",
|
||||
"4da20c2960132d909767cb328a2c70d7",
|
||||
"a5d0eb676eabcb9b808c1b7c6b312c3e",
|
||||
"c06cabd771e2c42a9e2c3ca7738525a0",
|
||||
"e87e67d2e0ffbd9762a4e99ddeba53be",
|
||||
"3eb39b20537cd8cd12f15ccd6848f672",
|
||||
"f3212f83868cbf07b06774c0283b25f2",
|
||||
"746d5d5355f10892237e9d0dab554485",
|
||||
"1956d40b46bf714d8bec22d784c54611",
|
||||
"fba00831cfc6f6d948917c0e02a22ca0",
|
||||
"c744b4f54702e34f47c0f4c4f40ea615",
|
||||
"7c7adfc5fa5d03b5b7e07cd6e8293b4a",
|
||||
"5825b5ba1960c3b1a88aa1e10e5f0474",
|
||||
"d90b42024fda5312a0d886cdc2ce20f8",
|
||||
"0592eee5f90d9dbd2ac17b03ccc0ed2a",
|
||||
"2ff9315ce6dd9f4c6ec501c481dceba8",
|
||||
"0a3ed552d91de9a403120f2e118cfad0",
|
||||
"ee32ab17ec770aba340cb68e181275d0",
|
||||
"3a36fa6fb7140d2354ba1ff2f1d287ec",
|
||||
"77e8b7f41eb1cd46c389c9c3fecfed44",
|
||||
"7f8f710b7bbd5a033300d0e4fb47f71d",
|
||||
"28eefbb77d26f698bb658ed7f58cb17c",
|
||||
"811d2afc4e6f5e8efcfc03563d1374d2",
|
||||
"53d51c878f1aa62fb2753d67f2decc02",
|
||||
"1a20e2c1da568ac283173c60807d7bb7",
|
||||
"f77541cb2afd1633cb4e5294e99de8a2",
|
||||
"e859d77a2cc87972cc7df32e6c625f00",
|
||||
"18d8d2ab6cf205ce70316ce7a3e7e3b8",
|
||||
"fa2e35da2ad12625ed5f50be46bdd61c",
|
||||
"463169e7371dc37f3d082a5f166b904e",
|
||||
"5e7f7593bf77b346cbf9906741623d94",
|
||||
"60089de0fd61bf8547cff25da75d79db",
|
||||
"609dff1ad553656a98bd6ea178f093c1",
|
||||
"34ba858360b9943770e3b2c9594dbbdd",
|
||||
"02dbd49e186b241f42c59f9f77d74e13",
|
||||
"0632f6c62ee2b72e3dcd3ebbaf3f8e59",
|
||||
"0cf0fe04e5bda8159176da2150ae56dc",
|
||||
"ea48f3c5ee4fda7b7c44ad0f9aed7ce5",
|
||||
"25a1a468110f7819dfa688bf08bb08c8",
|
||||
"702f29070dae81d71fd4b6ec16766967",
|
||||
"bb8e273c432a96b4c8fa92fde5210a54",
|
||||
"702cccf5fe0f912c4a369e0c1b0d1d6c",
|
||||
"bbdef9ec58db645eef1b52129e914dcb",
|
||||
"3816969dc45df4e2d39db44f460bc0cc",
|
||||
"db25e3bb20d5a30bf9170897e3075732",
|
||||
"43875d9f264821d179f0d861cd5c82e6",
|
||||
"467945c3124b2e4a4d65ce6a55e4f889",
|
||||
"47ad1273bfc4b8575515498fb3e68570",
|
||||
"8cf9200d7ce629344fad9e7772c5f099",
|
||||
"a2d784b07f4f64ba41309138f408bf3b",
|
||||
"aa7de9e0f6765a7b5a9dd6a37de1e474",
|
||||
"4e82c66108b942323c95223d729731b0",
|
||||
"4d7dc2ac3395345977678913400d671f",
|
||||
"817546d45e1d74c5f5211002947ce94a",
|
||||
"d4b41f15f106231c194db91bba1c9350",
|
||||
"a61f9dd98999e8b90093817f280046f7",
|
||||
"3a6943d566df3f8d9aa342554f2a30f6",
|
||||
"1738e3cb6680ce1b09c9dd25b7b51d16",
|
||||
"846b40c6d1023862b5ab86c558cc75e6",
|
||||
"8a6156e1d440d1694e9df3e7c0b0a2dc",
|
||||
"f6be779252c9d6d9409c94a899f23090",
|
||||
"11086af958413f0ae757571535d7ecc8",
|
||||
"701254468010c99da0d1f98a39099bed",
|
||||
"2624e584871b8fed98168aaa31c7d264",
|
||||
"8fec6cc28ab6d0072a9ded2861e13f96",
|
||||
"700b06457ff7f99b47e5412c2fec7324",
|
||||
"b34f8ff874d0c9e4730ad94cde30722e",
|
||||
"814a5d8724ac31d3af0d1076c4d3c2e1",
|
||||
"342befc9829aa640b36de1085e3849c7",
|
||||
"e7879857be414f0215a5716dafcce729",
|
||||
"874ea752b65d583b44615f23ec00e3de",
|
||||
"8b555f7686aec7c61df83504275b0491",
|
||||
"7a1763fab40e8e049c8320e603be4bab",
|
||||
"e50ef5703efbd0b38266057a05b4e56f",
|
||||
"014bb33e138fb10157a062cd4906a032",
|
||||
"94224a6b01c4b088d429a78421b777d7",
|
||||
"8bb86793ac81fc54f3a6c9ff354ff9f4",
|
||||
"6b90162e6ba9308ac891770528a0b2a1",
|
||||
"5a63e607041536fa3f633c769f0a9e17",
|
||||
"3b33f8e78890e8a41d8cd93ebee7078e",
|
||||
"fbb59915d51c7f56386777e70ba2dddc"
|
||||
]
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
c147a6c80d9209e5a1e992d4e610a95e
|
||||
807f9c05d06ccfb7f6a77018f52c07d0
|
||||
df198689de44a69924d8cfe791e5dc84
|
||||
856efa94272c5b0fabec7e1179563806
|
||||
b5586069cc2a58a38d0271136949c760
|
||||
5a0a2be53ff9bc19f131469bee430262
|
||||
40374e2eabce3cb67b9f0d9992f31edc
|
||||
2c0881752530fa3fec18f3aa3277f938
|
||||
c86341015022064f0070cc8b70f2edbf
|
||||
ad05d275a93b63de6327436b48cf9e80
|
||||
4ed78beec93f00af0d6cf78cac200494
|
||||
9273549b482b591a9da3543c490d4847
|
||||
59b84f1b3e971e27212a8f690d8920c0
|
||||
07b78dec9c8070b40e87fdaa18b4627f
|
||||
ee7e9db173349fe2ac2c199831bd5eed
|
||||
ccaabbed17e58a6f77da8a5b00f9f24b
|
||||
436aada1f8eeef8b11bfb454310461a3
|
||||
2bb8c17d108b4b5b9594461efe48ffe8
|
||||
04e89161b5ddd1cee2850f19c1ea9af7
|
||||
bf527e3dca6c046d5b0aba1cdcd95f28
|
||||
564fce13d1ddbaa1d587bae33130e0f1
|
||||
e7f84fd6b22935634144d85818ed0ce0
|
||||
389109c513f164483e1cdf67d1d17e20
|
||||
888e96338562ea5ac11882ff897bc45e
|
||||
0734d839755f4b660e282fbdfd303da4
|
||||
86ba362ca374dea486493877bc83830b
|
||||
1549542e46f6c9a412779461b3b2e1c1
|
||||
b90ec322166c72e41e9605f7a0c00e34
|
||||
2e293965ced430e72dc44daac571ae96
|
||||
8952e34cad20b1ad4460b0510c255caa
|
||||
d6cfbb47f87f2c6d27bdec96fd86bc80
|
||||
57fa0881469337f201b01d025c255070
|
||||
e3c562edb81b8ed8bdda8ead100b47f7
|
||||
60faf70b449db2ce46010a71d10e9a37
|
||||
2d5fd1fa5fd07021be4be51e279496d7
|
||||
8094a24162877f21e8e2c876631d911c
|
||||
cc675882c3a3998f19875e291c1f158a
|
||||
4a049974b54cdf78f45c775bbe21cfc5
|
||||
6f78137fee79f8882b8bee2b5830aebc
|
||||
25e75b7a102c32988bb676743d46da7f
|
||||
bae608bf6d8b156669cc884ab37e6d7d
|
||||
883651afc0bdaebea1a7906f51b1f07a
|
||||
71047b3c17d1aeb3eb3cdad867a6cc1c
|
||||
fa5b4d415cca2d417e1ee5fd2177eb6f
|
||||
fe4dccf6135bb46db063b1b1b09a1b1b
|
||||
4f111590afad4f98c70ef2f7ae2ab302
|
||||
c39c4467809fdf8b396f2f4643c72a39
|
||||
5eb42d6e49b71cc75748052104cdaee1
|
||||
07398ff06268387fd10a956b12dff28e
|
||||
5e568ba441a984e117d5a9362267e4f1
|
||||
6bcbfebe110cc1014a325b0be3ebac52
|
||||
3ad42d2755b6e9fdbd2d92abd212d636
|
||||
a2a368e017d5cb835d0953a00a6bf2cd
|
||||
c3955a9d37d474036e1457d486093aab
|
||||
584fcc9af0395b6e6c3f28d64473bcc2
|
||||
511a81a66dfd9c83b15c561a81fa45d6
|
||||
62364a344fd1f9706c011a197c6b0cf2
|
||||
3f1c26938b57f0973fb73c064dfa9bf3
|
||||
dab959b019d40ca4114893d774945fa8
|
||||
1c33008422a5351bc61423912fabc669
|
||||
f20ec6445ed4d41421fb6f3fde5bbaca
|
||||
ca43b98fd0e7c94c60b403f2acc2e948
|
||||
a5efd2ae15724d229993842a9c919011
|
||||
da547900d3e9eb01bf4765e2354fe88a
|
||||
7259dc31f78637c9a70ef43906fa5807
|
||||
be346c4bb4516f67883802c200179e06
|
||||
8c8f6991b9124c0aa7dbdfad68bd2c9c
|
||||
6049aa8416cf2a3b7df3cddd86b44e64
|
||||
363eaac4e65bad5556a3e175d643123a
|
||||
b6822e13f6db695c822afd73e0b989ef
|
||||
61c375d0f9dfedc67304e920c08301f1
|
||||
7a46f29451ca727ef7361420cffeabdb
|
||||
80edef5ace96379c40db611885141c34
|
||||
1697174088d86b17d6b372c20aecadea
|
||||
148fca7be383caf8adf8433a25e4d4cf
|
||||
c2eac8e9ca853bea1e76acbcd774e2a9
|
||||
c8310d2b03328f17f9ea602df338d279
|
||||
fe641d1b7be37c948e30bde65f609fff
|
||||
00c13ad8d2766ab091d96960cf6609e1
|
||||
44d4d30bdcffdab69e16d4f07aa66c9c
|
||||
62fbf74f8cdca21c0c7814ef3c515a4c
|
||||
9762ed61bb1c78c1dc84bd67d05c8016
|
||||
31a4ac35433525329bafd764405058ce
|
||||
6bf0c3b23613d7fbcb04e8b715eb96e6
|
||||
a20bde62736096ad152544f195afc41b
|
||||
0b1f0a21f64623b268ee55f8ecb0dc27
|
||||
8d77996095e9a258d3505bbf17fda0b4
|
||||
49eb262a315de652dadb7a22c1e8d601
|
||||
d466dd053e522f653be20c2d81540c03
|
||||
6e1afad04dd7f9f72a59c5a173686ab8
|
||||
9726e527b395492dcb6ff72a0d5a4796
|
||||
f272035189417682ab283889a9dc1fac
|
||||
2bbd94a07488d59f8147388f0c394a40
|
||||
f7d750c1a7a88d1684f42cb535430280
|
||||
1ba751a04d93c7bcdfce9391001997e3
|
||||
68cd83e38eb422ced19838e7167765c4
|
||||
f003f95a69519492fbf6b08969a0c261
|
||||
5701ccb9205417896a193a800d32c38f
|
||||
b712418e2276267553b1056782a7e96f
|
||||
1be965ee1da3c8dc4e1e5bd01f850ef5
|
||||
02da1c68b982cd7a30e104320d04b36b
|
||||
61e0a8d7df2d01909aa463701a3bab30
|
||||
dcad9c4c4bb4855c2fc31c47f5a0c12c
|
||||
c0de7fba39fcee42577dde05f4d8b0af
|
||||
6052cb7ece90c1c64861fff7421a9d69
|
||||
ef669757e94008168aff1646b5c04c0c
|
||||
e03f821f36ca1b59c2054a5aa72cb82e
|
||||
a32fee7e3e39f3e69f69c940a9782493
|
||||
dfbe0be3fce78c0c6bea90058b5321c3
|
||||
669b2200b96bbe5049a37ef88f86b1a2
|
||||
d95206a7ecad0f0d154d59b8b81c398f
|
||||
f1939cbbc7f9803b03551e0ee8e976e4
|
||||
54a25909ecfc627c161ac9bd5dde0dd1
|
||||
be6a415aec10a459061cab5f856c1dae
|
||||
398d56c536ac7b051fb8a96d7c12e147
|
||||
06b0b34464aacfb4221d4a1d17781a70
|
||||
d25f64611b9d7bebb6124c2f0c39250c
|
||||
94c2b637e08ee1ee8c79eb662a199450
|
||||
7febb4a4f4b711ea70e86e7054b41277
|
||||
04b884c1af9ac9806495c65de8dcb748
|
||||
00dd0c5d65933dfa721a61e3683c54a1
|
||||
ab6974a3b1aa3a510e84ffa04b4b3f89
|
||||
297d608c848d13c71c42289326d169f2
|
||||
89c514f843b17cc07ec1c4c08feabee9
|
||||
8055e52cacff9cddfe49432d20d0bfd7
|
||||
ccefb98fa05dc5863b6deb905ff1c3ac
|
||||
11406e832f5a98f031c717a30d4f3861
|
||||
f173396fc7e7bffd8d6df55551dcf51a
|
||||
54d7421b70b4d182e3fb4dee07c70178
|
||||
2e43573aace01f9fdb6a6dd6537407f1
|
||||
eb6c3ca7906821794693205a27609dcd
|
||||
fd686d26cde34b7d11527a9794813e3f
|
||||
9b82ec0d251d5e294ccae92896b0bbb2
|
||||
509ffb563baa8b528e463dd0c1606229
|
||||
6344839db52a21e64cf93fb23a1cf8a9
|
||||
a0781ac759a9017b75a8e6ee58261adc
|
||||
00cdccc8b20608e9fadba7cab2a52aa4
|
||||
d2f5a572735fb09ff0a2765366980985
|
||||
9ae66ea9466618e8d30f3dfaaf05cdc4
|
||||
8e18ba56741b48ce88c23baac7b60d83
|
||||
1530c8f53fe1edd5e290eb70969c4e0d
|
||||
9fd6cf8b4992dd5a83617fa0540fdb49
|
||||
eeddde09d799b59f9676957095f7b545
|
||||
9acb5a05373f57a9dca7ba745bea066f
|
||||
d85400d97728f0850a53de94eaaefa1f
|
||||
88ea3f31c331b394a01f6f4ea44dbe73
|
||||
38ca4b29acc8922e012e274b2306b484
|
||||
4d3ac7cc0f7df2363eeafc1d3916904b
|
||||
e7307e525f8a833de862cd1b953757be
|
||||
ee6208f9f33ed8680e2bc04babad0843
|
||||
2e45bfc6975708fd3e7e0c4524755231
|
||||
3dddbaf8b60bfc79492749d5230ec23d
|
||||
713eba2ea4aebf9d73c525971d6e9bd4
|
||||
396a002c7217fefd9c760f63ecfd0e44
|
||||
1ba18897ba27c7913dc78eca0b465a6c
|
||||
9f80d56ce61776d19688b71fa20e66b6
|
||||
fe0fd66f26f13ab470e7696ed57440ab
|
||||
7ac35e1a6f9de5a5247c55d9971ed02c
|
||||
b45218ddbeaf8b1c1cc61836d49bf331
|
||||
647c6c98430ad0f6304d1f7ab54b0791
|
||||
a5b2c31a77130f10c81f9b1e8c0b36db
|
||||
f85a9d6ab3fa171217d01c9eddd520fe
|
||||
d294eb44a6972cd33c6c9ccd492ee4d9
|
||||
c776f43b7b879779221a2cb6fe363062
|
||||
dfbe59edcc434a5a2efe95aca98929fd
|
||||
c5b7bc6f751ae1da4c4d9b596c208300
|
||||
aee6993c994fe114192cd440f2529ba2
|
||||
c16a35af9d237d8bb00bfd78d7910177
|
||||
5b17eb3d2946acc9936f54b092236e18
|
||||
35ab79392d55fe4383171693cc4f1b07
|
||||
65bb08bf3f1fd317baf8249bc39fccce
|
||||
6e9db766a1563d160a646d3cee97e82e
|
||||
dd4c49639c8c3d7bfb950efeec7af608
|
||||
32ba1749595850aa1f7e5430c168f1a9
|
||||
9aefbafbc6e058822f743c48cbeea6e6
|
||||
e73cbbb909c9a6e6e016b454313e00b1
|
||||
b5cdf19a48d33b8476b5b751a2f0398a
|
||||
6ab09966690b0ea5c87269d4a0547597
|
||||
43ee16fe7b45c986fa99441b8c0a64d2
|
||||
1ef3e648b93a33b31084f030223dc2d3
|
||||
619b4e87d66c772be269e32443bfd768
|
||||
f30c876850197446f344597f63299fce
|
||||
7c8a639e3f8175fd35516a1f03517d8e
|
||||
b487f19e64626e5982f52f8de4238732
|
||||
4b41df592b2c341b9821c2c1b7385607
|
||||
f781fa740d9c3148343e1a133ee1235a
|
||||
e4e7c51802d9156046e746804d2c3960
|
||||
3a63be1c6da417534b10a261604797ee
|
||||
dce7b40962fa4ba57d0c2f3ffd5cd939
|
||||
dace0df358316264cdedac24fe984907
|
||||
6f6199ca0aeb0aad15eb613c37fd7db6
|
||||
cce509a1501aaa3739dadcd1351d83d9
|
||||
772877b6930a6f69b717a4d286f70259
|
||||
d8f658e3732b7ae095c89d2cfc29fe2c
|
||||
a5e57567b758e1636bba4bb605598846
|
||||
7f0cc4258ce46fb86d310efa337d5dd9
|
||||
3c9586b001cc1e61d7df35c4f793f8f1
|
||||
94a0e6e24b394725a66b6c9c8ba3072b
|
||||
4c01c47409d56a9ba57c421ce529b015
|
||||
f52cda4db0cd197d5a4577cc3e1d7ed9
|
||||
f2c479c08e12dc3db08cc803d0a2a74e
|
||||
f5dfcc218ae104eba96007de1aceae2e
|
||||
1a6e97ef60fd4dce42ce071d2e2eacbe
|
||||
91e4d4e2361fcff17b342f4bccaab971
|
||||
9d47703a6842aaac5af6c5d030518e7e
|
||||
eece44627dbea68991083644fc2381cd
|
||||
51869793a192ffcf48cf21da662ecc9e
|
||||
163be4c547f021ca8cb28a846eebf391
|
||||
344f9a7106be2be501b8e4058be63db1
|
||||
fa2fe8613470850bc170ca1f12b290cd
|
||||
b8de6ae393a5942f594106575cc6ba9f
|
||||
14a91b5383dc58a04629135783aa9530
|
||||
2eb55d859f402efccaedf26bdd5e7902
|
||||
590f580c70c9786da51aa8c51179e56a
|
||||
74fac2eaf11337dfb26e3526fca79fae
|
||||
d88e4d50c166be51882d8661fbeccf96
|
||||
88af6551d54e4ed178dce48233d2e5c0
|
||||
28fa953a8f34f100e579ca2c7009f38d
|
||||
985fd0061c8219c4696c77f6bf115b5d
|
||||
bd145b09d36a4fe829198e996fbb5a94
|
||||
c0fbb7395a9445007c6f48cfe663d7af
|
||||
0af2f819e0d26a06f5e2fc093f9c543b
|
||||
4a618df8ff7b52d9488d55640d455bb3
|
||||
83042b532a5feaa5a5330c36c70484b4
|
||||
39b3379e8a674abaf69c67fa2d9a309f
|
||||
2510362eadc9668087a4464bef146a44
|
||||
afd98f5903cf76c395904e0bb634b4aa
|
||||
c8a6d4f5db71bb848292eada0ce9b5c9
|
||||
4437d4d02ae857c35cafb4a86a9c819c
|
||||
b5bc681646a7065caf5a5a3ec93b976a
|
||||
7a7b91f1c78eba0b5da0203dabd3d972
|
||||
b4346ff7c1cb9074e51c7f0ef962e2a0
|
||||
d5958a235c658ef6af3177d59a2f980d
|
||||
047e5c8dbf486d1017e335c38005711d
|
||||
96a7fd8916f7b2bf5c192b2b52a5566a
|
||||
5c555d4a1e27a0d72bfa06b1c655cd78
|
||||
80d6238d61e3f2281f7567c4816b20b7
|
||||
72160290ff45fe6fdb995555508fc592
|
||||
4696ab63675996dc280b290f51b8d095
|
||||
2d2440a00a59b3ec9edcd09e9899f30b
|
||||
4493b8a3446daf20f34541bde3c24d41
|
||||
0b4bc2afc7e9af942c1dc79fd120862f
|
||||
1758e3ad8cf7cf842955968ef22c68be
|
||||
5811fbff95273c5413591fbc96b07a0c
|
||||
dad847f2b0916baded9b5f219b99c213
|
||||
69d82cb277d48c60c9baf260b55c8792
|
||||
8c4d98b207141ca2fa344fcc7415d164
|
||||
a5421ea000aca629c3185e9270d34c8f
|
||||
5dda27e72e1d5fff2614b14967aa89db
|
||||
14e209d94a0bf732aaab43f272825d0e
|
||||
BIN
Binary file not shown.
crates/pf-bitstream/vendor/cros-codecs/src/codec/vp9/test_data/vp90-2-10-show-existing-frame.vp9.ivf
Vendored
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user