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

View file

@ -11,7 +11,6 @@ use crate::Context;
use crate::ElementFactory; use crate::ElementFactory;
use crate::Object; use crate::Object;
use crate::Pad; use crate::Pad;
use crate::PadLinkCheck;
use crate::PadTemplate; use crate::PadTemplate;
use crate::State; use crate::State;
use crate::StateChange; use crate::StateChange;
@ -147,42 +146,6 @@ pub trait ElementExt: 'static {
#[doc(alias = "gst_element_is_locked_state")] #[doc(alias = "gst_element_is_locked_state")]
fn is_locked_state(&self) -> bool; 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")] #[doc(alias = "gst_element_lost_state")]
fn lost_state(&self); 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) { fn lost_state(&self) {
unsafe { unsafe {
ffi::gst_element_lost_state(self.as_ref().to_glib_none().0); 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[0].as_ref().to_glib_none().0,
e[1].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 = "get_request_pad")]
#[doc(alias = "gst_element_request_pad_simple")] #[doc(alias = "gst_element_request_pad_simple")]
fn request_pad_simple(&self, name: &str) -> Option<Pad>; 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 { 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 { pub unsafe trait ElementClassExt {