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
This commit is contained in:
Sebastian Dröge 2020-06-22 11:03:52 +03:00
parent c917e77687
commit 9bb3e75fb9
19 changed files with 872 additions and 822 deletions

View file

@ -1746,34 +1746,35 @@ impl ObjectSubclass for AudioLoudNorm {
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> 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,

View file

@ -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>) -> 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);

View file

@ -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>) -> 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);

View file

@ -385,69 +385,71 @@ impl PadSrc {
}
fn init_pad_functions<H: PadSrcHandler>(&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<H: PadSinkHandler>(&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 =
<H::ElementImpl as ObjectSubclass>::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 =
<H::ElementImpl as ObjectSubclass>::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 {
<H::ElementImpl as ObjectSubclass>::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 =
<H::ElementImpl as ObjectSubclass>::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 = <H::ElementImpl as ObjectSubclass>::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);
}
}
}

View file

@ -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));

View file

@ -230,43 +230,6 @@ fn build_packet(payload: &[u8]) -> Vec<u8> {
}
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>) -> 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 {

View file

@ -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>) -> 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());

View file

@ -29,54 +29,6 @@ static CAT: Lazy<gst::DebugCategory> = 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>) -> 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

View file

@ -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();

View file

@ -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(),

View file

@ -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<T: HandleData>(
&self,
element: &gst::Element,
@ -1537,11 +1484,61 @@ impl ObjectSubclass for ToggleRecord {
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> 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();

View file

@ -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>) -> 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,

View file

@ -379,27 +379,28 @@ impl ObjectSubclass for Cea608ToTt {
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> 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,

View file

@ -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<u8>) -> 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>) -> 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,

View file

@ -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>) -> 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,

View file

@ -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>) -> 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,

View file

@ -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>) -> 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,

View file

@ -793,34 +793,35 @@ impl ObjectSubclass for TtToCea608 {
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> 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,

View file

@ -132,43 +132,41 @@ impl ObjectSubclass for FlvDemux {
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> 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();