@@ -117,14 +117,22 @@ const COEFF_PROB_NODES: TokenProbTreeNodes = {
117117#[ derive( Default , Clone , Copy ) ]
118118struct MacroBlock {
119119 bpred : [ IntraMode ; 16 ] ,
120- complexity : [ u8 ; 9 ] ,
121120 luma_mode : LumaMode ,
122121 chroma_mode : ChromaMode ,
123122 segmentid : u8 ,
124123 coeffs_skipped : bool ,
125124 non_zero_dct : bool ,
126125}
127126
127+ /// Info required from a previously decoded macro block in future
128+ /// For the top macroblocks this will be the bottom values, for the left macroblock the right values
129+ #[ derive( Default , Clone , Copy ) ]
130+ struct PreviousMacroBlock {
131+ bpred : [ IntraMode ; 4 ] ,
132+ // complexity is laid out like: y2,y,y,y,y,u,u,v,v
133+ complexity : [ u8 ; 9 ] ,
134+ }
135+
128136/// A Representation of the last decoded video frame
129137#[ derive( Default , Debug , Clone ) ]
130138pub struct Frame {
@@ -269,8 +277,8 @@ pub struct Vp8Decoder<R> {
269277 // Section 9.11
270278 prob_skip_false : Option < Prob > ,
271279
272- top : Vec < MacroBlock > ,
273- left : MacroBlock ,
280+ top : Vec < PreviousMacroBlock > ,
281+ left : PreviousMacroBlock ,
274282
275283 // The borders from the previous macroblock, used for predictions
276284 // See Section 12
@@ -291,7 +299,6 @@ impl<R: Read> Vp8Decoder<R> {
291299 fn new ( r : R ) -> Self {
292300 let f = Frame :: default ( ) ;
293301 let s = Segment :: default ( ) ;
294- let m = MacroBlock :: default ( ) ;
295302
296303 Self {
297304 r,
@@ -330,7 +337,7 @@ impl<R: Read> Vp8Decoder<R> {
330337 prob_skip_false : None ,
331338
332339 top : Vec :: new ( ) ,
333- left : m ,
340+ left : PreviousMacroBlock :: default ( ) ,
334341
335342 top_border_y : Vec :: new ( ) ,
336343 left_border_y : Vec :: new ( ) ,
@@ -529,13 +536,13 @@ impl<R: Read> Vp8Decoder<R> {
529536 self . frame . width = w & 0x3FFF ;
530537 self . frame . height = h & 0x3FFF ;
531538
532- self . top = init_top_macroblocks ( self . frame . width as usize ) ;
533- // Almost always the first macro block, except when non exists (i.e. `width == 0`)
534- self . left = self . top . first ( ) . copied ( ) . unwrap_or_default ( ) ;
535-
536539 self . mbwidth = self . frame . width . div_ceil ( 16 ) ;
537540 self . mbheight = self . frame . height . div_ceil ( 16 ) ;
538541
542+ // defaults are intra mode DC and complexity 0
543+ self . top = vec ! [ PreviousMacroBlock :: default ( ) ; self . mbwidth. into( ) ] ;
544+ self . left = PreviousMacroBlock :: default ( ) ;
545+
539546 self . frame . ybuf =
540547 vec ! [ 0u8 ; usize :: from( self . mbwidth) * 16 * usize :: from( self . mbheight) * 16 ] ;
541548 self . frame . ubuf = vec ! [ 0u8 ; usize :: from( self . mbwidth) * 8 * usize :: from( self . mbheight) * 8 ] ;
@@ -630,7 +637,7 @@ impl<R: Read> Vp8Decoder<R> {
630637 None => {
631638 for y in 0usize ..4 {
632639 for x in 0usize ..4 {
633- let top = self . top [ mbx] . bpred [ 12 + x] ;
640+ let top = self . top [ mbx] . bpred [ x] ;
634641 let left = self . left . bpred [ y] ;
635642 let intra = self . b . read_with_tree (
636643 & KEYFRAME_BPRED_MODE_NODES [ top as usize ] [ left as usize ] ,
@@ -640,7 +647,7 @@ impl<R: Read> Vp8Decoder<R> {
640647 . ok_or ( DecodingError :: IntraPredictionModeInvalid ( intra) ) ?;
641648 mb. bpred [ x + y * 4 ] = bmode;
642649
643- self . top [ mbx] . bpred [ 12 + x] = bmode;
650+ self . top [ mbx] . bpred [ x] = bmode;
644651 self . left . bpred [ y] = bmode;
645652 }
646653 }
@@ -657,9 +664,8 @@ impl<R: Read> Vp8Decoder<R> {
657664 mb. chroma_mode = ChromaMode :: from_i8 ( chroma)
658665 . ok_or ( DecodingError :: ChromaPredictionModeInvalid ( chroma) ) ?;
659666
660- self . top [ mbx] . chroma_mode = mb. chroma_mode ;
661- self . top [ mbx] . luma_mode = mb. luma_mode ;
662- self . top [ mbx] . bpred = mb. bpred ;
667+ // top should store the bottom of the current bpred, which is the final 4 values
668+ self . top [ mbx] . bpred = mb. bpred [ 12 ..] . try_into ( ) . unwrap ( ) ;
663669
664670 self . b . check ( res, mb)
665671 }
@@ -1248,7 +1254,7 @@ impl<R: Read> Vp8Decoder<R> {
12481254
12491255 for mby in 0 ..self . mbheight as usize {
12501256 let p = mby % self . num_partitions as usize ;
1251- self . left = MacroBlock :: default ( ) ;
1257+ self . left = PreviousMacroBlock :: default ( ) ;
12521258
12531259 for mbx in 0 ..self . mbwidth as usize {
12541260 let mut mb = self . read_macroblock_header ( mbx) ?;
@@ -1291,19 +1297,6 @@ impl<R: Read> Vp8Decoder<R> {
12911297 }
12921298}
12931299
1294- fn init_top_macroblocks ( width : usize ) -> Vec < MacroBlock > {
1295- let mb_width = width. div_ceil ( 16 ) ;
1296-
1297- let mb = MacroBlock {
1298- // Section 11.3 #3
1299- bpred : [ IntraMode :: DC ; 16 ] ,
1300- luma_mode : LumaMode :: DC ,
1301- ..MacroBlock :: default ( )
1302- } ;
1303-
1304- vec ! [ mb; mb_width]
1305- }
1306-
13071300// set border
13081301fn set_chroma_border (
13091302 left_border : & mut [ u8 ] ,
0 commit comments