From 85e882932ed16fd77885bd17b19ab7192ef5e069 Mon Sep 17 00:00:00 2001
From: Thomas Daede <tdaede@xiph.org>
Date: Wed, 22 Aug 2018 15:35:52 -0700
Subject: [PATCH] Add tx_dist based rate estimate.

---
 Cargo.toml        |   1 +
 src/api.rs        |   9 +++
 src/bin/common.rs |  10 ++-
 src/ec.rs         |  15 +++-
 src/encoder.rs    |  55 ++++++++++++---
 src/lib.rs        |   2 +
 src/rdo.rs        | 119 ++++++++++++++++++++++++++++---
 src/rdo_tables.rs | 173 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/rdo.sh      |   6 ++
 9 files changed, 368 insertions(+), 22 deletions(-)
 create mode 100644 src/rdo_tables.rs
 create mode 100755 tools/rdo.sh

diff --git a/Cargo.toml b/Cargo.toml
index 6a30fa64..98fba912 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,6 +35,7 @@ aom-sys = { version = "0.1.0", optional = true }
 scan_fmt = { version = "0.1.3", optional = true }
 ivf = { path = "ivf/", optional = true }
 rayon = "1.0"
+bincode = "=1.0.1"
 
 [target.'cfg(target_arch = "x86_64")'.build-dependencies]
 nasm-rs = { version = "0.1.4", optional = true }
diff --git a/src/api.rs b/src/api.rs
index 13211457..950695f1 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -78,6 +78,7 @@ pub struct EncoderConfig {
   pub pass: Option<u8>,
   pub show_psnr: bool,
   pub stats_file: Option<PathBuf>,
+  pub train_rdo: bool,
 }
 
 impl Default for EncoderConfig {
@@ -112,6 +113,7 @@ impl EncoderConfig {
       pass: None,
       show_psnr: false,
       stats_file: None,
+      train_rdo: false
     }
   }
 }
@@ -123,6 +125,7 @@ pub struct SpeedSettings {
   pub fast_deblock: bool,
   pub reduced_tx_set: bool,
   pub tx_domain_distortion: bool,
+  pub tx_domain_rate: bool,
   pub encode_bottomup: bool,
   pub rdo_tx_decision: bool,
   pub prediction_modes: PredictionModesSetting,
@@ -139,6 +142,7 @@ impl Default for SpeedSettings {
       fast_deblock: false,
       reduced_tx_set: false,
       tx_domain_distortion: false,
+      tx_domain_rate: false,
       encode_bottomup: false,
       rdo_tx_decision: false,
       prediction_modes: PredictionModesSetting::Simple,
@@ -157,6 +161,7 @@ impl SpeedSettings {
       fast_deblock: Self::fast_deblock_preset(speed),
       reduced_tx_set: Self::reduced_tx_set_preset(speed),
       tx_domain_distortion: Self::tx_domain_distortion_preset(speed),
+      tx_domain_rate: Self::tx_domain_rate_preset(speed),
       encode_bottomup: Self::encode_bottomup_preset(speed),
       rdo_tx_decision: Self::rdo_tx_decision_preset(speed),
       prediction_modes: Self::prediction_modes_preset(speed),
@@ -199,6 +204,10 @@ impl SpeedSettings {
     true
   }
 
+  fn tx_domain_rate_preset(_speed: usize) -> bool {
+    false
+  }
+
   fn encode_bottomup_preset(speed: usize) -> bool {
     speed == 0
   }
diff --git a/src/bin/common.rs b/src/bin/common.rs
index 043e8f7a..975531ab 100644
--- a/src/bin/common.rs
+++ b/src/bin/common.rs
@@ -245,6 +245,10 @@ pub fn parse_cli() -> CliOptions {
         .long("speed-test")
         .takes_value(true)
     )
+    .arg(
+      Arg::with_name("train-rdo")
+        .long("train-rdo")
+    )
     .subcommand(SubCommand::with_name("advanced")
                 .setting(AppSettings::Hidden)
                 .about("Advanced features")
@@ -313,6 +317,7 @@ fn parse_config(matches: &ArgMatches<'_>) -> EncoderConfig {
     }
   });
   let bitrate = maybe_bitrate.unwrap_or(0);
+  let train_rdo = matches.is_present("train-rdo");
   if quantizer == 0 {
     unimplemented!("Lossless encoding not yet implemented");
   } else if quantizer > 255 {
@@ -422,7 +427,7 @@ fn parse_config(matches: &ArgMatches<'_>) -> EncoderConfig {
   };
   cfg.tune = matches.value_of("TUNE").unwrap().parse().unwrap();
   cfg.low_latency = matches.value_of("LOW_LATENCY").unwrap().parse().unwrap();
-
+  cfg.train_rdo = train_rdo;
   cfg
 }
 
@@ -455,6 +460,9 @@ fn apply_speed_test_cfg(cfg: &mut EncoderConfig, setting: &str) {
     "tx_domain_distortion" => {
       cfg.speed_settings.tx_domain_distortion = true;
     },
+    "tx_domain_rate" => {
+      cfg.speed_settings.tx_domain_rate = true;
+    },
     "encode_bottomup" => {
       cfg.speed_settings.encode_bottomup = true;
     },
diff --git a/src/ec.rs b/src/ec.rs
index 5f65ea20..0e68b838 100644
--- a/src/ec.rs
+++ b/src/ec.rs
@@ -78,6 +78,8 @@ pub trait Writer {
   fn checkpoint(&mut self) -> WriterCheckpoint;
   /// Restore saved position in coding/recording from a checkpoint
   fn rollback(&mut self, _: &WriterCheckpoint);
+  /// Add additional bits from rate estimators without coding a real symbol
+  fn add_bits_frac(&mut self, bits_frac: u32);
 }
 
 /// StorageBackend is an internal trait used to tie a specific Writer
@@ -103,6 +105,9 @@ pub struct WriterBase<S> {
   cnt: i16,
   /// Debug enable flag
   debug: bool,
+  /// Extra offset added to tell() and tell_frac() to approximate costs
+  /// of actually coding a symbol
+  fake_bits_frac: u32,
   /// Use-specific storage
   s: S
 }
@@ -298,7 +303,7 @@ impl<S> WriterBase<S> {
   /// Internal constructor called by the subtypes that implement the
   /// actual encoder and Recorder.
   fn new(storage: S) -> Self {
-    WriterBase { rng: 0x8000, cnt: -9, debug: false, s: storage }
+    WriterBase { rng: 0x8000, cnt: -9, debug: false, fake_bits_frac: 0, s: storage }
   }
 
   /// Compute low and range values from token cdf values and local state
@@ -478,6 +483,10 @@ where
   fn bit(&mut self, bit: u16) {
     self.bool(bit == 1, 16384);
   }
+  // fake add bits
+  fn add_bits_frac(&mut self, bits_frac: u32) {
+    self.fake_bits_frac += bits_frac
+  }
   /// Encode a literal bitstring, bit by bit in MSB order, with flat
   /// probability.
   /// 'bits': Length of bitstring
@@ -721,7 +730,7 @@ where
   fn tell(&mut self) -> u32 {
     // The 10 here counteracts the offset of -9 baked into cnt, and adds 1 extra
     // bit, which we reserve for terminating the stream.
-    (((self.stream_bytes() * 8) as i32) + (self.cnt as i32) + 10) as u32
+    (((self.stream_bytes() * 8) as i32) + (self.cnt as i32) + 10) as u32 + (self.fake_bits_frac >> 8)
   }
   /// Returns the number of bits "used" by the encoded symbols so far.
   /// This same number can be computed in either the encoder or the
@@ -731,7 +740,7 @@ where
   ///         This will always be slightly larger than the exact value (e.g., all
   ///          rounding error is in the positive direction).
   fn tell_frac(&mut self) -> u32 {
-    Self::frac_compute(self.tell(), self.rng as u32)
+    Self::frac_compute(self.tell(), self.rng as u32) + self.fake_bits_frac
   }
   /// Save current point in coding/recording to a checkpoint that can
   /// be restored later.  A WriterCheckpoint can be generated for an
diff --git a/src/encoder.rs b/src/encoder.rs
index 11a3fdb3..fca9e821 100644
--- a/src/encoder.rs
+++ b/src/encoder.rs
@@ -29,10 +29,13 @@ use crate::partition::PartitionType::*;
 use crate::header::*;
 
 use bitstream_io::{BitWriter, BigEndian};
+use bincode::{serialize, deserialize};
 use std;
 use std::{fmt, io, mem};
 use std::io::Write;
+use std::io::Read;
 use std::sync::Arc;
+use std::fs::File;
 
 extern {
   pub fn av1_rtcd();
@@ -396,6 +399,7 @@ pub struct FrameState<T: Pixel> {
   pub segmentation: SegmentationState,
   pub restoration: RestorationState,
   pub frame_mvs: Vec<Vec<MotionVector>>,
+  pub t: RDOTracker,
 }
 
 impl<T: Pixel> FrameState<T> {
@@ -422,7 +426,8 @@ impl<T: Pixel> FrameState<T> {
       deblock: Default::default(),
       segmentation: Default::default(),
       restoration: rs,
-      frame_mvs: vec![vec![MotionVector::default(); fi.w_in_b * fi.h_in_b]; REF_FRAMES]
+      frame_mvs: vec![vec![MotionVector::default(); fi.w_in_b * fi.h_in_b]; REF_FRAMES],
+      t: RDOTracker::new()
     }
   }
 }
@@ -538,6 +543,7 @@ pub struct FrameInvariants<T: Pixel> {
   pub me_lambda: f64,
   pub me_range_scale: u8,
   pub use_tx_domain_distortion: bool,
+  pub use_tx_domain_rate: bool,
   pub inter_cfg: Option<InterPropsConfig>,
   pub enable_early_exit: bool,
 }
@@ -562,6 +568,7 @@ impl<T: Pixel> FrameInvariants<T> {
     let min_partition_size = config.speed_settings.min_block_size;
     let use_reduced_tx_set = config.speed_settings.reduced_tx_set;
     let use_tx_domain_distortion = config.tune == Tune::Psnr && config.speed_settings.tx_domain_distortion;
+    let use_tx_domain_rate = config.speed_settings.tx_domain_rate;
 
     let w_in_b = 2 * config.width.align_power_of_two_and_shift(3); // MiCols, ((width+7)/8)<<3 >> MI_SIZE_LOG2
     let h_in_b = 2 * config.height.align_power_of_two_and_shift(3); // MiRows, ((height+7)/8)<<3 >> MI_SIZE_LOG2
@@ -617,6 +624,7 @@ impl<T: Pixel> FrameInvariants<T> {
       me_lambda: 0.0,
       me_range_scale: 1,
       use_tx_domain_distortion,
+      use_tx_domain_rate,
       inter_cfg: None,
       enable_early_exit: true,
       config,
@@ -981,9 +989,14 @@ pub fn encode_tx_block<T: Pixel>(
   let coded_tx_size = av1_get_coded_tx_size(tx_size).area();
   fs.qc.quantize(coeffs, qcoeffs, coded_tx_size);
 
-  let has_coeff = cw.write_coeffs_lv_map(w, p, bo, &qcoeffs, mode, tx_size, tx_type, plane_bsize, xdec, ydec,
-                                         fi.use_reduced_tx_set);
-
+  let tell_coeffs = w.tell_frac();
+  let has_coeff = if !for_rdo_use || rdo_type.needs_coeff_rate() {
+    cw.write_coeffs_lv_map(w, p, bo, &qcoeffs, mode, tx_size, tx_type, plane_bsize, xdec, ydec,
+                           fi.use_reduced_tx_set)
+  } else {
+    true
+  };
+  let cost_coeffs = w.tell_frac() - tell_coeffs;
   // Reconstruct
   dequantize(qidx, qcoeffs, rcoeffs, tx_size, fi.sequence.bit_depth, fi.dc_delta_q[p], fi.ac_delta_q[p]);
 
@@ -1006,6 +1019,15 @@ pub fn encode_tx_block<T: Pixel>(
     let tx_dist_scale_rounding_offset = 1 << (tx_dist_scale_bits - 1);
     tx_dist = (tx_dist + tx_dist_scale_rounding_offset) >> tx_dist_scale_bits;
   }
+  if fi.config.train_rdo {
+    fs.t.add_rate(fi.base_q_idx, tx_size, tx_dist as u64, cost_coeffs as u64);
+  }
+
+  if rdo_type == RDOType::TxDistEstRate {
+    // look up rate and distortion in table
+    let estimated_rate = estimate_rate(fi.base_q_idx, tx_size, tx_dist as u64);
+    w.add_bits_frac(estimated_rate as u32);
+  }
   (has_coeff, tx_dist)
 }
 
@@ -1446,7 +1468,8 @@ pub fn write_tx_tree<T: Pixel>(
 pub fn encode_block_with_modes<T: Pixel>(
   fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
   cw: &mut ContextWriter, w_pre_cdef: &mut dyn Writer, w_post_cdef: &mut dyn Writer,
-  bsize: BlockSize, bo: &BlockOffset, mode_decision: &RDOPartitionOutput
+  bsize: BlockSize, bo: &BlockOffset, mode_decision: &RDOPartitionOutput,
+  rdo_type: RDOType
 ) {
   let (mode_luma, mode_chroma) =
     (mode_decision.pred_mode_luma, mode_decision.pred_mode_chroma);
@@ -1469,7 +1492,7 @@ pub fn encode_block_with_modes<T: Pixel>(
                               bsize, bo, skip);
   encode_block_b(fi, fs, cw, if cdef_coded  {w_post_cdef} else {w_pre_cdef},
                  mode_luma, mode_chroma, ref_frames, mvs, bsize, bo, skip, cfl,
-                 tx_size, tx_type, mode_context, &mv_stack, RDOType::PixelDistRealRate, false);
+                 tx_size, tx_type, mode_context, &mv_stack, rdo_type, false);
 }
 
 fn encode_partition_bottomup<T: Pixel>(
@@ -1478,6 +1501,7 @@ fn encode_partition_bottomup<T: Pixel>(
   bo: &BlockOffset, pmvs: &[[Option<MotionVector>; REF_FRAMES]; 5],
   ref_rd_cost: f64
 ) -> (RDOOutput) {
+  let rdo_type = RDOType::PixelDistRealRate;
   let mut rd_cost = std::f64::MAX;
   let mut best_rd = std::f64::MAX;
   let mut rdo_output = RDOOutput {
@@ -1536,7 +1560,7 @@ fn encode_partition_bottomup<T: Pixel>(
 
     if !can_split {
       encode_block_with_modes(fi, fs, cw, w_pre_cdef, w_post_cdef, bsize, bo,
-                              &mode_decision);
+                              &mode_decision, rdo_type);
     }
   }
 
@@ -1652,7 +1676,7 @@ fn encode_partition_bottomup<T: Pixel>(
           let offset = mode.bo.clone();
           // FIXME: redundant block re-encode
           encode_block_with_modes(fi, fs, cw, w_pre_cdef, w_post_cdef,
-                                  mode.bsize, &offset, &mode);
+                                  mode.bsize, &offset, &mode, rdo_type);
         }
       }
   }
@@ -1686,6 +1710,7 @@ fn encode_partition_topdown<T: Pixel>(
   let bsw = bsize.width_mi();
   let bsh = bsize.height_mi();
   let is_square = bsize.is_sqr();
+  let rdo_type = RDOType::PixelDistRealRate;
 
   // Always split if the current partition is too large
   let must_split = (bo.x + bsw as usize > fi.w_in_b ||
@@ -1726,7 +1751,7 @@ fn encode_partition_topdown<T: Pixel>(
       partition_types.push(PartitionType::PARTITION_SPLIT);
     }
     rdo_output = rdo_partition_decision(fi, fs, cw,
-                                        w_pre_cdef, w_post_cdef, bsize, bo, &rdo_output, pmvs, &partition_types);
+                                        w_pre_cdef, w_post_cdef, bsize, bo, &rdo_output, pmvs, &partition_types, rdo_type);
     partition = rdo_output.part_type;
   } else {
     // Blocks of sizes below the supported range are encoded directly
@@ -2059,7 +2084,6 @@ fn encode_tile<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>) -> Vec
   if fs.deblock.levels[0] != 0 || fs.deblock.levels[1] != 0 {
     deblock_filter_frame(fs, &mut cw.bc, fi.sequence.bit_depth);
   }
-  {
     // Until the loop filters are pipelined, we'll need to keep
     // around a copy of both the pre- and post-cdef frame.
     let pre_cdef_frame = fs.rec.clone();
@@ -2072,6 +2096,17 @@ fn encode_tile<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>) -> Vec
     if fi.sequence.enable_restoration {
       fs.restoration.lrf_filter_frame(&mut fs.rec, &pre_cdef_frame, &fi);
     }
+
+  if fi.config.train_rdo {
+    eprintln!("train rdo");
+    if let Ok(mut file) = File::open("rdo.dat") {
+      let mut data = vec![];
+      file.read_to_end(&mut data).unwrap();
+      fs.t.merge_in(&deserialize(data.as_slice()).unwrap());
+    }
+    let mut rdo_file = File::create("rdo.dat").unwrap();
+    rdo_file.write_all(&serialize(&fs.t).unwrap()).unwrap();
+    fs.t.print_code();
   }
 
   fs.cdfs = cw.fc;
diff --git a/src/lib.rs b/src/lib.rs
index 19bbf74f..293faa7a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,6 +11,7 @@
 
 #[macro_use]
 extern crate serde_derive;
+extern crate bincode;
 
 #[cfg(all(test, feature="decode_test_dav1d"))]
 extern crate dav1d_sys;
@@ -30,6 +31,7 @@ pub mod transform;
 pub mod quantize;
 pub mod predict;
 pub mod rdo;
+pub mod rdo_tables;
 #[macro_use]
 pub mod util;
 pub mod context;
diff --git a/src/rdo.rs b/src/rdo.rs
index f8c879b3..ee352872 100644
--- a/src/rdo.rs
+++ b/src/rdo.rs
@@ -32,16 +32,19 @@ use crate::Tune;
 use crate::write_tx_blocks;
 use crate::write_tx_tree;
 use crate::util::{CastFromPrimitive, Pixel};
+use crate::rdo_tables::*;
 
 use std;
 use std::cmp;
 use std::vec::Vec;
 use crate::partition::PartitionType::*;
 
-#[derive(Copy,Clone)]
+#[derive(Copy,Clone,PartialEq)]
 pub enum RDOType {
   PixelDistRealRate,
-  TxDistRealRate
+  TxDistRealRate,
+  TxDistEstRate,
+  Train
 }
 
 impl RDOType {
@@ -50,7 +53,18 @@ impl RDOType {
       // Pixel-domain distortion and exact ec rate
       RDOType::PixelDistRealRate => false,
       // Tx-domain distortion and exact ec rate
-      RDOType::TxDistRealRate => true
+      RDOType::TxDistRealRate => true,
+      // Tx-domain distortion and txdist-based rate
+      RDOType::TxDistEstRate => true,
+      RDOType::Train => true,
+    }
+  }
+  pub fn needs_coeff_rate(self) -> bool {
+    match self {
+      RDOType::PixelDistRealRate => true,
+      RDOType::TxDistRealRate => true,
+      RDOType::TxDistEstRate => false,
+      RDOType::Train => true,
     }
   }
 }
@@ -77,6 +91,86 @@ pub struct RDOPartitionOutput {
   pub tx_type: TxType,
 }
 
+#[derive(Serialize, Deserialize, Debug, Clone, Default)]
+pub struct RDOTracker {
+  rate_bins: Vec<Vec<Vec<u64>>>,
+  rate_counts: Vec<Vec<Vec<u64>>>,
+}
+
+impl RDOTracker {
+  pub fn new() -> RDOTracker {
+    RDOTracker {
+      rate_bins: vec![vec![vec![0; RDO_NUM_BINS]; TxSize::TX_SIZES_ALL]; RDO_QUANT_BINS],
+      rate_counts: vec![vec![vec![0; RDO_NUM_BINS]; TxSize::TX_SIZES_ALL]; RDO_QUANT_BINS],
+    }
+  }
+  fn merge_array(new: &mut Vec<u64>, old: &[u64]) {
+    for (n, o) in new.iter_mut().zip(old.iter()) {
+      *n += o;
+    }
+  }
+  fn merge_2d_array(new: &mut Vec<Vec<u64>>, old: &[Vec<u64>]) {
+    for (n, o) in new.iter_mut().zip(old.iter()) {
+      RDOTracker::merge_array(n, o);
+    }
+  }
+  fn merge_3d_array(new: &mut Vec<Vec<Vec<u64>>>, old: &[Vec<Vec<u64>>]) {
+    for (n, o) in new.iter_mut().zip(old.iter()) {
+      RDOTracker::merge_2d_array(n, o);
+    }
+  }
+  pub fn merge_in(&mut self, input: &RDOTracker) {
+    RDOTracker::merge_3d_array(&mut self.rate_bins, &input.rate_bins);
+    RDOTracker::merge_3d_array(&mut self.rate_counts, &input.rate_counts);
+  }
+  pub fn add_rate(&mut self, qindex: u8, ts: TxSize, fast_distortion: u64, rate: u64) {
+    if fast_distortion != 0 {
+      let bs_index = ts as usize;
+      let q_bin_idx = (qindex as usize)/RDO_QUANT_DIV;
+      let bin_idx_tmp = ((fast_distortion as i64 - (RATE_EST_BIN_SIZE as i64) / 2) as u64 / RATE_EST_BIN_SIZE) as usize;
+      let bin_idx = if bin_idx_tmp >= RDO_NUM_BINS {
+        RDO_NUM_BINS - 1
+      } else {
+        bin_idx_tmp
+      };
+      self.rate_counts[q_bin_idx][bs_index][bin_idx] += 1;
+      self.rate_bins[q_bin_idx][bs_index][bin_idx] += rate;
+    }
+  }
+  pub fn print_code(&self) {
+    println!("pub static RDO_RATE_TABLE: [[[u64; RDO_NUM_BINS]; TxSize::TX_SIZES_ALL]; RDO_QUANT_BINS] = [");
+    for q_bin in 0..RDO_QUANT_BINS {
+      print!("[");
+      for bs_index in 0..TxSize::TX_SIZES_ALL {
+        print!("[");
+        for (rate_total, rate_count) in self.rate_bins[q_bin][bs_index].iter().zip(self.rate_counts[q_bin][bs_index].iter()) {
+          if *rate_count > 100 {
+            print!("{},", rate_total / rate_count);
+          } else {
+            print!("99999,");
+          }
+        }
+        println!("],");
+      }
+      println!("],");
+    }
+    println!("];");
+  }
+}
+
+pub fn estimate_rate(qindex: u8, ts: TxSize, fast_distortion: u64) -> u64 {
+  let bs_index = ts as usize;
+  let q_bin_idx = (qindex as usize)/RDO_QUANT_DIV;
+  let bin_idx_down = ((fast_distortion) / RATE_EST_BIN_SIZE).min((RDO_NUM_BINS - 2) as u64);
+  let bin_idx_up = (bin_idx_down + 1).min((RDO_NUM_BINS - 1) as u64);
+  let x0 = (bin_idx_down * RATE_EST_BIN_SIZE) as i64;
+  let x1 = (bin_idx_up * RATE_EST_BIN_SIZE) as i64;
+  let y0 = RDO_RATE_TABLE[q_bin_idx][bs_index][bin_idx_down as usize] as i64;
+  let y1 = RDO_RATE_TABLE[q_bin_idx][bs_index][bin_idx_up as usize] as i64;
+  let slope = ((y1 - y0) << 8) / (x1 - x0);
+  (y0 + (((fast_distortion as i64 - x0) * slope) >> 8)).max(0) as u64
+}
+
 #[allow(unused)]
 fn cdef_dist_wxh_8x8<T: Pixel>(
   src1: &PlaneSlice<'_, T>, src2: &PlaneSlice<'_, T>, bit_depth: usize
@@ -370,7 +464,11 @@ pub fn rdo_mode_decision<T: Pixel>(
   let mut fwdref = None;
   let mut bwdref = None;
 
-  let rdo_type = if fi.use_tx_domain_distortion {
+  let rdo_type = if fi.config.train_rdo {
+    RDOType::Train
+  } else if fi.use_tx_domain_rate {
+    RDOType::TxDistEstRate
+  } else if fi.use_tx_domain_distortion {
     RDOType::TxDistRealRate
   } else {
     RDOType::PixelDistRealRate
@@ -722,8 +820,8 @@ pub fn rdo_mode_decision<T: Pixel>(
       let wr: &mut dyn Writer = &mut WriterCounter::new();
       let tell = wr.tell_frac();
 
-      encode_block_a(&fi.sequence, fs, cw, wr, bsize, bo, best.skip);
-      encode_block_b(
+        encode_block_a(&fi.sequence, fs, cw, wr, bsize, bo, best.skip);
+        let _ = encode_block_b(
         fi,
         fs,
         cw,
@@ -996,7 +1094,7 @@ pub fn rdo_partition_decision<T: Pixel>(
   cw: &mut ContextWriter, w_pre_cdef: &mut dyn Writer, w_post_cdef: &mut dyn Writer,
   bsize: BlockSize, bo: &BlockOffset,
   cached_block: &RDOOutput, pmvs: &[[Option<MotionVector>; REF_FRAMES]; 5],
-  partition_types: &[PartitionType],
+  partition_types: &[PartitionType], rdo_type: RDOType
 ) -> RDOOutput {
   let mut best_partition = cached_block.part_type;
   let mut best_rd = cached_block.rd_cost;
@@ -1089,7 +1187,7 @@ pub fn rdo_partition_decision<T: Pixel>(
             cw.write_partition(w, offset, PartitionType::PARTITION_NONE, subsize);
           }
           encode_block_with_modes(fi, fs, cw, w_pre_cdef, w_post_cdef, subsize,
-                                  offset, &mode_decision);
+                                  offset, &mode_decision, rdo_type);
           child_modes.push(mode_decision);
         }
       }
@@ -1335,3 +1433,8 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: &SuperBlockOffset, fi: &FrameInvariants<
     }
   }
 }
+
+#[test]
+fn estimate_rate_test() {
+  assert_eq!(estimate_rate(0, TxSize::TX_4X4, 0), RDO_RATE_TABLE[0][0][0]);
+}
diff --git a/src/rdo_tables.rs b/src/rdo_tables.rs
new file mode 100644
index 00000000..3f41fb39
--- /dev/null
+++ b/src/rdo_tables.rs
@@ -0,0 +1,173 @@
+
+pub const RDO_NUM_BINS: usize =  50;
+pub const RDO_MAX_BIN: usize = 10000;
+pub const RATE_EST_MAX_BIN: usize = 100_000;
+pub const RDO_QUANT_BINS: usize = 8;
+pub const RDO_QUANT_DIV: usize = 256/RDO_QUANT_BINS;
+pub const RDO_BIN_SIZE: u64 = (RDO_MAX_BIN / RDO_NUM_BINS) as u64;
+pub const RATE_EST_BIN_SIZE: u64 = (RATE_EST_MAX_BIN / RDO_NUM_BINS) as u64;
+
+use crate::partition::*;
+
+pub static RDO_RATE_TABLE: [[[u64; RDO_NUM_BINS]; TxSize::TX_SIZES_ALL]; RDO_QUANT_BINS] = [
+[[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,104,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,707,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,2756,],
+[13934,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,7628,],
+[3155,8704,12726,17300,19395,20872,22052,23156,24014,25176,26269,27336,28359,28967,29713,30205,30847,31286,31776,32355,32826,33232,33367,33741,34095,34472,34726,35087,35195,35531,35614,35728,35934,35973,36165,36360,36281,36651,36759,36921,37014,37095,37188,37012,37310,37255,37157,37399,37753,41014,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,146,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,1159,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[7612,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,4525,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,56,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,446,],
+[3456,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,1438,],
+[5300,12376,13413,21251,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,1449,],
+[468,2455,5285,8433,10917,12155,13651,14712,15475,16484,17678,18613,19609,20313,20833,21383,21834,22277,22758,23300,23686,24012,24419,24739,25112,25439,25602,26011,26256,26389,26539,26662,26827,26946,27059,27145,27358,27485,27510,27509,27594,27720,27792,28033,28029,28087,28285,28548,28657,31616,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,69,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[2627,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,668,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[3957,6158,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,955,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,26,],
+[814,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,217,],
+[1127,2725,4344,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,154,],
+[345,1365,2879,4614,6905,9707,9334,9812,11542,14962,22525,28756,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,717,],
+[116,270,689,1041,1618,2298,3748,5051,5800,6310,6909,7391,7745,8030,8482,8996,9557,10112,10633,11148,11623,12152,12614,13089,13592,14000,14425,14886,15182,15630,15871,16282,16506,16780,17018,17139,17228,17411,17463,17587,17723,17634,17696,17944,18012,17950,18006,18005,18182,22725,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,23,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[873,2245,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,182,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[519,1820,3040,5457,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,154,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[169,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,15,],
+[463,859,1141,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,76,],
+[295,923,1607,2072,2388,3105,4419,5573,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,65,],
+[112,343,674,1102,1578,2089,2648,3376,4342,4869,5708,5918,5901,6998,8658,8258,7166,7837,9781,10973,10590,11659,11882,12548,15440,19254,22300,24169,25287,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,413,],
+[60,105,217,365,586,798,1010,1287,1563,1952,2385,2825,3135,3158,3796,4070,4377,4574,4794,5032,5350,5507,5762,5986,6267,6519,6741,7016,7346,7645,8040,8413,8750,9012,9362,9687,9982,10270,10558,10725,11056,11204,11387,11663,11752,11877,12042,12104,12188,16345,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[154,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,9,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[327,950,1500,1781,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,78,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[125,384,795,1244,2031,2451,3184,3711,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,75,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[83,148,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,7,],
+[170,381,574,822,1042,1186,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,28,],
+[89,233,449,680,867,1082,1319,1445,1725,1907,2163,2432,2636,3171,3869,4433,4818,5081,5327,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,29,],
+[43,112,190,282,370,477,587,725,913,1105,1315,1542,1773,1992,2173,2337,2526,2703,2884,3072,3276,3472,3668,3886,4168,4521,4923,5082,4981,5031,5290,5598,6069,6710,7558,8505,9363,9523,8687,7810,7479,7697,8214,8970,9562,9978,10067,9798,9430,843,],
+[46,58,75,129,207,265,340,426,505,554,662,771,873,1023,1097,1183,1270,1342,1445,1561,1642,1741,1852,1992,2037,2170,2236,2339,2387,2507,2713,2837,2893,3108,3262,3364,3466,3592,3758,3811,4050,4191,4326,4493,4607,4773,4846,5055,5247,9882,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[81,155,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,3,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[120,275,521,750,987,1167,1264,1373,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,55,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[57,85,114,227,424,686,890,1071,1436,1495,1521,1956,2182,2247,2349,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,58,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[22,47,62,81,106,116,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,2,],
+[46,108,158,203,253,296,333,371,429,500,558,587,580,542,505,502,529,554,590,612,632,645,678,684,687,735,716,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,12,],
+[24,56,96,144,195,247,297,343,387,427,463,499,533,568,605,642,685,739,806,872,904,929,982,1068,1168,1238,1254,1246,1201,1202,1257,1346,1445,1572,1661,1755,1851,1966,2062,2201,2290,2405,2448,2482,2488,2474,2367,2270,2085,17,],
+[22,34,52,72,93,112,130,149,170,198,226,261,292,326,359,395,427,464,507,553,605,655,716,757,804,856,902,944,987,1030,1064,1114,1159,1192,1226,1262,1308,1339,1367,1395,1440,1470,1504,1548,1568,1604,1647,1680,1715,1461,],
+[40,42,47,54,72,98,111,130,148,159,182,200,231,246,285,298,312,324,357,375,394,418,439,467,472,501,518,536,564,562,604,620,632,644,674,691,735,770,786,781,827,856,947,939,993,1008,1030,1092,1120,3819,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[11,38,44,35,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,1,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[70,90,117,151,195,243,297,339,386,425,475,508,517,492,487,494,510,499,524,617,599,652,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,46,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[43,47,47,51,65,97,120,149,181,229,277,314,371,449,480,499,435,616,671,604,596,586,679,832,927,876,960,923,1070,1101,1148,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,53,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[4,11,16,18,24,30,39,46,56,58,51,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,0,],
+[14,30,46,60,73,84,94,105,115,126,137,150,162,175,188,199,207,213,217,226,235,251,263,284,301,319,336,351,363,373,384,393,392,391,397,390,387,376,370,357,348,338,335,328,321,318,318,331,320,6,],
+[6,13,21,31,43,55,67,79,91,103,114,125,135,145,156,164,174,184,193,202,212,221,229,238,245,255,263,270,281,289,299,308,317,326,332,343,349,357,368,374,385,399,405,417,425,439,452,469,480,30,],
+[16,17,20,23,27,31,35,39,43,48,52,57,62,68,73,78,84,90,96,102,108,113,120,124,129,137,143,150,157,162,170,177,186,195,201,207,221,225,233,244,248,259,270,274,283,292,302,311,320,624,],
+[37,37,37,38,40,42,46,48,51,55,58,60,66,69,72,77,82,81,86,89,93,97,98,102,107,114,116,119,128,132,130,135,137,138,138,139,151,156,153,153,153,154,168,172,171,170,178,182,191,1284,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[1,3,7,14,17,19,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,0,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[47,52,58,63,69,73,79,84,88,94,101,106,114,124,136,141,146,166,193,202,223,211,243,263,279,301,264,299,308,321,327,337,328,346,319,321,307,329,323,304,328,315,99999,99999,99999,99999,99999,99999,99999,33,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[38,39,41,42,41,43,42,42,45,46,53,56,60,68,70,77,84,84,88,75,86,121,135,137,144,154,161,162,178,183,189,196,202,245,286,295,251,270,265,242,242,233,182,326,183,447,294,330,318,108,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+[[1,2,2,3,3,3,3,4,5,6,8,15,17,24,25,23,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,0,],
+[9,16,22,26,30,34,38,42,46,49,53,55,58,61,64,66,69,71,74,75,78,78,83,85,87,88,88,92,94,97,97,101,102,105,107,106,110,113,115,119,118,117,122,126,129,129,126,131,134,6,],
+[3,5,6,9,11,13,16,19,22,25,28,31,34,37,40,44,47,51,54,58,62,65,68,72,75,78,79,84,88,91,95,96,100,103,106,107,110,111,117,119,119,122,125,127,130,132,134,138,140,21,],
+[11,13,13,15,16,17,18,18,19,21,22,24,25,27,28,29,31,32,33,34,36,37,38,39,40,41,42,43,44,45,46,48,48,49,51,52,54,55,56,57,59,60,61,62,63,64,66,67,69,181,],
+[33,32,34,34,34,35,35,36,37,37,38,38,39,39,39,40,41,41,42,43,43,44,45,45,46,47,47,48,50,50,51,52,53,52,52,53,55,55,56,56,58,58,58,59,60,60,58,59,61,393,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[0,1,1,1,2,1,2,1,2,1,0,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,0,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[40,44,47,49,50,51,52,52,51,52,53,55,55,57,57,57,59,60,62,63,64,65,66,67,67,69,68,72,76,77,80,76,76,85,85,90,92,98,87,87,88,98,94,103,107,98,107,109,109,31,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[36,37,38,38,37,37,37,37,37,36,37,37,37,37,38,37,38,38,40,40,41,40,38,44,47,44,43,44,45,50,44,44,46,49,49,54,58,56,64,63,62,60,54,54,59,59,65,57,60,78,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+[99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,99999,],
+],
+];
diff --git a/tools/rdo.sh b/tools/rdo.sh
new file mode 100755
index 00000000..22850b11
--- /dev/null
+++ b/tools/rdo.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+rm -f rdo.dat
+cargo build --release
+ls ~/sets/objective-1-fast/*.y4m | parallel target/release/rav1e --threads 1 --quantizer {2} -o /dev/null --train-rdo {1} :::: - ::: 16 48 80 112 144 176 208 240
+gnuplot rdo.plt -p
-- 
GitLab