From 0326f7b306cd4cd4fb121a2dd42fa9dc94d39d6e Mon Sep 17 00:00:00 2001
From: Kyle Siefring <kylesiefring@gmail.com>
Date: Thu, 13 Sep 2018 18:29:12 -0400
Subject: [PATCH] Partition blocks using iterators and closures

---
 src/encoder.rs | 53 +++++++++++++++++++++++++++++++++++---------------
 src/rdo.rs     | 39 ++++++++++++++-----------------------
 2 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/src/encoder.rs b/src/encoder.rs
index 69ddf1b2..6d988ec7 100644
--- a/src/encoder.rs
+++ b/src/encoder.rs
@@ -1723,14 +1723,24 @@ fn encode_partition_bottomup(seq: &Sequence, fi: &FrameInvariants, fs: &mut Fram
             rd_cost = (w.tell_frac() - tell) as f64 * get_lambda(fi, seq.bit_depth)/ ((1 << OD_BITRES) as f64);
         }
 
-        rd_cost += encode_partition_bottomup(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                             bo);
-        rd_cost += encode_partition_bottomup(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                             &BlockOffset { x: bo.x + hbs as usize, y: bo.y });
-        rd_cost += encode_partition_bottomup(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                             &BlockOffset { x: bo.x, y: bo.y + hbs as usize });
-        rd_cost += encode_partition_bottomup(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                             &BlockOffset { x: bo.x + hbs as usize, y: bo.y + hbs as usize });
+        let partitions = [
+            bo,
+            &BlockOffset{ x: bo.x + hbs as usize, y: bo.y },
+            &BlockOffset{ x: bo.x, y: bo.y + hbs as usize },
+            &BlockOffset{ x: bo.x + hbs as usize, y: bo.y + hbs as usize }
+        ];
+        rd_cost += partitions.iter().map(|&offset| {
+                encode_partition_bottomup(
+                    seq,
+                    fi,
+                    fs,
+                    cw,
+                    w_pre_cdef,
+                    w_post_cdef,
+                    subsize,
+                    offset
+                )
+            }).sum::<f64>();
 
         // Recode the full block if it is more efficient
         if !must_split && nosplit_rd_cost < rd_cost {
@@ -1893,14 +1903,25 @@ fn encode_partition_topdown(seq: &Sequence, fi: &FrameInvariants, fs: &mut Frame
                 }
             }
             else {
-                encode_partition_topdown(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                         bo, &None);
-                encode_partition_topdown(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                         &BlockOffset{x: bo.x + hbs as usize, y: bo.y}, &None);
-                encode_partition_topdown(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                         &BlockOffset{x: bo.x, y: bo.y + hbs as usize}, &None);
-                encode_partition_topdown(seq, fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                         &BlockOffset{x: bo.x + hbs as usize, y: bo.y + hbs as usize}, &None);
+                let partitions = [
+                    bo,
+                    &BlockOffset{ x: bo.x + hbs as usize, y: bo.y },
+                    &BlockOffset{ x: bo.x, y: bo.y + hbs as usize },
+                    &BlockOffset{ x: bo.x + hbs as usize, y: bo.y + hbs as usize }
+                ];
+                partitions.iter().for_each(|&offset| {
+                        encode_partition_topdown(
+                            seq,
+                            fi,
+                            fs,
+                            cw,
+                            w_pre_cdef,
+                            w_post_cdef,
+                            subsize,
+                            offset,
+                            &None
+                        );
+                    });
             }
         },
         _ => { assert!(false); },
diff --git a/src/rdo.rs b/src/rdo.rs
index 5198abf5..bc37bd71 100755
--- a/src/rdo.rs
+++ b/src/rdo.rs
@@ -606,30 +606,21 @@ pub fn rdo_partition_decision(
         assert!(best_pred_modes.len() <= 4);
         let bs = bsize.width_mi();
         let hbs = bs >> 1; // Half the block size in blocks
-        let offset = BlockOffset { x: bo.x, y: bo.y };
-        let mode_decision =
-          rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
-            .clone();
-        child_modes.push(mode_decision);
-
-        let offset = BlockOffset { x: bo.x + hbs as usize, y: bo.y };
-        let mode_decision =
-          rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
-            .clone();
-        child_modes.push(mode_decision);
-
-        let offset = BlockOffset { x: bo.x, y: bo.y + hbs as usize };
-        let mode_decision =
-          rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
-            .clone();
-        child_modes.push(mode_decision);
-
-        let offset =
-          BlockOffset { x: bo.x + hbs as usize, y: bo.y + hbs as usize };
-        let mode_decision =
-          rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
-            .clone();
-        child_modes.push(mode_decision);
+        let partitions = [
+          bo,
+          &BlockOffset{ x: bo.x + hbs as usize, y: bo.y },
+          &BlockOffset{ x: bo.x, y: bo.y + hbs as usize },
+          &BlockOffset{ x: bo.x + hbs as usize, y: bo.y + hbs as usize }
+        ];
+        child_modes.extend(
+          partitions
+            .iter()
+            .map(|&offset| {
+              rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv)
+                .part_modes[0]
+                .clone()
+            }).collect::<Vec<_>>()
+        );
       }
       _ => {
         assert!(false);
-- 
GitLab