use gstreamer::{ self as gst, prelude::{Cast, ElementExtManual, GstBinExtManual}, ElementFactory, }; use gstreamer_app as gst_app; use crate::config::AppConfig; pub struct Pipeline { pub pipeline: gst::Pipeline, pub sink: gst_app::AppSink, } const HEIGHT: usize = 480; pub fn new_pipeline(config: &AppConfig) -> Pipeline { let pipeline = gst::Pipeline::builder() .name("camera_to_rtp_pipeine") .build(); let source = ElementFactory::make("mfvideosrc").build().unwrap(); let video_convert = ElementFactory::make("videoconvert").build().unwrap(); let video_scale = ElementFactory::make("videoscale") .property("add-borders", true) .build() .unwrap(); let video_scale_caps = gstreamer::Caps::builder("video/x-raw") .field("height", HEIGHT as i32) .field("width", (HEIGHT as f64 * config.aspect_ratio) as i32) .build(); // We are using VP8 because VP9 resulted in much worse video quality // when testing -NY 8/25/2024 let vp8enc = ElementFactory::make("vp8enc").build().unwrap(); let rtp = ElementFactory::make("rtpvp8pay").build().unwrap(); let app_sink = gst_app::AppSink::builder().build(); pipeline .add_many([ &source, &video_convert, &video_scale, &vp8enc, &rtp, app_sink.upcast_ref(), ]) .expect("Could not add all the stuff to the pipeline"); gst::Element::link_many(&[&source, &video_convert, &video_scale]).unwrap(); video_scale .link_filtered(&vp8enc, &video_scale_caps) .expect("Could not link videoscale to vp8enc with caps!"); gst::Element::link_many(&[&vp8enc, &rtp, app_sink.upcast_ref()]).unwrap(); Pipeline { pipeline, sink: app_sink, } }