mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-27 05:51:01 +00:00
Refactor NDI receiver logic
This commit is contained in:
parent
3e9b1a85ca
commit
24f2cd57ad
1 changed files with 159 additions and 62 deletions
|
@ -5,6 +5,7 @@ use gst;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
use gst_video;
|
use gst_video;
|
||||||
use gst_base::prelude::*;
|
use gst_base::prelude::*;
|
||||||
|
use gst::Fraction;
|
||||||
|
|
||||||
use gst_plugin::base_src::*;
|
use gst_plugin::base_src::*;
|
||||||
use gst_plugin::element::*;
|
use gst_plugin::element::*;
|
||||||
|
@ -144,6 +145,7 @@ impl NdiSrc {
|
||||||
(
|
(
|
||||||
"format",
|
"format",
|
||||||
&gst::List::new(&[
|
&gst::List::new(&[
|
||||||
|
//TODO add all formats?
|
||||||
&gst_video::VideoFormat::Uyvy.to_string(),
|
&gst_video::VideoFormat::Uyvy.to_string(),
|
||||||
//&gst_video::VideoFormat::Rgb.to_string(),
|
//&gst_video::VideoFormat::Rgb.to_string(),
|
||||||
//&gst_video::VideoFormat::Gray8.to_string(),
|
//&gst_video::VideoFormat::Gray8.to_string(),
|
||||||
|
@ -167,6 +169,7 @@ impl NdiSrc {
|
||||||
gst::PadDirection::Src,
|
gst::PadDirection::Src,
|
||||||
gst::PadPresence::Always,
|
gst::PadPresence::Always,
|
||||||
&caps,
|
&caps,
|
||||||
|
//&gst::Caps::new_any(),
|
||||||
);
|
);
|
||||||
klass.add_pad_template(src_pad_template);
|
klass.add_pad_template(src_pad_template);
|
||||||
|
|
||||||
|
@ -247,6 +250,75 @@ impl NdiSrc {
|
||||||
impl ElementImpl<BaseSrc> for NdiSrc {
|
impl ElementImpl<BaseSrc> for NdiSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_frame(ndisrc_struct: &NdiSrc, element: &BaseSrc, pNDI_recv : NDIlib_recv_instance_t, pts2 : &mut u64, pts : &mut u64) -> NDIlib_video_frame_v2_t{
|
||||||
|
unsafe{
|
||||||
|
let video_frame: NDIlib_video_frame_v2_t = Default::default();
|
||||||
|
let audio_frame: NDIlib_audio_frame_v2_t = Default::default();
|
||||||
|
let metadata_frame: NDIlib_metadata_frame_t = Default::default();
|
||||||
|
|
||||||
|
//TODO Only create buffer when we got a video frame
|
||||||
|
let mut frame = false;
|
||||||
|
while !frame{
|
||||||
|
let frame_type = NDIlib_recv_capture_v2(
|
||||||
|
pNDI_recv,
|
||||||
|
&video_frame,
|
||||||
|
ptr::null(),
|
||||||
|
ptr::null(),
|
||||||
|
1000,
|
||||||
|
);
|
||||||
|
|
||||||
|
match frame_type {
|
||||||
|
NDIlib_frame_type_e::NDIlib_frame_type_video => {
|
||||||
|
gst_debug!(ndisrc_struct.cat, obj: element, "Received video frame: {:?}", video_frame);
|
||||||
|
frame = true;
|
||||||
|
//pts = ((video_frame.timestamp as u64) * 100) - state.start_pts.unwrap();
|
||||||
|
// println!("{:?}", pts/1000000);
|
||||||
|
*pts = ((video_frame.timestamp as u64) * 100);
|
||||||
|
if *pts2 == 0{
|
||||||
|
*pts2 = (video_frame.timestamp as u64) * 100;
|
||||||
|
*pts = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// println!("{:?}", video_frame.timecode * 100);
|
||||||
|
// println!("{:?}", pts2.pts);
|
||||||
|
*pts = (((video_frame.timestamp as u64) * 100) - *pts2);
|
||||||
|
//println!("{:?}", pts/1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
NDIlib_frame_type_e::NDIlib_frame_type_audio => {
|
||||||
|
gst_debug!(ndisrc_struct.cat, obj: element, "Received audio frame: {:?}", video_frame);
|
||||||
|
}
|
||||||
|
NDIlib_frame_type_e::NDIlib_frame_type_metadata => {
|
||||||
|
// println!(
|
||||||
|
// "Tengo metadata {} '{}'",
|
||||||
|
// metadata_frame.length,
|
||||||
|
// CStr::from_ptr(metadata_frame.p_data)
|
||||||
|
// .to_string_lossy()
|
||||||
|
// .into_owned(),
|
||||||
|
// );
|
||||||
|
//TODO Change gst_warning to gst_debug
|
||||||
|
gst_debug!(ndisrc_struct.cat, obj: element, "Received metadata frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned(),);
|
||||||
|
}
|
||||||
|
NDIlib_frame_type_e::NDIlib_frame_type_error => {
|
||||||
|
// println!(
|
||||||
|
// "Tengo error {} '{}'",
|
||||||
|
// metadata_frame.length,
|
||||||
|
// CStr::from_ptr(metadata_frame.p_data)
|
||||||
|
// .to_string_lossy()
|
||||||
|
// .into_owned(),
|
||||||
|
// );
|
||||||
|
//TODO Change gst_warning to gst_debug
|
||||||
|
gst_debug!(ndisrc_struct.cat, obj: element, "Received error frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned());
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
_ => println!("Tengo {:?}", frame_type),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return video_frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Virtual methods of gst_base::BaseSrc
|
// Virtual methods of gst_base::BaseSrc
|
||||||
impl BaseSrcImpl<BaseSrc> for NdiSrc {
|
impl BaseSrcImpl<BaseSrc> for NdiSrc {
|
||||||
// Called whenever the input/output caps are changing, i.e. in the very beginning before data
|
// Called whenever the input/output caps are changing, i.e. in the very beginning before data
|
||||||
|
@ -483,72 +555,97 @@ impl NdiSrc {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe{
|
unsafe{
|
||||||
// loop {
|
// // loop {
|
||||||
let video_frame: NDIlib_video_frame_v2_t = Default::default();
|
let mut pts: u64 = 0;
|
||||||
|
let video_frame: NDIlib_video_frame_v2_t = get_frame(self, element, pNDI_recv, &mut pts2.pts, &mut pts);
|
||||||
let audio_frame: NDIlib_audio_frame_v2_t = Default::default();
|
let audio_frame: NDIlib_audio_frame_v2_t = Default::default();
|
||||||
let metadata_frame: NDIlib_metadata_frame_t = Default::default();
|
let metadata_frame: NDIlib_metadata_frame_t = Default::default();
|
||||||
|
//video_frame = get_frame(self, element, pNDI_recv, pts2.pts);
|
||||||
|
|
||||||
//TODO Only create buffer when we got a video frame
|
// //TODO Only create buffer when we got a video frame
|
||||||
let mut frame = false;
|
// let mut frame = false;
|
||||||
let mut pts: u64 = 0;
|
// let mut pts: u64 = 0;
|
||||||
while !frame{
|
// while !frame{
|
||||||
let frame_type = NDIlib_recv_capture_v2(
|
// let frame_type = NDIlib_recv_capture_v2(
|
||||||
pNDI_recv,
|
// pNDI_recv,
|
||||||
&video_frame,
|
// &video_frame,
|
||||||
&audio_frame,
|
// &audio_frame,
|
||||||
&metadata_frame,
|
// &metadata_frame,
|
||||||
1000,
|
// 1000,
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
match frame_type {
|
// match frame_type {
|
||||||
NDIlib_frame_type_e::NDIlib_frame_type_video => {
|
// NDIlib_frame_type_e::NDIlib_frame_type_video => {
|
||||||
gst_debug!(self.cat, obj: element, "Received video frame: {:?}", video_frame);
|
// gst_debug!(self.cat, obj: element, "Received video frame: {:?}", video_frame);
|
||||||
frame = true;
|
// frame = true;
|
||||||
//pts = ((video_frame.timestamp as u64) * 100) - state.start_pts.unwrap();
|
// //pts = ((video_frame.timestamp as u64) * 100) - state.start_pts.unwrap();
|
||||||
// println!("{:?}", pts/1000000);
|
// // println!("{:?}", pts/1000000);
|
||||||
pts = (video_frame.timestamp as u64) * 100;
|
// pts = (video_frame.timestamp as u64) * 100;
|
||||||
if pts2.pts == 0{
|
// if pts2.pts == 0{
|
||||||
pts2.pts = (video_frame.timestamp as u64) * 100;
|
// pts2.pts = (video_frame.timestamp as u64) * 100;
|
||||||
pts = 0;
|
// pts = 0;
|
||||||
}
|
// //let mut caps = _info.to_caps();
|
||||||
else{
|
// // let s = caps.get_mut_structure(0).unwrap();
|
||||||
// println!("{:?}", video_frame.timecode * 100);
|
// // s.fixate_field_nearest_int("width", 1500);
|
||||||
// println!("{:?}", pts2.pts);
|
// // s.fixate_field_nearest_int("framerate", 25/1);
|
||||||
pts = (((video_frame.timestamp as u64) * 100) - pts2.pts);
|
// // self.set_caps(&self, s);
|
||||||
//println!("{:?}", pts/1000000);
|
// // let mut caps = Some(gst::Caps::new_simple(
|
||||||
}
|
// // "video/x-raw",
|
||||||
|
// // &[("format",
|
||||||
}
|
// // &gst_video::VideoFormat::Uyvy.to_string()
|
||||||
NDIlib_frame_type_e::NDIlib_frame_type_audio => {
|
// // )],
|
||||||
gst_debug!(self.cat, obj: element, "Received audio frame: {:?}", video_frame);
|
// // ));
|
||||||
}
|
// // caps.as_mut().map(|c| {
|
||||||
NDIlib_frame_type_e::NDIlib_frame_type_metadata => {
|
// // c.get_mut()
|
||||||
// println!(
|
// // .unwrap()
|
||||||
// "Tengo metadata {} '{}'",
|
// // .set_simple(&[("framerate", &(25/1 as i32)), ("width", &(1600 as i32)), ("height", &(1200 as i32))])
|
||||||
// metadata_frame.length,
|
// // });
|
||||||
// CStr::from_ptr(metadata_frame.p_data)
|
// //caps.unwrap().set_simple(&[("framerate", &(20/1 as i32))]);
|
||||||
// .to_string_lossy()
|
// //let mut caps2 = _info.to_caps().unwrap();
|
||||||
// .into_owned(),
|
// // println!("{:?}", caps);
|
||||||
// );
|
// //element.parent_set_caps(&caps.unwrap());
|
||||||
//TODO Change gst_warning to gst_debug
|
// //element.parent_fixate(caps.unwrap());
|
||||||
gst_debug!(self.cat, obj: element, "Received metadata frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned(),);
|
// //gst_video::VideoInfo::from_caps(&caps.unwrap());
|
||||||
}
|
// //self.set_caps(element, &caps.unwrap());
|
||||||
NDIlib_frame_type_e::NDIlib_frame_type_error => {
|
// }
|
||||||
// println!(
|
// else{
|
||||||
// "Tengo error {} '{}'",
|
// // println!("{:?}", video_frame.timecode * 100);
|
||||||
// metadata_frame.length,
|
// // println!("{:?}", pts2.pts);
|
||||||
// CStr::from_ptr(metadata_frame.p_data)
|
// pts = (((video_frame.timestamp as u64) * 100) - pts2.pts);
|
||||||
// .to_string_lossy()
|
// //println!("{:?}", pts/1000000);
|
||||||
// .into_owned(),
|
// }
|
||||||
// );
|
//
|
||||||
//TODO Change gst_warning to gst_debug
|
// }
|
||||||
gst_debug!(self.cat, obj: element, "Received error frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned());
|
// NDIlib_frame_type_e::NDIlib_frame_type_audio => {
|
||||||
// break;
|
// gst_debug!(self.cat, obj: element, "Received audio frame: {:?}", video_frame);
|
||||||
}
|
// }
|
||||||
_ => println!("Tengo {:?}", frame_type),
|
// NDIlib_frame_type_e::NDIlib_frame_type_metadata => {
|
||||||
}
|
// // println!(
|
||||||
}
|
// // "Tengo metadata {} '{}'",
|
||||||
|
// // metadata_frame.length,
|
||||||
|
// // CStr::from_ptr(metadata_frame.p_data)
|
||||||
|
// // .to_string_lossy()
|
||||||
|
// // .into_owned(),
|
||||||
|
// // );
|
||||||
|
// //TODO Change gst_warning to gst_debug
|
||||||
|
// gst_debug!(self.cat, obj: element, "Received metadata frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned(),);
|
||||||
|
// }
|
||||||
|
// NDIlib_frame_type_e::NDIlib_frame_type_error => {
|
||||||
|
// // println!(
|
||||||
|
// // "Tengo error {} '{}'",
|
||||||
|
// // metadata_frame.length,
|
||||||
|
// // CStr::from_ptr(metadata_frame.p_data)
|
||||||
|
// // .to_string_lossy()
|
||||||
|
// // .into_owned(),
|
||||||
|
// // );
|
||||||
|
// //TODO Change gst_warning to gst_debug
|
||||||
|
// gst_debug!(self.cat, obj: element, "Received error frame: {:?}", CStr::from_ptr(metadata_frame.p_data).to_string_lossy().into_owned());
|
||||||
|
// // break;
|
||||||
|
// }
|
||||||
|
// _ => println!("Tengo {:?}", frame_type),
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
let buff_size = (video_frame.yres * video_frame.line_stride_in_bytes) as usize;
|
let buff_size = (video_frame.yres * video_frame.line_stride_in_bytes) as usize;
|
||||||
|
|
Loading…
Reference in a new issue