mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-27 20:16:50 -06:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ebb43fe60 | ||
|
|
4134ace141 | ||
|
|
9d23ff97b2 | ||
|
|
1bee1857d6 | ||
|
|
13ed8889da |
Generated
+23
-97
@@ -208,9 +208,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "arboard"
|
||||
version = "3.6.1"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf"
|
||||
checksum = "aeb9553e62312c8756a5979254fc6d7da8bbeb5986a1e17037fab932f7037917"
|
||||
dependencies = [
|
||||
"clipboard-win",
|
||||
"image",
|
||||
@@ -222,7 +222,7 @@ dependencies = [
|
||||
"objc2-foundation 0.3.2",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
"wl-clipboard-rs",
|
||||
"x11rb",
|
||||
]
|
||||
@@ -1593,7 +1593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2181,15 +2181,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "i_key_sort"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c6c58d0c60705e66264ce0f788a69a2f21472aeb8188559e7c8c619dbdc10fa"
|
||||
checksum = "14269ee362009550495e20650ff3c2bca14a8147fe251e216760381ffed90b6f"
|
||||
|
||||
[[package]]
|
||||
name = "i_overlay"
|
||||
version = "9.0.0"
|
||||
version = "9.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a518dce2d7cf7e3758159747e7175c8b86ccdcd8d333dfcb7dbeb3eac2e324fc"
|
||||
checksum = "913fd692c02408adc76cead636f8e7e07c705f8b995a8b54b454b995e8e197d5"
|
||||
dependencies = [
|
||||
"i_float",
|
||||
"i_key_sort",
|
||||
@@ -2208,9 +2208,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "i_tree"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e9d4a992a9fe83130f41ceacceac3bb116a4355dfc9c8d6ecea4f1e4b4c6caf"
|
||||
checksum = "048af31de955890c62a8506fec511335a5089e91e1c516537add16f96c507d84"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
@@ -2847,7 +2847,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3320,7 +3320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.45.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3863,7 +3863,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.12.1",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3920,7 +3920,7 @@ dependencies = [
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4077,9 +4077,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.151"
|
||||
version = "1.0.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||
checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
@@ -4541,10 +4541,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.4.3",
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"rustix 1.1.5",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4810,7 +4810,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||
dependencies = [
|
||||
"memoffset",
|
||||
"tempfile",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5461,7 +5461,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5621,15 +5621,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets 0.53.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
@@ -5663,30 +5654,13 @@ dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm 0.53.1",
|
||||
"windows_aarch64_msvc 0.53.1",
|
||||
"windows_i686_gnu 0.53.1",
|
||||
"windows_i686_gnullvm 0.53.1",
|
||||
"windows_i686_msvc 0.53.1",
|
||||
"windows_x86_64_gnu 0.53.1",
|
||||
"windows_x86_64_gnullvm 0.53.1",
|
||||
"windows_x86_64_msvc 0.53.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.2.1"
|
||||
@@ -5708,12 +5682,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
@@ -5726,12 +5694,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
@@ -5744,24 +5706,12 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
@@ -5774,12 +5724,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
@@ -5792,12 +5736,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@@ -5810,12 +5748,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
@@ -5828,12 +5760,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.30.13"
|
||||
@@ -5905,9 +5831,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winresource"
|
||||
version = "0.1.31"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087"
|
||||
checksum = "a2bc6d36480b829272a5bdabf08e6dca8004761c1da7e35efef800540c66221b"
|
||||
dependencies = [
|
||||
"toml",
|
||||
"version_check",
|
||||
|
||||
@@ -104,7 +104,7 @@ impl<const L: usize> Lane for [i32; L] {
|
||||
}
|
||||
#[inline(always)]
|
||||
fn neg(self) -> Self {
|
||||
self.map(|v| v.wrapping_neg())
|
||||
self.map(i32::wrapping_neg)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn mul_round12(self, m: i32) -> Self {
|
||||
|
||||
+197
-149
@@ -3,7 +3,7 @@
|
||||
|
||||
use crate::error::{Result, ensure};
|
||||
use crate::picture::{FrameRef, RefPic};
|
||||
use crate::slice::{Mmco, SliceHeader, SliceType};
|
||||
use crate::slice::{Mmco, RefPicListMod, SliceHeader, SliceType};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
@@ -174,6 +174,103 @@ impl Dpb {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initial reference picture lists (8.2.4.2) as DPB entries.
|
||||
fn initial_entry_lists<'a>(
|
||||
sh: &SliceHeader,
|
||||
cur_poc: i32,
|
||||
short: &[&'a DpbEntry],
|
||||
long: &[&'a DpbEntry],
|
||||
pic_num: impl Fn(&DpbEntry) -> i32,
|
||||
) -> [Vec<&'a DpbEntry>; 2] {
|
||||
let mut entry_lists: [Vec<&'a DpbEntry>; 2] = [Vec::new(), Vec::new()];
|
||||
if sh.slice_type != SliceType::B {
|
||||
let mut s = short.to_vec();
|
||||
s.sort_by_key(|e| std::cmp::Reverse(pic_num(e)));
|
||||
entry_lists[0] = s.into_iter().chain(long.iter().copied()).collect();
|
||||
} else {
|
||||
let mut before: Vec<&'a DpbEntry> = short.iter().copied().filter(|e| e.poc < cur_poc).collect();
|
||||
let mut after: Vec<&'a DpbEntry> = short.iter().copied().filter(|e| e.poc > cur_poc).collect();
|
||||
before.sort_by_key(|e| std::cmp::Reverse(e.poc));
|
||||
after.sort_by_key(|e| e.poc);
|
||||
entry_lists[0] = before.iter().chain(after.iter()).chain(long.iter()).copied().collect();
|
||||
entry_lists[1] = after.iter().chain(before.iter()).chain(long.iter()).copied().collect();
|
||||
if entry_lists[1].len() > 1 && entry_lists[0].len() == entry_lists[1].len() {
|
||||
let same = entry_lists[0].iter().zip(entry_lists[1].iter()).all(|(a, b)| std::ptr::eq(*a, *b));
|
||||
if same {
|
||||
entry_lists[1].swap(0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
entry_lists
|
||||
}
|
||||
|
||||
/// Reference picture list modification (8.2.4.3) of one list; `n` is num_ref_idx_active.
|
||||
fn modify_ref_list<'a>(
|
||||
list: &mut Vec<Option<&'a DpbEntry>>,
|
||||
mods: &[RefPicListMod],
|
||||
n: usize,
|
||||
cur_fn: u32,
|
||||
max_frame_num: u32,
|
||||
short: &[&'a DpbEntry],
|
||||
long: &[&'a DpbEntry],
|
||||
) -> Result<()> {
|
||||
let max_pic_num = max_frame_num as i32;
|
||||
let curr_pic_num = cur_fn as i32;
|
||||
let mut pred = curr_pic_num;
|
||||
let mut ref_idx = 0usize;
|
||||
for m in mods {
|
||||
ensure!(ref_idx < n, "too many ref_pic_list_modification entries");
|
||||
list.push(None); // temporarily one longer
|
||||
let (target, is_long): (Option<&DpbEntry>, bool) = match m.idc {
|
||||
0 | 1 => {
|
||||
let d = m.value as i32 + 1;
|
||||
let no_wrap = if m.idc == 0 {
|
||||
if pred - d < 0 { pred - d + max_pic_num } else { pred - d }
|
||||
} else if pred + d >= max_pic_num {
|
||||
pred + d - max_pic_num
|
||||
} else {
|
||||
pred + d
|
||||
};
|
||||
pred = no_wrap;
|
||||
let pn = if no_wrap > curr_pic_num { no_wrap - max_pic_num } else { no_wrap };
|
||||
(short.iter().copied().find(|e| Self::frame_num_wrap(e, cur_fn, max_frame_num) == pn), false)
|
||||
}
|
||||
2 => (long.iter().copied().find(|e| e.long_term_frame_idx == m.value), true),
|
||||
_ => continue,
|
||||
};
|
||||
let Some(target) = target else {
|
||||
// Missing picture: keep the list unchanged (error concealment).
|
||||
list.pop();
|
||||
ref_idx += 1;
|
||||
continue;
|
||||
};
|
||||
for c in (ref_idx + 1..=n).rev() {
|
||||
list[c] = list[c - 1];
|
||||
}
|
||||
list[ref_idx] = Some(target);
|
||||
ref_idx += 1;
|
||||
let mut nidx = ref_idx;
|
||||
for c in ref_idx..=n {
|
||||
let keep = match list[c] {
|
||||
None => true,
|
||||
Some(e) => {
|
||||
if is_long {
|
||||
!(e.mark == RefMark::Long && e.long_term_frame_idx == target.long_term_frame_idx)
|
||||
} else {
|
||||
!(e.mark == RefMark::Short && std::ptr::eq(e, target))
|
||||
}
|
||||
}
|
||||
};
|
||||
if keep {
|
||||
list[nidx] = list[c];
|
||||
nidx += 1;
|
||||
}
|
||||
}
|
||||
list.truncate(n);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initial reference picture lists (8.2.4.2) + modification (8.2.4.3) for a frame slice.
|
||||
pub fn build_ref_lists(&self, sh: &SliceHeader, cur_poc: i32, max_frame_num: u32) -> Result<[Vec<RefPic>; 2]> {
|
||||
let mut lists: [Vec<RefPic>; 2] = [Vec::new(), Vec::new()];
|
||||
@@ -186,25 +283,7 @@ impl Dpb {
|
||||
let mut long: Vec<&DpbEntry> = self.entries.iter().filter(|e| e.mark == RefMark::Long).collect();
|
||||
long.sort_by_key(|e| e.long_term_frame_idx);
|
||||
let to_ref = |e: &&DpbEntry| RefPic { frame: e.frame.clone(), long_term: e.mark == RefMark::Long };
|
||||
let mut entry_lists: [Vec<&DpbEntry>; 2] = [Vec::new(), Vec::new()];
|
||||
if sh.slice_type != SliceType::B {
|
||||
let mut s = short.clone();
|
||||
s.sort_by_key(|e| std::cmp::Reverse(pic_num(e)));
|
||||
entry_lists[0] = s.into_iter().chain(long.iter().copied()).collect();
|
||||
} else {
|
||||
let mut before: Vec<&DpbEntry> = short.iter().copied().filter(|e| e.poc < cur_poc).collect();
|
||||
let mut after: Vec<&DpbEntry> = short.iter().copied().filter(|e| e.poc > cur_poc).collect();
|
||||
before.sort_by_key(|e| std::cmp::Reverse(e.poc));
|
||||
after.sort_by_key(|e| e.poc);
|
||||
entry_lists[0] = before.iter().chain(after.iter()).chain(long.iter()).copied().collect();
|
||||
entry_lists[1] = after.iter().chain(before.iter()).chain(long.iter()).copied().collect();
|
||||
if entry_lists[1].len() > 1 && entry_lists[0].len() == entry_lists[1].len() {
|
||||
let same = entry_lists[0].iter().zip(entry_lists[1].iter()).all(|(a, b)| std::ptr::eq(*a, *b));
|
||||
if same {
|
||||
entry_lists[1].swap(0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
let entry_lists = Self::initial_entry_lists(sh, cur_poc, &short, &long, pic_num);
|
||||
let nlists = if sh.slice_type == SliceType::B { 2 } else { 1 };
|
||||
for l in 0..nlists {
|
||||
let n = sh.num_ref_idx_active[l] as usize;
|
||||
@@ -212,60 +291,7 @@ impl Dpb {
|
||||
list.truncate(n);
|
||||
list.resize(n, None);
|
||||
if !sh.ref_pic_list_mod[l].is_empty() {
|
||||
let max_pic_num = max_frame_num as i32;
|
||||
let curr_pic_num = cur_fn as i32;
|
||||
let mut pred = curr_pic_num;
|
||||
let mut ref_idx = 0usize;
|
||||
for m in &sh.ref_pic_list_mod[l] {
|
||||
ensure!(ref_idx < n, "too many ref_pic_list_modification entries");
|
||||
list.push(None); // temporarily one longer
|
||||
let (target, is_long): (Option<&DpbEntry>, bool) = match m.idc {
|
||||
0 | 1 => {
|
||||
let d = m.value as i32 + 1;
|
||||
let no_wrap = if m.idc == 0 {
|
||||
if pred - d < 0 { pred - d + max_pic_num } else { pred - d }
|
||||
} else if pred + d >= max_pic_num {
|
||||
pred + d - max_pic_num
|
||||
} else {
|
||||
pred + d
|
||||
};
|
||||
pred = no_wrap;
|
||||
let pn = if no_wrap > curr_pic_num { no_wrap - max_pic_num } else { no_wrap };
|
||||
(short.iter().copied().find(|e| pic_num(e) == pn), false)
|
||||
}
|
||||
2 => (long.iter().copied().find(|e| e.long_term_frame_idx == m.value), true),
|
||||
_ => continue,
|
||||
};
|
||||
let Some(target) = target else {
|
||||
// Missing picture: keep the list unchanged (error concealment).
|
||||
list.pop();
|
||||
ref_idx += 1;
|
||||
continue;
|
||||
};
|
||||
for c in (ref_idx + 1..=n).rev() {
|
||||
list[c] = list[c - 1];
|
||||
}
|
||||
list[ref_idx] = Some(target);
|
||||
ref_idx += 1;
|
||||
let mut nidx = ref_idx;
|
||||
for c in ref_idx..=n {
|
||||
let keep = match list[c] {
|
||||
None => true,
|
||||
Some(e) => {
|
||||
if is_long {
|
||||
!(e.mark == RefMark::Long && e.long_term_frame_idx == target.long_term_frame_idx)
|
||||
} else {
|
||||
!(e.mark == RefMark::Short && std::ptr::eq(e, target))
|
||||
}
|
||||
}
|
||||
};
|
||||
if keep {
|
||||
list[nidx] = list[c];
|
||||
nidx += 1;
|
||||
}
|
||||
}
|
||||
list.truncate(n);
|
||||
}
|
||||
Self::modify_ref_list(&mut list, &sh.ref_pic_list_mod[l], n, cur_fn, max_frame_num, &short, &long)?;
|
||||
}
|
||||
// Fill missing entries (should not happen in conforming streams) with the first valid entry.
|
||||
let fallback = list.iter().flatten().next().copied().or_else(|| self.entries.last());
|
||||
@@ -275,91 +301,88 @@ impl Dpb {
|
||||
Ok(lists)
|
||||
}
|
||||
|
||||
/// Adaptive memory control (8.2.5.4). Returns true if MMCO 5 was executed.
|
||||
fn apply_mmcos(&mut self, mmcos: &[Mmco], cur_frame_num: u32, max_frame_num: u32, cur_long: &mut Option<u32>) -> bool {
|
||||
/// One memory management control operation; returns true for MMCO 5.
|
||||
fn apply_mmco(&mut self, m: &Mmco, cur_frame_num: u32, max_frame_num: u32, cur_long: &mut Option<u32>) -> bool {
|
||||
let mut had5 = false;
|
||||
let curr_pic_num = cur_frame_num as i32;
|
||||
for m in mmcos {
|
||||
match m.op {
|
||||
1 => {
|
||||
let pn = curr_pic_num - (m.difference_of_pic_nums_minus1 as i32 + 1);
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Short && Self::frame_num_wrap(e, cur_frame_num, max_frame_num) == pn {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
match m.op {
|
||||
1 => {
|
||||
let pn = curr_pic_num - (m.difference_of_pic_nums_minus1 as i32 + 1);
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Short && Self::frame_num_wrap(e, cur_frame_num, max_frame_num) == pn {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && e.long_term_frame_idx == m.long_term_pic_num {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && e.long_term_frame_idx == m.long_term_pic_num {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
3 => {
|
||||
let pn = curr_pic_num - (m.difference_of_pic_nums_minus1 as i32 + 1);
|
||||
}
|
||||
3 => {
|
||||
let pn = curr_pic_num - (m.difference_of_pic_nums_minus1 as i32 + 1);
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && e.long_term_frame_idx == m.long_term_frame_idx {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Short && Self::frame_num_wrap(e, cur_frame_num, max_frame_num) == pn {
|
||||
e.mark = RefMark::Long;
|
||||
e.long_term_frame_idx = m.long_term_frame_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
4 => {
|
||||
let max = m.max_long_term_frame_idx_plus1;
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && (max == 0 || e.long_term_frame_idx > max - 1) {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
self.max_long_term_frame_idx = if max == 0 { None } else { Some(max - 1) };
|
||||
}
|
||||
5 => {
|
||||
for e in &mut self.entries {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
self.max_long_term_frame_idx = None;
|
||||
had5 = true;
|
||||
}
|
||||
6 => {
|
||||
// Only an index within the allowed range may be assigned (8.2.5.4.6).
|
||||
let allowed = match self.max_long_term_frame_idx {
|
||||
Some(max) => m.long_term_frame_idx <= max,
|
||||
None => false,
|
||||
};
|
||||
if allowed {
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && e.long_term_frame_idx == m.long_term_frame_idx {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Short && Self::frame_num_wrap(e, cur_frame_num, max_frame_num) == pn {
|
||||
e.mark = RefMark::Long;
|
||||
e.long_term_frame_idx = m.long_term_frame_idx;
|
||||
}
|
||||
}
|
||||
*cur_long = Some(m.long_term_frame_idx);
|
||||
}
|
||||
4 => {
|
||||
let max = m.max_long_term_frame_idx_plus1;
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && (max == 0 || e.long_term_frame_idx > max - 1) {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
self.max_long_term_frame_idx = if max == 0 { None } else { Some(max - 1) };
|
||||
}
|
||||
5 => {
|
||||
for e in &mut self.entries {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
self.max_long_term_frame_idx = None;
|
||||
had5 = true;
|
||||
}
|
||||
6 => {
|
||||
let allowed = match self.max_long_term_frame_idx {
|
||||
Some(max) => m.long_term_frame_idx <= max,
|
||||
None => false,
|
||||
};
|
||||
if allowed {
|
||||
for e in &mut self.entries {
|
||||
if e.mark == RefMark::Long && e.long_term_frame_idx == m.long_term_frame_idx {
|
||||
e.mark = RefMark::Unused;
|
||||
}
|
||||
}
|
||||
*cur_long = Some(m.long_term_frame_idx);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
had5
|
||||
}
|
||||
|
||||
/// Adaptive memory control (8.2.5.4). Returns true if MMCO 5 was executed.
|
||||
fn apply_mmcos(&mut self, mmcos: &[Mmco], cur_frame_num: u32, max_frame_num: u32, cur_long: &mut Option<u32>) -> bool {
|
||||
let mut had5 = false;
|
||||
for m in mmcos {
|
||||
had5 |= self.apply_mmco(m, cur_frame_num, max_frame_num, cur_long);
|
||||
}
|
||||
self.prune();
|
||||
had5
|
||||
}
|
||||
|
||||
/// Reference marking for the just-decoded picture and insertion into the DPB with output bumping.
|
||||
/// Returns pictures ready for output.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn store_picture(
|
||||
&mut self,
|
||||
sh: &SliceHeader,
|
||||
frame: FrameRef,
|
||||
poc: i32,
|
||||
max_frame_num: u32,
|
||||
max_num_ref_frames: usize,
|
||||
meta: Arc<OutputMeta>,
|
||||
out: &mut Vec<Output>,
|
||||
) {
|
||||
/// Reference marking of the current picture (8.2.5); returns (mark, long-term idx, MMCO 5 executed).
|
||||
fn mark_current(&mut self, sh: &SliceHeader, max_frame_num: u32, max_num_ref_frames: usize) -> (RefMark, u32, bool) {
|
||||
let mut mark = RefMark::Unused;
|
||||
let mut long_idx = 0;
|
||||
let mut had5 = false;
|
||||
@@ -391,12 +414,12 @@ impl Dpb {
|
||||
}
|
||||
}
|
||||
}
|
||||
if had5 {
|
||||
// All earlier pictures are output before the current one (C.4.4).
|
||||
self.flush(out);
|
||||
}
|
||||
let frame_num = if had5 { 0 } else { sh.frame_num };
|
||||
// Bumping until there is space (C.4.5.1 / C.4.5.2).
|
||||
(mark, long_idx, had5)
|
||||
}
|
||||
|
||||
/// Bumping until there is space (C.4.5.1 / C.4.5.2). Returns true when the (non-reference) current
|
||||
/// picture has the smallest POC and is to be output directly instead of being stored.
|
||||
fn bump_for_space(&mut self, mark: RefMark, poc: i32, out: &mut Vec<Output>) -> bool {
|
||||
if mark == RefMark::Unused {
|
||||
loop {
|
||||
let waiting = self.entries.len();
|
||||
@@ -406,8 +429,7 @@ impl Dpb {
|
||||
// non-reference picture with the smallest POC is output directly
|
||||
let min_poc = self.entries.iter().filter(|e| e.needed_for_output).map(|e| e.poc).min();
|
||||
if min_poc.is_none_or(|m| poc < m) {
|
||||
out.push(Output { frame, poc, meta });
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if !self.bump(out) {
|
||||
break;
|
||||
@@ -425,6 +447,32 @@ impl Dpb {
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Reference marking for the just-decoded picture and insertion into the DPB with output bumping.
|
||||
/// Returns pictures ready for output.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn store_picture(
|
||||
&mut self,
|
||||
sh: &SliceHeader,
|
||||
frame: FrameRef,
|
||||
poc: i32,
|
||||
max_frame_num: u32,
|
||||
max_num_ref_frames: usize,
|
||||
meta: Arc<OutputMeta>,
|
||||
out: &mut Vec<Output>,
|
||||
) {
|
||||
let (mark, long_idx, had5) = self.mark_current(sh, max_frame_num, max_num_ref_frames);
|
||||
if had5 {
|
||||
// All earlier pictures are output before the current one (C.4.4).
|
||||
self.flush(out);
|
||||
}
|
||||
let frame_num = if had5 { 0 } else { sh.frame_num };
|
||||
if self.bump_for_space(mark, poc, out) {
|
||||
out.push(Output { frame, poc, meta });
|
||||
return;
|
||||
}
|
||||
self.entries.push(DpbEntry {
|
||||
frame,
|
||||
poc,
|
||||
|
||||
Reference in New Issue
Block a user