| 1 | // Copyright (c) 2019-2022, The rav1e contributors. All rights reserved |
| 2 | // |
| 3 | // This source code is subject to the terms of the BSD 2 Clause License and |
| 4 | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 5 | // was not distributed with this source code in the LICENSE file, you can |
| 6 | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 7 | // Media Patent License 1.0 was not distributed with this source code in the |
| 8 | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| 9 | |
| 10 | use crate::partition::BlockSize; |
| 11 | use crate::predict::PREDICTION_MODES; |
| 12 | use crate::serialize::{Deserialize, Serialize}; |
| 13 | use crate::transform::TX_TYPES; |
| 14 | |
| 15 | #[cfg (feature = "serialize" )] |
| 16 | use serde_big_array::BigArray; |
| 17 | |
| 18 | use std::ops::{Add, AddAssign}; |
| 19 | |
| 20 | #[derive (Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] |
| 21 | pub struct EncoderStats { |
| 22 | /// Stores count of pixels belonging to each block size in this frame |
| 23 | pub block_size_counts: [usize; BlockSize::BLOCK_SIZES_ALL], |
| 24 | /// Stores count of pixels belonging to skip blocks in this frame |
| 25 | pub skip_block_count: usize, |
| 26 | /// Stores count of pixels belonging to each transform type in this frame |
| 27 | pub tx_type_counts: [usize; TX_TYPES], |
| 28 | /// Stores count of pixels belonging to each luma prediction mode in this frame |
| 29 | #[serde(with = "BigArray" )] |
| 30 | pub luma_pred_mode_counts: [usize; PREDICTION_MODES], |
| 31 | /// Stores count of pixels belonging to each chroma prediction mode in this frame |
| 32 | #[serde(with = "BigArray" )] |
| 33 | pub chroma_pred_mode_counts: [usize; PREDICTION_MODES], |
| 34 | } |
| 35 | |
| 36 | impl Default for EncoderStats { |
| 37 | fn default() -> Self { |
| 38 | let luma_pred_mode_counts: [usize; 34] = [0; PREDICTION_MODES]; |
| 39 | let chroma_pred_mode_counts: [usize; 34] = [0; PREDICTION_MODES]; |
| 40 | EncoderStats { |
| 41 | block_size_counts: [0; BlockSize::BLOCK_SIZES_ALL], |
| 42 | skip_block_count: 0, |
| 43 | tx_type_counts: [0; TX_TYPES], |
| 44 | luma_pred_mode_counts, |
| 45 | chroma_pred_mode_counts, |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | impl Add<&Self> for EncoderStats { |
| 51 | type Output = Self; |
| 52 | |
| 53 | fn add(self, rhs: &EncoderStats) -> Self::Output { |
| 54 | let mut lhs: EncoderStats = self; |
| 55 | lhs += rhs; |
| 56 | lhs |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | impl AddAssign<&Self> for EncoderStats { |
| 61 | fn add_assign(&mut self, rhs: &EncoderStats) { |
| 62 | for (s, v) in |
| 63 | self.block_size_counts.iter_mut().zip(rhs.block_size_counts.iter()) |
| 64 | { |
| 65 | *s += v; |
| 66 | } |
| 67 | for (s, v) in self |
| 68 | .chroma_pred_mode_counts |
| 69 | .iter_mut() |
| 70 | .zip(rhs.chroma_pred_mode_counts.iter()) |
| 71 | { |
| 72 | *s += v; |
| 73 | } |
| 74 | for (s, v) in self |
| 75 | .luma_pred_mode_counts |
| 76 | .iter_mut() |
| 77 | .zip(rhs.luma_pred_mode_counts.iter()) |
| 78 | { |
| 79 | *s += v; |
| 80 | } |
| 81 | for (s, v) in self.tx_type_counts.iter_mut().zip(rhs.tx_type_counts.iter()) |
| 82 | { |
| 83 | *s += v; |
| 84 | } |
| 85 | self.skip_block_count += rhs.skip_block_count; |
| 86 | } |
| 87 | } |
| 88 | |