From 9bb3e75fb9f64b531fa5ac60776c4c934b635e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 22 Jun 2020 11:03:52 +0300 Subject: [PATCH] Update to use the new pad builders for safely setting pad functions Only two uses of unsafely setting the pad functions is left: - fallbacksrc for overriding the chain function of the proxy pad of a ghost pad - threadshare for overriding the pad functions after creationg, which probably needs some fixing at some point --- audio/audiofx/src/audioloudnorm.rs | 55 +-- generic/sodium/src/decrypter.rs | 68 ++-- generic/sodium/src/encrypter.rs | 70 ++-- generic/threadshare/src/runtime/pad.rs | 476 ++++++++++++----------- net/reqwest/tests/reqwesthttpsrc.rs | 29 +- net/rusoto/src/aws_transcribe_parse.rs | 81 ++-- text/wrap/src/gsttextwrap.rs | 33 +- tutorial/src/identity.rs | 104 +++-- tutorial/src/progressbin.rs | 4 +- utils/fallbackswitch/src/fallbacksrc.rs | 45 ++- utils/togglerecord/src/togglerecord.rs | 169 +++++--- video/closedcaption/src/cea608overlay.rs | 44 +-- video/closedcaption/src/cea608tott.rs | 41 +- video/closedcaption/src/mcc_enc.rs | 69 ++-- video/closedcaption/src/mcc_parse.rs | 108 +++-- video/closedcaption/src/scc_enc.rs | 69 ++-- video/closedcaption/src/scc_parse.rs | 69 ++-- video/closedcaption/src/tttocea608.rs | 55 +-- video/flavors/src/flvdemux.rs | 105 +++-- 19 files changed, 872 insertions(+), 822 deletions(-) diff --git a/audio/audiofx/src/audioloudnorm.rs b/audio/audiofx/src/audioloudnorm.rs index 1ea70822..9113111e 100644 --- a/audio/audiofx/src/audioloudnorm.rs +++ b/audio/audiofx/src/audioloudnorm.rs @@ -1746,34 +1746,35 @@ impl ObjectSubclass for AudioLoudNorm { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - sinkpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Self::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |this, element| this.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Self::catch_panic_pad_function( + parent, + || false, + |this, element| this.sink_event(pad, element, event), + ) + }) + .flags(gst::PadFlags::PROXY_CAPS) + .build(); + let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - srcpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); - - sinkpad.set_chain_function(|pad, parent, buffer| { - Self::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |this, element| this.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Self::catch_panic_pad_function( - parent, - || false, - |this, element| this.sink_event(pad, element, event), - ) - }); - - srcpad.set_query_function(|pad, parent, query| { - Self::catch_panic_pad_function( - parent, - || false, - |this, element| this.src_query(pad, element, query), - ) - }); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .query_function(|pad, parent, query| { + Self::catch_panic_pad_function( + parent, + || false, + |this, element| this.src_query(pad, element, query), + ) + }) + .flags(gst::PadFlags::PROXY_CAPS) + .build(); Self { sinkpad, diff --git a/generic/sodium/src/decrypter.rs b/generic/sodium/src/decrypter.rs index a52a83bd..87a8fcbc 100644 --- a/generic/sodium/src/decrypter.rs +++ b/generic/sodium/src/decrypter.rs @@ -269,39 +269,6 @@ struct Decrypter { } impl Decrypter { - fn set_pad_functions(_sinkpad: &gst::Pad, srcpad: &gst::Pad) { - srcpad.set_getrange_function(|pad, parent, offset, buffer, size| { - Decrypter::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |decrypter, element| decrypter.get_range(pad, element, offset, buffer, size), - ) - }); - - srcpad.set_activatemode_function(|pad, parent, mode, active| { - Decrypter::catch_panic_pad_function( - parent, - || { - Err(gst_loggable_error!( - CAT, - "Panic activating srcpad with mode" - )) - }, - |decrypter, element| { - decrypter.src_activatemode_function(pad, element, mode, active) - }, - ) - }); - - srcpad.set_query_function(|pad, parent, query| { - Decrypter::catch_panic_pad_function( - parent, - || false, - |decrypter, element| decrypter.src_query(pad, element, query), - ) - }); - } - fn src_activatemode_function( &self, _pad: &gst::Pad, @@ -597,10 +564,39 @@ impl ObjectSubclass for Decrypter { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - Decrypter::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .getrange_function(|pad, parent, offset, buffer, size| { + Decrypter::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |decrypter, element| decrypter.get_range(pad, element, offset, buffer, size), + ) + }) + .activatemode_function(|pad, parent, mode, active| { + Decrypter::catch_panic_pad_function( + parent, + || { + Err(gst_loggable_error!( + CAT, + "Panic activating srcpad with mode" + )) + }, + |decrypter, element| { + decrypter.src_activatemode_function(pad, element, mode, active) + }, + ) + }) + .query_function(|pad, parent, query| { + Decrypter::catch_panic_pad_function( + parent, + || false, + |decrypter, element| decrypter.src_query(pad, element, query), + ) + }) + .build(); + let props = Mutex::new(Props::default()); let state = Mutex::new(None); diff --git a/generic/sodium/src/encrypter.rs b/generic/sodium/src/encrypter.rs index 129967bd..2acf9906 100644 --- a/generic/sodium/src/encrypter.rs +++ b/generic/sodium/src/encrypter.rs @@ -198,38 +198,6 @@ struct Encrypter { } impl Encrypter { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - Encrypter::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |encrypter, element| encrypter.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Encrypter::catch_panic_pad_function( - parent, - || false, - |encrypter, element| encrypter.sink_event(pad, element, event), - ) - }); - - srcpad.set_query_function(|pad, parent, query| { - Encrypter::catch_panic_pad_function( - parent, - || false, - |encrypter, element| encrypter.src_query(pad, element, query), - ) - }); - srcpad.set_event_function(|pad, parent, event| { - Encrypter::catch_panic_pad_function( - parent, - || false, - |encrypter, element| encrypter.src_event(pad, element, event), - ) - }); - } - fn sink_chain( &self, pad: &gst::Pad, @@ -425,11 +393,41 @@ impl ObjectSubclass for Encrypter { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Encrypter::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |encrypter, element| encrypter.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Encrypter::catch_panic_pad_function( + parent, + || false, + |encrypter, element| encrypter.sink_event(pad, element, event), + ) + }) + .build(); + + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .query_function(|pad, parent, query| { + Encrypter::catch_panic_pad_function( + parent, + || false, + |encrypter, element| encrypter.src_query(pad, element, query), + ) + }) + .event_function(|pad, parent, event| { + Encrypter::catch_panic_pad_function( + parent, + || false, + |encrypter, element| encrypter.src_event(pad, element, event), + ) + }) + .build(); - Encrypter::set_pad_functions(&sinkpad, &srcpad); let props = Mutex::new(Props::default()); let state = Mutex::new(None); diff --git a/generic/threadshare/src/runtime/pad.rs b/generic/threadshare/src/runtime/pad.rs index d42663ef..89e5e01d 100644 --- a/generic/threadshare/src/runtime/pad.rs +++ b/generic/threadshare/src/runtime/pad.rs @@ -385,69 +385,71 @@ impl PadSrc { } fn init_pad_functions(&self, handler: H) { - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.0 - .gst_pad() - .set_activate_function(move |gst_pad, parent| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || { - gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activate"); - Err(gst_loggable_error!(RUNTIME_CAT, "Panic in PadSrc activate")) - }, - move |imp, element| { - let this_ref = PadSrcRef::new(inner_arc); - handler.src_activate(&this_ref, imp, element) - }, - ) - }); + // FIXME: Do this better + unsafe { + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.0 + .gst_pad() + .set_activate_function(move |gst_pad, parent| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || { + gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activate"); + Err(gst_loggable_error!(RUNTIME_CAT, "Panic in PadSrc activate")) + }, + move |imp, element| { + let this_ref = PadSrcRef::new(inner_arc); + handler.src_activate(&this_ref, imp, element) + }, + ) + }); - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_activatemode_function(move |gst_pad, parent, mode, active| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || { - gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activatemode"); - Err(gst_loggable_error!( - RUNTIME_CAT, - "Panic in PadSrc activatemode" - )) - }, - move |imp, element| { - let this_ref = PadSrcRef::new(inner_arc); - this_ref.activate_mode_hook(mode, active)?; - handler.src_activatemode(&this_ref, imp, element, mode, active) - }, - ) - }); + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_activatemode_function(move |gst_pad, parent, mode, active| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || { + gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activatemode"); + Err(gst_loggable_error!( + RUNTIME_CAT, + "Panic in PadSrc activatemode" + )) + }, + move |imp, element| { + let this_ref = PadSrcRef::new(inner_arc); + this_ref.activate_mode_hook(mode, active)?; + handler.src_activatemode(&this_ref, imp, element, mode, active) + }, + ) + }); - // No need to `set_event_function` since `set_event_full_function` - // overrides it and dispatches to `src_event` when necessary - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_event_full_function(move |_gst_pad, parent, event| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || Err(FlowError::Error), - move |imp, element| { - let this_ref = PadSrcRef::new(inner_arc); - handler.src_event_full(&this_ref, imp, &element, event) - }, - ) - }); + // No need to `set_event_function` since `set_event_full_function` + // overrides it and dispatches to `src_event` when necessary + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_event_full_function(move |_gst_pad, parent, event| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || Err(FlowError::Error), + move |imp, element| { + let this_ref = PadSrcRef::new(inner_arc); + handler.src_event_full(&this_ref, imp, &element, event) + }, + ) + }); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() + let inner_arc = Arc::clone(&self.0); + self.gst_pad() .set_query_function(move |_gst_pad, parent, query| { let handler = handler.clone(); let inner_arc = inner_arc.clone(); @@ -465,25 +467,29 @@ impl PadSrc { }, ) }); + } } } impl Drop for PadSrc { fn drop(&mut self) { - self.gst_pad() - .set_activate_function(move |_gst_pad, _parent| { - Err(gst_loggable_error!(RUNTIME_CAT, "PadSrc no longer exists")) - }); - self.gst_pad() - .set_activatemode_function(move |_gst_pad, _parent, _mode, _active| { - Err(gst_loggable_error!(RUNTIME_CAT, "PadSrc no longer exists")) - }); - self.gst_pad() - .set_event_function(move |_gst_pad, _parent, _event| false); - self.gst_pad() - .set_event_full_function(move |_gst_pad, _parent, _event| Err(FlowError::Flushing)); - self.gst_pad() - .set_query_function(move |_gst_pad, _parent, _query| false); + // FIXME: Do this better + unsafe { + self.gst_pad() + .set_activate_function(move |_gst_pad, _parent| { + Err(gst_loggable_error!(RUNTIME_CAT, "PadSrc no longer exists")) + }); + self.gst_pad() + .set_activatemode_function(move |_gst_pad, _parent, _mode, _active| { + Err(gst_loggable_error!(RUNTIME_CAT, "PadSrc no longer exists")) + }); + self.gst_pad() + .set_event_function(move |_gst_pad, _parent, _event| false); + self.gst_pad() + .set_event_full_function(move |_gst_pad, _parent, _event| Err(FlowError::Flushing)); + self.gst_pad() + .set_query_function(move |_gst_pad, _parent, _query| false); + } } } @@ -781,134 +787,64 @@ impl PadSink { } fn init_pad_functions(&self, handler: H) { - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_activate_function(move |gst_pad, parent| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || { - gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activate"); - Err(gst_loggable_error!( - RUNTIME_CAT, - "Panic in PadSink activate" - )) - }, - move |imp, element| { - let this_ref = PadSinkRef::new(inner_arc); - handler.sink_activate(&this_ref, imp, element) - }, - ) - }); - - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_activatemode_function(move |gst_pad, parent, mode, active| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || { - gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activatemode"); - Err(gst_loggable_error!( - RUNTIME_CAT, - "Panic in PadSink activatemode" - )) - }, - move |imp, element| { - let this_ref = PadSinkRef::new(inner_arc); - this_ref.activate_mode_hook(mode, active)?; - - handler.sink_activatemode(&this_ref, imp, element, mode, active) - }, - ) - }); - - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_chain_function(move |_gst_pad, parent, buffer| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || Err(FlowError::Error), - move |imp, element| { - if Context::current_has_sub_tasks() { - let this_weak = PadSinkWeak(Arc::downgrade(&inner_arc)); - let handler = handler.clone(); - let element = element.clone(); - let delayed_fut = async move { - let imp = - ::from_instance(&element); - let this_ref = - this_weak.upgrade().ok_or(gst::FlowError::Flushing)?; - handler.sink_chain(&this_ref, imp, &element, buffer).await - }; - let _ = Context::add_sub_task(delayed_fut.map(|res| res.map(drop))); - - Ok(gst::FlowSuccess::Ok) - } else { + // FIXME: Do this better + unsafe { + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_activate_function(move |gst_pad, parent| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || { + gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activate"); + Err(gst_loggable_error!( + RUNTIME_CAT, + "Panic in PadSink activate" + )) + }, + move |imp, element| { let this_ref = PadSinkRef::new(inner_arc); - let chain_fut = handler.sink_chain(&this_ref, imp, &element, buffer); - this_ref.handle_future(chain_fut) - } - }, - ) - }); + handler.sink_activate(&this_ref, imp, element) + }, + ) + }); - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_chain_list_function(move |_gst_pad, parent, list| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || Err(FlowError::Error), - move |imp, element| { - if Context::current_has_sub_tasks() { - let this_weak = PadSinkWeak(Arc::downgrade(&inner_arc)); - let handler = handler.clone(); - let element = element.clone(); - let delayed_fut = async move { - let imp = - ::from_instance(&element); - let this_ref = - this_weak.upgrade().ok_or(gst::FlowError::Flushing)?; - handler - .sink_chain_list(&this_ref, imp, &element, list) - .await - }; - let _ = Context::add_sub_task(delayed_fut.map(|res| res.map(drop))); - - Ok(gst::FlowSuccess::Ok) - } else { + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_activatemode_function(move |gst_pad, parent, mode, active| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || { + gst_error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activatemode"); + Err(gst_loggable_error!( + RUNTIME_CAT, + "Panic in PadSink activatemode" + )) + }, + move |imp, element| { let this_ref = PadSinkRef::new(inner_arc); - let chain_list_fut = - handler.sink_chain_list(&this_ref, imp, &element, list); - this_ref.handle_future(chain_list_fut) - } - }, - ) - }); + this_ref.activate_mode_hook(mode, active)?; - // No need to `set_event_function` since `set_event_full_function` - // overrides it and dispatches to `sink_event` when necessary - let handler_clone = handler.clone(); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() - .set_event_full_function(move |_gst_pad, parent, event| { - let handler = handler_clone.clone(); - let inner_arc = inner_arc.clone(); - H::ElementImpl::catch_panic_pad_function( - parent, - || Err(FlowError::Error), - move |imp, element| { - if event.is_serialized() { + handler.sink_activatemode(&this_ref, imp, element, mode, active) + }, + ) + }); + + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_chain_function(move |_gst_pad, parent, buffer| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || Err(FlowError::Error), + move |imp, element| { if Context::current_has_sub_tasks() { let this_weak = PadSinkWeak(Arc::downgrade(&inner_arc)); let handler = handler.clone(); @@ -918,9 +854,42 @@ impl PadSink { ::from_instance(&element); let this_ref = this_weak.upgrade().ok_or(gst::FlowError::Flushing)?; + handler.sink_chain(&this_ref, imp, &element, buffer).await + }; + let _ = Context::add_sub_task(delayed_fut.map(|res| res.map(drop))); + Ok(gst::FlowSuccess::Ok) + } else { + let this_ref = PadSinkRef::new(inner_arc); + let chain_fut = + handler.sink_chain(&this_ref, imp, &element, buffer); + this_ref.handle_future(chain_fut) + } + }, + ) + }); + + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_chain_list_function(move |_gst_pad, parent, list| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || Err(FlowError::Error), + move |imp, element| { + if Context::current_has_sub_tasks() { + let this_weak = PadSinkWeak(Arc::downgrade(&inner_arc)); + let handler = handler.clone(); + let element = element.clone(); + let delayed_fut = async move { + let imp = + ::from_instance(&element); + let this_ref = + this_weak.upgrade().ok_or(gst::FlowError::Flushing)?; handler - .sink_event_full_serialized(&this_ref, imp, &element, event) + .sink_chain_list(&this_ref, imp, &element, list) .await }; let _ = Context::add_sub_task(delayed_fut.map(|res| res.map(drop))); @@ -928,20 +897,65 @@ impl PadSink { Ok(gst::FlowSuccess::Ok) } else { let this_ref = PadSinkRef::new(inner_arc); - let event_fut = handler - .sink_event_full_serialized(&this_ref, imp, &element, event); - this_ref.handle_future(event_fut) + let chain_list_fut = + handler.sink_chain_list(&this_ref, imp, &element, list); + this_ref.handle_future(chain_list_fut) } - } else { - let this_ref = PadSinkRef::new(inner_arc); - handler.sink_event_full(&this_ref, imp, &element, event) - } - }, - ) - }); + }, + ) + }); - let inner_arc = Arc::clone(&self.0); - self.gst_pad() + // No need to `set_event_function` since `set_event_full_function` + // overrides it and dispatches to `sink_event` when necessary + let handler_clone = handler.clone(); + let inner_arc = Arc::clone(&self.0); + self.gst_pad() + .set_event_full_function(move |_gst_pad, parent, event| { + let handler = handler_clone.clone(); + let inner_arc = inner_arc.clone(); + H::ElementImpl::catch_panic_pad_function( + parent, + || Err(FlowError::Error), + move |imp, element| { + if event.is_serialized() { + if Context::current_has_sub_tasks() { + let this_weak = PadSinkWeak(Arc::downgrade(&inner_arc)); + let handler = handler.clone(); + let element = element.clone(); + let delayed_fut = async move { + let imp = ::from_instance( + &element, + ); + let this_ref = + this_weak.upgrade().ok_or(gst::FlowError::Flushing)?; + + handler + .sink_event_full_serialized( + &this_ref, imp, &element, event, + ) + .await + }; + let _ = + Context::add_sub_task(delayed_fut.map(|res| res.map(drop))); + + Ok(gst::FlowSuccess::Ok) + } else { + let this_ref = PadSinkRef::new(inner_arc); + let event_fut = handler.sink_event_full_serialized( + &this_ref, imp, &element, event, + ); + this_ref.handle_future(event_fut) + } + } else { + let this_ref = PadSinkRef::new(inner_arc); + handler.sink_event_full(&this_ref, imp, &element, event) + } + }, + ) + }); + + let inner_arc = Arc::clone(&self.0); + self.gst_pad() .set_query_function(move |_gst_pad, parent, query| { let handler = handler.clone(); let inner_arc = inner_arc.clone(); @@ -959,29 +973,33 @@ impl PadSink { }, ) }); + } } } impl Drop for PadSink { fn drop(&mut self) { - self.gst_pad() - .set_activate_function(move |_gst_pad, _parent| { - Err(gst_loggable_error!(RUNTIME_CAT, "PadSink no longer exists")) - }); - self.gst_pad() - .set_activatemode_function(move |_gst_pad, _parent, _mode, _active| { - Err(gst_loggable_error!(RUNTIME_CAT, "PadSink no longer exists")) - }); - self.gst_pad() - .set_chain_function(move |_gst_pad, _parent, _buffer| Err(FlowError::Flushing)); - self.gst_pad() - .set_chain_list_function(move |_gst_pad, _parent, _list| Err(FlowError::Flushing)); - self.gst_pad() - .set_event_function(move |_gst_pad, _parent, _event| false); - self.gst_pad() - .set_event_full_function(move |_gst_pad, _parent, _event| Err(FlowError::Flushing)); - self.gst_pad() - .set_query_function(move |_gst_pad, _parent, _query| false); + // FIXME: Do this better + unsafe { + self.gst_pad() + .set_activate_function(move |_gst_pad, _parent| { + Err(gst_loggable_error!(RUNTIME_CAT, "PadSink no longer exists")) + }); + self.gst_pad() + .set_activatemode_function(move |_gst_pad, _parent, _mode, _active| { + Err(gst_loggable_error!(RUNTIME_CAT, "PadSink no longer exists")) + }); + self.gst_pad() + .set_chain_function(move |_gst_pad, _parent, _buffer| Err(FlowError::Flushing)); + self.gst_pad() + .set_chain_list_function(move |_gst_pad, _parent, _list| Err(FlowError::Flushing)); + self.gst_pad() + .set_event_function(move |_gst_pad, _parent, _event| false); + self.gst_pad() + .set_event_full_function(move |_gst_pad, _parent, _event| Err(FlowError::Flushing)); + self.gst_pad() + .set_query_function(move |_gst_pad, _parent, _query| false); + } } } diff --git a/net/reqwest/tests/reqwesthttpsrc.rs b/net/reqwest/tests/reqwesthttpsrc.rs index 4daa1421..661a3c32 100644 --- a/net/reqwest/tests/reqwesthttpsrc.rs +++ b/net/reqwest/tests/reqwesthttpsrc.rs @@ -65,21 +65,26 @@ impl Harness { let (sender, receiver) = mpsc::sync_channel(0); // Sink pad that receives everything the source is generating - let pad = gst::Pad::new(Some("sink"), gst::PadDirection::Sink); + let pad = gst::Pad::builder(Some("sink"), gst::PadDirection::Sink) + .chain_function({ + let sender_clone = sender.clone(); + move |_pad, _parent, buffer| { + let _ = sender_clone.send(Message::Buffer(buffer)); + Ok(gst::FlowSuccess::Ok) + } + }) + .event_function({ + let sender_clone = sender.clone(); + move |_pad, _parent, event| { + let _ = sender_clone.send(Message::Event(event)); + true + } + }) + .build(); + let srcpad = src.get_static_pad("src").unwrap(); srcpad.link(&pad).unwrap(); - // Collect all buffers, events and messages sent from the source - let sender_clone = sender.clone(); - pad.set_chain_function(move |_pad, _parent, buffer| { - let _ = sender_clone.send(Message::Buffer(buffer)); - Ok(gst::FlowSuccess::Ok) - }); - let sender_clone = sender.clone(); - pad.set_event_function(move |_pad, _parent, event| { - let _ = sender_clone.send(Message::Event(event)); - true - }); let bus = gst::Bus::new(); bus.set_flushing(false); src.set_bus(Some(&bus)); diff --git a/net/rusoto/src/aws_transcribe_parse.rs b/net/rusoto/src/aws_transcribe_parse.rs index 259d8de9..49523814 100644 --- a/net/rusoto/src/aws_transcribe_parse.rs +++ b/net/rusoto/src/aws_transcribe_parse.rs @@ -230,43 +230,6 @@ fn build_packet(payload: &[u8]) -> Vec { } impl Transcriber { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - Transcriber::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |transcriber, element| transcriber.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Transcriber::catch_panic_pad_function( - parent, - || false, - |transcriber, element| transcriber.sink_event(pad, element, event), - ) - }); - - srcpad.set_activatemode_function(|pad, parent, mode, active| { - Transcriber::catch_panic_pad_function( - parent, - || { - Err(gst_loggable_error!( - CAT, - "Panic activating src pad with mode" - )) - }, - |transcriber, element| transcriber.src_activatemode(pad, element, mode, active), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - Transcriber::catch_panic_pad_function( - parent, - || false, - |transcriber, element| transcriber.src_query(pad, element, query), - ) - }); - } - fn dequeue(&self, element: &gst::Element) -> bool { /* First, check our pending buffers */ let mut items = vec![]; @@ -1031,13 +994,47 @@ impl ObjectSubclass for Transcriber { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Transcriber::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |transcriber, element| transcriber.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Transcriber::catch_panic_pad_function( + parent, + || false, + |transcriber, element| transcriber.sink_event(pad, element, event), + ) + }) + .build(); + let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .activatemode_function(|pad, parent, mode, active| { + Transcriber::catch_panic_pad_function( + parent, + || { + Err(gst_loggable_error!( + CAT, + "Panic activating src pad with mode" + )) + }, + |transcriber, element| transcriber.src_activatemode(pad, element, mode, active), + ) + }) + .query_function(|pad, parent, query| { + Transcriber::catch_panic_pad_function( + parent, + || false, + |transcriber, element| transcriber.src_query(pad, element, query), + ) + }) + .flags(gst::PadFlags::FIXED_CAPS) + .build(); - srcpad.use_fixed_caps(); - - Transcriber::set_pad_functions(&sinkpad, &srcpad); let settings = Mutex::new(Settings::default()); Self { diff --git a/text/wrap/src/gsttextwrap.rs b/text/wrap/src/gsttextwrap.rs index 6d9b157b..a9c851cb 100644 --- a/text/wrap/src/gsttextwrap.rs +++ b/text/wrap/src/gsttextwrap.rs @@ -127,16 +127,6 @@ struct TextWrap { } impl TextWrap { - fn set_pad_functions(sinkpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - TextWrap::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |textwrap, element| textwrap.sink_chain(pad, element, buffer), - ) - }); - } - fn update_wrapper(&self, element: &gst::Element) { let settings = self.settings.lock().unwrap(); let mut state = self.state.lock().unwrap(); @@ -279,16 +269,21 @@ impl ObjectSubclass for TextWrap { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - sinkpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + TextWrap::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |textwrap, element| textwrap.sink_chain(pad, element, buffer), + ) + }) + .flags(gst::PadFlags::PROXY_CAPS | gst::PadFlags::FIXED_CAPS) + .build(); + let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - srcpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); - - srcpad.use_fixed_caps(); - sinkpad.use_fixed_caps(); - - TextWrap::set_pad_functions(&sinkpad); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .flags(gst::PadFlags::PROXY_CAPS | gst::PadFlags::FIXED_CAPS) + .build(); let settings = Mutex::new(Settings::default()); let state = Mutex::new(State::default()); diff --git a/tutorial/src/identity.rs b/tutorial/src/identity.rs index ddea99e8..c4d615a9 100644 --- a/tutorial/src/identity.rs +++ b/tutorial/src/identity.rs @@ -29,54 +29,6 @@ static CAT: Lazy = Lazy::new(|| { }); impl Identity { - // After creating of our two pads set all the functions on them - // - // Each function is wrapped in catch_panic_pad_function(), which will - // - Catch panics from the pad functions and instead of aborting the process - // it will simply convert them into an error message and poison the element - // instance - // - Extract our Identity struct from the object instance and pass it to us - // - // Details about what each function is good for is next to each function definition - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - Identity::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |identity, element| identity.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Identity::catch_panic_pad_function( - parent, - || false, - |identity, element| identity.sink_event(pad, element, event), - ) - }); - sinkpad.set_query_function(|pad, parent, query| { - Identity::catch_panic_pad_function( - parent, - || false, - |identity, element| identity.sink_query(pad, element, query), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - Identity::catch_panic_pad_function( - parent, - || false, - |identity, element| identity.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - Identity::catch_panic_pad_function( - parent, - || false, - |identity, element| identity.src_query(pad, element, query), - ) - }); - } - // Called whenever a new buffer is passed to our sink pad. Here buffers should be processed and // whenever some output buffer is available have to push it out of the source pad. // Here we just pass through all buffers directly @@ -173,15 +125,57 @@ impl ObjectSubclass for Identity { // of our struct here and also get the class struct passed in case it's needed fn with_class(klass: &subclass::simple::ClassStruct) -> Self { // Create our two pads from the templates that were registered with - // the class + // the class and set all the functions on them. + // + // Each function is wrapped in catch_panic_pad_function(), which will + // - Catch panics from the pad functions and instead of aborting the process + // it will simply convert them into an error message and poison the element + // instance + // - Extract our Identity struct from the object instance and pass it to us + // + // Details about what each function is good for is next to each function definition let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Identity::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |identity, element| identity.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Identity::catch_panic_pad_function( + parent, + || false, + |identity, element| identity.sink_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + Identity::catch_panic_pad_function( + parent, + || false, + |identity, element| identity.sink_query(pad, element, query), + ) + }) + .build(); - // And then set all our pad functions for handling anything that happens - // on these pads - Identity::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + Identity::catch_panic_pad_function( + parent, + || false, + |identity, element| identity.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + Identity::catch_panic_pad_function( + parent, + || false, + |identity, element| identity.src_query(pad, element, query), + ) + }) + .build(); // Return an instance of our struct and also include our debug category here. // The debug category will be used later whenever we need to put something diff --git a/tutorial/src/progressbin.rs b/tutorial/src/progressbin.rs index ef685ac7..0af0871b 100644 --- a/tutorial/src/progressbin.rs +++ b/tutorial/src/progressbin.rs @@ -88,9 +88,9 @@ impl ObjectSubclass for ProgressBin { // // We do that and adding the pads inside glib::Object::constructed() later. let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::GhostPad::new_no_target_from_template(Some("sink"), &templ).unwrap(); + let sinkpad = gst::GhostPad::from_template(&templ, Some("sink")); let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::GhostPad::new_no_target_from_template(Some("src"), &templ).unwrap(); + let srcpad = gst::GhostPad::from_template(&templ, Some("src")); // Create the progressreport element. let progress = gst::ElementFactory::make("progressreport", Some("progress")).unwrap(); diff --git a/utils/fallbackswitch/src/fallbacksrc.rs b/utils/fallbackswitch/src/fallbacksrc.rs index 9883bb32..1a9325c4 100644 --- a/utils/fallbackswitch/src/fallbacksrc.rs +++ b/utils/fallbackswitch/src/fallbacksrc.rs @@ -704,7 +704,11 @@ impl FallbackSrc { }; input - .add_pad(&gst::GhostPad::new(Some("src"), &srcpad).unwrap()) + .add_pad( + &gst::GhostPad::builder(Some("src"), gst::PadDirection::Src) + .build_with_target(&srcpad) + .unwrap(), + ) .unwrap(); Ok(input.upcast()) @@ -724,7 +728,11 @@ impl FallbackSrc { let srcpad = audiotestsrc.get_static_pad("src").unwrap(); input - .add_pad(&gst::GhostPad::new(Some("src"), &srcpad).unwrap()) + .add_pad( + &gst::GhostPad::builder(Some("src"), gst::PadDirection::Src) + .build_with_target(&srcpad) + .unwrap(), + ) .unwrap(); Ok(input.upcast()) @@ -772,22 +780,27 @@ impl FallbackSrc { let templ = element .get_pad_template(if is_audio { "audio" } else { "video" }) .unwrap(); - let ghostpad = - gst::GhostPad::from_template(Some(&templ.get_name()), &srcpad, &templ).unwrap(); - - element.add_pad(&ghostpad).unwrap(); + let ghostpad = gst::GhostPad::builder_with_template(&templ, Some(&templ.get_name())) + .build_with_target(&srcpad) + .unwrap(); let proxypad = ghostpad.get_internal().expect("no internal pad"); let element_weak = element.downgrade(); - proxypad.set_chain_function(move |pad, _parent, buffer| { - let element = match element_weak.upgrade() { - None => return Err(gst::FlowError::Flushing), - Some(element) => element, - }; + // Safety: Nothing else can have a reference to the proxy pad yet apart from the ghost pad + // itself, so changing the chain function is still safe. + unsafe { + proxypad.set_chain_function(move |pad, _parent, buffer| { + let element = match element_weak.upgrade() { + None => return Err(gst::FlowError::Flushing), + Some(element) => element, + }; - let src = FallbackSrc::from_instance(&element); - src.proxy_pad_chain(&element, pad, buffer) - }); + let src = FallbackSrc::from_instance(&element); + src.proxy_pad_chain(&element, pad, buffer) + }); + } + + element.add_pad(&ghostpad).unwrap(); Ok(Stream { fallback_input, @@ -2215,7 +2228,9 @@ mod custom_source { (element.get_pad_template("video_%u").unwrap(), name) }; - let ghost_pad = gst::GhostPad::from_template(Some(&name), pad, &templ).unwrap(); + let ghost_pad = gst::GhostPad::builder_with_template(&templ, Some(&name)) + .build_with_target(pad) + .unwrap(); let stream = Stream { source_pad: pad.clone(), diff --git a/utils/togglerecord/src/togglerecord.rs b/utils/togglerecord/src/togglerecord.rs index 201fce38..146aa3a0 100644 --- a/utils/togglerecord/src/togglerecord.rs +++ b/utils/togglerecord/src/togglerecord.rs @@ -362,59 +362,6 @@ lazy_static! { } impl ToggleRecord { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - ToggleRecord::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |togglerecord, element| togglerecord.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - ToggleRecord::catch_panic_pad_function( - parent, - || false, - |togglerecord, element| togglerecord.sink_event(pad, element, event), - ) - }); - sinkpad.set_query_function(|pad, parent, query| { - ToggleRecord::catch_panic_pad_function( - parent, - || false, - |togglerecord, element| togglerecord.sink_query(pad, element, query), - ) - }); - sinkpad.set_iterate_internal_links_function(|pad, parent| { - ToggleRecord::catch_panic_pad_function( - parent, - || gst::Iterator::from_vec(vec![]), - |togglerecord, element| togglerecord.iterate_internal_links(pad, element), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - ToggleRecord::catch_panic_pad_function( - parent, - || false, - |togglerecord, element| togglerecord.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - ToggleRecord::catch_panic_pad_function( - parent, - || false, - |togglerecord, element| togglerecord.src_query(pad, element, query), - ) - }); - srcpad.set_iterate_internal_links_function(|pad, parent| { - ToggleRecord::catch_panic_pad_function( - parent, - || gst::Iterator::from_vec(vec![]), - |togglerecord, element| togglerecord.iterate_internal_links(pad, element), - ) - }); - } - fn handle_main_stream( &self, element: &gst::Element, @@ -1537,11 +1484,61 @@ impl ObjectSubclass for ToggleRecord { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + ToggleRecord::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |togglerecord, element| togglerecord.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.sink_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.sink_query(pad, element, query), + ) + }) + .iterate_internal_links_function(|pad, parent| { + ToggleRecord::catch_panic_pad_function( + parent, + || gst::Iterator::from_vec(vec![]), + |togglerecord, element| togglerecord.iterate_internal_links(pad, element), + ) + }) + .build(); - ToggleRecord::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.src_query(pad, element, query), + ) + }) + .iterate_internal_links_function(|pad, parent| { + ToggleRecord::catch_panic_pad_function( + parent, + || gst::Iterator::from_vec(vec![]), + |togglerecord, element| togglerecord.iterate_internal_links(pad, element), + ) + }) + .build(); let main_stream = Stream::new(sinkpad, srcpad); @@ -1734,12 +1731,62 @@ impl ElementImpl for ToggleRecord { *pad_count += 1; let templ = element.get_pad_template("sink_%u").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some(format!("sink_{}", id).as_str())); + let sinkpad = + gst::Pad::builder_with_template(&templ, Some(format!("sink_{}", id).as_str())) + .chain_function(|pad, parent, buffer| { + ToggleRecord::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |togglerecord, element| togglerecord.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.sink_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.sink_query(pad, element, query), + ) + }) + .iterate_internal_links_function(|pad, parent| { + ToggleRecord::catch_panic_pad_function( + parent, + || gst::Iterator::from_vec(vec![]), + |togglerecord, element| togglerecord.iterate_internal_links(pad, element), + ) + }) + .build(); let templ = element.get_pad_template("src_%u").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some(format!("src_{}", id).as_str())); - - ToggleRecord::set_pad_functions(&sinkpad, &srcpad); + let srcpad = gst::Pad::builder_with_template(&templ, Some(format!("src_{}", id).as_str())) + .event_function(|pad, parent, event| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + ToggleRecord::catch_panic_pad_function( + parent, + || false, + |togglerecord, element| togglerecord.src_query(pad, element, query), + ) + }) + .iterate_internal_links_function(|pad, parent| { + ToggleRecord::catch_panic_pad_function( + parent, + || gst::Iterator::from_vec(vec![]), + |togglerecord, element| togglerecord.iterate_internal_links(pad, element), + ) + }) + .build(); sinkpad.set_active(true).unwrap(); srcpad.set_active(true).unwrap(); diff --git a/video/closedcaption/src/cea608overlay.rs b/video/closedcaption/src/cea608overlay.rs index f39cb51c..f9cd95ef 100644 --- a/video/closedcaption/src/cea608overlay.rs +++ b/video/closedcaption/src/cea608overlay.rs @@ -75,23 +75,6 @@ struct Cea608Overlay { } impl Cea608Overlay { - fn set_pad_functions(sinkpad: &gst::Pad, _srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - Cea608Overlay::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |overlay, element| overlay.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Cea608Overlay::catch_panic_pad_function( - parent, - || false, - |overlay, element| overlay.sink_event(pad, element, event), - ) - }); - } - // FIXME: we want to render the text in the largest 32 x 15 characters // that will fit the viewport. This is a truly terrible way to determine // the appropriate font size, but we only need to run that on resolution @@ -413,13 +396,28 @@ impl ObjectSubclass for Cea608Overlay { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - sinkpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - srcpad.set_pad_flags(gst::PadFlags::PROXY_CAPS); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Cea608Overlay::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |overlay, element| overlay.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Cea608Overlay::catch_panic_pad_function( + parent, + || false, + |overlay, element| overlay.sink_event(pad, element, event), + ) + }) + .flags(gst::PadFlags::PROXY_CAPS) + .build(); - Cea608Overlay::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .flags(gst::PadFlags::PROXY_CAPS) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/cea608tott.rs b/video/closedcaption/src/cea608tott.rs index 2fdf7a7e..b235b7e5 100644 --- a/video/closedcaption/src/cea608tott.rs +++ b/video/closedcaption/src/cea608tott.rs @@ -379,27 +379,28 @@ impl ObjectSubclass for Cea608ToTt { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + Cea608ToTt::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |this, element| this.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + Cea608ToTt::catch_panic_pad_function( + parent, + || false, + |this, element| this.sink_event(pad, element, event), + ) + }) + .flags(gst::PadFlags::FIXED_CAPS) + .build(); + let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - - sinkpad.set_chain_function(|pad, parent, buffer| { - Cea608ToTt::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |this, element| this.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - Cea608ToTt::catch_panic_pad_function( - parent, - || false, - |this, element| this.sink_event(pad, element, event), - ) - }); - - sinkpad.use_fixed_caps(); - srcpad.use_fixed_caps(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .flags(gst::PadFlags::FIXED_CAPS) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/mcc_enc.rs b/video/closedcaption/src/mcc_enc.rs index b4241372..7a9fdfa1 100644 --- a/video/closedcaption/src/mcc_enc.rs +++ b/video/closedcaption/src/mcc_enc.rs @@ -105,38 +105,6 @@ lazy_static! { } impl MccEnc { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - MccEnc::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |enc, element| enc.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - MccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.sink_event(pad, element, event), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - MccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - MccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.src_query(pad, element, query), - ) - }); - } - #[allow(clippy::write_with_newline)] fn generate_headers(&self, _state: &State, buffer: &mut Vec) -> Result<(), gst::FlowError> { let settings = self.settings.lock().unwrap(); @@ -502,11 +470,40 @@ impl ObjectSubclass for MccEnc { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + MccEnc::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |enc, element| enc.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + MccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.sink_event(pad, element, event), + ) + }) + .build(); - MccEnc::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + MccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + MccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.src_query(pad, element, query), + ) + }) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/mcc_parse.rs b/video/closedcaption/src/mcc_parse.rs index ef7ea3d8..9be176b5 100644 --- a/video/closedcaption/src/mcc_parse.rs +++ b/video/closedcaption/src/mcc_parse.rs @@ -367,58 +367,6 @@ impl AsMut<[u8]> for OffsetVec { } impl MccParse { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_activate_function(|pad, parent| { - MccParse::catch_panic_pad_function( - parent, - || Err(gst_loggable_error!(CAT, "Panic activating sink pad")), - |parse, element| parse.sink_activate(pad, element), - ) - }); - - sinkpad.set_activatemode_function(|pad, parent, mode, active| { - MccParse::catch_panic_pad_function( - parent, - || { - Err(gst_loggable_error!( - CAT, - "Panic activating sink pad with mode" - )) - }, - |parse, element| parse.sink_activatemode(pad, element, mode, active), - ) - }); - sinkpad.set_chain_function(|pad, parent, buffer| { - MccParse::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |parse, element| parse.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - MccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.sink_event(pad, element, event), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - MccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - MccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.src_query(pad, element, query), - ) - }); - } - fn handle_buffer( &self, element: &gst::Element, @@ -1174,11 +1122,59 @@ impl ObjectSubclass for MccParse { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .activate_function(|pad, parent| { + MccParse::catch_panic_pad_function( + parent, + || Err(gst_loggable_error!(CAT, "Panic activating sink pad")), + |parse, element| parse.sink_activate(pad, element), + ) + }) + .activatemode_function(|pad, parent, mode, active| { + MccParse::catch_panic_pad_function( + parent, + || { + Err(gst_loggable_error!( + CAT, + "Panic activating sink pad with mode" + )) + }, + |parse, element| parse.sink_activatemode(pad, element, mode, active), + ) + }) + .chain_function(|pad, parent, buffer| { + MccParse::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |parse, element| parse.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + MccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.sink_event(pad, element, event), + ) + }) + .build(); - MccParse::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + MccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + MccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.src_query(pad, element, query), + ) + }) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/scc_enc.rs b/video/closedcaption/src/scc_enc.rs index 40bff20b..949c3e4f 100644 --- a/video/closedcaption/src/scc_enc.rs +++ b/video/closedcaption/src/scc_enc.rs @@ -225,38 +225,6 @@ struct SccEnc { } impl SccEnc { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - SccEnc::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |enc, element| enc.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - SccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.sink_event(pad, element, event), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - SccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - SccEnc::catch_panic_pad_function( - parent, - || false, - |enc, element| enc.src_query(pad, element, query), - ) - }); - } - fn sink_chain( &self, pad: &gst::Pad, @@ -370,11 +338,40 @@ impl ObjectSubclass for SccEnc { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + SccEnc::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |enc, element| enc.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + SccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.sink_event(pad, element, event), + ) + }) + .build(); - SccEnc::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + SccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + SccEnc::catch_panic_pad_function( + parent, + || false, + |enc, element| enc.src_query(pad, element, query), + ) + }) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/scc_parse.rs b/video/closedcaption/src/scc_parse.rs index 33f4a74a..36bffa5f 100644 --- a/video/closedcaption/src/scc_parse.rs +++ b/video/closedcaption/src/scc_parse.rs @@ -182,38 +182,6 @@ struct SccParse { } impl SccParse { - fn set_pad_functions(sinkpad: &gst::Pad, srcpad: &gst::Pad) { - sinkpad.set_chain_function(|pad, parent, buffer| { - SccParse::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |parse, element| parse.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - SccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.sink_event(pad, element, event), - ) - }); - - srcpad.set_event_function(|pad, parent, event| { - SccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.src_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - SccParse::catch_panic_pad_function( - parent, - || false, - |parse, element| parse.src_query(pad, element, query), - ) - }); - } - fn handle_buffer( &self, element: &gst::Element, @@ -453,11 +421,40 @@ impl ObjectSubclass for SccParse { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + SccParse::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |parse, element| parse.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + SccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.sink_event(pad, element, event), + ) + }) + .build(); - SccParse::set_pad_functions(&sinkpad, &srcpad); + let templ = klass.get_pad_template("src").unwrap(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .event_function(|pad, parent, event| { + SccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + SccParse::catch_panic_pad_function( + parent, + || false, + |parse, element| parse.src_query(pad, element, query), + ) + }) + .build(); Self { srcpad, diff --git a/video/closedcaption/src/tttocea608.rs b/video/closedcaption/src/tttocea608.rs index 85bc841e..dde0288a 100644 --- a/video/closedcaption/src/tttocea608.rs +++ b/video/closedcaption/src/tttocea608.rs @@ -793,34 +793,35 @@ impl ObjectSubclass for TtToCea608 { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .chain_function(|pad, parent, buffer| { + TtToCea608::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |this, element| this.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + TtToCea608::catch_panic_pad_function( + parent, + || false, + |this, element| this.sink_event(pad, element, event), + ) + }) + .flags(gst::PadFlags::FIXED_CAPS) + .build(); + let templ = klass.get_pad_template("src").unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some("src")); - - sinkpad.set_chain_function(|pad, parent, buffer| { - TtToCea608::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |this, element| this.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - TtToCea608::catch_panic_pad_function( - parent, - || false, - |this, element| this.sink_event(pad, element, event), - ) - }); - srcpad.set_query_function(|pad, parent, query| { - TtToCea608::catch_panic_pad_function( - parent, - || false, - |this, element| this.src_query(pad, element, query), - ) - }); - - sinkpad.use_fixed_caps(); - srcpad.use_fixed_caps(); + let srcpad = gst::Pad::builder_with_template(&templ, Some("src")) + .query_function(|pad, parent, query| { + TtToCea608::catch_panic_pad_function( + parent, + || false, + |this, element| this.src_query(pad, element, query), + ) + }) + .flags(gst::PadFlags::FIXED_CAPS) + .build(); Self { srcpad, diff --git a/video/flavors/src/flvdemux.rs b/video/flavors/src/flvdemux.rs index bba03ad5..d6679264 100644 --- a/video/flavors/src/flvdemux.rs +++ b/video/flavors/src/flvdemux.rs @@ -132,43 +132,41 @@ impl ObjectSubclass for FlvDemux { fn with_class(klass: &subclass::simple::ClassStruct) -> Self { let templ = klass.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::from_template(&templ, Some("sink")); - - sinkpad.set_activate_function(|pad, parent| { - FlvDemux::catch_panic_pad_function( - parent, - || Err(gst_loggable_error!(CAT, "Panic activating sink pad")), - |demux, element| demux.sink_activate(pad, element), - ) - }); - - sinkpad.set_activatemode_function(|pad, parent, mode, active| { - FlvDemux::catch_panic_pad_function( - parent, - || { - Err(gst_loggable_error!( - CAT, - "Panic activating sink pad with mode" - )) - }, - |demux, element| demux.sink_activatemode(pad, element, mode, active), - ) - }); - - sinkpad.set_chain_function(|pad, parent, buffer| { - FlvDemux::catch_panic_pad_function( - parent, - || Err(gst::FlowError::Error), - |demux, element| demux.sink_chain(pad, element, buffer), - ) - }); - sinkpad.set_event_function(|pad, parent, event| { - FlvDemux::catch_panic_pad_function( - parent, - || false, - |demux, element| demux.sink_event(pad, element, event), - ) - }); + let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) + .activate_function(|pad, parent| { + FlvDemux::catch_panic_pad_function( + parent, + || Err(gst_loggable_error!(CAT, "Panic activating sink pad")), + |demux, element| demux.sink_activate(pad, element), + ) + }) + .activatemode_function(|pad, parent, mode, active| { + FlvDemux::catch_panic_pad_function( + parent, + || { + Err(gst_loggable_error!( + CAT, + "Panic activating sink pad with mode" + )) + }, + |demux, element| demux.sink_activatemode(pad, element, mode, active), + ) + }) + .chain_function(|pad, parent, buffer| { + FlvDemux::catch_panic_pad_function( + parent, + || Err(gst::FlowError::Error), + |demux, element| demux.sink_chain(pad, element, buffer), + ) + }) + .event_function(|pad, parent, event| { + FlvDemux::catch_panic_pad_function( + parent, + || false, + |demux, element| demux.sink_event(pad, element, event), + ) + }) + .build(); FlvDemux { sinkpad, @@ -639,23 +637,22 @@ impl FlvDemux { fn create_srcpad(&self, element: &gst::Element, name: &str, caps: &gst::Caps) -> gst::Pad { let templ = element.get_element_class().get_pad_template(name).unwrap(); - let srcpad = gst::Pad::from_template(&templ, Some(name)); - - srcpad.set_event_function(|pad, parent, event| { - FlvDemux::catch_panic_pad_function( - parent, - || false, - |demux, element| demux.src_event(pad, element, event), - ) - }); - - srcpad.set_query_function(|pad, parent, query| { - FlvDemux::catch_panic_pad_function( - parent, - || false, - |demux, element| demux.src_query(pad, element, query), - ) - }); + let srcpad = gst::Pad::builder_with_template(&templ, Some(name)) + .event_function(|pad, parent, event| { + FlvDemux::catch_panic_pad_function( + parent, + || false, + |demux, element| demux.src_event(pad, element, event), + ) + }) + .query_function(|pad, parent, query| { + FlvDemux::catch_panic_pad_function( + parent, + || false, + |demux, element| demux.src_query(pad, element, query), + ) + }) + .build(); srcpad.set_active(true).unwrap();