forked from mirrors/gstreamer-rs
video: Add various VideoFormatInfo/VideoInfo/VideoFrame helper API
This commit is contained in:
parent
4d002786ec
commit
eed648831d
4 changed files with 160 additions and 2 deletions
|
@ -12,6 +12,7 @@ pub use gst_base;
|
||||||
|
|
||||||
macro_rules! assert_initialized_main_thread {
|
macro_rules! assert_initialized_main_thread {
|
||||||
() => {
|
() => {
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
if unsafe { gst::ffi::gst_is_initialized() } != glib::ffi::GTRUE {
|
if unsafe { gst::ffi::gst_is_initialized() } != glib::ffi::GTRUE {
|
||||||
panic!("GStreamer has not been initialized. Call `gst::init` first.");
|
panic!("GStreamer has not been initialized. Call `gst::init` first.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,12 @@ use glib::translate::{from_glib, IntoGlib, ToGlibPtr};
|
||||||
pub struct VideoFormatInfo(&'static ffi::GstVideoFormatInfo);
|
pub struct VideoFormatInfo(&'static ffi::GstVideoFormatInfo);
|
||||||
|
|
||||||
impl VideoFormatInfo {
|
impl VideoFormatInfo {
|
||||||
|
pub unsafe fn from_ptr(format_info: *const ffi::GstVideoFormatInfo) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
assert!(!format_info.is_null());
|
||||||
|
Self(&*format_info)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_format(format: crate::VideoFormat) -> Self {
|
pub fn from_format(format: crate::VideoFormat) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,16 @@ impl<T> VideoFrame<T> {
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_bottom_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& !self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_top_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn n_planes(&self) -> u32 {
|
pub fn n_planes(&self) -> u32 {
|
||||||
self.info().n_planes()
|
self.info().n_planes()
|
||||||
}
|
}
|
||||||
|
@ -136,6 +146,43 @@ impl<T> VideoFrame<T> {
|
||||||
self.info().offset()
|
self.info().offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
|
Ok(&self.plane_data(self.format_info().plane()[component as usize])?[poffset..])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_depth(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_depth(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_height(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_height(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_width(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_width(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_offset(&self, component: u32) -> usize {
|
||||||
|
self.info().comp_offset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_poffset(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_poffset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_pstride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_pstride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_stride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_stride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_plane(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_plane(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn buffer(&self) -> &gst::BufferRef {
|
pub fn buffer(&self) -> &gst::BufferRef {
|
||||||
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
|
unsafe { gst::BufferRef::from_ptr(self.frame.buffer) }
|
||||||
}
|
}
|
||||||
|
@ -364,6 +411,11 @@ impl VideoFrame<Writable> {
|
||||||
unsafe { gst::BufferRef::from_mut_ptr(self.frame.buffer) }
|
unsafe { gst::BufferRef::from_mut_ptr(self.frame.buffer) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn comp_data_mut(&mut self, component: u32) -> Result<&mut [u8], glib::BoolError> {
|
||||||
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
|
Ok(&mut self.plane_data_mut(self.format_info().plane()[component as usize])?[poffset..])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
|
pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
|
||||||
if plane >= self.n_planes() {
|
if plane >= self.n_planes() {
|
||||||
return Err(glib::bool_error!(
|
return Err(glib::bool_error!(
|
||||||
|
@ -510,6 +562,16 @@ impl<T> VideoFrameRef<T> {
|
||||||
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_bottom_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& !self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_top_field(&self) -> bool {
|
||||||
|
self.flags().contains(crate::VideoFrameFlags::ONEFIELD)
|
||||||
|
&& self.flags().contains(crate::VideoFrameFlags::TFF)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn n_planes(&self) -> u32 {
|
pub fn n_planes(&self) -> u32 {
|
||||||
self.info().n_planes()
|
self.info().n_planes()
|
||||||
}
|
}
|
||||||
|
@ -526,6 +588,43 @@ impl<T> VideoFrameRef<T> {
|
||||||
self.info().offset()
|
self.info().offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn comp_data(&self, component: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
|
Ok(&self.plane_data(self.format_info().plane()[component as usize])?[poffset..])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_depth(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_depth(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_height(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_height(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_width(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_width(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_offset(&self, component: u32) -> usize {
|
||||||
|
self.info().comp_offset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_poffset(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_poffset(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_pstride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_pstride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_stride(&self, component: u32) -> i32 {
|
||||||
|
self.info().comp_stride(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_plane(&self, component: u32) -> u32 {
|
||||||
|
self.info().comp_plane(component as u8)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
|
pub fn plane_data(&self, plane: u32) -> Result<&[u8], glib::BoolError> {
|
||||||
if plane >= self.n_planes() {
|
if plane >= self.n_planes() {
|
||||||
return Err(glib::bool_error!(
|
return Err(glib::bool_error!(
|
||||||
|
@ -764,6 +863,11 @@ impl<'a> VideoFrameRef<&'a mut gst::BufferRef> {
|
||||||
self.buffer.as_mut().unwrap()
|
self.buffer.as_mut().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn comp_data_mut(&mut self, component: u32) -> Result<&mut [u8], glib::BoolError> {
|
||||||
|
let poffset = self.info().comp_poffset(component as u8) as usize;
|
||||||
|
Ok(&mut self.plane_data_mut(self.format_info().plane()[component as usize])?[poffset..])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
|
pub fn plane_data_mut(&mut self, plane: u32) -> Result<&mut [u8], glib::BoolError> {
|
||||||
if plane >= self.n_planes() {
|
if plane >= self.n_planes() {
|
||||||
return Err(glib::bool_error!(
|
return Err(glib::bool_error!(
|
||||||
|
|
|
@ -630,11 +630,15 @@ impl VideoInfo {
|
||||||
return crate::VideoFormat::Unknown;
|
return crate::VideoFormat::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { from_glib((*self.0.finfo).format) }
|
self.format_info().format()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_info(&self) -> crate::VideoFormatInfo {
|
pub fn format_info(&self) -> crate::VideoFormatInfo {
|
||||||
crate::VideoFormatInfo::from_format(self.format())
|
unsafe { crate::VideoFormatInfo::from_ptr(self.0.finfo) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name<'a>(&self) -> &'a str {
|
||||||
|
self.format_info().name()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(&self) -> u32 {
|
pub fn width(&self) -> u32 {
|
||||||
|
@ -679,6 +683,39 @@ impl VideoInfo {
|
||||||
unsafe { VideoColorimetry(ptr::read(&self.0.colorimetry)) }
|
unsafe { VideoColorimetry(ptr::read(&self.0.colorimetry)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn comp_depth(&self, component: u8) -> u32 {
|
||||||
|
self.format_info().depth()[component as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_height(&self, component: u8) -> u32 {
|
||||||
|
self.format_info().scale_height(component, self.height())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_width(&self, component: u8) -> u32 {
|
||||||
|
self.format_info().scale_width(component, self.width())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_offset(&self, component: u8) -> usize {
|
||||||
|
self.offset()[self.format_info().plane()[component as usize] as usize]
|
||||||
|
+ self.format_info().poffset()[component as usize] as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_plane(&self, component: u8) -> u32 {
|
||||||
|
self.format_info().plane()[component as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_poffset(&self, component: u8) -> u32 {
|
||||||
|
self.format_info().poffset()[component as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_pstride(&self, component: u8) -> i32 {
|
||||||
|
self.format_info().pixel_stride()[component as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn comp_stride(&self, component: u8) -> i32 {
|
||||||
|
self.stride()[self.format_info().plane()[component as usize] as usize]
|
||||||
|
}
|
||||||
|
|
||||||
pub fn par(&self) -> gst::Fraction {
|
pub fn par(&self) -> gst::Fraction {
|
||||||
gst::Fraction::new(self.0.par_n, self.0.par_d)
|
gst::Fraction::new(self.0.par_n, self.0.par_d)
|
||||||
}
|
}
|
||||||
|
@ -687,6 +724,16 @@ impl VideoInfo {
|
||||||
gst::Fraction::new(self.0.fps_n, self.0.fps_d)
|
gst::Fraction::new(self.0.fps_n, self.0.fps_d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
|
||||||
|
pub fn field_rate(&self) -> gst::Fraction {
|
||||||
|
if self.interlace_mode() == crate::VideoInterlaceMode::Alternate {
|
||||||
|
2 * self.fps()
|
||||||
|
} else {
|
||||||
|
self.fps()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn offset(&self) -> &[usize] {
|
pub fn offset(&self) -> &[usize] {
|
||||||
&self.0.offset[0..(self.format_info().n_planes() as usize)]
|
&self.0.offset[0..(self.format_info().n_planes() as usize)]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue