diff --git a/tools/avm_analyzer/avm_stats/src/stats.rs b/tools/avm_analyzer/avm_stats/src/stats.rs
new file mode 100644
index 0000000..abcf844
--- /dev/null
+++ b/tools/avm_analyzer/avm_stats/src/stats.rs
@@ -0,0 +1,331 @@
+use std::collections::{HashMap, HashSet};
+
+use itertools::Itertools;
+
+use ordered_float::OrderedFloat;
+use serde::{Deserialize, Serialize};
+
+use crate::{CodingUnitKind, Frame, Plane, PlaneType, ProtoEnumMapping, Spatial};
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
+pub enum FrameStatistic {
+    LumaModes,
+    ChromaModes,
+    BlockSizes,
+    Symbols,
+    PartitionSplit,
+}
+
+#[derive(Default, Debug, Deserialize, Serialize, PartialEq)]
+pub struct StatsFilter {
+    pub include: Vec<String>,
+    pub exclude: Vec<String>,
+}
+
+impl StatsFilter {
+    fn from_comma_separated(include: &str, exclude: &str) -> Self {
+        Self {
+            include: include
+                .split(',')
+                .map(|s| s.trim().to_string())
+                .filter(|s| !s.is_empty())
+                .collect(),
+            exclude: exclude
+                .split(',')
+                .map(|s| s.trim().to_string())
+                .filter(|s| !s.is_empty())
+                .collect(),
+        }
+    }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
+pub enum StatSortMode {
+    Unsorted,
+    ByName,
+    ByValue,
+}
+impl StatSortMode {
+    pub fn name(&self) -> &'static str {
+        match self {
+            Self::Unsorted => "Unsorted",
+            Self::ByName => "By name",
+            Self::ByValue => "By value",
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
+pub struct StatsSettings {
+    pub sort_by: StatSortMode,
+    // Using separate bool + value fields rather than an Option to make the UI design a bit more intuitive (e.g. checkbox + disabled number input).
+    pub apply_limit_count: bool,
+    pub limit_count: usize,
+    pub apply_limit_frac: bool,
+    pub limit_frac: f32,
+    pub include_filter: String,
+    pub exclude_filter: String,
+    pub include_filter_exact_match: bool,
+    pub exclude_filter_exact_match: bool,
+    pub show_relative_total: bool,
+    // Comma separated list of block sizes to include for partition split stats.
+    pub partition_split_block_sizes: String,
+}
+
+impl Default for StatsSettings {
+    fn default() -> Self {
+        Self {
+            sort_by: StatSortMode::ByValue,
+            apply_limit_count: false,
+            limit_count: 20,
+            apply_limit_frac: false,
+            limit_frac: 0.01,
+            include_filter: "".into(),
+            exclude_filter: "".into(),
+            include_filter_exact_match: false,
+            exclude_filter_exact_match: false,
+            show_relative_total: false,
+            partition_split_block_sizes: "".into(),
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct Sample {
+    pub name: String,
+    pub value: f64,
+}
+impl Sample {
+    pub fn new(name: String, value: f64) -> Self {
+        Self { name, value }
+    }
+}
+
+impl FrameStatistic {
+    fn luma_modes(&self, frame: &Frame) -> HashMap<String, f64> {
+        let modes = frame.iter_coding_units(CodingUnitKind::Shared).map(|ctx| {
+            let cu = ctx.coding_unit;
+            let prediction_mode = cu.prediction_mode.as_ref().unwrap();
+            frame
+                .enum_lookup(ProtoEnumMapping::PredictionMode, prediction_mode.mode)
+                .unwrap_or("UNKNOWN".into())
+        });
+        let mut modes_map: HashMap<String, f64> = HashMap::new();
+
+        for mode in modes {
+            *modes_map.entry(mode).or_default() += 1.0;
+        }
+
+        modes_map
+    }
+
+    fn chroma_modes(&self, frame: &Frame) -> HashMap<String, f64> {
+        let kind = frame.coding_unit_kind(PlaneType::Planar(Plane::U));
+        let modes = frame.iter_coding_units(kind).map(|ctx| {
+            let cu = ctx.coding_unit;
+            let prediction_mode = cu.prediction_mode.as_ref().unwrap();
+            frame
+                .enum_lookup(ProtoEnumMapping::UvPredictionMode, prediction_mode.uv_mode)
+                .unwrap_or("UNKNOWN".into())
+        });
+        let mut modes_map: HashMap<String, f64> = HashMap::new();
+
+        for mode in modes {
+            *modes_map.entry(mode).or_default() += 1.0;
+        }
+
+        modes_map
+    }
+
+    fn block_sizes(&self, frame: &Frame) -> HashMap<String, f64> {
+        let sizes = frame.iter_coding_units(CodingUnitKind::Shared).map(|ctx| {
+            let cu = ctx.coding_unit;
+            let w = cu.width();
+            let h = cu.height();
+            format!("{w}x{h}")
+        });
+        let mut sizes_map: HashMap<String, f64> = HashMap::new();
+
+        for size in sizes {
+            *sizes_map.entry(size).or_default() += 1.0;
+        }
+        sizes_map
+    }
+
+    fn partition_split(&self, frame: &Frame, settings: &StatsSettings) -> HashMap<String, f64> {
+        // TODO(comc): Add settings option for partition kind.
+        let filter = StatsFilter::from_comma_separated(&settings.partition_split_block_sizes, "");
+        let splits = frame.iter_partitions(CodingUnitKind::Shared).filter_map(|ctx| {
+            let partition = ctx.partition;
+            let size = partition.size_name();
+            if !filter.include.is_empty() && !filter.include.iter().any(|incl| &size == incl) {
+                return None;
+            }
+            let partition_type = frame
+                .enum_lookup(ProtoEnumMapping::PartitionType, partition.partition_type)
+                .unwrap_or("UNKNOWN".into());
+            Some(partition_type)
+        });
+        let mut splits_map: HashMap<String, f64> = HashMap::new();
+
+        for split in splits {
+            *splits_map.entry(split).or_default() += 1.0;
+        }
+        splits_map
+    }
+
+    fn symbols(&self, frame: &Frame) -> HashMap<String, f64> {
+        let mut symbols: HashMap<String, f64> = HashMap::new();
+        // TODO(comc): Use iter_symbols. Add iter_symbols method for partition blocks as well.
+        let sbs = frame.iter_superblocks().map(|sb_ctx| {
+            let sb = sb_ctx.superblock;
+            let mut symbols_sb: HashMap<String, f64> = HashMap::new();
+            for symbol in sb.symbols.iter() {
+                let info = symbol.info_id;
+                let info = &frame.symbol_info[&info];
+                let name = info.source_function.clone();
+                let bits = symbol.bits;
+                *symbols_sb.entry(name.clone()).or_default() += bits as f64;
+            }
+            symbols_sb
+        });
+        for symbols_sb in sbs {
+            for (name, bits) in symbols_sb {
+                *symbols.entry(name.clone()).or_default() += bits;
+            }
+        }
+        symbols
+    }
+
+    fn apply_settings(&self, mapping: HashMap<String, f64>, settings: &StatsSettings) -> Vec<Sample> {
+        let mut samples: Vec<_> = mapping
+            .into_iter()
+            .map(|(name, value)| Sample::new(name, value))
+            .collect();
+        let filter: StatsFilter = StatsFilter::from_comma_separated(&settings.include_filter, &settings.exclude_filter);
+        let total: f64 = samples.iter().map(|sample| sample.value).sum();
+        let mut other = 0.0;
+        samples.retain(|Sample { name, value }| {
+            let mut keep = true;
+            // TODO(comc): Make this a method of StatsFilter.
+            if !filter.include.is_empty() {
+                if settings.include_filter_exact_match {
+                    if !filter.include.contains(name) {
+                        keep = false;
+                    }
+                } else if !filter.include.iter().any(|incl| name.contains(incl)) {
+                    keep = false;
+                }
+            }
+            if settings.exclude_filter_exact_match {
+                if filter.exclude.contains(name) {
+                    keep = false
+                }
+            } else if filter.exclude.iter().any(|excl| name.contains(excl)) {
+                keep = false;
+            }
+            if !keep {
+                other += value;
+            }
+            keep
+        });
+
+        let filtered_total: f64 = samples.iter().map(|sample| sample.value).sum();
+
+        let top_n = if settings.apply_limit_count {
+            let top_n: HashSet<_> = samples
+                .iter()
+                .sorted_by_key(|sample| (OrderedFloat(sample.value), &sample.name)) // name used as a tie-breaker.
+                .rev()
+                .map(|sample| sample.name.clone())
+                .take(settings.limit_count)
+                .collect();
+            Some(top_n)
+        } else {
+            None
+        };
+
+        samples.retain(|Sample { name, value }| {
+            let mut keep = true;
+            if settings.apply_limit_frac {
+                let frac = if settings.show_relative_total {
+                    *value / filtered_total
+                } else {
+                    *value / total
+                };
+                if frac < settings.limit_frac as f64 {
+                    keep = false;
+                }
+            }
+
+            if let Some(top_n) = &top_n {
+                if !top_n.contains(name) {
+                    keep = false;
+                }
+            }
+
+            if !keep {
+                other += value;
+            }
+            keep
+        });
+
+        if !settings.show_relative_total && other > 0.0 {
+            samples.push(Sample::new("Other".into(), other));
+        }
+        match settings.sort_by {
+            StatSortMode::ByName => samples
+                .into_iter()
+                .sorted_by_key(|sample| sample.name.clone())
+                .collect(),
+            StatSortMode::ByValue => samples
+                .into_iter()
+                .sorted_by_key(|sample| (OrderedFloat(sample.value), sample.name.clone())) // name used as a tie-breaker.
+                .collect(),
+            StatSortMode::Unsorted => samples,
+        }
+    }
+
+    pub fn calculate(&self, frame: &Frame, settings: &StatsSettings) -> Vec<Sample> {
+        let mapping = match self {
+            FrameStatistic::LumaModes => self.luma_modes(frame),
+            FrameStatistic::ChromaModes => self.chroma_modes(frame),
+            FrameStatistic::BlockSizes => self.block_sizes(frame),
+            FrameStatistic::Symbols => self.symbols(frame),
+            FrameStatistic::PartitionSplit => self.partition_split(frame, settings),
+        };
+        self.apply_settings(mapping, settings)
+    }
+
+    pub fn name(&self) -> &'static str {
+        match self {
+            FrameStatistic::LumaModes => "Luma modes",
+            FrameStatistic::ChromaModes => "Chroma modes",
+            FrameStatistic::BlockSizes => "Block sizes",
+            FrameStatistic::Symbols => "Symbols",
+            FrameStatistic::PartitionSplit => "Partition split",
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+
+    #[test]
+    fn test_exclude_filter() {
+        let mapping: HashMap<String, f64> = [("ABC", 1.0), ("AAA", 2.0)]
+            .iter()
+            .map(|(k, v)| (k.to_string(), *v))
+            .collect();
+        let settings = StatsSettings {
+            exclude_filter: "A".into(),
+            exclude_filter_exact_match: true,
+            show_relative_total: true,
+            ..Default::default()
+        };
+        let samples = FrameStatistic::Symbols.apply_settings(mapping, &settings);
+        assert_eq!(samples.len(), 2);
+    }
+}
