element: Implement linking functions manually for better error reporting

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/318
This commit is contained in:
Sebastian Dröge 2022-10-19 17:57:16 +03:00
parent 7423b1dea6
commit 130cc9d63b
3 changed files with 175 additions and 141 deletions

View file

@ -1038,13 +1038,13 @@ manual_traits = ["ElementExtManual"]
# but gir considers these methods on `ElementExtManual` in the docs.
[[object.function]]
name = "link_many"
ignore = true
manual = true
[[object.function]]
name = "unlink_many"
ignore = true
manual = true
[[object.function]]
name = "register"
ignore = true
manual = true
[[object.function]]
name = "call_async"
@ -1094,38 +1094,34 @@ manual_traits = ["ElementExtManual"]
[object.function.return]
bool_return_is_error = "Failed to remove pad"
# Manual implementations with better error reporting
[[object.function]]
name = "link"
[object.function.return]
bool_return_is_error = "Failed to link elements"
manual = true
[[object.function]]
name = "link_filtered"
manual = true
[[object.function.parameter]]
name = "filter"
# Can use `link` instead
nullable = false
[object.function.return]
bool_return_is_error = "Failed to link elements"
[[object.function]]
name = "link_pads"
[object.function.return]
bool_return_is_error = "Failed to link pads"
manual = true
[[object.function]]
name = "link_pads_filtered"
manual = true
[[object.function.parameter]]
name = "filter"
# Can use `link` instead
nullable = false
[object.function.return]
bool_return_is_error = "Failed to link pads"
[[object.function]]
name = "link_pads_full"
[object.function.return]
bool_return_is_error = "Failed to link pads"
manual = true
[[object.function]]
name = "set_clock"

View file

@ -11,7 +11,6 @@ use crate::Context;
use crate::ElementFactory;
use crate::Object;
use crate::Pad;
use crate::PadLinkCheck;
use crate::PadTemplate;
use crate::State;
use crate::StateChange;
@ -147,42 +146,6 @@ pub trait ElementExt: 'static {
#[doc(alias = "gst_element_is_locked_state")]
fn is_locked_state(&self) -> bool;
#[doc(alias = "gst_element_link")]
fn link(&self, dest: &impl IsA<Element>) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_filtered")]
fn link_filtered(
&self,
dest: &impl IsA<Element>,
filter: &Caps,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads")]
fn link_pads(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads_filtered")]
fn link_pads_filtered(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
filter: &Caps,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads_full")]
fn link_pads_full(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
flags: PadLinkCheck,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_lost_state")]
fn lost_state(&self);
@ -475,96 +438,6 @@ impl<O: IsA<Element>> ElementExt for O {
}
}
fn link(&self, dest: &impl IsA<Element>) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link(
self.as_ref().to_glib_none().0,
dest.as_ref().to_glib_none().0
),
"Failed to link elements"
)
}
}
fn link_filtered(
&self,
dest: &impl IsA<Element>,
filter: &Caps,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_filtered(
self.as_ref().to_glib_none().0,
dest.as_ref().to_glib_none().0,
filter.to_glib_none().0
),
"Failed to link elements"
)
}
}
fn link_pads(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0
),
"Failed to link pads"
)
}
}
fn link_pads_filtered(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
filter: &Caps,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads_filtered(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0,
filter.to_glib_none().0
),
"Failed to link pads"
)
}
}
fn link_pads_full(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
flags: PadLinkCheck,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads_full(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0,
flags.into_glib()
),
"Failed to link pads"
)
}
}
fn lost_state(&self) {
unsafe {
ffi::gst_element_lost_state(self.as_ref().to_glib_none().0);

View file

@ -39,7 +39,9 @@ impl Element {
e[0].as_ref().to_glib_none().0,
e[1].as_ref().to_glib_none().0,
),
"Failed to link elements"
"Failed to link elements '{}' and '{}'",
e[0].as_ref().name(),
e[1].as_ref().name(),
)?;
}
}
@ -268,6 +270,42 @@ pub trait ElementExtManual: 'static {
#[doc(alias = "get_request_pad")]
#[doc(alias = "gst_element_request_pad_simple")]
fn request_pad_simple(&self, name: &str) -> Option<Pad>;
#[doc(alias = "gst_element_link")]
fn link(&self, dest: &impl IsA<Element>) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_filtered")]
fn link_filtered(
&self,
dest: &impl IsA<Element>,
filter: &crate::Caps,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads")]
fn link_pads(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads_filtered")]
fn link_pads_filtered(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
filter: &crate::Caps,
) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_element_link_pads_full")]
fn link_pads_full(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
flags: crate::PadLinkCheck,
) -> Result<(), glib::error::BoolError>;
}
impl<O: IsA<Element>> ElementExtManual for O {
@ -793,6 +831,133 @@ impl<O: IsA<Element>> ElementExtManual for O {
}
}
}
fn link(&self, dest: &impl IsA<Element>) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link(
self.as_ref().to_glib_none().0,
dest.as_ref().to_glib_none().0
),
"Failed to link elements '{}' and '{}'",
self.as_ref().name(),
dest.as_ref().name(),
)
}
}
fn link_filtered(
&self,
dest: &impl IsA<Element>,
filter: &crate::Caps,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_filtered(
self.as_ref().to_glib_none().0,
dest.as_ref().to_glib_none().0,
filter.to_glib_none().0
),
"Failed to link elements '{}' and '{}' with filter '{:?}'",
self.as_ref().name(),
dest.as_ref().name(),
filter,
)
}
}
fn link_pads(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0
),
"Failed to link pads '{}' and '{}'",
if let Some(srcpadname) = srcpadname {
format!("{}:{}", self.as_ref().name(), srcpadname)
} else {
format!("{}:*", self.as_ref().name())
},
if let Some(destpadname) = destpadname {
format!("{}:{}", dest.as_ref().name(), destpadname)
} else {
format!("{}:*", dest.as_ref().name())
},
)
}
}
fn link_pads_filtered(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
filter: &crate::Caps,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads_filtered(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0,
filter.to_glib_none().0
),
"Failed to link pads '{}' and '{}' with filter '{:?}'",
if let Some(srcpadname) = srcpadname {
format!("{}:{}", self.as_ref().name(), srcpadname)
} else {
format!("{}:*", self.as_ref().name())
},
if let Some(destpadname) = destpadname {
format!("{}:{}", dest.as_ref().name(), destpadname)
} else {
format!("{}:*", dest.as_ref().name())
},
filter,
)
}
}
fn link_pads_full(
&self,
srcpadname: Option<&str>,
dest: &impl IsA<Element>,
destpadname: Option<&str>,
flags: crate::PadLinkCheck,
) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_element_link_pads_full(
self.as_ref().to_glib_none().0,
srcpadname.to_glib_none().0,
dest.as_ref().to_glib_none().0,
destpadname.to_glib_none().0,
flags.into_glib()
),
"Failed to link pads '{}' and '{}' with flags '{:?}'",
if let Some(srcpadname) = srcpadname {
format!("{}:{}", self.as_ref().name(), srcpadname)
} else {
format!("{}:*", self.as_ref().name())
},
if let Some(destpadname) = destpadname {
format!("{}:{}", dest.as_ref().name(), destpadname)
} else {
format!("{}:*", dest.as_ref().name())
},
flags,
)
}
}
}
pub unsafe trait ElementClassExt {