use {Encoder, Error, Format};
use std::marker::PhantomData;
use std::mem;
use std::os::raw::{c_char, c_int};
use x264;
pub struct Setup {
raw: x264::x264_param_t
}
impl Setup {
pub fn preset(
preset: Preset,
tune: Tune,
fast_decode: bool,
zero_latency: bool
) -> Self {
let mut raw = unsafe { mem::uninitialized() };
assert_eq!(0, unsafe {
x264::x264_param_default_preset(
&mut raw,
preset.to_cstr(),
tune.to_cstr(fast_decode, zero_latency)
)
});
Self { raw }
}
pub fn fastfirstpass(mut self) -> Self {
unsafe { x264::x264_param_apply_fastfirstpass(&mut self.raw); }
self
}
pub fn width(mut self, width: c_int) -> Self {
self.raw.i_width = width;
self
}
pub fn height(mut self, height: c_int) -> Self {
self.raw.i_height = height;
self
}
pub fn fps(mut self, num: u32, den: u32) -> Self {
self.raw.i_fps_num = num;
self.raw.i_fps_den = den;
self
}
pub fn timebase(mut self, num: u32, den: u32) -> Self {
self.raw.i_timebase_num = num;
self.raw.i_timebase_den = den;
self
}
pub fn annexb(mut self, annexb: bool) -> Self {
self.raw.b_annexb = if annexb { 1 } else { 0 };
self
}
pub fn bitrate(mut self, bitrate: c_int) -> Self {
self.raw.rc.i_bitrate = bitrate;
self
}
pub fn baseline(mut self) -> Self {
unsafe {
x264::x264_param_apply_profile(
&mut self.raw,
b"baseline\0" as *const _ as _
);
}
self
}
pub fn main(mut self) -> Self {
unsafe {
x264::x264_param_apply_profile(
&mut self.raw,
b"main\0" as *const _ as _
);
}
self
}
pub fn high(mut self) -> Self {
unsafe {
x264::x264_param_apply_profile(
&mut self.raw,
b"high\0" as *const _ as _
);
}
self
}
pub fn build<F: Format>(mut self) -> Result<Encoder<F>, Error> {
self.raw.i_csp = F::colorspace();
let raw = unsafe { x264::x264_encoder_open(&mut self.raw) };
if raw.is_null() {
return Err(Error);
}
Ok(Encoder { raw, spooky: PhantomData })
}
}
impl Default for Setup {
fn default() -> Self {
let raw = unsafe {
let mut raw = mem::uninitialized();
x264::x264_param_default(&mut raw);
raw
};
Self { raw }
}
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Hash, Debug, Eq, PartialEq)]
pub enum Preset {
Ultrafast,
Superfast,
Veryfast,
Faster,
Fast,
Medium,
Slow,
Slower,
Veryslow,
Placebo
}
impl Preset {
pub fn to_cstr(self) -> *const c_char {
use self::Preset::*;
(match self {
Ultrafast => b"ultrafast\0" as *const u8,
Superfast => b"superfast\0" as *const u8,
Veryfast => b"veryfast\0" as *const u8,
Faster => b"faster\0" as *const u8,
Fast => b"fast\0" as *const u8,
Medium => b"medium\0" as *const u8,
Slow => b"slow\0" as *const u8,
Slower => b"slower\0" as *const u8,
Veryslow => b"veryslow\0" as *const u8,
Placebo => b"placebo\0" as *const u8,
}) as _
}
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Hash, Debug, Eq, PartialEq)]
pub enum Tune {
None,
Film,
Animation,
Grain,
StillImage,
Psnr,
Ssim
}
impl Tune {
pub fn to_cstr(
self,
fast_decode: bool,
zero_latency: bool
) -> *const c_char {
(if !fast_decode && !zero_latency {
match self {
Tune::None => b"\0" as *const u8,
Tune::Film => b"film\0" as *const u8,
Tune::Animation => b"animation\0" as *const u8,
Tune::Grain => b"grain\0" as *const u8,
Tune::StillImage => b"stillimage\0" as *const u8,
Tune::Psnr => b"psnr\0" as *const u8,
Tune::Ssim => b"ssim\0" as *const u8,
}
} else if fast_decode && !zero_latency {
match self {
Tune::None => b"fastdecode\0" as *const u8,
Tune::Film => b"fastdecode,film\0" as *const u8,
Tune::Animation => b"fastdecode,animation\0" as *const u8,
Tune::Grain => b"fastdecode,grain\0" as *const u8,
Tune::StillImage => b"fastdecode,stillimage\0" as *const u8,
Tune::Psnr => b"fastdecode,psnr\0" as *const u8,
Tune::Ssim => b"fastdecode,ssim\0" as *const u8,
}
} else if !fast_decode && zero_latency {
match self {
Tune::None => b"zerolatency\0" as *const u8,
Tune::Film => b"zerolatency,film\0" as *const u8,
Tune::Animation => b"zerolatency,animation\0" as *const u8,
Tune::Grain => b"zerolatency,grain\0" as *const u8,
Tune::StillImage => b"zerolatency,stillimage\0" as *const u8,
Tune::Psnr => b"zerolatency,psnr\0" as *const u8,
Tune::Ssim => b"zerolatency,ssim\0" as *const u8,
}
} else {
match self {
Tune::None =>
b"fastdecode,zerolatency\0" as *const u8,
Tune::Film =>
b"fastdecode,zerolatency,film\0" as *const u8,
Tune::Animation =>
b"fastdecode,zerolatency,animation\0" as *const u8,
Tune::Grain =>
b"fastdecode,zerolatency,grain\0" as *const u8,
Tune::StillImage =>
b"fastdecode,zerolatency,stillimage\0" as *const u8,
Tune::Psnr =>
b"fastdecode,zerolatency,psnr\0" as *const u8,
Tune::Ssim =>
b"fastdecode,zerolatency,ssim\0" as *const u8,
}
}) as _
}
}