use crate::frame::*;
use crate::index::*;
use crate::*;
use ffms2_sys::*;
use std::ffi::CString;
use std::path::Path;
create_enum!(
SeekMode,
FFMS_SeekMode,
seek_mode,
(
SEEK_LINEAR_NO_RW,
SEEK_LINEAR,
SEEK_NORMAL,
SEEK_UNSAFE,
SEEK_AGGRESSIVE,
)
);
simple_enum!(
Stereo3DType,
(
S3D_TYPE_2D,
S3D_TYPE_SIDEBYSIDE,
S3D_TYPE_TOPBOTTOM,
S3D_TYPE_FRAMESEQUENCE,
S3D_TYPE_CHECKERBOARD,
S3D_TYPE_SIDEBYSIDE_QUINCUNX,
S3D_TYPE_LINES,
S3D_TYPE_COLUMNS,
)
);
simple_enum!(Stereo3DFlags, (S3D_FLAGS_INVERT));
create_enum!(
ColorRanges,
FFMS_ColorRanges,
color_ranges,
(CR_UNSPECIFIED, CR_MPEG, CR_JPEG)
);
create_struct!(
VideoProperties,
video_properties,
FFMS_VideoProperties,
(
FPSDenominator,
FPSNumerator,
RFFDenominator,
RFFNumerator,
NumFrames,
SARNum,
SARDen,
CropTop,
CropBottom,
CropLeft,
CropRight,
TopFieldFirst,
ColorSpace,
ColorRange,
FirstTime,
LastTime,
Rotation,
Stereo3DType,
Stereo3DFlags,
LastEndTime,
HasMasteringDisplayPrimaries,
MasteringDisplayPrimariesX,
MasteringDisplayPrimariesY,
MasteringDisplayWhitePointX,
MasteringDisplayWhitePointY,
HasMasteringDisplayLuminance,
MasteringDisplayMinLuminance,
MasteringDisplayMaxLuminance,
HasContentLightLevel,
ContentLightLevelMax,
ContentLightLevelAverage,
Flip
),
(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0,
[0.0; 3], [0.0; 3], 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0
)
);
pub struct VideoSource {
video_source: *mut FFMS_VideoSource,
}
unsafe impl Send for VideoSource {}
impl VideoSource {
pub fn new(
SourceFile: &Path,
Track: usize,
Index: &Index,
Threads: usize,
SeekMode: SeekMode,
) -> Result<Self, Error> {
let source = CString::new(SourceFile.to_str().unwrap()).unwrap();
let mut error: Error = Default::default();
let seek = SeekMode::to_seek_mode(&SeekMode) as i32;
let video_source = unsafe {
FFMS_CreateVideoSource(
source.as_ptr(),
Track as i32,
Index.as_mut_ptr(),
Threads as i32,
seek,
error.as_mut_ptr(),
)
};
if video_source.is_null() {
Err(error)
} else {
Ok(VideoSource { video_source })
}
}
pub fn GetVideoProperties(&self) -> VideoProperties {
let video_prop = unsafe { FFMS_GetVideoProperties(self.video_source) };
let ref_video = unsafe { &*video_prop };
VideoProperties {
video_properties: *ref_video,
}
}
pub fn SetInputFormatV(
&self,
ColorSpace: usize,
ColorRange: ColorRanges,
PixelFormat: usize,
) -> Result<(), Error> {
let mut error: Error = Default::default();
let colorange = ColorRanges::to_color_ranges(&ColorRange) as i32;
let err = unsafe {
FFMS_SetInputFormatV(
self.video_source,
ColorSpace as i32,
colorange,
PixelFormat as i32,
error.as_mut_ptr(),
)
};
if err != 0 {
Err(error)
} else {
Ok(())
}
}
pub fn ResetInputFormatV(&self) {
unsafe {
FFMS_ResetInputFormatV(self.video_source);
}
}
pub fn SetOutputFormatV2(
&self,
TargetFormats: &mut Vec<i32>,
Width: usize,
Height: usize,
Resizer: Resizers,
) -> Result<(), Error> {
let mut error: Error = Default::default();
let resize = Resizers::to_resizers(&Resizer) as i32;
TargetFormats.push(-1);
let err = unsafe {
FFMS_SetOutputFormatV2(
self.video_source,
TargetFormats.as_ptr(),
Width as i32,
Height as i32,
resize,
error.as_mut_ptr(),
)
};
TargetFormats.pop();
if err != 0 {
Err(error)
} else {
Ok(())
}
}
pub fn ResetOutputFormatV(&self) {
unsafe {
FFMS_ResetOutputFormatV(self.video_source);
}
}
pub(crate) fn as_mut_ptr(&mut self) -> *mut FFMS_VideoSource {
self.video_source
}
}
impl Drop for VideoSource {
fn drop(&mut self) {
unsafe {
FFMS_DestroyVideoSource(self.video_source);
}
}
}