Skip to content

Commit d7821cf

Browse files
Split out macroblock from previous macroblock to reduce redundant (#169)
Co-authored-by: steschu77 <steschu77@gmail.com>
1 parent 3529fd1 commit d7821cf

File tree

1 file changed

+21
-28
lines changed

1 file changed

+21
-28
lines changed

src/vp8.rs

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,22 @@ const COEFF_PROB_NODES: TokenProbTreeNodes = {
117117
#[derive(Default, Clone, Copy)]
118118
struct 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)]
130138
pub 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
13081301
fn set_chroma_border(
13091302
left_border: &mut [u8],

0 commit comments

Comments
 (0)