base: add bindings for GstBaseParse

Fix #157
This commit is contained in:
Guillaume Desmottes 2019-05-25 21:29:04 +02:00
parent e9fbbc2b40
commit c774bd8114
10 changed files with 879 additions and 2 deletions

View file

@ -18,6 +18,7 @@ external_libraries = [
generate = [
"GstBase.PushSrc",
"GstBase.BaseParseFrameFlags",
]
manual = [
@ -32,6 +33,8 @@ manual = [
"Gst.Format",
"Gst.Pad",
"Gst.TypeFindProbability",
"Gst.TagMergeMode",
"GstBase.BaseParseFrame",
]
[[object]]
@ -196,3 +199,33 @@ ref_mode = "ref"
name = "Gst.ClockTime"
status = "manual"
conversion_type = "scalar"
[[object]]
name = "Gst.TagList"
status = "manual"
ref_mode = "ref"
[[object]]
name = "GstBase.BaseParse"
subclassing = true
status = "generate"
[[object.function]]
name = "finish_frame"
ignore = true
[[object.function]]
name = "set_duration"
ignore = true
[[object.function]]
name = "convert_default"
ignore = true
[[object.function]]
name = "set_frame_rate"
ignore = true
# Didn't bind gst_base_parse_frame_{new,init} so not needed
[[object.function]]
name = "push_frame"
ignore = true

View file

@ -0,0 +1,166 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use glib::StaticType;
use glib::Value;
use glib::object::Cast;
use glib::object::IsA;
use glib::signal::SignalHandlerId;
use glib::signal::connect_raw;
use glib::translate::*;
use glib_sys;
use gobject_sys;
use gst;
use gst_base_sys;
use std::boxed::Box as Box_;
use std::mem::transmute;
glib_wrapper! {
pub struct BaseParse(Object<gst_base_sys::GstBaseParse, gst_base_sys::GstBaseParseClass, BaseParseClass>) @extends gst::Element, gst::Object;
match fn {
get_type => || gst_base_sys::gst_base_parse_get_type(),
}
}
unsafe impl Send for BaseParse {}
unsafe impl Sync for BaseParse {}
pub const NONE_BASE_PARSE: Option<&BaseParse> = None;
pub trait BaseParseExt: 'static {
fn add_index_entry(&self, offset: u64, ts: gst::ClockTime, key: bool, force: bool) -> bool;
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn drain(&self);
fn merge_tags(&self, tags: Option<&gst::TagList>, mode: gst::TagMergeMode);
fn set_average_bitrate(&self, bitrate: u32);
fn set_has_timing_info(&self, has_timing: bool);
fn set_infer_ts(&self, infer_ts: bool);
fn set_latency(&self, min_latency: gst::ClockTime, max_latency: gst::ClockTime);
fn set_min_frame_size(&self, min_size: u32);
fn set_passthrough(&self, passthrough: bool);
fn set_pts_interpolation(&self, pts_interpolate: bool);
fn set_syncable(&self, syncable: bool);
fn set_ts_at_offset(&self, offset: usize);
fn get_property_disable_passthrough(&self) -> bool;
fn set_property_disable_passthrough(&self, disable_passthrough: bool);
fn connect_property_disable_passthrough_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
}
impl<O: IsA<BaseParse>> BaseParseExt for O {
fn add_index_entry(&self, offset: u64, ts: gst::ClockTime, key: bool, force: bool) -> bool {
unsafe {
from_glib(gst_base_sys::gst_base_parse_add_index_entry(self.as_ref().to_glib_none().0, offset, ts.to_glib(), key.to_glib(), force.to_glib()))
}
}
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn drain(&self) {
unsafe {
gst_base_sys::gst_base_parse_drain(self.as_ref().to_glib_none().0);
}
}
fn merge_tags(&self, tags: Option<&gst::TagList>, mode: gst::TagMergeMode) {
unsafe {
gst_base_sys::gst_base_parse_merge_tags(self.as_ref().to_glib_none().0, tags.to_glib_none().0, mode.to_glib());
}
}
fn set_average_bitrate(&self, bitrate: u32) {
unsafe {
gst_base_sys::gst_base_parse_set_average_bitrate(self.as_ref().to_glib_none().0, bitrate);
}
}
fn set_has_timing_info(&self, has_timing: bool) {
unsafe {
gst_base_sys::gst_base_parse_set_has_timing_info(self.as_ref().to_glib_none().0, has_timing.to_glib());
}
}
fn set_infer_ts(&self, infer_ts: bool) {
unsafe {
gst_base_sys::gst_base_parse_set_infer_ts(self.as_ref().to_glib_none().0, infer_ts.to_glib());
}
}
fn set_latency(&self, min_latency: gst::ClockTime, max_latency: gst::ClockTime) {
unsafe {
gst_base_sys::gst_base_parse_set_latency(self.as_ref().to_glib_none().0, min_latency.to_glib(), max_latency.to_glib());
}
}
fn set_min_frame_size(&self, min_size: u32) {
unsafe {
gst_base_sys::gst_base_parse_set_min_frame_size(self.as_ref().to_glib_none().0, min_size);
}
}
fn set_passthrough(&self, passthrough: bool) {
unsafe {
gst_base_sys::gst_base_parse_set_passthrough(self.as_ref().to_glib_none().0, passthrough.to_glib());
}
}
fn set_pts_interpolation(&self, pts_interpolate: bool) {
unsafe {
gst_base_sys::gst_base_parse_set_pts_interpolation(self.as_ref().to_glib_none().0, pts_interpolate.to_glib());
}
}
fn set_syncable(&self, syncable: bool) {
unsafe {
gst_base_sys::gst_base_parse_set_syncable(self.as_ref().to_glib_none().0, syncable.to_glib());
}
}
fn set_ts_at_offset(&self, offset: usize) {
unsafe {
gst_base_sys::gst_base_parse_set_ts_at_offset(self.as_ref().to_glib_none().0, offset);
}
}
fn get_property_disable_passthrough(&self) -> bool {
unsafe {
let mut value = Value::from_type(<bool as StaticType>::static_type());
gobject_sys::g_object_get_property(self.to_glib_none().0 as *mut gobject_sys::GObject, b"disable-passthrough\0".as_ptr() as *const _, value.to_glib_none_mut().0);
value.get().unwrap()
}
}
fn set_property_disable_passthrough(&self, disable_passthrough: bool) {
unsafe {
gobject_sys::g_object_set_property(self.to_glib_none().0 as *mut gobject_sys::GObject, b"disable-passthrough\0".as_ptr() as *const _, Value::from(&disable_passthrough).to_glib_none().0);
}
}
fn connect_property_disable_passthrough_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(self.as_ptr() as *mut _, b"notify::disable-passthrough\0".as_ptr() as *const _,
Some(transmute(notify_disable_passthrough_trampoline::<Self, F> as usize)), Box_::into_raw(f))
}
}
}
unsafe extern "C" fn notify_disable_passthrough_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(this: *mut gst_base_sys::GstBaseParse, _param_spec: glib_sys::gpointer, f: glib_sys::gpointer)
where P: IsA<BaseParse> {
let f: &F = &*(f as *const F);
f(&BaseParse::from_glib_borrow(this).unsafe_cast())
}

View file

@ -2,6 +2,34 @@
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use gst_base_sys;
use glib::translate::*;
use gst_base_sys;
bitflags! {
pub struct BaseParseFrameFlags: u32 {
const NONE = 0;
const NEW_FRAME = 1;
const NO_FRAME = 2;
const CLIP = 4;
const DROP = 8;
const QUEUE = 16;
}
}
#[doc(hidden)]
impl ToGlib for BaseParseFrameFlags {
type GlibType = gst_base_sys::GstBaseParseFrameFlags;
fn to_glib(&self) -> gst_base_sys::GstBaseParseFrameFlags {
self.bits()
}
}
#[doc(hidden)]
impl FromGlib<gst_base_sys::GstBaseParseFrameFlags> for BaseParseFrameFlags {
fn from_glib(value: gst_base_sys::GstBaseParseFrameFlags) -> BaseParseFrameFlags {
skip_assert_initialized!();
BaseParseFrameFlags::from_bits_truncate(value)
}
}

View file

@ -19,6 +19,10 @@ pub use self::aggregator_pad::{AggregatorPad, AggregatorPadClass, NONE_AGGREGATO
#[cfg(any(feature = "v1_14", feature = "dox"))]
pub use self::aggregator_pad::AggregatorPadExt;
mod base_parse;
pub use self::base_parse::{BaseParse, BaseParseClass, NONE_BASE_PARSE};
pub use self::base_parse::BaseParseExt;
mod base_sink;
pub use self::base_sink::{BaseSink, BaseSinkClass, NONE_BASE_SINK};
pub use self::base_sink::BaseSinkExt;
@ -34,6 +38,9 @@ pub use self::base_transform::BaseTransformExt;
mod push_src;
pub use self::push_src::{PushSrc, PushSrcClass, NONE_PUSH_SRC};
mod flags;
pub use self::flags::BaseParseFrameFlags;
pub mod functions;
#[doc(hidden)]
@ -42,6 +49,7 @@ pub mod traits {
pub use super::AggregatorExt;
#[cfg(any(feature = "v1_14", feature = "dox"))]
pub use super::AggregatorPadExt;
pub use super::BaseParseExt;
pub use super::BaseSinkExt;
pub use super::BaseSrcExt;
pub use super::BaseTransformExt;

View file

@ -1,2 +1,2 @@
Generated by gir (https://github.com/gtk-rs/gir @ 58cffd4)
Generated by gir (https://github.com/gtk-rs/gir @ f511aae)
from gir-files (https://github.com/gtk-rs/gir-files @ ???)

View file

@ -0,0 +1,142 @@
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib::object::IsA;
use glib::translate::*;
use gst;
use gst::FormattedValue;
use gst_base_sys;
use std::convert::TryFrom;
use std::mem;
use BaseParse;
use BaseParseFrame;
pub trait BaseParseExtManual: 'static {
fn get_sink_pad(&self) -> gst::Pad;
fn get_src_pad(&self) -> gst::Pad;
fn set_duration<V: Into<gst::GenericFormattedValue>>(&self, duration: V, interval: u32);
fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32);
fn convert_default<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
&self,
src_val: V,
) -> Option<U>;
fn convert_default_generic<V: Into<gst::GenericFormattedValue>>(
&self,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue>;
fn finish_frame(
&self,
frame: BaseParseFrame,
size: u32,
) -> Result<gst::FlowSuccess, gst::FlowError>;
}
impl<O: IsA<BaseParse>> BaseParseExtManual for O {
fn get_sink_pad(&self) -> gst::Pad {
unsafe {
let elt: &gst_base_sys::GstBaseParse = &*(self.as_ptr() as *const _);
from_glib_none(elt.sinkpad)
}
}
fn get_src_pad(&self) -> gst::Pad {
unsafe {
let elt: &gst_base_sys::GstBaseParse = &*(self.as_ptr() as *const _);
from_glib_none(elt.srcpad)
}
}
fn set_duration<V: Into<gst::GenericFormattedValue>>(&self, duration: V, interval: u32) {
let duration = duration.into();
unsafe {
gst_base_sys::gst_base_parse_set_duration(
self.as_ref().to_glib_none().0,
duration.get_format().to_glib(),
duration.get_value(),
interval as i32,
);
}
}
fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32) {
let (fps_num, fps_den) = fps.into();
unsafe {
gst_base_sys::gst_base_parse_set_frame_rate(
self.as_ref().to_glib_none().0,
fps_num as u32,
fps_den as u32,
lead_in,
lead_out,
);
}
}
fn convert_default<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
&self,
src_val: V,
) -> Option<U> {
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
let ret = from_glib(gst_base_sys::gst_base_parse_convert_default(
self.as_ref().to_glib_none().0,
src_val.get_format().to_glib(),
src_val.to_raw_value(),
U::get_default_format().to_glib(),
&mut dest_val,
));
if ret {
Some(U::from_raw(U::get_default_format(), dest_val))
} else {
None
}
}
}
fn convert_default_generic<V: Into<gst::GenericFormattedValue>>(
&self,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue> {
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
let ret = from_glib(gst_base_sys::gst_base_parse_convert_default(
self.as_ref().to_glib_none().0,
src_val.get_format().to_glib(),
src_val.to_raw_value(),
dest_format.to_glib(),
&mut dest_val,
));
if ret {
Some(gst::GenericFormattedValue::new(dest_format, dest_val))
} else {
None
}
}
}
fn finish_frame(
&self,
frame: BaseParseFrame,
size: u32,
) -> Result<gst::FlowSuccess, gst::FlowError> {
unsafe {
gst::FlowReturn::from_glib(gst_base_sys::gst_base_parse_finish_frame(
self.as_ref().to_glib_none().0,
frame.to_glib_none().0,
i32::try_from(size).expect("size higher than i32::MAX"),
))
.into_result()
}
}
}

View file

@ -0,0 +1,175 @@
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib::translate::*;
use gst;
use gst::MiniObject;
use gst_base_sys;
use std::convert::TryFrom;
use std::fmt;
use std::marker::PhantomData;
use std::ptr;
use BaseParse;
use BaseParseFrameFlags;
pub struct BaseParseFrame<'a>(
ptr::NonNull<gst_base_sys::GstBaseParseFrame>,
PhantomData<&'a BaseParse>,
);
#[derive(Debug)]
pub enum Overhead {
None,
Frame,
Bytes(u32),
}
#[doc(hidden)]
impl ToGlib for Overhead {
type GlibType = i32;
fn to_glib(&self) -> i32 {
match *self {
Overhead::None => 0,
Overhead::Frame => -1,
Overhead::Bytes(b) => i32::try_from(b).expect("overhead is higher than i32::MAX"),
}
}
}
impl FromGlib<i32> for Overhead {
#[inline]
fn from_glib(val: i32) -> Overhead {
match val {
0 => Overhead::None,
1 => Overhead::Frame,
b if b > 0 => Overhead::Bytes(val as u32),
_ => panic!("overheader is lower than -1"),
}
}
}
#[doc(hidden)]
impl<'a> ::glib::translate::ToGlibPtr<'a, *mut gst_base_sys::GstBaseParseFrame>
for BaseParseFrame<'a>
{
type Storage = &'a Self;
fn to_glib_none(
&'a self,
) -> ::glib::translate::Stash<*mut gst_base_sys::GstBaseParseFrame, Self> {
Stash(self.0.as_ptr(), self)
}
fn to_glib_full(&self) -> *mut gst_base_sys::GstBaseParseFrame {
unimplemented!()
}
}
impl<'a> fmt::Debug for BaseParseFrame<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let mut b = f.debug_struct("BaseParseFrame");
b.field("buffer", &self.get_buffer())
.field("output_buffer", &self.get_output_buffer())
.field("flags", &self.get_flags())
.field("offset", &self.get_offset())
.field("overhead", &self.get_overhead());
b.finish()
}
}
impl<'a> BaseParseFrame<'a> {
#[cfg(feature = "subclassing")]
pub(crate) unsafe fn new(
frame: *mut gst_base_sys::GstBaseParseFrame,
_parse: &'a BaseParse,
) -> BaseParseFrame<'a> {
assert!(!frame.is_null());
BaseParseFrame(ptr::NonNull::new_unchecked(frame), PhantomData)
}
pub fn get_buffer(&self) -> Option<&mut gst::BufferRef> {
unsafe {
let ptr = (*self.to_glib_none().0).buffer;
if ptr.is_null() {
None
} else {
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
ptr as *const gst_sys::GstMiniObject,
));
assert!(writable);
Some(gst::BufferRef::from_mut_ptr(ptr))
}
}
}
pub fn get_output_buffer(&self) -> Option<&mut gst::BufferRef> {
unsafe {
let ptr = (*self.to_glib_none().0).out_buffer;
if ptr.is_null() {
None
} else {
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
ptr as *const gst_sys::GstMiniObject,
));
assert!(writable);
Some(gst::BufferRef::from_mut_ptr(ptr))
}
}
}
pub fn set_output_buffer(&self, output_buffer: gst::Buffer) {
unsafe {
let prev = (*self.to_glib_none().0).out_buffer;
if !prev.is_null() {
gst_sys::gst_mini_object_unref(prev as *mut gst_sys::GstMiniObject);
}
let ptr = output_buffer.into_ptr();
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
ptr as *const gst_sys::GstMiniObject,
));
assert!(writable);
(*self.to_glib_none().0).out_buffer = ptr;
}
}
pub fn get_flags(&self) -> BaseParseFrameFlags {
let flags = unsafe { (*self.to_glib_none().0).flags };
BaseParseFrameFlags::from_bits_truncate(flags)
}
pub fn set_flags(&self, flags: BaseParseFrameFlags) {
unsafe { (*self.to_glib_none().0).flags |= flags.bits() }
}
pub fn unset_flags(&self, flags: BaseParseFrameFlags) {
unsafe { (*self.to_glib_none().0).flags &= !flags.bits() }
}
pub fn get_offset(&self) -> u64 {
unsafe { (*self.to_glib_none().0).offset }
}
pub fn get_overhead(&self) -> Overhead {
unsafe { from_glib((*self.to_glib_none().0).overhead) }
}
pub fn set_overhead(&self, overhead: Overhead) {
unsafe {
(*self.to_glib_none().0).overhead = overhead.to_glib();
}
}
}

View file

@ -14,6 +14,8 @@ extern crate gstreamer_base_sys as gst_base_sys;
extern crate gstreamer_sys as gst_sys;
extern crate libc;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate glib;
@ -26,6 +28,10 @@ macro_rules! assert_initialized_main_thread {
};
}
macro_rules! skip_assert_initialized {
() => {};
}
pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value};
#[allow(clippy::unreadable_literal)]
@ -48,10 +54,14 @@ pub use flow_combiner::*;
mod aggregator;
#[cfg(any(feature = "v1_14", feature = "dox"))]
mod aggregator_pad;
mod base_parse;
mod base_sink;
mod base_src;
mod base_transform;
pub mod base_parse_frame;
pub use base_parse_frame::BaseParseFrame;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts
pub mod prelude {
@ -63,6 +73,8 @@ pub mod prelude {
#[cfg(any(feature = "v1_14", feature = "dox"))]
pub use aggregator_pad::AggregatorPadExtManual;
pub use auto::traits::*;
pub use base_parse::BaseParseExtManual;
pub use base_parse_frame::BaseParseFrame;
pub use base_sink::BaseSinkExtManual;
pub use base_src::BaseSrcExtManual;
pub use base_transform::BaseTransformExtManual;

View file

@ -0,0 +1,311 @@
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib_sys;
use gst_base_sys;
use gst_sys;
use std::convert::TryFrom;
use std::mem;
use glib::translate::*;
use prelude::*;
use glib::subclass::prelude::*;
use gst;
use gst::subclass::prelude::*;
use BaseParse;
use BaseParseClass;
pub trait BaseParseImpl: BaseParseImplExt + ElementImpl + Send + Sync + 'static {
fn start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage> {
self.parent_start(element)
}
fn set_sink_caps(
&self,
element: &BaseParse,
caps: &gst::Caps,
) -> Result<(), gst::ErrorMessage> {
self.parent_set_sink_caps(element, caps)
}
fn handle_frame<'a>(
&'a self,
element: &BaseParse,
frame: BaseParseFrame,
) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
self.parent_handle_frame(element, frame)
}
fn convert<V: Into<gst::GenericFormattedValue>>(
&self,
element: &BaseParse,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue>;
}
pub trait BaseParseImplExt {
fn parent_start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage>;
fn parent_set_sink_caps(
&self,
element: &BaseParse,
caps: &gst::Caps,
) -> Result<(), gst::ErrorMessage>;
fn parent_handle_frame<'a>(
&'a self,
element: &BaseParse,
frame: BaseParseFrame,
) -> Result<(gst::FlowSuccess, u32), gst::FlowError>;
fn parent_convert<V: Into<gst::GenericFormattedValue>>(
&self,
element: &BaseParse,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue>;
}
impl<T: BaseParseImpl + ObjectImpl> BaseParseImplExt for T {
fn parent_start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
(*parent_class)
.start
.map(|f| {
if from_glib(f(element.to_glib_none().0)) {
Ok(())
} else {
Err(gst_error_msg!(
gst::CoreError::StateChange,
["Parent function `start` failed"]
))
}
})
.unwrap_or(Ok(()))
}
}
fn parent_set_sink_caps(
&self,
element: &BaseParse,
caps: &gst::Caps,
) -> Result<(), gst::ErrorMessage> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
(*parent_class)
.set_sink_caps
.map(|f| {
if from_glib(f(element.to_glib_none().0, caps.to_glib_none().0)) {
Ok(())
} else {
Err(gst_error_msg!(
gst::CoreError::StateChange,
["Parent function `set_sink_caps` failed"]
))
}
})
.unwrap_or(Ok(()))
}
}
fn parent_handle_frame<'a>(
&'a self,
element: &'a BaseParse,
frame: BaseParseFrame,
) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
let mut skipsize = 0;
let res = (*parent_class).handle_frame.map(|f| {
let res = gst::FlowReturn::from_glib(f(
element.to_glib_none().0,
frame.to_glib_none().0,
&mut skipsize,
));
(res, skipsize as u32)
});
match res {
Some((res, skipsize)) => {
let res = res.into_result();
Ok((res.unwrap(), skipsize))
}
None => Err(gst::FlowError::Error),
}
}
}
fn parent_convert<V: Into<gst::GenericFormattedValue>>(
&self,
element: &BaseParse,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue> {
unsafe {
let data = self.get_type_data();
let parent_class =
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
let src_val = src_val.into();
let res = (*parent_class).convert.map(|f| {
let mut dest_val = mem::uninitialized();
let res = from_glib(f(
element.to_glib_none().0,
src_val.get_format().to_glib(),
src_val.to_raw_value(),
dest_format.to_glib(),
&mut dest_val,
));
(res, dest_val)
});
match res {
Some((true, dest_val)) => {
Some(gst::GenericFormattedValue::new(dest_format, dest_val))
}
_ => None,
}
}
}
}
unsafe impl<T: ObjectSubclass + BaseParseImpl> IsSubclassable<T> for BaseParseClass
where
<T as ObjectSubclass>::Instance: PanicPoison,
{
fn override_vfuncs(&mut self) {
<gst::ElementClass as IsSubclassable<T>>::override_vfuncs(self);
unsafe {
let klass = &mut *(self as *mut Self as *mut gst_base_sys::GstBaseParseClass);
klass.start = Some(base_parse_start::<T>);
klass.set_sink_caps = Some(base_parse_set_sink_caps::<T>);
klass.handle_frame = Some(base_parse_handle_frame::<T>);
klass.convert = Some(base_parse_convert::<T>);
}
}
}
unsafe extern "C" fn base_parse_start<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstBaseParse,
) -> glib_sys::gboolean
where
T: BaseParseImpl,
T::Instance: PanicPoison,
{
glib_floating_reference_guard!(ptr);
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: BaseParse = from_glib_borrow(ptr);
gst_panic_to_error!(&wrap, &instance.panicked(), false, {
match imp.start(&wrap) {
Ok(()) => true,
Err(err) => {
wrap.post_error_message(&err);
false
}
}
})
.to_glib()
}
unsafe extern "C" fn base_parse_set_sink_caps<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstBaseParse,
caps: *mut gst_sys::GstCaps,
) -> glib_sys::gboolean
where
T: BaseParseImpl,
T::Instance: PanicPoison,
{
glib_floating_reference_guard!(ptr);
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: BaseParse = from_glib_borrow(ptr);
let caps: gst::Caps = from_glib_none(caps);
gst_panic_to_error!(&wrap, &instance.panicked(), false, {
match imp.set_sink_caps(&wrap, &caps) {
Ok(()) => true,
Err(err) => {
wrap.post_error_message(&err);
false
}
}
})
.to_glib()
}
unsafe extern "C" fn base_parse_handle_frame<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstBaseParse,
frame: *mut gst_base_sys::GstBaseParseFrame,
skipsize: *mut i32,
) -> gst_sys::GstFlowReturn
where
T: BaseParseImpl,
T::Instance: PanicPoison,
{
glib_floating_reference_guard!(ptr);
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: BaseParse = from_glib_borrow(ptr);
let wrap_frame = BaseParseFrame::new(frame, &wrap);
let res = gst_panic_to_error!(&wrap, &instance.panicked(), Err(gst::FlowError::Error), {
imp.handle_frame(&wrap, wrap_frame)
});
match res {
Ok((flow, skip)) => {
*skipsize = i32::try_from(skip).expect("skip is higher than i32::MAX");
gst::FlowReturn::from_ok(flow)
}
Err(flow) => gst::FlowReturn::from_error(flow),
}
.to_glib()
}
unsafe extern "C" fn base_parse_convert<T: ObjectSubclass>(
ptr: *mut gst_base_sys::GstBaseParse,
source_format: gst_sys::GstFormat,
source_value: i64,
dest_format: gst_sys::GstFormat,
dest_value: *mut i64,
) -> glib_sys::gboolean
where
T: BaseParseImpl,
T::Instance: PanicPoison,
{
glib_floating_reference_guard!(ptr);
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: BaseParse = from_glib_borrow(ptr);
let source = gst::GenericFormattedValue::new(from_glib(source_format), source_value);
let res = gst_panic_to_error!(&wrap, &instance.panicked(), None, {
imp.convert(&wrap, source, from_glib(dest_format))
});
match res {
Some(dest) => {
*dest_value = dest.to_raw_value();
true
}
_ => false,
}
.to_glib()
}

View file

@ -8,6 +8,7 @@
// except according to those terms.
#![allow(clippy::cast_ptr_alignment)]
pub mod base_parse;
pub mod base_sink;
pub mod base_src;
pub mod base_transform;
@ -24,6 +25,7 @@ pub mod prelude {
pub use super::aggregator::{AggregatorImpl, AggregatorImplExt};
#[cfg(any(feature = "v1_14", feature = "dox"))]
pub use super::aggregator_pad::{AggregatorPadImpl, AggregatorPadImplExt};
pub use super::base_parse::{BaseParseImpl, BaseParseImplExt};
pub use super::base_sink::{BaseSinkImpl, BaseSinkImplExt};
pub use super::base_src::{BaseSrcImpl, BaseSrcImplExt};
pub use super::base_transform::{