fn has_scenecut<T: Pixel>(
    &self, frame1: Arc<Frame<T>>, frame2: Arc<Frame<T>>, frameno: u64,
    previous_keyframe: u64,
  ) -> ScenecutResult {
    if self.fast_mode {
      let len = frame2.planes[0].cfg.width * frame2.planes[0].cfg.height;
      let delta = self.delta_in_planes(&frame1.planes[0], &frame2.planes[0]);
      let threshold = self.threshold * len as u64;
      ScenecutResult {
        intra_cost: threshold as f64,
        threshold: threshold as f64,
        inter_cost: delta as f64,
        has_scenecut: delta >= threshold,
      }
    } else {
      let intra_costs =
        estimate_intra_costs(&*frame2, self.bit_depth, self.cpu_feature_level);
      let intra_cost = intra_costs.iter().map(|&cost| cost as u64).sum::<u64>()
        as f64
        / intra_costs.len() as f64;

      let inter_costs = estimate_inter_costs(
        frame2,
        frame1,
        self.bit_depth,
        self.encoder_config,
        self.sequence,
      );
      let inter_cost = inter_costs.iter().map(|&cost| cost as u64).sum::<u64>()
        as f64
        / inter_costs.len() as f64;

      // Sliding scale, more likely to choose a keyframe
      // as we get farther from the last keyframe.
      // Based on x264 scenecut code.
      //
      // `THRESH_MAX` determines how likely we are
      // to choose a keyframe, between 0.0-1.0.
      // Higher values mean we are more likely to choose a keyframe.
      // `0.4` was chosen based on trials of the `scenecut-720p` set in AWCY,
      // as it appeared to provide the best average compression.
      // This also matches the default scenecut threshold in x264.
      const THRESH_MAX: f64 = 0.4;
      const THRESH_MIN: f64 = THRESH_MAX * 0.25;
      let distance_from_keyframe = frameno - previous_keyframe;
      let min_keyint = self.encoder_config.min_key_frame_interval;
      let max_keyint = self.encoder_config.max_key_frame_interval;
      let bias = if distance_from_keyframe <= min_keyint / 4 {
        THRESH_MIN / 4.0
      } else if distance_from_keyframe <= min_keyint {
        THRESH_MIN * distance_from_keyframe as f64 / min_keyint as f64
      } else {
        THRESH_MIN
          + (THRESH_MAX - THRESH_MIN)
            * (distance_from_keyframe - min_keyint) as f64
            / (max_keyint - min_keyint) as f64
      };
      let threshold = intra_cost * (1.0 - bias);

      ScenecutResult {
        intra_cost,
        threshold,
        inter_cost,
        has_scenecut: inter_cost > threshold,
      }
    }
  }
/// Run a comparison between two frames to determine if they qualify for a scenecut.
///
/// The standard algorithm uses block intra and inter costs
/// to determine which method would be more efficient
/// for coding this frame.
///
/// The fast algorithm detects fast cuts using a raw difference
/// in pixel values between the frames.
/// It does not handle pans well, but the scene flash detection compensates for this
/// in many cases.
Run a comparison between two frames to determine if they qualify for a scenecut.
The standard algorithm uses block intra and inter costs
to determine which method would be more efficient
for coding this frame.

The fast algorithm detects fast cuts using a raw difference
in pixel values between the frames.
It does not handle pans well, but the scene flash detection compensates for this
in many cases.
Run a comparison between two frames to determine if they qualify for a scenecut . The standard algorithm uses block intra and inter costs to determine which method would be more efficient for coding this frame . The fast algorithm detects fast cuts using a raw difference in pixel values between the frames . It does not handle pans well but the scene flash detection compensates for this in many cases .
fn has_scenecut<T: Pixel>(
    &self, frame1: Arc<Frame<T>>, frame2: Arc<Frame<T>>, frameno: u64,
    previous_keyframe: u64,
  ) -> ScenecutResult {
    if self.fast_mode {
      let len = frame2.planes[0].cfg.width * frame2.planes[0].cfg.height;
      let delta = self.delta_in_planes(&frame1.planes[0], &frame2.planes[0]);
      let threshold = self.threshold * len as u64;
      ScenecutResult {
        intra_cost: threshold as f64,
        threshold: threshold as f64,
        inter_cost: delta as f64,
        has_scenecut: delta >= threshold,
      }
    } else {
      let intra_costs =
        estimate_intra_costs(&*frame2, self.bit_depth, self.cpu_feature_level);
      let intra_cost = intra_costs.iter().map(|&cost| cost as u64).sum::<u64>()
        as f64
        / intra_costs.len() as f64;
      let inter_costs = estimate_inter_costs(
        frame2,
        frame1,
        self.bit_depth,
        self.encoder_config,
        self.sequence,
      );
      let inter_cost = inter_costs.iter().map(|&cost| cost as u64).sum::<u64>()
        as f64
        / inter_costs.len() as f64;
      // Sliding scale, more likely to choose a keyframe
      // as we get farther from the last keyframe.
      // Based on x264 scenecut code.
      //
      // `THRESH_MAX` determines how likely we are
      // to choose a keyframe, between 0.0-1.0.
      // Higher values mean we are more likely to choose a keyframe.
      // `0.4` was chosen based on trials of the `scenecut-720p` set in AWCY,
      // as it appeared to provide the best average compression.
      // This also matches the default scenecut threshold in x264.
      const THRESH_MAX: f64 = 0.4;
      const THRESH_MIN: f64 = THRESH_MAX * 0.25;
      let distance_from_keyframe = frameno - previous_keyframe;
      let min_keyint = self.encoder_config.min_key_frame_interval;
      let max_keyint = self.encoder_config.max_key_frame_interval;
      let bias = if distance_from_keyframe <= min_keyint / 4 {
        THRESH_MIN / 4.0
      } else if distance_from_keyframe <= min_keyint {
        THRESH_MIN * distance_from_keyframe as f64 / min_keyint as f64
      } else {
        THRESH_MIN
          + (THRESH_MAX - THRESH_MIN)
            * (distance_from_keyframe - min_keyint) as f64
            / (max_keyint - min_keyint) as f64
      };
      let threshold = intra_cost * (1.0 - bias);
      ScenecutResult {
        intra_cost,
        threshold,
        inter_cost,
        has_scenecut: inter_cost > threshold,
      }
    }
  }
fn has_scenecut < T : Pixel > ( & self , frame1 : Arc < Frame < T > > , frame2 : Arc < Frame < T > > , frameno : u64 , previous_keyframe : u64 , ) -> ScenecutResult { if self . fast_mode { let len = frame2 . planes [ 0 ] . cfg . width * frame2 . planes [ 0 ] . cfg . height ; let delta = self . delta_in_planes ( & frame1 . planes [ 0 ] , & frame2 . planes [ 0 ] ) ; let threshold = self . threshold * len as u64 ; ScenecutResult { intra_cost : threshold as f64 , threshold : threshold as f64 , inter_cost : delta as f64 , has_scenecut : delta >= threshold , } } else { let intra_costs = estimate_intra_costs ( & * frame2 , self . bit_depth , self . cpu_feature_level ) ; let intra_cost = intra_costs . iter ( ) . map ( | & cost | cost as u64 ) . sum :: < u64 > ( ) as f64 / intra_costs . len ( ) as f64 ; let inter_costs = estimate_inter_costs ( frame2 , frame1 , self . bit_depth , self . encoder_config , self . sequence , ) ; let inter_cost = inter_costs . iter ( ) . map ( | & cost | cost as u64 ) . sum :: < u64 > ( ) as f64 / inter_costs . len ( ) as f64 ; // Sliding scale, more likely to choose a keyframe // as we get farther from the last keyframe. // Based on x264 scenecut code. // // `THRESH_MAX` determines how likely we are // to choose a keyframe, between 0.0-1.0. // Higher values mean we are more likely to choose a keyframe. // `0.4` was chosen based on trials of the `scenecut-720p` set in AWCY, // as it appeared to provide the best average compression. // This also matches the default scenecut threshold in x264. const THRESH_MAX : f64 = 0.4 ; const THRESH_MIN : f64 = THRESH_MAX * 0.25 ; let distance_from_keyframe = frameno - previous_keyframe ; let min_keyint = self . encoder_config . min_key_frame_interval ; let max_keyint = self . encoder_config . max_key_frame_interval ; let bias = if distance_from_keyframe <= min_keyint / 4 { THRESH_MIN / 4.0 } else if distance_from_keyframe <= min_keyint { THRESH_MIN * distance_from_keyframe as f64 / min_keyint as f64 } else { THRESH_MIN + ( THRESH_MAX - THRESH_MIN ) * ( distance_from_keyframe - min_keyint ) as f64 / ( max_keyint - min_keyint ) as f64 } ; let threshold = intra_cost * ( 1.0 - bias ) ; ScenecutResult { intra_cost , threshold , inter_cost , has_scenecut : inter_cost > threshold , } } }
Run a comparison between two frames to determine if they qualify for a scenecut.
Run a comparison between two frames to determine if they qualify for a scenecut .
&self
frame1
Arc<Frame<T>>
frame2
Arc<Frame<T>>
frameno
u64
previous_keyframe
u64
&self
frame1
Arc<Frame<T>>
frame2
Arc<Frame<T>>
frameno
u64
previous_keyframe
u64