From 70f4b2036445a6b8c92da5aef06d22e9548587c5 Mon Sep 17 00:00:00 2001 From: Luca Barbato <lu_zero@gentoo.org> Date: Mon, 13 Aug 2018 09:43:39 +0200 Subject: [PATCH] Move the clap dependency outside the library --- Cargo.toml | 4 +- src/bin/common.rs | 89 ++++++++++++++++++++++++++++++++++++ src/bin/rav1e.rs | 1 + src/bin/rav1repl.rs | 1 + src/lib.rs | 95 ++------------------------------------ src/util.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 92 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93200843..be0fd541 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,12 +11,12 @@ autobins = false repl = ["rustyline", "binaries"] comparative_bench = [] decode_test = ["bindgen"] -binaries = ["y4m"] +binaries = ["y4m", "clap"] default = ["binaries"] [dependencies] bitstream-io = "0.6" -clap = "2" +clap = { version = "2", optional = true } libc = "0.2" rand = "0.5" rustyline = { version = "1", optional = true } diff --git a/src/bin/common.rs b/src/bin/common.rs index b1f107b0..41b20941 100644 --- a/src/bin/common.rs +++ b/src/bin/common.rs @@ -1,7 +1,96 @@ use y4m; use rav1e::*; +use std::fs::File; +use std::io; use std::io::prelude::*; use std::slice; +use clap::{App, Arg}; + +pub struct EncoderIO { + pub input: Box<Read>, + pub output: Box<Write>, + pub rec: Option<Box<Write>>, +} + +pub trait FromCli { + fn from_cli() -> (EncoderIO, EncoderConfig); +} + +impl FromCli for EncoderConfig { + fn from_cli() -> (EncoderIO, EncoderConfig) { + let matches = App::new("rav1e") + .version("0.1.0") + .about("AV1 video encoder") + .arg(Arg::with_name("INPUT") + .help("Uncompressed YUV4MPEG2 video input") + .required(true) + .index(1)) + .arg(Arg::with_name("OUTPUT") + .help("Compressed AV1 in IVF video output") + .short("o") + .long("output") + .required(true) + .takes_value(true)) + .arg(Arg::with_name("RECONSTRUCTION") + .short("r") + .takes_value(true)) + .arg(Arg::with_name("LIMIT") + .help("Maximum number of frames to encode") + .short("l") + .long("limit") + .takes_value(true) + .default_value("0")) + .arg(Arg::with_name("QP") + .help("Quantizer (0-255)") + .long("quantizer") + .takes_value(true) + .default_value("100")) + .arg(Arg::with_name("SPEED") + .help("Speed level (0(slow)-10(fast))") + .short("s") + .long("speed") + .takes_value(true) + .default_value("3")) + .arg(Arg::with_name("TUNE") + .help("Quality tuning (Will enforce partition sizes >= 8x8)") + .long("tune") + .possible_values(&Tune::variants()) + .default_value("psnr") + .case_insensitive(true)) + .get_matches(); + + + let io = EncoderIO { + input: match matches.value_of("INPUT").unwrap() { + "-" => Box::new(io::stdin()) as Box<Read>, + f => Box::new(File::open(&f).unwrap()) as Box<Read> + }, + output: match matches.value_of("OUTPUT").unwrap() { + "-" => Box::new(io::stdout()) as Box<Write>, + f => Box::new(File::create(&f).unwrap()) as Box<Write> + }, + rec: matches.value_of("RECONSTRUCTION").map(|f| { + Box::new(File::create(&f).unwrap()) as Box<Write> + }) + }; + + let config = EncoderConfig { + limit: matches.value_of("LIMIT").unwrap().parse().unwrap(), + quantizer: matches.value_of("QP").unwrap().parse().unwrap(), + speed: matches.value_of("SPEED").unwrap().parse().unwrap(), + tune: matches.value_of("TUNE").unwrap().parse().unwrap() + }; + + // Validate arguments + if config.quantizer == 0 { + unimplemented!(); + } else if config.quantizer > 255 || config.speed > 10 { + panic!("argument out of range"); + } + + (io, config) + } +} /// Encode and write a frame. pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants, diff --git a/src/bin/rav1e.rs b/src/bin/rav1e.rs index af2e34cb..240db3b6 100755 --- a/src/bin/rav1e.rs +++ b/src/bin/rav1e.rs @@ -9,6 +9,7 @@ extern crate rav1e; extern crate y4m; +extern crate clap; mod common; use common::*; diff --git a/src/bin/rav1repl.rs b/src/bin/rav1repl.rs index f9a10049..cae2c40b 100644 --- a/src/bin/rav1repl.rs +++ b/src/bin/rav1repl.rs @@ -9,6 +9,7 @@ extern crate rustyline; extern crate y4m; +extern crate clap; extern crate rav1e; diff --git a/src/lib.rs b/src/lib.rs index 289e1e42..b03cb50b 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,6 @@ extern crate bitstream_io; extern crate backtrace; -#[macro_use] -extern crate clap; extern crate libc; extern crate rand; @@ -22,10 +20,8 @@ extern crate enum_iterator_derive; extern crate num_traits; -use std::fs::File; use std::io::prelude::*; use bitstream_io::{BE, LE, BitWriter}; -use clap::{App, Arg}; use std::rc::Rc; use std::*; @@ -37,6 +33,7 @@ pub mod transform; pub mod quantize; pub mod predict; pub mod rdo; +#[macro_use] pub mod util; pub mod cdef; @@ -185,12 +182,12 @@ impl Sequence { assert!(width_bits <= 16); assert!(height_bits <= 16); - let profile = if bit_depth == 12 { + let profile = if bit_depth == 12 { 2 } else if chroma_sampling == ChromaSampling::Cs444 { 1 } else { - 0 + 0 }; let mut operating_point_idc = [0 as u16; MAX_NUM_OPERATING_POINTS]; @@ -447,12 +444,6 @@ impl fmt::Display for FrameType{ } } -pub struct EncoderIO { - pub input: Box<Read>, - pub output: Box<Write>, - pub rec: Option<Box<Write>>, -} - #[derive(Copy, Clone, Debug)] pub struct EncoderConfig { pub limit: u64, @@ -472,82 +463,6 @@ impl Default for EncoderConfig { } } -impl EncoderConfig { - pub fn from_cli() -> (EncoderIO, EncoderConfig) { - let matches = App::new("rav1e") - .version("0.1.0") - .about("AV1 video encoder") - .arg(Arg::with_name("INPUT") - .help("Uncompressed YUV4MPEG2 video input") - .required(true) - .index(1)) - .arg(Arg::with_name("OUTPUT") - .help("Compressed AV1 in IVF video output") - .short("o") - .long("output") - .required(true) - .takes_value(true)) - .arg(Arg::with_name("RECONSTRUCTION") - .short("r") - .takes_value(true)) - .arg(Arg::with_name("LIMIT") - .help("Maximum number of frames to encode") - .short("l") - .long("limit") - .takes_value(true) - .default_value("0")) - .arg(Arg::with_name("QP") - .help("Quantizer (0-255)") - .long("quantizer") - .takes_value(true) - .default_value("100")) - .arg(Arg::with_name("SPEED") - .help("Speed level (0(slow)-10(fast))") - .short("s") - .long("speed") - .takes_value(true) - .default_value("3")) - .arg(Arg::with_name("TUNE") - .help("Quality tuning (Will enforce partition sizes >= 8x8)") - .long("tune") - .possible_values(&Tune::variants()) - .default_value("psnr") - .case_insensitive(true)) - .get_matches(); - - - let io = EncoderIO { - input: match matches.value_of("INPUT").unwrap() { - "-" => Box::new(std::io::stdin()) as Box<Read>, - f => Box::new(File::open(&f).unwrap()) as Box<Read> - }, - output: match matches.value_of("OUTPUT").unwrap() { - "-" => Box::new(std::io::stdout()) as Box<Write>, - f => Box::new(File::create(&f).unwrap()) as Box<Write> - }, - rec: matches.value_of("RECONSTRUCTION").map(|f| { - Box::new(File::create(&f).unwrap()) as Box<Write> - }) - }; - - let config = EncoderConfig { - limit: matches.value_of("LIMIT").unwrap().parse().unwrap(), - quantizer: matches.value_of("QP").unwrap().parse().unwrap(), - speed: matches.value_of("SPEED").unwrap().parse().unwrap(), - tune: matches.value_of("TUNE").unwrap().parse().unwrap() - }; - - // Validate arguments - if config.quantizer == 0 { - unimplemented!(); - } else if config.quantizer > 255 || config.speed > 10 { - panic!("argument out of range"); - } - - (io, config) - } -} - pub fn write_ivf_header(output_file: &mut Write, width: usize, height: usize, num: usize, den: usize) { let mut bw = BitWriter::<LE>::new(output_file); bw.write_bytes(b"DKIF").unwrap(); @@ -721,7 +636,7 @@ impl<'a> UncompressedHeader for BitWriter<'a, BE> { } else { unimplemented!(); // 4:4:4 sampling at 8 or 10 bits } - + self.write_bit(false)?; // No color description present if seq.monochrome { @@ -1860,7 +1775,7 @@ mod test_encode_decode { } - fn setup_encoder(w: usize, h: usize, speed: usize, quantizer: usize, + fn setup_encoder(w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize, chroma_sampling: ChromaSampling) -> (FrameInvariants, Sequence) { unsafe { av1_rtcd(); diff --git a/src/util.rs b/src/util.rs index c9770fc5..ccc4b691 100755 --- a/src/util.rs +++ b/src/util.rs @@ -7,6 +7,115 @@ // Media Patent License 1.0 was not distributed with this source code in the // PATENTS file, you can obtain it at www.aomedia.org/license/patent. +// Imported from clap, to avoid to depend directly to the crate +macro_rules! _clap_count_exprs { + () => { 0 }; + ($e:expr) => { 1 }; + ($e:expr, $($es:expr),+) => { 1 + _clap_count_exprs!($($es),*) }; +} +macro_rules! arg_enum { + (@as_item $($i:item)*) => ($($i)*); + (@impls ( $($tts:tt)* ) -> ($e:ident, $($v:ident),+)) => { + arg_enum!(@as_item + $($tts)* + + impl ::std::str::FromStr for $e { + type Err = String; + + fn from_str(s: &str) -> ::std::result::Result<Self,Self::Err> { + #[allow(deprecated, unused_imports)] + use ::std::ascii::AsciiExt; + match s { + $(stringify!($v) | + _ if s.eq_ignore_ascii_case(stringify!($v)) => Ok($e::$v)),+, + _ => Err({ + let v = vec![ + $(stringify!($v),)+ + ]; + format!("valid values: {}", + v.join(" ,")) + }), + } + } + } + impl ::std::fmt::Display for $e { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + $($e::$v => write!(f, stringify!($v)),)+ + } + } + } + impl $e { + #[allow(dead_code)] + pub fn variants() -> [&'static str; _clap_count_exprs!($(stringify!($v)),+)] { + [ + $(stringify!($v),)+ + ] + } + }); + }; + ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + arg_enum!(@impls + ($(#[$($m),+])+ + pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + arg_enum!(@impls + ($(#[$($m),+])+ + pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + arg_enum!(@impls + ($(#[$($m),+])+ + enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + arg_enum!(@impls + ($(#[$($m),+])+ + enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + arg_enum!(@impls + (pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + arg_enum!(@impls + (pub enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { + arg_enum!(@impls + (enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; + (enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { + arg_enum!(@impls + (enum $e { + $($v$(=$val)*),+ + }) -> ($e, $($v),+) + ); + }; +} + #[repr(align(16))] struct Align16; -- GitLab