use crate::frame::*;
use crate::index::*;
use crate::*;
use ffms2_sys::*;
use std::ffi::CString;
use std::path::PathBuf;
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)
);
set_struct!(VideoProperties, video_properties, FFMS_VideoProperties);
default_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
)
);
set_params!(
VideoProperties,
video_properties,
(
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
),
(
usize, usize, usize, usize, usize, usize, usize, usize, usize, usize,
usize, usize, usize, usize, f64, f64, usize, usize, usize, f64, usize,
&[f64; 3], &[f64; 3], f64, f64, usize, f64, f64, usize, usize, usize,
usize
),
(
FPSDenominator as i32,
FPSNumerator as i32,
RFFDenominator as i32,
RFFNumerator as i32,
NumFrames as i32,
SARNum as i32,
SARDen as i32,
CropTop as i32,
CropBottom as i32,
CropLeft as i32,
CropRight as i32,
TopFieldFirst as i32,
ColorSpace as i32,
ColorRange as i32,
FirstTime as f64,
LastTime as f64,
Rotation as i32,
Stereo3DType as i32,
Stereo3DFlags as i32,
LastEndTime as f64,
HasMasteringDisplayPrimaries as i32,
*MasteringDisplayPrimariesX as [f64; 3],
*MasteringDisplayPrimariesY as [f64; 3],
MasteringDisplayWhitePointX as f64,
MasteringDisplayWhitePointY as f64,
HasMasteringDisplayLuminance as i32,
MasteringDisplayMinLuminance as f64,
MasteringDisplayMaxLuminance as f64,
HasContentLightLevel as i32,
ContentLightLevelMax as u32,
ContentLightLevelAverage as u32,
Flip as i32
)
);
pub struct VideoSource {
video_source: *mut FFMS_VideoSource,
}
impl VideoSource {
pub fn new(
SourceFile: &PathBuf,
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);
}
}
}