From 01d3cef73e1403b8d22427f9b48bc9bebfa879c4 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Thu, 9 Mar 2023 11:42:44 +0100 Subject: [PATCH] gstreamer: element: more generic (un)link_many() API No longer enforces to pass an array of references. Part-of: --- examples/src/bin/appsrc.rs | 2 +- examples/src/bin/decodebin.rs | 2 +- examples/src/bin/encodebin.rs | 2 +- examples/src/bin/fd_allocator.rs | 4 ++-- examples/src/bin/overlay-composition.rs | 2 +- examples/src/bin/pango-cairo.rs | 2 +- examples/src/bin/rtpfecclient.rs | 4 ++-- examples/src/bin/rtsp-server-subclass.rs | 2 +- examples/src/bin/toc.rs | 2 +- gstreamer/Cargo.toml | 1 + gstreamer/src/element.rs | 23 +++++++++++++---------- gstreamer/src/subclass/element.rs | 2 +- tutorials/src/bin/basic-tutorial-3.rs | 2 +- tutorials/src/bin/basic-tutorial-7.rs | 6 +++--- tutorials/src/bin/basic-tutorial-8.rs | 9 ++++----- tutorials/src/bin/playback-tutorial-7.rs | 2 +- 16 files changed, 35 insertions(+), 32 deletions(-) diff --git a/examples/src/bin/appsrc.rs b/examples/src/bin/appsrc.rs index 7ef012f27..4901d6846 100644 --- a/examples/src/bin/appsrc.rs +++ b/examples/src/bin/appsrc.rs @@ -50,7 +50,7 @@ fn create_pipeline() -> Result { let sink = gst::ElementFactory::make("autovideosink").build()?; pipeline.add_many([appsrc.upcast_ref(), &videoconvert, &sink])?; - gst::Element::link_many(&[appsrc.upcast_ref(), &videoconvert, &sink])?; + gst::Element::link_many([appsrc.upcast_ref(), &videoconvert, &sink])?; // Our frame counter, that is stored in the mutable environment // of the closure of the need-data callback diff --git a/examples/src/bin/decodebin.rs b/examples/src/bin/decodebin.rs index 3ffb3091e..e07ccc5ea 100644 --- a/examples/src/bin/decodebin.rs +++ b/examples/src/bin/decodebin.rs @@ -71,7 +71,7 @@ fn example_main() -> Result<(), Error> { let decodebin = gst::ElementFactory::make("decodebin").build()?; pipeline.add_many([&src, &decodebin])?; - gst::Element::link_many(&[&src, &decodebin])?; + gst::Element::link_many([&src, &decodebin])?; // Need to move a new reference into the closure. // !!ATTENTION!!: diff --git a/examples/src/bin/encodebin.rs b/examples/src/bin/encodebin.rs index e7003b9fd..268802ca6 100644 --- a/examples/src/bin/encodebin.rs +++ b/examples/src/bin/encodebin.rs @@ -103,7 +103,7 @@ fn example_main() -> Result<(), Error> { // directly link it to our filesink without problems. // The caps of encodebin's src-pad are set after we configured the encoding-profile. // (But filesink doesn't really care about the caps at its input anyway) - gst::Element::link_many(&[&encodebin, &sink])?; + gst::Element::link_many([&encodebin, &sink])?; // Need to move a new reference into the closure. // !!ATTENTION!!: diff --git a/examples/src/bin/fd_allocator.rs b/examples/src/bin/fd_allocator.rs index 803ca20c3..fa298afaf 100644 --- a/examples/src/bin/fd_allocator.rs +++ b/examples/src/bin/fd_allocator.rs @@ -46,7 +46,7 @@ fn create_receiver_pipeline( let sink = gst::ElementFactory::make("autovideosink").build()?; pipeline.add_many([src.upcast_ref(), &filter, &convert, &queue, &sink])?; - gst::Element::link_many(&[src.upcast_ref(), &filter, &convert, &queue, &sink])?; + gst::Element::link_many([src.upcast_ref(), &filter, &convert, &queue, &sink])?; let fd_allocator = gst_allocators::FdAllocator::new(); let video_info = video_info.clone(); @@ -116,7 +116,7 @@ fn create_sender_pipeline( .set_caps(Some(&caps)); pipeline.add_many([&src, &sink])?; - gst::Element::link_many(&[&src, &sink])?; + gst::Element::link_many([&src, &sink])?; let appsink = sink .downcast::() diff --git a/examples/src/bin/overlay-composition.rs b/examples/src/bin/overlay-composition.rs index 4a83cac63..4b55181f1 100644 --- a/examples/src/bin/overlay-composition.rs +++ b/examples/src/bin/overlay-composition.rs @@ -78,7 +78,7 @@ fn create_pipeline() -> Result { let sink = gst::ElementFactory::make("autovideosink").build()?; pipeline.add_many([&src, &overlay, &capsfilter, &videoconvert, &sink])?; - gst::Element::link_many(&[&src, &overlay, &capsfilter, &videoconvert, &sink])?; + gst::Element::link_many([&src, &overlay, &capsfilter, &videoconvert, &sink])?; // The PangoFontMap represents the set of fonts available for a particular rendering system. let fontmap = pangocairo::FontMap::new(); diff --git a/examples/src/bin/pango-cairo.rs b/examples/src/bin/pango-cairo.rs index 05c63bfca..74e807ff2 100644 --- a/examples/src/bin/pango-cairo.rs +++ b/examples/src/bin/pango-cairo.rs @@ -77,7 +77,7 @@ fn create_pipeline() -> Result { let sink = gst::ElementFactory::make("autovideosink").build()?; pipeline.add_many([&src, &overlay, &capsfilter, &videoconvert, &sink])?; - gst::Element::link_many(&[&src, &overlay, &capsfilter, &videoconvert, &sink])?; + gst::Element::link_many([&src, &overlay, &capsfilter, &videoconvert, &sink])?; // The PangoFontMap represents the set of fonts available for a particular rendering system. let fontmap = pangocairo::FontMap::new(); diff --git a/examples/src/bin/rtpfecclient.rs b/examples/src/bin/rtpfecclient.rs index b7848e7c0..afdaef32b 100644 --- a/examples/src/bin/rtpfecclient.rs +++ b/examples/src/bin/rtpfecclient.rs @@ -115,7 +115,7 @@ fn example_main() -> Result<(), Error> { .build()?; pipeline.add_many([&src, &netsim, &rtpbin, &depay, &dec, &conv, &scale, &filter])?; - gst::Element::link_many(&[&depay, &dec, &conv, &scale, &filter])?; + gst::Element::link_many([&depay, &dec, &conv, &scale, &filter])?; match args[1].as_str() { "play" => { @@ -133,7 +133,7 @@ fn example_main() -> Result<(), Error> { .build()?; pipeline.add_many([&enc, &mux, &sink])?; - gst::Element::link_many(&[&filter, &enc, &mux, &sink])?; + gst::Element::link_many([&filter, &enc, &mux, &sink])?; eprintln!("Recording to out.mkv"); } _ => return Err(Error::from(UsageError(args[0].clone()))), diff --git a/examples/src/bin/rtsp-server-subclass.rs b/examples/src/bin/rtsp-server-subclass.rs index 2b22c3d5a..170149603 100644 --- a/examples/src/bin/rtsp-server-subclass.rs +++ b/examples/src/bin/rtsp-server-subclass.rs @@ -138,7 +138,7 @@ mod media_factory { .unwrap(); bin.add_many([&src, &enc, &pay]).unwrap(); - gst::Element::link_many(&[&src, &enc, &pay]).unwrap(); + gst::Element::link_many([&src, &enc, &pay]).unwrap(); Some(bin.upcast()) } diff --git a/examples/src/bin/toc.rs b/examples/src/bin/toc.rs index 4503d1eb4..9bfb1f6cb 100644 --- a/examples/src/bin/toc.rs +++ b/examples/src/bin/toc.rs @@ -35,7 +35,7 @@ fn example_main() { let decodebin = gst::ElementFactory::make("decodebin").build().unwrap(); pipeline.add_many([&src, &decodebin]).unwrap(); - gst::Element::link_many(&[&src, &decodebin]).unwrap(); + gst::Element::link_many([&src, &decodebin]).unwrap(); // Need to move a new reference into the closure. // !!ATTENTION!!: diff --git a/gstreamer/Cargo.toml b/gstreamer/Cargo.toml index 9e61b56db..ccaf186b6 100644 --- a/gstreamer/Cargo.toml +++ b/gstreamer/Cargo.toml @@ -33,6 +33,7 @@ paste = "1.0" pretty-hex = "0.3" thiserror = "1" smallvec = { version = "1.0", features = ["write"] } +itertools = "0.10" [dev-dependencies] ron = "0.8" diff --git a/gstreamer/src/element.rs b/gstreamer/src/element.rs index dc4c36083..22b62e21b 100644 --- a/gstreamer/src/element.rs +++ b/gstreamer/src/element.rs @@ -3,6 +3,7 @@ use std::{ffi::CStr, future::Future, mem, num::NonZeroU64, pin::Pin}; use glib::translate::*; +use itertools::Itertools; use crate::{ format::{ @@ -16,18 +17,20 @@ use crate::{ impl Element { #[doc(alias = "gst_element_link_many")] - pub fn link_many>(elements: &[&E]) -> Result<(), glib::BoolError> { + pub fn link_many( + elements: impl IntoIterator + Clone>, + ) -> Result<(), glib::BoolError> { skip_assert_initialized!(); - for e in elements.windows(2) { + for (src, dest) in elements.into_iter().tuple_windows() { unsafe { glib::result_from_gboolean!( ffi::gst_element_link( - e[0].as_ref().to_glib_none().0, - e[1].as_ref().to_glib_none().0, + src.as_ref().to_glib_none().0, + dest.as_ref().to_glib_none().0, ), "Failed to link elements '{}' and '{}'", - e[0].as_ref().name(), - e[1].as_ref().name(), + src.as_ref().name(), + dest.as_ref().name(), )?; } } @@ -36,13 +39,13 @@ impl Element { } #[doc(alias = "gst_element_unlink_many")] - pub fn unlink_many>(elements: &[&E]) { + pub fn unlink_many(elements: impl IntoIterator + Clone>) { skip_assert_initialized!(); - for e in elements.windows(2) { + for (src, dest) in elements.into_iter().tuple_windows() { unsafe { ffi::gst_element_unlink( - e[0].as_ref().to_glib_none().0, - e[1].as_ref().to_glib_none().0, + src.as_ref().to_glib_none().0, + dest.as_ref().to_glib_none().0, ); } } diff --git a/gstreamer/src/subclass/element.rs b/gstreamer/src/subclass/element.rs index 315a334cb..e906f8dab 100644 --- a/gstreamer/src/subclass/element.rs +++ b/gstreamer/src/subclass/element.rs @@ -735,7 +735,7 @@ mod tests { pipeline .add_many([&src, element.upcast_ref(), &sink]) .unwrap(); - Element::link_many(&[&src, element.upcast_ref(), &sink]).unwrap(); + Element::link_many([&src, element.upcast_ref(), &sink]).unwrap(); pipeline.set_state(crate::State::Playing).unwrap(); let bus = pipeline.bus().unwrap(); diff --git a/tutorials/src/bin/basic-tutorial-3.rs b/tutorials/src/bin/basic-tutorial-3.rs index a91f9da88..b2d8259e4 100644 --- a/tutorials/src/bin/basic-tutorial-3.rs +++ b/tutorials/src/bin/basic-tutorial-3.rs @@ -37,7 +37,7 @@ fn tutorial_main() { pipeline .add_many([&source, &convert, &resample, &sink]) .unwrap(); - gst::Element::link_many(&[&convert, &resample, &sink]).expect("Elements could not be linked."); + gst::Element::link_many([&convert, &resample, &sink]).expect("Elements could not be linked."); // Connect the pad-added signal source.connect_pad_added(move |src, src_pad| { diff --git a/tutorials/src/bin/basic-tutorial-7.rs b/tutorials/src/bin/basic-tutorial-7.rs index 1f64a9085..1c819078f 100644 --- a/tutorials/src/bin/basic-tutorial-7.rs +++ b/tutorials/src/bin/basic-tutorial-7.rs @@ -71,9 +71,9 @@ fn tutorial_main() { ]) .unwrap(); - gst::Element::link_many(&[&audio_source, &tee]).unwrap(); - gst::Element::link_many(&[&audio_queue, &audio_convert, &audio_resample, &audio_sink]).unwrap(); - gst::Element::link_many(&[&video_queue, &visual, &video_convert, &video_sink]).unwrap(); + gst::Element::link_many([&audio_source, &tee]).unwrap(); + gst::Element::link_many([&audio_queue, &audio_convert, &audio_resample, &audio_sink]).unwrap(); + gst::Element::link_many([&video_queue, &visual, &video_convert, &video_sink]).unwrap(); let tee_audio_pad = tee.request_pad_simple("src_%u").unwrap(); println!( diff --git a/tutorials/src/bin/basic-tutorial-8.rs b/tutorials/src/bin/basic-tutorial-8.rs index 436609fa1..689e1d137 100644 --- a/tutorials/src/bin/basic-tutorial-8.rs +++ b/tutorials/src/bin/basic-tutorial-8.rs @@ -127,10 +127,9 @@ fn main() { ]) .unwrap(); - gst::Element::link_many(&[appsrc.upcast_ref(), &tee]).unwrap(); - gst::Element::link_many(&[&audio_queue, &audio_convert1, &audio_resample, &audio_sink]) - .unwrap(); - gst::Element::link_many(&[ + gst::Element::link_many([appsrc.upcast_ref(), &tee]).unwrap(); + gst::Element::link_many([&audio_queue, &audio_convert1, &audio_resample, &audio_sink]).unwrap(); + gst::Element::link_many([ &video_queue, &audio_convert2, &visual, @@ -138,7 +137,7 @@ fn main() { &video_sink, ]) .unwrap(); - gst::Element::link_many(&[&app_queue, appsink.upcast_ref()]).unwrap(); + gst::Element::link_many([&app_queue, appsink.upcast_ref()]).unwrap(); let tee_audio_pad = tee.request_pad_simple("src_%u").unwrap(); println!( diff --git a/tutorials/src/bin/playback-tutorial-7.rs b/tutorials/src/bin/playback-tutorial-7.rs index deba437c3..4c23beed1 100644 --- a/tutorials/src/bin/playback-tutorial-7.rs +++ b/tutorials/src/bin/playback-tutorial-7.rs @@ -29,7 +29,7 @@ fn tutorial_main() -> Result<(), Error> { // Create the sink bin, add the elements and link them let bin = gst::Bin::builder().name("audio_sink_bin").build(); bin.add_many([&equalizer, &convert, &sink]).unwrap(); - gst::Element::link_many(&[&equalizer, &convert, &sink]).expect("Failed to link elements."); + gst::Element::link_many([&equalizer, &convert, &sink]).expect("Failed to link elements."); let pad = equalizer .static_pad("sink")