av_scenechange/analyze/
importance.rs1use std::sync::Arc;
2
3use v_frame::{
4 frame::Frame,
5 pixel::{CastFromPrimitive, Pixel},
6};
7
8use super::intra::BLOCK_TO_PLANE_SHIFT;
9use crate::data::plane::{Area, AsRegion, PlaneRegion, Rect};
10
11pub const IMPORTANCE_BLOCK_SIZE: usize =
13 1 << (IMPORTANCE_BLOCK_TO_BLOCK_SHIFT + BLOCK_TO_PLANE_SHIFT);
14pub const IMPORTANCE_BLOCK_TO_BLOCK_SHIFT: usize = 1;
15pub const IMP_BLOCK_MV_UNITS_PER_PIXEL: i64 = 8;
16pub const IMP_BLOCK_SIZE_IN_MV_UNITS: i64 =
17 IMPORTANCE_BLOCK_SIZE as i64 * IMP_BLOCK_MV_UNITS_PER_PIXEL;
18
19pub(crate) fn estimate_importance_block_difference<T: Pixel>(
20 frame: Arc<Frame<T>>,
21 ref_frame: Arc<Frame<T>>,
22) -> f64 {
23 let plane_org = &frame.planes[0];
24 let plane_ref = &ref_frame.planes[0];
25 let h_in_imp_b = plane_org.cfg.height / IMPORTANCE_BLOCK_SIZE;
26 let w_in_imp_b = plane_org.cfg.width / IMPORTANCE_BLOCK_SIZE;
27
28 let mut imp_block_costs = 0;
29
30 (0..h_in_imp_b).for_each(|y| {
31 (0..w_in_imp_b).for_each(|x| {
32 let region_org = plane_org.region(Area::Rect(Rect {
35 x: (x * IMPORTANCE_BLOCK_SIZE) as isize,
36 y: (y * IMPORTANCE_BLOCK_SIZE) as isize,
37 width: IMPORTANCE_BLOCK_SIZE,
38 height: IMPORTANCE_BLOCK_SIZE,
39 }));
40
41 let region_ref = plane_ref.region(Area::Rect(Rect {
42 x: (x * IMPORTANCE_BLOCK_SIZE) as isize,
43 y: (y * IMPORTANCE_BLOCK_SIZE) as isize,
44 width: IMPORTANCE_BLOCK_SIZE,
45 height: IMPORTANCE_BLOCK_SIZE,
46 }));
47
48 let sum_8x8_block = |region: &PlaneRegion<T>| {
49 region
50 .rows_iter()
51 .map(|row| {
52 row.iter().map(|pixel| u16::cast_from(*pixel)).sum::<u16>() as i64
56 })
57 .sum::<i64>()
58 };
59
60 let histogram_org_sum = sum_8x8_block(®ion_org);
61 let histogram_ref_sum = sum_8x8_block(®ion_ref);
62
63 let count = (IMPORTANCE_BLOCK_SIZE * IMPORTANCE_BLOCK_SIZE) as i64;
64
65 let mean = (((histogram_org_sum + count / 2) / count)
66 - ((histogram_ref_sum + count / 2) / count))
67 .abs();
68
69 imp_block_costs += mean as u64;
70 });
71 });
72
73 imp_block_costs as f64 / (w_in_imp_b * h_in_imp_b) as f64
74}