• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use crate::codec::av1::parser::NUM_REF_FRAMES;
6 
7 const DIV_LUT: [i32; 257] = [
8     16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768, 15709, 15650,
9     15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142, 15087, 15033, 14980, 14926,
10     14873, 14821, 14769, 14717, 14665, 14614, 14564, 14513, 14463, 14413, 14364, 14315, 14266,
11     14218, 14170, 14122, 14075, 14028, 13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662,
12     13618, 13574, 13530, 13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107,
13     13066, 13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633, 12596,
14     12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228, 12193, 12157, 12122,
15     12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848, 11815, 11782, 11749, 11716, 11683,
16     11651, 11619, 11586, 11555, 11523, 11491, 11460, 11429, 11398, 11367, 11336, 11305, 11275,
17     11245, 11215, 11185, 11155, 11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894,
18     10866, 10838, 10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538,
19     10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255, 10230, 10205,
20     10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986, 9963, 9939, 9916, 9892, 9869,
21     9846, 9823, 9800, 9777, 9754, 9732, 9709, 9687, 9664, 9642, 9620, 9598, 9576, 9554, 9533, 9511,
22     9489, 9468, 9447, 9425, 9404, 9383, 9362, 9341, 9321, 9300, 9279, 9259, 9239, 9218, 9198, 9178,
23     9158, 9138, 9118, 9098, 9079, 9059, 9039, 9020, 9001, 8981, 8962, 8943, 8924, 8905, 8886, 8867,
24     8849, 8830, 8812, 8793, 8775, 8756, 8738, 8720, 8702, 8684, 8666, 8648, 8630, 8613, 8595, 8577,
25     8560, 8542, 8525, 8508, 8490, 8473, 8456, 8439, 8422, 8405, 8389, 8372, 8355, 8339, 8322, 8306,
26     8289, 8273, 8257, 8240, 8224, 8208, 8192,
27 ];
28 
29 const DIV_LUT_BITS: u32 = 8;
30 const DIV_LUT_PREC_BITS: u32 = 14;
31 
32 /// Implements FloorLog2(x), which is defined to be the floor of the base 2
33 /// logarithm of the input x.
34 ///
35 /// The input x will always be an integer, and will always be greater than or equal to 1.
36 /// This function extracts the location of the most significant bit in x.
floor_log2(mut x: u32) -> u3237 pub fn floor_log2(mut x: u32) -> u32 {
38     assert!(x > 0);
39     let mut s = 0;
40 
41     while x != 0 {
42         x >>= 1;
43         s += 1;
44     }
45 
46     s - 1
47 }
48 
49 /// Implements 5.9.3. Get relative distance function
get_relative_dist(enable_order_hint: bool, order_hint_bits: i32, a: i32, b: i32) -> i3250 pub fn get_relative_dist(enable_order_hint: bool, order_hint_bits: i32, a: i32, b: i32) -> i32 {
51     if !enable_order_hint {
52         0
53     } else {
54         let diff = a - b;
55         let m = 1 << (order_hint_bits - 1);
56         (diff & (m - 1)) - (diff & m)
57     }
58 }
59 
60 /// Implements find_latest_backward from section 7.8.
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, ) -> i3261 pub fn find_latest_backward(
62     shifted_order_hints: &[i32; NUM_REF_FRAMES],
63     used_frame: &[bool; NUM_REF_FRAMES],
64     cur_frame_hint: i32,
65     latest_order_hint: &mut i32,
66 ) -> i32 {
67     let mut _ref = -1;
68 
69     for i in 0..NUM_REF_FRAMES {
70         let hint = shifted_order_hints[i];
71         if !used_frame[i] && hint >= cur_frame_hint && (_ref < 0 || hint >= *latest_order_hint) {
72             _ref = i as i32;
73             *latest_order_hint = hint;
74         }
75     }
76 
77     _ref
78 }
79 
80 /// Implements find_earliest_backward from section 7.8.
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, ) -> i3281 pub fn find_earliest_backward(
82     shifted_order_hints: &[i32; NUM_REF_FRAMES],
83     used_frame: &[bool; NUM_REF_FRAMES],
84     cur_frame_hint: i32,
85     earliest_order_hint: &mut i32,
86 ) -> i32 {
87     let mut _ref = -1;
88 
89     for i in 0..NUM_REF_FRAMES {
90         let hint = shifted_order_hints[i];
91         if !used_frame[i] && hint >= cur_frame_hint && (_ref < 0 || hint < *earliest_order_hint) {
92             _ref = i as i32;
93             *earliest_order_hint = hint;
94         }
95     }
96 
97     _ref
98 }
99 
100 /// Implements find_latest_forward from section 7.8.
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, ) -> i32101 pub fn find_latest_forward(
102     shifted_order_hints: &[i32; NUM_REF_FRAMES],
103     used_frame: &[bool; NUM_REF_FRAMES],
104     cur_frame_hint: i32,
105     latest_order_hint: &mut i32,
106 ) -> i32 {
107     let mut _ref = -1;
108     for i in 0..NUM_REF_FRAMES {
109         let hint = shifted_order_hints[i];
110         if !used_frame[i] && hint < cur_frame_hint && (_ref < 0 || hint >= *latest_order_hint) {
111             _ref = i as i32;
112             *latest_order_hint = hint;
113         }
114     }
115 
116     _ref
117 }
118 
tile_log2(blk_size: u32, target: u32) -> u32119 pub fn tile_log2(blk_size: u32, target: u32) -> u32 {
120     let mut k = 0;
121 
122     while (blk_size << k) < target {
123         k += 1;
124     }
125 
126     k
127 }
128 
clip3(x: i32, y: i32, z: i32) -> i32129 pub fn clip3(x: i32, y: i32, z: i32) -> i32 {
130     if z < x {
131         x
132     } else if z > y {
133         y
134     } else {
135         z
136     }
137 }
138 
139 /// 5.9.29
inverse_recenter(r: i32, v: i32) -> i32140 pub fn inverse_recenter(r: i32, v: i32) -> i32 {
141     if v > 2 * r {
142         v
143     } else if v & 1 != 0 {
144         r - ((v + 1) >> 1)
145     } else {
146         r + (v >> 1)
147     }
148 }
149 
150 /// Implements Round2. See 4.7: mathematical functions.
round2(x: u32, n: u32) -> u32151 pub fn round2(x: u32, n: u32) -> u32 {
152     (x + 2u32.pow(n - 1)) / 2u32.pow(n)
153 }
154 
155 /// Implements Round2Signed. See 4.7: mathematical functions.
round2signed(x: i32, n: u32) -> Result<i32, String>156 pub fn round2signed(x: i32, n: u32) -> Result<i32, String> {
157     if x >= 0 {
158         i32::try_from(round2(x as u32, n)).map_err(|e| e.to_string())
159     } else {
160         let x = x as i64;
161         let val = i32::try_from(round2(-x as u32, n)).map_err(|e| e.to_string())?;
162         Ok(-val)
163     }
164 }
165 
166 /// Implements 7.11.3.7. Resolve divisor process
resolve_divisor(d: i32) -> Result<(u32, i32), String>167 pub fn resolve_divisor(d: i32) -> Result<(u32, i32), String> {
168     let abs_d = u32::try_from(d.abs()).unwrap(); // abs cannot return a negative
169     let n = floor_log2(abs_d);
170     let e = abs_d - (1 << n);
171 
172     let f = if n > DIV_LUT_BITS { round2(e, n - DIV_LUT_BITS) } else { e << (DIV_LUT_BITS - n) };
173 
174     let div_shift = n + DIV_LUT_PREC_BITS;
175     let div_factor = if d < 0 { -DIV_LUT[f as usize] } else { DIV_LUT[f as usize] };
176 
177     Ok((div_shift, div_factor))
178 }
179