126 lines
2.8 KiB
Rust
126 lines
2.8 KiB
Rust
use std::ptr;
|
|
|
|
use libc::{c_int};
|
|
use ffi::*;
|
|
use ::{Error, frame};
|
|
use ::util::format;
|
|
use super::Flags;
|
|
|
|
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
|
pub struct Definition {
|
|
pub format: format::Pixel,
|
|
pub width: u32,
|
|
pub height: u32,
|
|
}
|
|
|
|
pub struct Context {
|
|
ptr: *mut SwsContext,
|
|
|
|
input: Definition,
|
|
output: Definition,
|
|
}
|
|
|
|
impl Context {
|
|
pub unsafe fn as_ptr(&self) -> *const SwsContext {
|
|
self.ptr as *const _
|
|
}
|
|
|
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut SwsContext {
|
|
self.ptr
|
|
}
|
|
}
|
|
|
|
impl Context {
|
|
pub fn get(src_format: format::Pixel, src_w: u32, src_h: u32,
|
|
dst_format: format::Pixel, dst_w: u32, dst_h: u32,
|
|
flags: Flags) -> Result<Self, Error> {
|
|
unsafe {
|
|
let ptr = sws_getContext(
|
|
src_w as c_int, src_h as c_int, src_format.into(),
|
|
dst_w as c_int, dst_h as c_int, dst_format.into(),
|
|
flags.bits(),
|
|
ptr::null_mut(), ptr::null_mut(), ptr::null_mut());
|
|
|
|
if ptr != ptr::null_mut() {
|
|
Ok(Context {
|
|
ptr: ptr,
|
|
|
|
input: Definition {
|
|
format: src_format,
|
|
width: src_w,
|
|
height: src_h,
|
|
},
|
|
|
|
output: Definition {
|
|
format: dst_format,
|
|
width: dst_w,
|
|
height: dst_h,
|
|
},
|
|
})
|
|
}
|
|
else {
|
|
Err(Error::InvalidData)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn cached(&mut self,
|
|
src_format: format::Pixel, src_w: u32, src_h: u32,
|
|
dst_format: format::Pixel, dst_w: u32, dst_h: u32,
|
|
flags: Flags) {
|
|
self.input = Definition {
|
|
format: src_format,
|
|
width: src_w,
|
|
height: src_h,
|
|
};
|
|
|
|
self.output = Definition {
|
|
format: dst_format,
|
|
width: dst_w,
|
|
height: dst_h,
|
|
};
|
|
|
|
unsafe {
|
|
self.ptr = sws_getCachedContext(self.as_mut_ptr(),
|
|
src_w as c_int, src_h as c_int, src_format.into(),
|
|
dst_w as c_int, dst_h as c_int, dst_format.into(),
|
|
flags.bits(), ptr::null_mut(), ptr::null_mut(), ptr::null());
|
|
}
|
|
}
|
|
|
|
pub fn input(&self) -> &Definition {
|
|
&self.input
|
|
}
|
|
|
|
pub fn output(&self) -> &Definition {
|
|
&self.output
|
|
}
|
|
|
|
pub fn run(&mut self, input: &frame::Video, output: &mut frame::Video) -> Result<(), Error> {
|
|
if input.format() != self.input.format || input.width() != self.input.width || input.height() != self.input.height {
|
|
return Err(Error::InputChanged);
|
|
}
|
|
|
|
if output.format() != self.output.format || output.width() != self.output.width || output.height() != self.output.height {
|
|
return Err(Error::OutputChanged);
|
|
}
|
|
|
|
unsafe {
|
|
sws_scale(self.as_mut_ptr(),
|
|
(*input.as_ptr()).data.as_ptr() as *const *const _, (*input.as_ptr()).linesize.as_ptr() as *const _,
|
|
0, self.output.height as c_int,
|
|
(*output.as_mut_ptr()).data.as_ptr() as *mut *mut _, (*output.as_mut_ptr()).linesize.as_ptr() as *mut _);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Drop for Context {
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
sws_freeContext(self.as_mut_ptr());
|
|
}
|
|
}
|
|
}
|