#![warn(missing_docs)]
extern crate framing;
extern crate x264_sys;
mod data;
mod format;
mod image;
mod setup;
pub use data::{Data, Priority, Unit};
pub use format::Format;
pub use image::Image;
pub use setup::{Preset, Setup, Tune};
use std::{mem, ptr};
use std::marker::PhantomData;
use x264_sys::x264;
pub struct Encoder<F> {
raw: *mut x264::x264_t,
spooky: PhantomData<F>
}
impl<F> Encoder<F> {
pub fn encode<T>(&mut self, pts: i64, image: &T)
-> Result<(Data, Picture), Error>
where
T: Image<Format = F>,
F: Format
{
let mut picture = unsafe {
let mut picture = mem::uninitialized();
x264::x264_picture_init(&mut picture);
picture.i_pts = pts;
picture.img = x264ify(image);
picture
};
let mut len = 0;
let mut stuff = unsafe { mem::uninitialized() };
let mut raw = unsafe { mem::uninitialized() };
let err = unsafe {
x264::x264_encoder_encode(
self.raw,
&mut stuff,
&mut len,
&mut picture,
&mut raw
)
};
if err < 0 {
Err(Error)
} else {
let data = unsafe { Data::from_raw_parts(stuff, len as _) };
Ok((data, Picture { raw }))
}
}
pub fn work(&mut self) -> Result<(Data, Picture), Error> {
let mut len = 0;
let mut stuff = unsafe { mem::uninitialized() };
let mut raw = unsafe { mem::uninitialized() };
let err = unsafe {
x264::x264_encoder_encode(
self.raw,
&mut stuff,
&mut len,
ptr::null_mut(),
&mut raw
)
};
if err < 0 {
Err(Error)
} else {
let data = unsafe { Data::from_raw_parts(stuff, len as _) };
Ok((data, Picture { raw }))
}
}
pub fn headers(&mut self) -> Result<Data, Error> {
let mut len = 0;
let mut stuff = unsafe { mem::uninitialized() };
let err = unsafe {
x264::x264_encoder_headers(
self.raw,
&mut stuff,
&mut len
)
};
if 0 > err {
return Err(Error);
}
Ok(unsafe { Data::from_raw_parts(stuff, len as _) })
}
pub fn done(&self) -> bool {
unsafe { 0 == x264::x264_encoder_delayed_frames(self.raw) }
}
}
impl<F> Drop for Encoder<F> {
fn drop(&mut self) {
unsafe { x264::x264_encoder_close(self.raw); }
}
}
pub struct Picture {
raw: x264::x264_picture_t
}
impl Picture {
pub fn keyframe(&self) -> bool {
self.raw.b_keyframe != 0
}
pub fn pts(&self) -> i64 {
self.raw.i_pts
}
pub fn dts(&self) -> i64 {
self.raw.i_dts
}
}
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub struct Error;
fn x264ify<T: Image>(img: &T) -> x264::x264_image_t {
let planes = img.planes();
x264::x264_image_t {
i_csp: T::Format::colorspace(),
i_plane: T::Format::plane_count(),
i_stride: img.strides(),
plane:
[
planes[0] as _,
planes[1] as _,
planes[2] as _,
planes[3] as _
]
}
}