Commit 12400b6b authored by Sebastian Dröge's avatar Sebastian Dröge 🍵
Browse files

Update everything for element factory builder API changes

And set properties as part of object construction wherever it makes
sense.
parent 9ce8e93c
Pipeline #715940 canceled with stages
in 50 seconds
......@@ -37,7 +37,7 @@ fn test_rnnoise_silence_small_buffers() {
}
fn test_rnnoise(audio_info: &gst_audio::AudioInfo, buffer_size: usize) {
let filter = gst::ElementFactory::make("audiornnoise", None).unwrap();
let filter = gst::ElementFactory::make("audiornnoise").build().unwrap();
let mut h = gst_check::Harness::with_element(&filter, Some("sink"), Some("src"));
let sink_caps = audio_info.to_caps().unwrap();
let src_caps = sink_caps.clone();
......
......@@ -27,8 +27,10 @@ fn init() {
}
fn build_harness(src_caps: gst::Caps, sink_caps: gst::Caps) -> (gst_check::Harness, gst::Element) {
let hrtf = gst::ElementFactory::make("hrtfrender", None).unwrap();
hrtf.set_property("hrir-raw", &*CONFIG);
let hrtf = gst::ElementFactory::make("hrtfrender")
.property("hrir-raw", &*CONFIG)
.build()
.unwrap();
let mut h = gst_check::Harness::with_element(&hrtf, Some("sink"), Some("src"));
h.set_caps(src_caps, sink_caps);
......
......@@ -79,8 +79,10 @@ fn create_pipeline() -> Result<gst::Pipeline, Box<dyn Error>> {
let audio_sink = gst::parse_bin_from_description(AUDIO_SINK, true)?.upcast();
let csoundfilter = gst::ElementFactory::make("csoundfilter", None)?;
csoundfilter.set_property("csd-text", &CSD);
let csoundfilter = gst::ElementFactory::make("csoundfilter")
.property("csd-text", &CSD)
.build()
.unwrap();
pipeline.add_many(&[&audio_src, &csoundfilter, &audio_sink])?;
......
......@@ -56,8 +56,10 @@ fn init() {
}
fn build_harness(src_caps: gst::Caps, sink_caps: gst::Caps, csd: &str) -> gst_check::Harness {
let filter = gst::ElementFactory::make("csoundfilter", None).unwrap();
filter.set_property("csd-text", &csd);
let filter = gst::ElementFactory::make("csoundfilter")
.property("csd-text", &csd)
.build()
.unwrap();
let mut h = gst_check::Harness::with_element(&filter, Some("sink"), Some("src"));
......
......@@ -15,7 +15,7 @@ use std::collections::VecDeque;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use anyhow::{anyhow, Error};
use anyhow::Error;
use chrono::{DateTime, Duration, Utc};
use m3u8_rs::{
AlternativeMedia, AlternativeMediaType, MasterPlaylist, MediaPlaylist, MediaSegment,
......@@ -139,11 +139,6 @@ struct AudioStream {
wave: String,
}
pub fn make_element(element: &str, name: Option<&str>) -> Result<gst::Element, Error> {
gst::ElementFactory::make(element, name)
.map_err(|_| anyhow!("Failed to make element {}", element))
}
fn trim_segments(state: &mut StreamState) {
// Arbitrary 5 segments window
while state.segments.len() > 5 {
......@@ -396,13 +391,24 @@ impl VideoStream {
pipeline: &gst::Pipeline,
path: &Path,
) -> Result<(), Error> {
let src = make_element("videotestsrc", None)?;
let raw_capsfilter = make_element("capsfilter", None)?;
let timeoverlay = make_element("timeoverlay", None)?;
let enc = make_element("x264enc", None)?;
let h264_capsfilter = make_element("capsfilter", None)?;
let mux = make_element("cmafmux", None)?;
let appsink = make_element("appsink", None)?;
let src = gst::ElementFactory::make("videotestsrc")
.property("is-live", true)
.build()?;
let raw_capsfilter = gst::ElementFactory::make("capsfilter").build()?;
let timeoverlay = gst::ElementFactory::make("timeoverlay").build()?;
let enc = gst::ElementFactory::make("x264enc")
.property("bframes", 0u32)
.property("bitrate", self.bitrate as u32 / 1000u32)
.property_from_str("tune", "zerolatency")
.build()?;
let h264_capsfilter = gst::ElementFactory::make("capsfilter").build()?;
let mux = gst::ElementFactory::make("cmafmux")
.property("fragment-duration", 2500.mseconds())
.property_from_str("header-update-mode", "update")
.property("write-mehd", true)
.build()?;
let appsink = gst::ElementFactory::make("appsink").build()?;
pipeline.add_many(&[
&src,
......@@ -414,16 +420,6 @@ impl VideoStream {
&appsink,
])?;
gst::Element::link_many(&[
&src,
&raw_capsfilter,
&timeoverlay,
&enc,
&h264_capsfilter,
&mux,
&appsink,
])?;
raw_capsfilter.set_property(
"caps",
gst_video::VideoCapsBuilder::new()
......@@ -441,13 +437,15 @@ impl VideoStream {
.build(),
);
src.set_property("is-live", true);
enc.set_property("bframes", 0u32);
enc.set_property("bitrate", self.bitrate as u32 / 1000u32);
enc.set_property_from_str("tune", "zerolatency");
mux.set_property("fragment-duration", 2500.mseconds());
mux.set_property_from_str("header-update-mode", "update");
mux.set_property("write-mehd", true);
gst::Element::link_many(&[
&src,
&raw_capsfilter,
&timeoverlay,
&enc,
&h264_capsfilter,
&mux,
&appsink,
])?;
probe_encoder(state, enc);
......@@ -466,21 +464,22 @@ impl AudioStream {
pipeline: &gst::Pipeline,
path: &Path,
) -> Result<(), Error> {
let src = make_element("audiotestsrc", None)?;
let enc = make_element("avenc_aac", None)?;
let mux = make_element("cmafmux", None)?;
let appsink = make_element("appsink", None)?;
let src = gst::ElementFactory::make("audiotestsrc")
.property("is-live", true)
.property_from_str("wave", &self.wave)
.property("fragment-duration", 2500.mseconds())
.build()?;
let enc = gst::ElementFactory::make("avenc_aac").build()?;
let mux = gst::ElementFactory::make("cmafmux")
.property_from_str("header-update-mode", "update")
.property("write-mehd", true)
.build()?;
let appsink = gst::ElementFactory::make("appsink").build()?;
pipeline.add_many(&[&src, &enc, &mux, &appsink])?;
gst::Element::link_many(&[&src, &enc, &mux, &appsink])?;
src.set_property("is-live", true);
src.set_property_from_str("wave", &self.wave);
mux.set_property("fragment-duration", 2500.mseconds());
mux.set_property_from_str("header-update-mode", "update");
mux.set_property("write-mehd", true);
probe_encoder(state, enc);
let appsink = appsink.downcast::<gst_app::AppSink>().unwrap();
......
......@@ -14,7 +14,7 @@ use gst::prelude::*;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use anyhow::{anyhow, Error};
use anyhow::Error;
use m3u8_rs::{
AlternativeMedia, AlternativeMediaType, MasterPlaylist, MediaPlaylist, MediaPlaylistType,
......@@ -127,11 +127,6 @@ impl State {
}
}
pub fn make_element(element: &str, name: Option<&str>) -> Result<gst::Element, Error> {
gst::ElementFactory::make(element, name)
.map_err(|_| anyhow!("Failed to make element {}", element))
}
fn setup_appsink(appsink: &gst_app::AppSink, name: &str, path: &Path, is_video: bool) {
let mut path: PathBuf = path.into();
path.push(name);
......@@ -291,13 +286,22 @@ impl VideoStream {
pipeline: &gst::Pipeline,
path: &Path,
) -> Result<(), Error> {
let src = make_element("videotestsrc", None)?;
let raw_capsfilter = make_element("capsfilter", None)?;
let timeoverlay = make_element("timeoverlay", None)?;
let enc = make_element("x264enc", None)?;
let h264_capsfilter = make_element("capsfilter", None)?;
let mux = make_element("cmafmux", None)?;
let appsink = make_element("appsink", None)?;
let src = gst::ElementFactory::make("videotestsrc")
.property("num-buffers", 300)
.build()?;
let raw_capsfilter = gst::ElementFactory::make("capsfilter").build()?;
let timeoverlay = gst::ElementFactory::make("timeoverlay").build()?;
let enc = gst::ElementFactory::make("x264enc")
.property("bframes", 0u32)
.property("bitrate", self.bitrate as u32 / 1000u32)
.build()?;
let h264_capsfilter = gst::ElementFactory::make("capsfilter").build()?;
let mux = gst::ElementFactory::make("cmafmux")
.property("fragment-duration", 2500.mseconds())
.property_from_str("header-update-mode", "update")
.property("write-mehd", true)
.build()?;
let appsink = gst::ElementFactory::make("appsink").build()?;
pipeline.add_many(&[
&src,
......@@ -336,13 +340,6 @@ impl VideoStream {
.build(),
);
src.set_property("num-buffers", 300);
enc.set_property("bframes", 0u32);
enc.set_property("bitrate", self.bitrate as u32 / 1000u32);
mux.set_property("fragment-duration", 2500.mseconds());
mux.set_property_from_str("header-update-mode", "update");
mux.set_property("write-mehd", true);
probe_encoder(state, enc);
let appsink = appsink.downcast::<gst_app::AppSink>().unwrap();
......@@ -360,28 +357,29 @@ impl AudioStream {
pipeline: &gst::Pipeline,
path: &Path,
) -> Result<(), Error> {
let src = make_element("audiotestsrc", None)?;
let raw_capsfilter = make_element("capsfilter", None)?;
let enc = make_element("avenc_aac", None)?;
let mux = make_element("cmafmux", None)?;
let appsink = make_element("appsink", None)?;
let src = gst::ElementFactory::make("audiotestsrc")
.property("num-buffers", 100)
.property("samplesperbuffer", 4410)
.property_from_str("wave", &self.wave)
.build()?;
let raw_capsfilter = gst::ElementFactory::make("capsfilter").build()?;
let enc = gst::ElementFactory::make("avenc_aac").build()?;
let mux = gst::ElementFactory::make("cmafmux")
.property("fragment-duration", 2500.mseconds())
.property_from_str("header-update-mode", "update")
.property("write-mehd", true)
.build()?;
let appsink = gst::ElementFactory::make("appsink").build()?;
pipeline.add_many(&[&src, &raw_capsfilter, &enc, &mux, &appsink])?;
gst::Element::link_many(&[&src, &raw_capsfilter, &enc, &mux, &appsink])?;
src.set_property("num-buffers", 100);
src.set_property("samplesperbuffer", 4410);
src.set_property_from_str("wave", &self.wave);
raw_capsfilter.set_property(
"caps",
gst_audio::AudioCapsBuilder::new().rate(44100).build(),
);
mux.set_property("fragment-duration", 2500.mseconds());
mux.set_property_from_str("header-update-mode", "update");
mux.set_property("write-mehd", true);
probe_encoder(state, enc);
let appsink = appsink.downcast::<gst_app::AppSink>().unwrap();
......
......@@ -85,16 +85,20 @@ fn main() -> Result<(), Box<dyn Error>> {
let receiver = &Keys::from_file(&receiver_keys)?;
let sender = &Keys::from_file(&sender_keys)?;
let filesrc = gst::ElementFactory::make("filesrc", None).unwrap();
let decrypter = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
let typefind = gst::ElementFactory::make("typefind", None).unwrap();
let filesink = gst::ElementFactory::make("filesink", None).unwrap();
filesrc.set_property("location", &args.input);
filesink.set_property("location", &args.output);
decrypter.set_property("receiver-key", glib::Bytes::from_owned(receiver.private.0));
decrypter.set_property("sender-key", glib::Bytes::from_owned(sender.public));
let filesrc = gst::ElementFactory::make("filesrc")
.property("location", &args.input)
.build()
.unwrap();
let decrypter = gst::ElementFactory::make("sodiumdecrypter")
.property("receiver-key", glib::Bytes::from_owned(receiver.private.0))
.property("sender-key", glib::Bytes::from_owned(sender.public))
.build()
.unwrap();
let typefind = gst::ElementFactory::make("typefind").build().unwrap();
let filesink = gst::ElementFactory::make("filesink")
.property("location", &args.output)
.build()
.unwrap();
let pipeline = gst::Pipeline::new(Some("test-pipeline"));
pipeline
......
......@@ -89,15 +89,19 @@ fn main() -> Result<(), Box<dyn Error>> {
let receiver = &Keys::from_file(&receiver_keys)?;
let sender = &Keys::from_file(&sender_keys)?;
let filesrc = gst::ElementFactory::make("filesrc", None).unwrap();
let encrypter = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
let filesink = gst::ElementFactory::make("filesink", None).unwrap();
filesrc.set_property("location", &args.input);
filesink.set_property("location", &args.output);
encrypter.set_property("receiver-key", glib::Bytes::from_owned(receiver.public));
encrypter.set_property("sender-key", glib::Bytes::from_owned(sender.private.0));
let filesrc = gst::ElementFactory::make("filesrc")
.property("location", &args.input)
.build()
.unwrap();
let encrypter = gst::ElementFactory::make("sodiumencrypter")
.property("receiver-key", glib::Bytes::from_owned(receiver.public))
.property("sender-key", glib::Bytes::from_owned(sender.private.0))
.build()
.unwrap();
let filesink = gst::ElementFactory::make("filesink")
.property("location", &args.output)
.build()
.unwrap();
let pipeline = gst::Pipeline::new(Some("test-pipeline"));
pipeline
......
......@@ -72,17 +72,21 @@ fn test_pipeline() {
r
};
let filesrc = gst::ElementFactory::make("filesrc", None).unwrap();
filesrc.set_property("location", &input_path.to_str().unwrap());
let filesrc = gst::ElementFactory::make("filesrc")
.property("location", &input_path.to_str().unwrap())
.build()
.unwrap();
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("sender-key", &*SENDER_PUBLIC);
dec.set_property("receiver-key", &*RECEIVER_PRIVATE);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("sender-key", &*SENDER_PUBLIC)
.property("receiver-key", &*RECEIVER_PRIVATE)
.build()
.unwrap();
// the typefind element here is cause the decrypter only supports
// operating in pull mode bu the filesink wants push-mode.
let typefind = gst::ElementFactory::make("typefind", None).unwrap();
let sink = gst::ElementFactory::make("appsink", None).unwrap();
let typefind = gst::ElementFactory::make("typefind").build().unwrap();
let sink = gst::ElementFactory::make("appsink").build().unwrap();
pipeline
.add_many(&[&filesrc, &dec, &typefind, &sink])
......@@ -160,12 +164,16 @@ fn test_pull_range() {
r
};
let filesrc = gst::ElementFactory::make("filesrc", None).unwrap();
filesrc.set_property("location", input_path.to_str().unwrap());
let filesrc = gst::ElementFactory::make("filesrc")
.property("location", input_path.to_str().unwrap())
.build()
.unwrap();
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("sender-key", &*SENDER_PUBLIC);
dec.set_property("receiver-key", &*RECEIVER_PRIVATE);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("sender-key", &*SENDER_PUBLIC)
.property("receiver-key", &*RECEIVER_PRIVATE)
.build()
.unwrap();
pipeline
.add_many(&[&filesrc, &dec])
......@@ -265,33 +273,43 @@ fn test_state_changes() {
// NullToReady without keys provided
{
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
let dec = gst::ElementFactory::make("sodiumdecrypter")
.build()
.unwrap();
assert!(dec.change_state(gst::StateChange::NullToReady).is_err());
// Set only receiver key
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("receiver-key", &*RECEIVER_PRIVATE);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("receiver-key", &*RECEIVER_PRIVATE)
.build()
.unwrap();
assert!(dec.change_state(gst::StateChange::NullToReady).is_err());
// Set only sender key
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("sender-key", &*SENDER_PUBLIC);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("sender-key", &*SENDER_PUBLIC)
.build()
.unwrap();
assert!(dec.change_state(gst::StateChange::NullToReady).is_err());
}
// NullToReady, no nonce provided
{
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("sender-key", &*SENDER_PUBLIC);
dec.set_property("receiver-key", &*RECEIVER_PRIVATE);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("sender-key", &*SENDER_PUBLIC)
.property("receiver-key", &*RECEIVER_PRIVATE)
.build()
.unwrap();
assert!(dec.change_state(gst::StateChange::NullToReady).is_ok());
}
// ReadyToNull
{
let dec = gst::ElementFactory::make("sodiumdecrypter", None).unwrap();
dec.set_property("sender-key", &*SENDER_PUBLIC);
dec.set_property("receiver-key", &*RECEIVER_PRIVATE);
let dec = gst::ElementFactory::make("sodiumdecrypter")
.property("sender-key", &*SENDER_PUBLIC)
.property("receiver-key", &*RECEIVER_PRIVATE)
.build()
.unwrap();
assert!(dec.change_state(gst::StateChange::NullToReady).is_ok());
}
}
......@@ -73,10 +73,12 @@ fn encrypt_file() {
let mut adapter = gst_base::UniqueAdapter::new();
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
enc.set_property("sender-key", &*SENDER_PRIVATE);
enc.set_property("receiver-key", &*RECEIVER_PUBLIC);
enc.set_property("block-size", 1024u32);
let enc = gst::ElementFactory::make("sodiumencrypter")
.property("sender-key", &*SENDER_PRIVATE)
.property("receiver-key", &*RECEIVER_PUBLIC)
.property("block-size", 1024u32)
.build()
.unwrap();
let mut h = gst_check::Harness::with_element(&enc, None, None);
h.add_element_src_pad(&enc.static_pad("src").expect("failed to get src pad"));
......@@ -109,33 +111,43 @@ fn test_state_changes() {
// NullToReady without keys provided
{
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
let enc = gst::ElementFactory::make("sodiumencrypter")
.build()
.unwrap();
assert!(enc.change_state(gst::StateChange::NullToReady).is_err());
// Set only receiver key
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
enc.set_property("receiver-key", &*RECEIVER_PUBLIC);
let enc = gst::ElementFactory::make("sodiumencrypter")
.property("receiver-key", &*RECEIVER_PUBLIC)
.build()
.unwrap();
assert!(enc.change_state(gst::StateChange::NullToReady).is_err());
// Set only sender key
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
enc.set_property("sender-key", &*SENDER_PRIVATE);
let enc = gst::ElementFactory::make("sodiumencrypter")
.property("sender-key", &*SENDER_PRIVATE)
.build()
.unwrap();
assert!(enc.change_state(gst::StateChange::NullToReady).is_err());
}
// NullToReady
{
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
enc.set_property("sender-key", &*SENDER_PRIVATE);
enc.set_property("receiver-key", &*RECEIVER_PUBLIC);
let enc = gst::ElementFactory::make("sodiumencrypter")
.property("sender-key", &*SENDER_PRIVATE)
.property("receiver-key", &*RECEIVER_PUBLIC)
.build()
.unwrap();
assert!(enc.change_state(gst::StateChange::NullToReady).is_ok());
}
// ReadyToNull
{
let enc = gst::ElementFactory::make("sodiumencrypter", None).unwrap();
enc.set_property("sender-key", &*SENDER_PRIVATE);
enc.set_property("receiver-key", &*RECEIVER_PUBLIC);
let enc = gst::ElementFactory::make("sodiumencrypter")
.property("sender-key", &*SENDER_PRIVATE)
.property("receiver-key", &*RECEIVER_PUBLIC)
.build()
.unwrap();
assert!(enc.change_state(gst::StateChange::NullToReady).is_ok());
}
}
......@@ -77,11 +77,13 @@ fn main() {
for i in 0..n_streams {
let build_context = || format!("context-{}", (i as u32) % n_groups);
let sink =
gst::ElementFactory::make("fakesink", Some(format!("sink-{}", i).as_str())).unwrap();
sink.set_property("sync", false);
sink.set_property("async", false);
sink.set_property("signal-handoffs", true);
let sink = gst::ElementFactory::make("fakesink")
.name(format!("sink-{}", i).as_str())
.property("sync", false)
.property("async", false)
.property("signal-handoffs", true)
.build()
.unwrap();
sink.connect(
"handoff",
true,
......@@ -93,22 +95,24 @@ fn main() {
let (source, context) = match source.as_str() {
"udpsrc" => {
let source =
gst::ElementFactory::make("udpsrc", Some(format!("source-{}", i).as_str()))
.unwrap();
source.set_property("port", 40000i32 + i as i32);
source.set_property("retrieve-sender-address", false);
let source = gst::ElementFactory::make("udpsrc")
.name(format!("source-{}", i).as_str())
.property("port", 40000i32 + i as i32)
.property("retrieve-sender-address", false)
.build()
.unwrap();
(source, None)
}
"ts-udpsrc" => {
let context = build_context();
let source =
gst::ElementFactory::make("ts-udpsrc", Some(format!("source-{}", i).as_str()))
.unwrap();
source.set_property("port", 40000i32 + i as i32);
source.set_property("context", &context);
source.set_property("context-wait", wait);
let source = gst::ElementFactory::make("ts-udpsrc")
.name(format!("source-{}", i).as_str())
.property("port", 40000i32 + i as i32)
.property("context", &context)
.property("context-wait", wait)
.build()
.unwrap();
if is_rtp {
source.set_property("caps", &rtp_caps);
......@@ -117,37 +121,34 @@ fn main() {
(source, Some(context))
}
"tcpclientsrc" => {
let source = gst::ElementFactory::make(
"tcpclientsrc",