1
1
use std:: num:: NonZeroUsize ;
2
2
use std:: { cmp, slice} ;
3
3
4
+ use cfg_if:: cfg_if;
4
5
use strum:: EnumCount ;
5
6
6
7
use crate :: cpu:: CpuFlags ;
@@ -32,7 +33,9 @@ use crate::levels::{
32
33
FLIPADST_ADST , FLIPADST_DCT , FLIPADST_FLIPADST , H_ADST , H_DCT , H_FLIPADST , IDTX ,
33
34
N_TX_TYPES_PLUS_LL , V_ADST , V_DCT , V_FLIPADST , WHT_WHT ,
34
35
} ;
36
+ use crate :: scan:: DAV1D_LAST_NONZERO_COL_FROM_EOB ;
35
37
use crate :: strided:: Strided as _;
38
+ use crate :: tables:: DAV1D_TXFM_DIMENSIONS ;
36
39
use crate :: wrap_fn_ptr:: wrap_fn_ptr;
37
40
38
41
pub type Itx1dFn = fn ( c : & mut [ i32 ] , stride : NonZeroUsize , min : i32 , max : i32 ) ;
@@ -42,16 +45,18 @@ fn inv_txfm_add<BD: BitDepth>(
42
45
dst : Rav1dPictureDataComponentOffset ,
43
46
coeff : & mut [ BD :: Coef ] ,
44
47
eob : i32 ,
45
- w : usize ,
46
- h : usize ,
48
+ tx : TxfmSize ,
47
49
shift : u8 ,
48
- first_1d_fn : Itx1dFn ,
49
- second_1d_fn : Itx1dFn ,
50
- has_dc_only : bool ,
50
+ txtp : TxfmType ,
51
51
bd : BD ,
52
52
) {
53
53
let bitdepth_max = bd. bitdepth_max ( ) . as_ :: < i32 > ( ) ;
54
54
55
+ let t_dim = & DAV1D_TXFM_DIMENSIONS [ tx as usize ] ;
56
+ let w = 4 * t_dim. w as usize ;
57
+ let h = 4 * t_dim. h as usize ;
58
+ let has_dc_only = txtp == DCT_DCT ;
59
+
55
60
assert ! ( w >= 4 && w <= 64 ) ;
56
61
assert ! ( h >= 4 && h <= 64 ) ;
57
62
assert ! ( eob >= 0 ) ;
@@ -78,6 +83,69 @@ fn inv_txfm_add<BD: BitDepth>(
78
83
return ;
79
84
}
80
85
86
+ #[ derive( PartialEq , Clone , Copy ) ]
87
+ enum Type {
88
+ Identity ,
89
+ Dct ,
90
+ Adst ,
91
+ FlipAdst ,
92
+ }
93
+ use Type :: * ;
94
+ // For some reason, this is flipped.
95
+ let ( second, first) = match txtp {
96
+ IDTX => ( Identity , Identity ) ,
97
+ DCT_DCT => ( Dct , Dct ) ,
98
+ ADST_DCT => ( Adst , Dct ) ,
99
+ FLIPADST_DCT => ( FlipAdst , Dct ) ,
100
+ H_DCT => ( Identity , Dct ) ,
101
+ DCT_ADST => ( Dct , Adst ) ,
102
+ ADST_ADST => ( Adst , Adst ) ,
103
+ FLIPADST_ADST => ( FlipAdst , Adst ) ,
104
+ DCT_FLIPADST => ( Dct , FlipAdst ) ,
105
+ ADST_FLIPADST => ( Adst , FlipAdst ) ,
106
+ FLIPADST_FLIPADST => ( FlipAdst , FlipAdst ) ,
107
+ V_DCT => ( Dct , Identity ) ,
108
+ H_ADST => ( Identity , Adst ) ,
109
+ H_FLIPADST => ( Identity , FlipAdst ) ,
110
+ V_ADST => ( Adst , Identity ) ,
111
+ V_FLIPADST => ( FlipAdst , Identity ) ,
112
+
113
+ WHT_WHT if ( w, h) == ( 4 , 4 ) => {
114
+ cfg_if ! {
115
+ if #[ cfg( not( all( feature = "asm" , target_feature = "neon" ) ) ) ] {
116
+ return inv_txfm_add_wht_wht_4x4_rust( dst, coeff, bd)
117
+ } else {
118
+ unreachable!( )
119
+ }
120
+ }
121
+ }
122
+ _ => unreachable ! ( ) ,
123
+ } ;
124
+
125
+ fn resolve_1d_fn ( r#type : Type , n : usize ) -> Itx1dFn {
126
+ match ( r#type, n) {
127
+ ( Identity , 4 ) => rav1d_inv_identity4_1d_c,
128
+ ( Identity , 8 ) => rav1d_inv_identity8_1d_c,
129
+ ( Identity , 16 ) => rav1d_inv_identity16_1d_c,
130
+ ( Identity , 32 ) => rav1d_inv_identity32_1d_c,
131
+ ( Dct , 4 ) => rav1d_inv_dct4_1d_c,
132
+ ( Dct , 8 ) => rav1d_inv_dct8_1d_c,
133
+ ( Dct , 16 ) => rav1d_inv_dct16_1d_c,
134
+ ( Dct , 32 ) => rav1d_inv_dct32_1d_c,
135
+ ( Dct , 64 ) => rav1d_inv_dct64_1d_c,
136
+ ( Adst , 4 ) => rav1d_inv_adst4_1d_c,
137
+ ( Adst , 8 ) => rav1d_inv_adst8_1d_c,
138
+ ( Adst , 16 ) => rav1d_inv_adst16_1d_c,
139
+ ( FlipAdst , 4 ) => rav1d_inv_flipadst4_1d_c,
140
+ ( FlipAdst , 8 ) => rav1d_inv_flipadst8_1d_c,
141
+ ( FlipAdst , 16 ) => rav1d_inv_flipadst16_1d_c,
142
+ _ => unreachable ! ( ) ,
143
+ }
144
+ }
145
+
146
+ let first_1d_fn = resolve_1d_fn ( first, w) ;
147
+ let second_1d_fn = resolve_1d_fn ( second, h) ;
148
+
81
149
let sh = cmp:: min ( h, 32 ) ;
82
150
let sw = cmp:: min ( w, 32 ) ;
83
151
@@ -96,8 +164,18 @@ fn inv_txfm_add<BD: BitDepth>(
96
164
let col_clip_max = !col_clip_min;
97
165
98
166
let mut tmp = [ 0 ; 64 * 64 ] ;
99
- let mut c = & mut tmp[ ..] ;
100
- for y in 0 ..sh {
167
+ let mut c = & mut tmp[ ..sh * w] ;
168
+ let eob = eob as usize ;
169
+ // in first 1d itx
170
+ let last_nonzero_col = if second == Identity && first != Identity {
171
+ std:: cmp:: min ( sh - 1 , eob)
172
+ } else if first == Identity && second != Identity {
173
+ eob >> ( t_dim. lw + 2 )
174
+ } else {
175
+ DAV1D_LAST_NONZERO_COL_FROM_EOB [ tx as usize ] [ eob as usize ] as usize
176
+ } ;
177
+ assert ! ( last_nonzero_col < sh) ;
178
+ for y in 0 ..=last_nonzero_col {
101
179
if is_rect2 {
102
180
for x in 0 ..sw {
103
181
c[ x] = coeff[ y + x * sh] . as_ :: < i32 > ( ) * 181 + 128 >> 8 ;
@@ -110,6 +188,8 @@ fn inv_txfm_add<BD: BitDepth>(
110
188
first_1d_fn ( c, 1 . try_into ( ) . unwrap ( ) , row_clip_min, row_clip_max) ;
111
189
c = & mut c[ w..] ;
112
190
}
191
+ // fill remaining values in slice `c` with 0
192
+ c. fill ( 0 ) ;
113
193
114
194
coeff. fill ( 0 . into ( ) ) ;
115
195
for i in 0 ..w * sh {
@@ -162,82 +242,9 @@ fn inv_txfm_add_rust<const W: usize, const H: usize, const TYPE: TxfmType, BD: B
162
242
( 64 , 64 ) => 2 ,
163
243
_ => unreachable ! ( ) ,
164
244
} ;
165
- let has_dc_only = TYPE == DCT_DCT ;
166
-
167
- enum Type {
168
- Identity ,
169
- Dct ,
170
- Adst ,
171
- FlipAdst ,
172
- }
173
- use Type :: * ;
174
- // For some reason, this is flipped.
175
- let ( second, first) = match TYPE {
176
- IDTX => ( Identity , Identity ) ,
177
- DCT_DCT => ( Dct , Dct ) ,
178
- ADST_DCT => ( Adst , Dct ) ,
179
- FLIPADST_DCT => ( FlipAdst , Dct ) ,
180
- H_DCT => ( Identity , Dct ) ,
181
- DCT_ADST => ( Dct , Adst ) ,
182
- ADST_ADST => ( Adst , Adst ) ,
183
- FLIPADST_ADST => ( FlipAdst , Adst ) ,
184
- DCT_FLIPADST => ( Dct , FlipAdst ) ,
185
- ADST_FLIPADST => ( Adst , FlipAdst ) ,
186
- FLIPADST_FLIPADST => ( FlipAdst , FlipAdst ) ,
187
- V_DCT => ( Dct , Identity ) ,
188
- H_ADST => ( Identity , Adst ) ,
189
- H_FLIPADST => ( Identity , FlipAdst ) ,
190
- V_ADST => ( Adst , Identity ) ,
191
- V_FLIPADST => ( FlipAdst , Identity ) ,
192
-
193
- WHT_WHT if ( W , H ) == ( 4 , 4 ) => {
194
- cfg_if ! {
195
- if #[ cfg( not( all( feature = "asm" , target_feature = "neon" ) ) ) ] {
196
- return inv_txfm_add_wht_wht_4x4_rust( dst, coeff, bd)
197
- } else {
198
- unreachable!( )
199
- }
200
- }
201
- }
202
- _ => unreachable ! ( ) ,
203
- } ;
204
-
205
- fn resolve_1d_fn ( r#type : Type , n : usize ) -> Itx1dFn {
206
- match ( r#type, n) {
207
- ( Identity , 4 ) => rav1d_inv_identity4_1d_c,
208
- ( Identity , 8 ) => rav1d_inv_identity8_1d_c,
209
- ( Identity , 16 ) => rav1d_inv_identity16_1d_c,
210
- ( Identity , 32 ) => rav1d_inv_identity32_1d_c,
211
- ( Dct , 4 ) => rav1d_inv_dct4_1d_c,
212
- ( Dct , 8 ) => rav1d_inv_dct8_1d_c,
213
- ( Dct , 16 ) => rav1d_inv_dct16_1d_c,
214
- ( Dct , 32 ) => rav1d_inv_dct32_1d_c,
215
- ( Dct , 64 ) => rav1d_inv_dct64_1d_c,
216
- ( Adst , 4 ) => rav1d_inv_adst4_1d_c,
217
- ( Adst , 8 ) => rav1d_inv_adst8_1d_c,
218
- ( Adst , 16 ) => rav1d_inv_adst16_1d_c,
219
- ( FlipAdst , 4 ) => rav1d_inv_flipadst4_1d_c,
220
- ( FlipAdst , 8 ) => rav1d_inv_flipadst8_1d_c,
221
- ( FlipAdst , 16 ) => rav1d_inv_flipadst16_1d_c,
222
- _ => unreachable ! ( ) ,
223
- }
224
- }
225
245
226
- let first_1d_fn = resolve_1d_fn ( first, W ) ;
227
- let second_1d_fn = resolve_1d_fn ( second, H ) ;
228
-
229
- inv_txfm_add (
230
- dst,
231
- coeff,
232
- eob,
233
- W ,
234
- H ,
235
- shift,
236
- first_1d_fn,
237
- second_1d_fn,
238
- has_dc_only,
239
- bd,
240
- )
246
+ let tx = TxfmSize :: from_wh ( W , H ) ;
247
+ inv_txfm_add ( dst, coeff, eob, tx, shift, TYPE , bd)
241
248
}
242
249
243
250
/// # Safety
0 commit comments