Skip to content

Commit

Permalink
Parallelize frame processing
Browse files Browse the repository at this point in the history
  • Loading branch information
Luni-4 committed Nov 22, 2019
1 parent 9d06a5f commit 64babcd
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 116 deletions.
63 changes: 25 additions & 38 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion av_metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ itertools = "0.8.1"
lab = "0.7.2"
num-traits = "0.2"
serde = { version = "1", features = ["derive"], optional = true }
rayon = { version = "1.2.1", optional = true }
y4m = { version = "0.4", optional = true }

[dev-dependencies]
criterion = "0.3"

[features]
default = ["y4m-decode"]
decode = []
decode = ["rayon"]
y4m-decode = ["y4m", "decode"]
bench = []

Expand Down
2 changes: 2 additions & 0 deletions av_metrics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ extern crate err_derive;
#[macro_use]
extern crate itertools;

extern crate rayon;

pub mod video;

/// Possible errors that may occur during processing of a metric.
Expand Down
24 changes: 19 additions & 5 deletions av_metrics/src/video/ciede/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#[cfg(feature = "decode")]
use crate::video::decode::Decoder;
use crate::video::pixel::{CastFromPrimitive, Pixel};
use crate::video::ParallelMethod;
use crate::video::{FrameInfo, VideoMetric};
use crate::MetricsError;
use std::f64;

mod rgbtolab;
Expand Down Expand Up @@ -54,7 +56,10 @@ pub fn calculate_frame_ciede<T: Pixel>(
frame1: &FrameInfo<T>,
frame2: &FrameInfo<T>,
) -> Result<f64, Box<dyn Error>> {
Ciede2000::default().process_frame(frame1, frame2)
match Ciede2000::default().process_frame(frame1, frame2) {
Ok((val, _)) => Ok(val),
Err(val) => Err(val.into()),
}
}

/// Calculate the CIEDE2000 metric between two video frames. Higher is better.
Expand All @@ -67,7 +72,10 @@ pub fn calculate_frame_ciede_nosimd<T: Pixel>(
frame1: &FrameInfo<T>,
frame2: &FrameInfo<T>,
) -> Result<f64, Box<dyn Error>> {
(Ciede2000 { use_simd: false }).process_frame(frame1, frame2)
match (Ciede2000 { use_simd: false }).process_frame(frame1, frame2) {
Ok((val, _)) => Ok(val),
Err(val) => Err(val.into()),
}
}

struct Ciede2000 {
Expand All @@ -85,10 +93,10 @@ impl VideoMetric for Ciede2000 {
type VideoResult = f64;

fn process_frame<T: Pixel>(
&mut self,
&self,
frame1: &FrameInfo<T>,
frame2: &FrameInfo<T>,
) -> Result<Self::FrameResult, Box<dyn Error>> {
) -> Result<(Self::FrameResult, Option<f64>), MetricsError> {
frame1.can_compare(&frame2)?;

let dec = frame1.chroma_sampling.get_decimation().unwrap_or((1, 1));
Expand Down Expand Up @@ -123,7 +131,7 @@ impl VideoMetric for Ciede2000 {
* (delta_e_vec.iter().map(|x| *x as f64).sum::<f64>()
/ ((y_width * y_height) as f64))
.log10();
Ok(score.min(100.))
Ok((score.min(100.), None))
}

#[cfg(feature = "decode")]
Expand All @@ -133,6 +141,12 @@ impl VideoMetric for Ciede2000 {
) -> Result<Self::VideoResult, Box<dyn Error>> {
Ok(metrics.iter().copied().sum::<f64>() / metrics.len() as f64)
}

fn which_method(&self) -> ParallelMethod {
ParallelMethod::Ciede
}

fn set_cweight(&mut self, _cweight: f64) {}
}

// Arguments for delta e
Expand Down
2 changes: 1 addition & 1 deletion av_metrics/src/video/decode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub use self::y4m::*;
/// Currently, y4m decoding support using the `y4m` crate is built-in
/// to this crate. This trait is extensible so users may implement
/// their own decoders.
pub trait Decoder {
pub trait Decoder: Send {
/// Read the next frame from the input video.
///
/// Expected to return `Err` if the end of the video is reached.
Expand Down
2 changes: 1 addition & 1 deletion av_metrics/src/video/decode/y4m.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn copy_from_raw_u8<T: Pixel>(source: &[u8]) -> Vec<T> {
}
}

impl<R: Read> Decoder for y4m::Decoder<'_, R> {
impl<R: Read + Send> Decoder for y4m::Decoder<'_, R> {
fn read_video_frame<T: Pixel>(&mut self) -> Result<FrameInfo<T>, ()> {
let bit_depth = self.get_bit_depth();
let (chroma_sampling, chroma_sample_pos) = get_chroma_sampling(self);
Expand Down
Loading

0 comments on commit 64babcd

Please sign in to comment.