rtp: add bindings for RTPBasePayload

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1008>
This commit is contained in:
Mathieu Duponchelle 2022-04-07 02:09:44 +02:00 committed by Sebastian Dröge
parent 52ae5e435b
commit 6c57d89e9c
7 changed files with 1501 additions and 1 deletions

View file

@ -30,7 +30,6 @@ manual = [
"Gst.Caps",
"Gst.Element",
"Gst.ElementFactory",
"Gst.Structure",
]
[[object]]
@ -38,6 +37,30 @@ name = "Gst.Buffer"
status = "manual"
ref_mode = "ref"
[[object]]
name = "Gst.BufferList"
status = "manual"
ref_mode = "ref"
[[object]]
name = "Gst.ClockTime"
status = "manual"
conversion_type = "Option"
[[object]]
name = "Gst.FlowReturn"
status = "manual"
must_use = true
[object.conversion_type]
variant = "Result"
ok_type = "gst::FlowSuccess"
err_type = "gst::FlowError"
[[object]]
name = "Gst.Structure"
status = "manual"
ref_mode = "ref"
[[object]]
name = "GstRtp.*"
status = "generate"
@ -56,6 +79,42 @@ status = "generate"
name = "rtp_source_meta_api_get_type"
ignore = true
[[object]]
name = "GstRtp.RTPBasePayload"
status = "generate"
manual_traits = ["RTPHeaderExtensionExtManual"]
[[object.function]]
name = "set_outcaps"
# varargs function
ignore = true
[[object.function]]
name = "push"
# Move buffer
manual = true
[[object.function]]
name = "push_list"
# Move buffer list
manual = true
[[object.function]]
name = "set_outcaps_structure"
# StructureRef instead of Structure
manual = true
rename = "set_outcaps"
[[object.function]]
name = "allocate_output_buffer"
[object.function.return]
nullable_return_is_error = "Failed to allocate output buffer"
[[object.signal]]
name = "request-extension"
[object.signal.return]
nullable = true
[[object]]
name = "GstRtp.RTPBuffer"
status = "manual"

View file

@ -3,6 +3,9 @@
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT
mod rtp_base_payload;
pub use self::rtp_base_payload::RTPBasePayload;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
mod rtp_header_extension;
@ -78,6 +81,7 @@ pub use self::constants::RTP_PAYLOAD_TS48_STRING;
#[doc(hidden)]
pub mod traits {
pub use super::rtp_base_payload::RTPBasePayloadExt;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub use super::rtp_header_extension::RTPHeaderExtensionExt;

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,7 @@ macro_rules! skip_assert_initialized {
#[allow(clippy::match_same_arms)]
#[allow(non_snake_case)]
#[allow(clippy::use_self)]
#[allow(unused_imports)]
mod auto;
pub use crate::auto::functions::*;
pub use crate::auto::*;
@ -38,6 +39,10 @@ pub use crate::rtp_buffer::{compare_seqnum, RTPBuffer};
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub mod rtp_header_extension;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub mod rtp_base_payload;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst_rtp::prelude::*" without getting conflicts
pub mod prelude {
@ -50,4 +55,8 @@ pub mod prelude {
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub use crate::rtp_header_extension::RTPHeaderExtensionExtManual;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub use crate::rtp_base_payload::RTPBasePayloadExtManual;
}

View file

@ -0,0 +1,54 @@
use crate::RTPBasePayload;
use glib::object::IsA;
use glib::translate::*;
use std::ptr;
pub trait RTPBasePayloadExtManual: 'static {
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
#[doc(alias = "gst_rtp_base_payload_set_outcaps_structure")]
#[doc(alias = "gst_rtp_base_payload_set_outcaps")]
fn set_outcaps(&self, s: Option<&gst::StructureRef>) -> Result<(), glib::error::BoolError>;
#[doc(alias = "gst_rtp_base_payload_push")]
fn push(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError>;
#[doc(alias = "gst_rtp_base_payload_push_list")]
fn push_list(&self, list: gst::BufferList) -> Result<gst::FlowSuccess, gst::FlowError>;
}
impl<O: IsA<RTPBasePayload>> RTPBasePayloadExtManual for O {
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
fn set_outcaps(&self, s: Option<&gst::StructureRef>) -> Result<(), glib::error::BoolError> {
unsafe {
glib::result_from_gboolean!(
ffi::gst_rtp_base_payload_set_outcaps_structure(
self.as_ref().to_glib_none().0,
s.as_ref()
.map(|s| s.as_ptr() as *mut _)
.unwrap_or(ptr::null_mut()),
),
"Failed to negotiate by setting outcaps structure"
)
}
}
fn push(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
unsafe {
try_from_glib(ffi::gst_rtp_base_payload_push(
self.as_ref().to_glib_none().0,
buffer.into_ptr(),
))
}
}
fn push_list(&self, list: gst::BufferList) -> Result<gst::FlowSuccess, gst::FlowError> {
unsafe {
try_from_glib(ffi::gst_rtp_base_payload_push_list(
self.as_ref().to_glib_none().0,
list.into_ptr(),
))
}
}
}

View file

@ -2,6 +2,10 @@
#![allow(clippy::cast_ptr_alignment)]
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
mod rtp_base_payload;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
mod rtp_header_extension;
@ -10,6 +14,10 @@ pub mod prelude {
#[doc(hidden)]
pub use gst::subclass::prelude::*;
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub use super::rtp_base_payload::{RTPBasePayloadImpl, RTPBasePayloadImplExt};
#[cfg(any(feature = "v1_20", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))]
pub use super::rtp_header_extension::{RTPHeaderExtensionImpl, RTPHeaderExtensionImplExt};

View file

@ -0,0 +1,311 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::*;
use gst::subclass::prelude::*;
use crate::prelude::*;
use crate::RTPBasePayload;
pub trait RTPBasePayloadImpl: RTPBasePayloadImplExt + ElementImpl {
fn caps(&self, element: &Self::Type, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps {
self.parent_caps(element, pad, filter)
}
fn set_caps(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
self.parent_set_caps(element, caps)
}
fn handle_buffer(
&self,
element: &Self::Type,
buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
self.parent_handle_buffer(element, buffer)
}
fn query(&self, element: &Self::Type, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
RTPBasePayloadImplExt::parent_query(self, element, pad, query)
}
fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool {
self.parent_sink_event(element, event)
}
fn src_event(&self, element: &Self::Type, event: gst::Event) -> bool {
self.parent_src_event(element, event)
}
}
pub trait RTPBasePayloadImplExt: ObjectSubclass {
fn parent_caps(
&self,
element: &Self::Type,
pad: &gst::Pad,
filter: Option<&gst::Caps>,
) -> gst::Caps;
fn parent_set_caps(
&self,
element: &Self::Type,
caps: &gst::Caps,
) -> Result<(), gst::LoggableError>;
fn parent_handle_buffer(
&self,
element: &Self::Type,
buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError>;
fn parent_query(&self, element: &Self::Type, pad: &gst::Pad, query: &mut gst::QueryRef)
-> bool;
fn parent_sink_event(&self, element: &Self::Type, event: gst::Event) -> bool;
fn parent_src_event(&self, element: &Self::Type, event: gst::Event) -> bool;
}
impl<T: RTPBasePayloadImpl> RTPBasePayloadImplExt for T {
fn parent_caps(
&self,
element: &Self::Type,
pad: &gst::Pad,
filter: Option<&gst::Caps>,
) -> gst::Caps {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
let f = (*parent_class)
.get_caps
.expect("Missing parent function `get_caps`");
from_glib_full(f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
pad.to_glib_none().0,
filter.to_glib_none().0,
))
}
}
fn parent_set_caps(
&self,
element: &Self::Type,
caps: &gst::Caps,
) -> Result<(), gst::LoggableError> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
(*parent_class)
.set_caps
.map(|f| {
gst::result_from_gboolean!(
f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
caps.to_glib_none().0
),
gst::CAT_RUST,
"Parent function `set_caps` failed"
)
})
.unwrap_or_else(|| {
// Trigger negotiation as the base class does
element
.unsafe_cast_ref::<RTPBasePayload>()
.set_outcaps(None)
.map_err(|_| gst::loggable_error!(gst::CAT_RUST, "Failed to negotiate"))
})
}
}
fn parent_handle_buffer(
&self,
element: &Self::Type,
buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
(*parent_class)
.handle_buffer
.map(|f| {
try_from_glib(f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
buffer.into_ptr(),
))
})
.unwrap_or(Err(gst::FlowError::Error))
}
}
fn parent_query(
&self,
element: &Self::Type,
pad: &gst::Pad,
query: &mut gst::QueryRef,
) -> bool {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
(*parent_class)
.query
.map(|f| {
from_glib(f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
pad.to_glib_none().0,
query.as_mut_ptr(),
))
})
.unwrap_or(false)
}
}
fn parent_sink_event(&self, element: &Self::Type, event: gst::Event) -> bool {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
(*parent_class)
.sink_event
.map(|f| {
from_glib(f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
event.into_ptr(),
))
})
.unwrap_or(false)
}
}
fn parent_src_event(&self, element: &Self::Type, event: gst::Event) -> bool {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
(*parent_class)
.src_event
.map(|f| {
from_glib(f(
element.unsafe_cast_ref::<RTPBasePayload>().to_glib_none().0,
event.into_ptr(),
))
})
.unwrap_or(false)
}
}
}
unsafe impl<T: RTPBasePayloadImpl> IsSubclassable<T> for RTPBasePayload {
fn class_init(klass: &mut glib::Class<Self>) {
Self::parent_class_init::<T>(klass);
let klass = klass.as_mut();
klass.get_caps = Some(rtp_base_payload_get_caps::<T>);
klass.set_caps = Some(rtp_base_payload_set_caps::<T>);
klass.handle_buffer = Some(rtp_base_payload_handle_buffer::<T>);
klass.query = Some(rtp_base_payload_query::<T>);
klass.sink_event = Some(rtp_base_payload_sink_event::<T>);
klass.src_event = Some(rtp_base_payload_src_event::<T>);
}
}
unsafe extern "C" fn rtp_base_payload_get_caps<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
pad: *mut gst::ffi::GstPad,
filter: *mut gst::ffi::GstCaps,
) -> *mut gst::ffi::GstCaps {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), gst::Caps::new_empty(), {
RTPBasePayloadImpl::caps(
imp,
wrap.unsafe_cast_ref(),
&from_glib_borrow(pad),
Option::<gst::Caps>::from_glib_borrow(filter)
.as_ref()
.as_ref(),
)
})
.to_glib_full()
}
unsafe extern "C" fn rtp_base_payload_set_caps<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
caps: *mut gst::ffi::GstCaps,
) -> glib::ffi::gboolean {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
let caps = from_glib_borrow(caps);
gst::panic_to_error!(&wrap, imp.panicked(), false, {
match imp.set_caps(wrap.unsafe_cast_ref(), &caps) {
Ok(()) => true,
Err(err) => {
err.log_with_object(&*wrap);
false
}
}
})
.into_glib()
}
unsafe extern "C" fn rtp_base_payload_handle_buffer<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
buffer: *mut gst::ffi::GstBuffer,
) -> gst::ffi::GstFlowReturn {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, {
imp.handle_buffer(wrap.unsafe_cast_ref(), from_glib_full(buffer))
.into()
})
.into_glib()
}
unsafe extern "C" fn rtp_base_payload_query<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
pad: *mut gst::ffi::GstPad,
query: *mut gst::ffi::GstQuery,
) -> glib::ffi::gboolean {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), false, {
RTPBasePayloadImpl::query(
imp,
wrap.unsafe_cast_ref(),
&from_glib_borrow(pad),
gst::QueryRef::from_mut_ptr(query),
)
})
.into_glib()
}
unsafe extern "C" fn rtp_base_payload_sink_event<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
event: *mut gst::ffi::GstEvent,
) -> glib::ffi::gboolean {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), false, {
imp.sink_event(wrap.unsafe_cast_ref(), from_glib_full(event))
})
.into_glib()
}
unsafe extern "C" fn rtp_base_payload_src_event<T: RTPBasePayloadImpl>(
ptr: *mut ffi::GstRTPBasePayload,
event: *mut gst::ffi::GstEvent,
) -> glib::ffi::gboolean {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
let wrap: Borrowed<RTPBasePayload> = from_glib_borrow(ptr);
gst::panic_to_error!(&wrap, imp.panicked(), false, {
imp.src_event(wrap.unsafe_cast_ref(), from_glib_full(event))
})
.into_glib()
}