mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-05-17 07:42:39 +00:00
fallbackswitch: Remove bundled aggregator copy and require GStreamer 1.18
1.18 is old enough at this point and carrying around a copy of aggregator is not sustainable.
This commit is contained in:
parent
c5d3a2efce
commit
54c8f5b3ab
|
@ -10,7 +10,7 @@ description = "Fallback Switcher Plugin"
|
|||
[dependencies]
|
||||
libc = { version = "0.2", optional = true }
|
||||
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_14"] }
|
||||
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_16"] }
|
||||
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_18"] }
|
||||
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_14"] }
|
||||
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_14"] }
|
||||
gtk = { git = "https://github.com/gtk-rs/gtk3-rs", optional = true }
|
||||
|
@ -33,13 +33,10 @@ required-features = ["gtk", "gio"]
|
|||
|
||||
[build-dependencies]
|
||||
gst-plugin-version-helper = { path="../../version-helper" }
|
||||
cc = "1.0"
|
||||
pkg-config = "0.3"
|
||||
|
||||
[features]
|
||||
default = ["libc"]
|
||||
v1_18 = ["gst-base/v1_18"]
|
||||
v1_20 = ["v1_18", "gst/v1_20"]
|
||||
v1_20 = ["gst/v1_20"]
|
||||
# We already use 1.14 which is new enough for static build
|
||||
static = []
|
||||
capi = []
|
||||
|
|
|
@ -1,38 +1,3 @@
|
|||
fn main() {
|
||||
gst_plugin_version_helper::info();
|
||||
|
||||
if cfg!(feature = "v1_18") {
|
||||
return;
|
||||
}
|
||||
|
||||
let gstreamer = pkg_config::probe_library("gstreamer-1.0").unwrap();
|
||||
let includes = [gstreamer.include_paths];
|
||||
|
||||
let files = ["src/base/gstaggregator.c"];
|
||||
|
||||
let mut build = cc::Build::new();
|
||||
build.include("src/base");
|
||||
|
||||
for f in files.iter() {
|
||||
build.file(f);
|
||||
}
|
||||
|
||||
for p in includes.iter().flatten() {
|
||||
build.include(p);
|
||||
}
|
||||
|
||||
build.define(
|
||||
"PACKAGE_BUGREPORT",
|
||||
"\"https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/new\"",
|
||||
);
|
||||
build.extra_warnings(false);
|
||||
build.define("GstAggregator", "GstAggregatorFallback");
|
||||
build.define("GstAggregatorClass", "GstAggregatorFallbackClass");
|
||||
build.define("GstAggregatorPrivate", "GstAggregatorFallbackPrivate");
|
||||
build.define("GstAggregatorPad", "GstAggregatorFallbackPad");
|
||||
build.define("GstAggregatorPadClass", "GstAggregatorFallbackPadClass");
|
||||
build.define("GstAggregatorPadPrivate", "GstAggregatorFallbackPadPrivate");
|
||||
build.define("GST_BASE_API", "G_GNUC_INTERNAL");
|
||||
|
||||
build.compile("libgstaggregator-c.a");
|
||||
}
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use super::ffi;
|
||||
use super::Aggregator;
|
||||
|
||||
use glib::signal::{connect_raw, SignalHandlerId};
|
||||
use glib::translate::*;
|
||||
use glib::IsA;
|
||||
use glib::Value;
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
||||
use std::boxed::Box as Box_;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
pub trait AggregatorExtManual: 'static {
|
||||
fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams);
|
||||
|
||||
fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
fn min_upstream_latency(&self) -> gst::ClockTime;
|
||||
|
||||
fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime);
|
||||
|
||||
#[doc(alias = "min-upstream-latency")]
|
||||
fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<Aggregator>> AggregatorExtManual for O {
|
||||
fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
|
||||
unsafe {
|
||||
let mut allocator = ptr::null_mut();
|
||||
let mut params = mem::zeroed();
|
||||
ffi::gst_aggregator_get_allocator(
|
||||
self.as_ref().to_glib_none().0,
|
||||
&mut allocator,
|
||||
&mut params,
|
||||
);
|
||||
(from_glib_full(allocator), params.into())
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
try_from_glib(ffi::gst_aggregator_finish_buffer(
|
||||
self.as_ref().to_glib_none().0,
|
||||
buffer.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn min_upstream_latency(&self) -> gst::ClockTime {
|
||||
unsafe {
|
||||
let mut value = Value::from_type(<gst::ClockTime as StaticType>::static_type());
|
||||
glib::gobject_ffi::g_object_get_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"min-upstream-latency\0".as_ptr() as *const _,
|
||||
value.to_glib_none_mut().0,
|
||||
);
|
||||
value
|
||||
.get()
|
||||
.expect("AggregatorExtManual::min_upstream_latency")
|
||||
}
|
||||
}
|
||||
|
||||
fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
|
||||
unsafe {
|
||||
glib::gobject_ffi::g_object_set_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"min-upstream-latency\0".as_ptr() as *const _,
|
||||
Value::from(&min_upstream_latency).to_glib_none().0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_min_upstream_latency_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::min-upstream-latency\0".as_ptr() as *const _,
|
||||
Some(mem::transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_min_upstream_latency_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
|
||||
this: *mut ffi::GstAggregator,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) where
|
||||
P: IsA<Aggregator>,
|
||||
{
|
||||
let f: &F = &*(f as *const F);
|
||||
f(&Aggregator::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use super::ffi;
|
||||
use super::AggregatorPad;
|
||||
|
||||
use glib::object::IsA;
|
||||
use glib::translate::*;
|
||||
use gst::glib;
|
||||
|
||||
pub trait AggregatorPadExtManual: 'static {
|
||||
#[doc(alias = "get_segment")]
|
||||
fn segment(&self) -> gst::Segment;
|
||||
}
|
||||
|
||||
impl<O: IsA<AggregatorPad>> AggregatorPadExtManual for O {
|
||||
fn segment(&self) -> gst::Segment {
|
||||
unsafe {
|
||||
let ptr: &ffi::GstAggregatorPad = &*(self.as_ptr() as *const _);
|
||||
let _guard = super::utils::MutexGuard::lock(&ptr.parent.object.lock);
|
||||
from_glib_none(&ptr.segment as *const gst::ffi::GstSegment)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
// This file was generated by gir (https://github.com/gtk-rs/gir)
|
||||
// from gir-files (https://github.com/gtk-rs/gir-files)
|
||||
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
|
||||
// DO NOT EDIT
|
||||
|
||||
use super::super::ffi;
|
||||
|
||||
use glib::signal::connect_raw;
|
||||
use glib::signal::SignalHandlerId;
|
||||
use glib::translate::*;
|
||||
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
||||
use std::boxed::Box as Box_;
|
||||
use std::mem::transmute;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Aggregator(Object<ffi::GstAggregator, ffi::GstAggregatorClass>) @extends gst::Element, gst::Object;
|
||||
|
||||
match fn {
|
||||
type_ => || ffi::gst_aggregator_get_type(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for Aggregator {}
|
||||
unsafe impl Sync for Aggregator {}
|
||||
|
||||
pub const NONE_AGGREGATOR: Option<&Aggregator> = None;
|
||||
|
||||
pub trait AggregatorExt: 'static {
|
||||
//#[doc(alias = "gst_aggregator_get_allocator")]
|
||||
//#[doc(alias = "get_allocator")]
|
||||
//fn allocator(&self, allocator: /*Ignored*/Option<gst::Allocator>, params: /*Ignored*/gst::AllocationParams);
|
||||
|
||||
#[doc(alias = "gst_aggregator_get_buffer_pool")]
|
||||
#[doc(alias = "get_buffer_pool")]
|
||||
fn buffer_pool(&self) -> Option<gst::BufferPool>;
|
||||
|
||||
#[doc(alias = "gst_aggregator_get_latency")]
|
||||
#[doc(alias = "get_latency")]
|
||||
fn latency(&self) -> Option<gst::ClockTime>;
|
||||
|
||||
#[doc(alias = "gst_aggregator_negotiate")]
|
||||
fn negotiate(&self) -> bool;
|
||||
|
||||
#[doc(alias = "gst_aggregator_set_latency")]
|
||||
fn set_latency(
|
||||
&self,
|
||||
min_latency: gst::ClockTime,
|
||||
max_latency: impl Into<Option<gst::ClockTime>>,
|
||||
);
|
||||
|
||||
#[doc(alias = "gst_aggregator_set_src_caps")]
|
||||
fn set_src_caps(&self, caps: &gst::Caps);
|
||||
|
||||
#[doc(alias = "gst_aggregator_simple_get_next_time")]
|
||||
fn simple_get_next_time(&self) -> Option<gst::ClockTime>;
|
||||
|
||||
#[doc(alias = "start-time")]
|
||||
fn start_time(&self) -> u64;
|
||||
|
||||
#[doc(alias = "start-time")]
|
||||
fn set_start_time(&self, start_time: u64);
|
||||
|
||||
#[doc(alias = "latency")]
|
||||
fn connect_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F)
|
||||
-> SignalHandlerId;
|
||||
|
||||
#[doc(alias = "start-time")]
|
||||
fn connect_start_time_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<Aggregator>> AggregatorExt for O {
|
||||
//fn allocator(&self, allocator: /*Ignored*/Option<gst::Allocator>, params: /*Ignored*/gst::AllocationParams) {
|
||||
// unsafe { TODO: call ffi:gst_aggregator_get_allocator() }
|
||||
//}
|
||||
|
||||
fn buffer_pool(&self) -> Option<gst::BufferPool> {
|
||||
unsafe {
|
||||
from_glib_full(ffi::gst_aggregator_get_buffer_pool(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn latency(&self) -> Option<gst::ClockTime> {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_get_latency(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn negotiate(&self) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_negotiate(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn set_latency(
|
||||
&self,
|
||||
min_latency: gst::ClockTime,
|
||||
max_latency: impl Into<Option<gst::ClockTime>>,
|
||||
) {
|
||||
unsafe {
|
||||
ffi::gst_aggregator_set_latency(
|
||||
self.as_ref().to_glib_none().0,
|
||||
min_latency.into_glib(),
|
||||
max_latency.into().into_glib(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_src_caps(&self, caps: &gst::Caps) {
|
||||
unsafe {
|
||||
ffi::gst_aggregator_set_src_caps(self.as_ref().to_glib_none().0, caps.to_glib_none().0);
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_get_next_time(&self) -> Option<gst::ClockTime> {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_simple_get_next_time(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn start_time(&self) -> u64 {
|
||||
unsafe {
|
||||
let mut value = glib::Value::from_type(<u64 as StaticType>::static_type());
|
||||
glib::gobject_ffi::g_object_get_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"start-time\0".as_ptr() as *const _,
|
||||
value.to_glib_none_mut().0,
|
||||
);
|
||||
value
|
||||
.get()
|
||||
.expect("Return Value for property `start-time` getter")
|
||||
}
|
||||
}
|
||||
|
||||
fn set_start_time(&self, start_time: u64) {
|
||||
unsafe {
|
||||
glib::gobject_ffi::g_object_set_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"start-time\0".as_ptr() as *const _,
|
||||
start_time.to_value().to_glib_none().0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "latency")]
|
||||
fn connect_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_latency_trampoline<
|
||||
P: IsA<Aggregator>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAggregator,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(&Aggregator::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"notify::latency\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_latency_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "start-time")]
|
||||
fn connect_start_time_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_start_time_trampoline<
|
||||
P: IsA<Aggregator>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAggregator,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(&Aggregator::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"notify::start-time\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_start_time_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
// 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 super::super::ffi;
|
||||
|
||||
use glib::signal::connect_raw;
|
||||
use glib::signal::SignalHandlerId;
|
||||
use glib::translate::*;
|
||||
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
||||
use std::boxed::Box as Box_;
|
||||
use std::mem::transmute;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AggregatorPad(Object<ffi::GstAggregatorPad, ffi::GstAggregatorPadClass>) @extends gst::Pad, gst::Object;
|
||||
|
||||
match fn {
|
||||
type_ => || ffi::gst_aggregator_pad_get_type(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for AggregatorPad {}
|
||||
unsafe impl Sync for AggregatorPad {}
|
||||
|
||||
pub const NONE_AGGREGATOR_PAD: Option<&AggregatorPad> = None;
|
||||
|
||||
pub trait AggregatorPadExt: 'static {
|
||||
#[doc(alias = "gst_aggregator_pad_drop_buffer")]
|
||||
fn drop_buffer(&self) -> bool;
|
||||
|
||||
#[doc(alias = "gst_aggregator_pad_has_buffer")]
|
||||
fn has_buffer(&self) -> bool;
|
||||
|
||||
#[doc(alias = "gst_aggregator_pad_is_eos")]
|
||||
fn is_eos(&self) -> bool;
|
||||
|
||||
#[doc(alias = "gst_aggregator_pad_peek_buffer")]
|
||||
fn peek_buffer(&self) -> Option<gst::Buffer>;
|
||||
|
||||
#[doc(alias = "gst_aggregator_pad_pop_buffer")]
|
||||
fn pop_buffer(&self) -> Option<gst::Buffer>;
|
||||
|
||||
#[doc(alias = "emit-signals")]
|
||||
fn emits_signals(&self) -> bool;
|
||||
|
||||
#[doc(alias = "emit-signals")]
|
||||
fn set_emit_signals(&self, emit_signals: bool);
|
||||
|
||||
fn connect_buffer_consumed<F: Fn(&Self, &gst::Buffer) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
|
||||
#[doc(alias = "emit-signals")]
|
||||
fn connect_emit_signals_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<AggregatorPad>> AggregatorPadExt for O {
|
||||
fn drop_buffer(&self) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_pad_drop_buffer(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_buffer(&self) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_pad_has_buffer(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn is_eos(&self) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_aggregator_pad_is_eos(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn peek_buffer(&self) -> Option<gst::Buffer> {
|
||||
unsafe {
|
||||
from_glib_full(ffi::gst_aggregator_pad_peek_buffer(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_buffer(&self) -> Option<gst::Buffer> {
|
||||
unsafe {
|
||||
from_glib_full(ffi::gst_aggregator_pad_pop_buffer(
|
||||
self.as_ref().to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn emits_signals(&self) -> bool {
|
||||
unsafe {
|
||||
let mut value = glib::Value::from_type(<bool as StaticType>::static_type());
|
||||
glib::gobject_ffi::g_object_get_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"emit-signals\0".as_ptr() as *const _,
|
||||
value.to_glib_none_mut().0,
|
||||
);
|
||||
value
|
||||
.get()
|
||||
.expect("Return Value for property `emit-signals` getter")
|
||||
}
|
||||
}
|
||||
|
||||
fn set_emit_signals(&self, emit_signals: bool) {
|
||||
unsafe {
|
||||
glib::gobject_ffi::g_object_set_property(
|
||||
self.to_glib_none().0 as *mut glib::gobject_ffi::GObject,
|
||||
b"emit-signals\0".as_ptr() as *const _,
|
||||
emit_signals.to_value().to_glib_none().0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "buffer-consumed")]
|
||||
fn connect_buffer_consumed<F: Fn(&Self, &gst::Buffer) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn buffer_consumed_trampoline<
|
||||
P: IsA<AggregatorPad>,
|
||||
F: Fn(&P, &gst::Buffer) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAggregatorPad,
|
||||
object: *mut gst::ffi::GstBuffer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(
|
||||
&AggregatorPad::from_glib_borrow(this).unsafe_cast_ref(),
|
||||
&from_glib_borrow(object),
|
||||
)
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"buffer-consumed\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
buffer_consumed_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "emit-signals")]
|
||||
fn connect_emit_signals_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_emit_signals_trampoline<
|
||||
P: IsA<AggregatorPad>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAggregatorPad,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(&AggregatorPad::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"notify::emit-signals\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_emit_signals_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
mod aggregator;
|
||||
pub use self::aggregator::AggregatorExt;
|
||||
pub use self::aggregator::{Aggregator, NONE_AGGREGATOR};
|
||||
|
||||
mod aggregator_pad;
|
||||
pub use self::aggregator_pad::AggregatorPadExt;
|
||||
pub use self::aggregator_pad::{AggregatorPad, NONE_AGGREGATOR_PAD};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod traits {
|
||||
pub use super::AggregatorExt;
|
||||
pub use super::AggregatorPadExt;
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
|
||||
#![allow(
|
||||
clippy::approx_constant,
|
||||
clippy::type_complexity,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
|
||||
use gst::ffi as gst;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use libc::{
|
||||
c_char, c_double, c_float, c_int, c_long, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void,
|
||||
intptr_t, size_t, ssize_t, time_t, uintptr_t, FILE,
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use ::gst::glib::ffi::{gboolean, gconstpointer, gpointer, GType};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct GstAggregatorClass {
|
||||
pub parent_class: gst::GstElementClass,
|
||||
pub flush: Option<unsafe extern "C" fn(*mut GstAggregator) -> gst::GstFlowReturn>,
|
||||
pub clip: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstBuffer,
|
||||
) -> *mut gst::GstBuffer,
|
||||
>,
|
||||
pub finish_buffer:
|
||||
Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstBuffer) -> gst::GstFlowReturn>,
|
||||
pub sink_event: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstEvent,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub sink_query: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstQuery,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub src_event: Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstEvent) -> gboolean>,
|
||||
pub src_query: Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstQuery) -> gboolean>,
|
||||
pub src_activate:
|
||||
Option<unsafe extern "C" fn(*mut GstAggregator, gst::GstPadMode, gboolean) -> gboolean>,
|
||||
pub aggregate: Option<unsafe extern "C" fn(*mut GstAggregator, gboolean) -> gst::GstFlowReturn>,
|
||||
pub stop: Option<unsafe extern "C" fn(*mut GstAggregator) -> gboolean>,
|
||||
pub start: Option<unsafe extern "C" fn(*mut GstAggregator) -> gboolean>,
|
||||
pub get_next_time: Option<unsafe extern "C" fn(*mut GstAggregator) -> gst::GstClockTime>,
|
||||
pub create_new_pad: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut gst::GstPadTemplate,
|
||||
*const c_char,
|
||||
*const gst::GstCaps,
|
||||
) -> *mut GstAggregatorPad,
|
||||
>,
|
||||
pub update_src_caps: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut gst::GstCaps,
|
||||
*mut *mut gst::GstCaps,
|
||||
) -> gst::GstFlowReturn,
|
||||
>,
|
||||
pub fixate_src_caps:
|
||||
Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstCaps) -> *mut gst::GstCaps>,
|
||||
pub negotiated_src_caps:
|
||||
Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstCaps) -> gboolean>,
|
||||
pub decide_allocation:
|
||||
Option<unsafe extern "C" fn(*mut GstAggregator, *mut gst::GstQuery) -> gboolean>,
|
||||
pub propose_allocation: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstQuery,
|
||||
*mut gst::GstQuery,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub negotiate: Option<unsafe extern "C" fn(*mut GstAggregator) -> gboolean>,
|
||||
pub sink_event_pre_queue: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstEvent,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub sink_query_pre_queue: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregator,
|
||||
*mut GstAggregatorPad,
|
||||
*mut gst::GstQuery,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub _gst_reserved: [gpointer; 17],
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAggregatorClass {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAggregatorClass @ {:?}", self as *const _))
|
||||
.field("parent_class", &self.parent_class)
|
||||
.field("flush", &self.flush)
|
||||
.field("clip", &self.clip)
|
||||
.field("finish_buffer", &self.finish_buffer)
|
||||
.field("sink_event", &self.sink_event)
|
||||
.field("sink_query", &self.sink_query)
|
||||
.field("src_event", &self.src_event)
|
||||
.field("src_query", &self.src_query)
|
||||
.field("src_activate", &self.src_activate)
|
||||
.field("aggregate", &self.aggregate)
|
||||
.field("stop", &self.stop)
|
||||
.field("start", &self.start)
|
||||
.field("get_next_time", &self.get_next_time)
|
||||
.field("create_new_pad", &self.create_new_pad)
|
||||
.field("update_src_caps", &self.update_src_caps)
|
||||
.field("fixate_src_caps", &self.fixate_src_caps)
|
||||
.field("negotiated_src_caps", &self.negotiated_src_caps)
|
||||
.field("decide_allocation", &self.decide_allocation)
|
||||
.field("propose_allocation", &self.propose_allocation)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct GstAggregatorPadClass {
|
||||
pub parent_class: gst::GstPadClass,
|
||||
pub flush: Option<
|
||||
unsafe extern "C" fn(*mut GstAggregatorPad, *mut GstAggregator) -> gst::GstFlowReturn,
|
||||
>,
|
||||
pub skip_buffer: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut GstAggregatorPad,
|
||||
*mut GstAggregator,
|
||||
*mut gst::GstBuffer,
|
||||
) -> gboolean,
|
||||
>,
|
||||
pub _gst_reserved: [gpointer; 20],
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAggregatorPadClass {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAggregatorPadClass @ {:?}", self as *const _))
|
||||
.field("parent_class", &self.parent_class)
|
||||
.field("flush", &self.flush)
|
||||
.field("skip_buffer", &self.skip_buffer)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _GstAggregatorPadPrivate(c_void);
|
||||
|
||||
pub type GstAggregatorPadPrivate = *mut _GstAggregatorPadPrivate;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _GstAggregatorPrivate(c_void);
|
||||
|
||||
pub type GstAggregatorPrivate = *mut _GstAggregatorPrivate;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct GstAggregator {
|
||||
pub parent: gst::GstElement,
|
||||
pub srcpad: *mut gst::GstPad,
|
||||
pub priv_: *mut GstAggregatorPrivate,
|
||||
pub _gst_reserved: [gpointer; 20],
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAggregator {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAggregator @ {:?}", self as *const _))
|
||||
.field("parent", &self.parent)
|
||||
.field("srcpad", &self.srcpad)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct GstAggregatorPad {
|
||||
pub parent: gst::GstPad,
|
||||
pub segment: gst::GstSegment,
|
||||
pub priv_: *mut GstAggregatorPadPrivate,
|
||||
pub _gst_reserved: [gpointer; 4],
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for GstAggregatorPad {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
f.debug_struct(&format!("GstAggregatorPad @ {:?}", self as *const _))
|
||||
.field("parent", &self.parent)
|
||||
.field("segment", &self.segment)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
//=========================================================================
|
||||
// GstAggregator
|
||||
//=========================================================================
|
||||
pub fn gst_aggregator_get_type() -> GType;
|
||||
pub fn gst_aggregator_finish_buffer(
|
||||
aggregator: *mut GstAggregator,
|
||||
buffer: *mut gst::GstBuffer,
|
||||
) -> gst::GstFlowReturn;
|
||||
pub fn gst_aggregator_negotiate(aggregator: *mut GstAggregator) -> gboolean;
|
||||
pub fn gst_aggregator_get_allocator(
|
||||
self_: *mut GstAggregator,
|
||||
allocator: *mut *mut gst::GstAllocator,
|
||||
params: *mut gst::GstAllocationParams,
|
||||
);
|
||||
pub fn gst_aggregator_get_buffer_pool(self_: *mut GstAggregator) -> *mut gst::GstBufferPool;
|
||||
pub fn gst_aggregator_get_latency(self_: *mut GstAggregator) -> gst::GstClockTime;
|
||||
pub fn gst_aggregator_set_latency(
|
||||
self_: *mut GstAggregator,
|
||||
min_latency: gst::GstClockTime,
|
||||
max_latency: gst::GstClockTime,
|
||||
);
|
||||
pub fn gst_aggregator_set_src_caps(self_: *mut GstAggregator, caps: *mut gst::GstCaps);
|
||||
pub fn gst_aggregator_simple_get_next_time(self_: *mut GstAggregator) -> gst::GstClockTime;
|
||||
|
||||
//=========================================================================
|
||||
// GstAggregatorPad
|
||||
//=========================================================================
|
||||
pub fn gst_aggregator_pad_get_type() -> GType;
|
||||
pub fn gst_aggregator_pad_drop_buffer(pad: *mut GstAggregatorPad) -> gboolean;
|
||||
pub fn gst_aggregator_pad_has_buffer(pad: *mut GstAggregatorPad) -> gboolean;
|
||||
pub fn gst_aggregator_pad_is_eos(pad: *mut GstAggregatorPad) -> gboolean;
|
||||
pub fn gst_aggregator_pad_peek_buffer(pad: *mut GstAggregatorPad) -> *mut gst::GstBuffer;
|
||||
pub fn gst_aggregator_pad_pop_buffer(pad: *mut GstAggregatorPad) -> *mut gst::GstBuffer;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,396 +0,0 @@
|
|||
/* GStreamer aggregator base class
|
||||
* Copyright (C) 2014 Mathieu Duponchelle <mathieu.duponchelle@oencreed.com>
|
||||
* Copyright (C) 2014 Thibault Saunier <tsaunier@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_AGGREGATOR_H__
|
||||
#define __GST_AGGREGATOR_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**************************
|
||||
* GstAggregator Structs *
|
||||
*************************/
|
||||
|
||||
typedef struct _GstAggregator GstAggregator;
|
||||
typedef struct _GstAggregatorPrivate GstAggregatorPrivate;
|
||||
typedef struct _GstAggregatorClass GstAggregatorClass;
|
||||
|
||||
/************************
|
||||
* GstAggregatorPad API *
|
||||
***********************/
|
||||
|
||||
#define GST_TYPE_AGGREGATOR_PAD (gst_aggregator_pad_get_type())
|
||||
#define GST_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPad))
|
||||
#define GST_AGGREGATOR_PAD_CAST(obj) ((GstAggregatorPad *)(obj))
|
||||
#define GST_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass))
|
||||
#define GST_AGGREGATOR_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass))
|
||||
#define GST_IS_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR_PAD))
|
||||
#define GST_IS_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR_PAD))
|
||||
|
||||
/****************************
|
||||
* GstAggregatorPad Structs *
|
||||
***************************/
|
||||
|
||||
typedef struct _GstAggregatorPad GstAggregatorPad;
|
||||
typedef struct _GstAggregatorPadClass GstAggregatorPadClass;
|
||||
typedef struct _GstAggregatorPadPrivate GstAggregatorPadPrivate;
|
||||
|
||||
/**
|
||||
* GstAggregatorPad:
|
||||
* @segment: last segment received.
|
||||
*
|
||||
* The implementation the GstPad to use with #GstAggregator
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
struct _GstAggregatorPad
|
||||
{
|
||||
GstPad parent;
|
||||
|
||||
/*< public >*/
|
||||
/* Protected by the OBJECT_LOCK */
|
||||
GstSegment segment;
|
||||
|
||||
/* < private > */
|
||||
GstAggregatorPadPrivate * priv;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstAggregatorPadClass:
|
||||
* @flush: Optional
|
||||
* Called when the pad has received a flush stop, this is the place
|
||||
* to flush any information specific to the pad, it allows for individual
|
||||
* pads to be flushed while others might not be.
|
||||
* @skip_buffer: Optional
|
||||
* Called before input buffers are queued in the pad, return %TRUE
|
||||
* if the buffer should be skipped.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
struct _GstAggregatorPadClass
|
||||
{
|
||||
GstPadClass parent_class;
|
||||
|
||||
GstFlowReturn (*flush) (GstAggregatorPad * aggpad, GstAggregator * aggregator);
|
||||
gboolean (*skip_buffer) (GstAggregatorPad * aggpad, GstAggregator * aggregator, GstBuffer * buffer);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
GST_BASE_API
|
||||
GType gst_aggregator_pad_get_type (void);
|
||||
|
||||
/****************************
|
||||
* GstAggregatorPad methods *
|
||||
***************************/
|
||||
|
||||
GST_BASE_API
|
||||
GstBuffer * gst_aggregator_pad_pop_buffer (GstAggregatorPad * pad);
|
||||
|
||||
GST_BASE_API
|
||||
GstBuffer * gst_aggregator_pad_peek_buffer (GstAggregatorPad * pad);
|
||||
|
||||
GST_BASE_API
|
||||
gboolean gst_aggregator_pad_drop_buffer (GstAggregatorPad * pad);
|
||||
|
||||
GST_BASE_API
|
||||
gboolean gst_aggregator_pad_has_buffer (GstAggregatorPad * pad);
|
||||
|
||||
GST_BASE_API
|
||||
gboolean gst_aggregator_pad_is_eos (GstAggregatorPad * pad);
|
||||
|
||||
/*********************
|
||||
* GstAggregator API *
|
||||
********************/
|
||||
|
||||
#define GST_TYPE_AGGREGATOR (gst_aggregator_get_type())
|
||||
#define GST_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR,GstAggregator))
|
||||
#define GST_AGGREGATOR_CAST(obj) ((GstAggregator *)(obj))
|
||||
#define GST_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR,GstAggregatorClass))
|
||||
#define GST_AGGREGATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR,GstAggregatorClass))
|
||||
#define GST_IS_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR))
|
||||
#define GST_IS_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR))
|
||||
|
||||
#define GST_AGGREGATOR_FLOW_NEED_DATA GST_FLOW_CUSTOM_ERROR
|
||||
|
||||
/**
|
||||
* GstAggregator:
|
||||
* @srcpad: the aggregator's source pad
|
||||
*
|
||||
* Aggregator base class object structure.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
struct _GstAggregator
|
||||
{
|
||||
GstElement parent;
|
||||
|
||||
/*< public >*/
|
||||
GstPad * srcpad;
|
||||
|
||||
/*< private >*/
|
||||
GstAggregatorPrivate * priv;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstAggregatorClass:
|
||||
* @flush: Optional.
|
||||
* Called after a successful flushing seek, once all the flush
|
||||
* stops have been received. Flush pad-specific data in
|
||||
* #GstAggregatorPad->flush.
|
||||
* @clip: Optional.
|
||||
* Called when a buffer is received on a sink pad, the task of
|
||||
* clipping it and translating it to the current segment falls
|
||||
* on the subclass. The function should use the segment of data
|
||||
* and the negotiated media type on the pad to perform
|
||||
* clipping of input buffer. This function takes ownership of
|
||||
* buf and should output a buffer or return NULL in
|
||||
* if the buffer should be dropped.
|
||||
* @finish_buffer: Optional.
|
||||
* Called when a subclass calls gst_aggregator_finish_buffer()
|
||||
* from their aggregate function to push out a buffer.
|
||||
* Subclasses can override this to modify or decorate buffers
|
||||
* before they get pushed out. This function takes ownership
|
||||
* of the buffer passed. Subclasses that override this method
|
||||
* should always chain up to the parent class virtual method.
|
||||
* @sink_event: Optional.
|
||||
* Called when an event is received on a sink pad, the subclass
|
||||
* should always chain up.
|
||||
* @sink_query: Optional.
|
||||
* Called when a query is received on a sink pad, the subclass
|
||||
* should always chain up.
|
||||
* @src_event: Optional.
|
||||
* Called when an event is received on the src pad, the subclass
|
||||
* should always chain up.
|
||||
* @src_query: Optional.
|
||||
* Called when a query is received on the src pad, the subclass
|
||||
* should always chain up.
|
||||
* @src_activate: Optional.
|
||||
* Called when the src pad is activated, it will start/stop its
|
||||
* pad task right after that call.
|
||||
* @aggregate: Mandatory.
|
||||
* Called when buffers are queued on all sinkpads. Classes
|
||||
* should iterate the GstElement->sinkpads and peek or steal
|
||||
* buffers from the #GstAggregatorPads. If the subclass returns
|
||||
* GST_FLOW_EOS, sending of the eos event will be taken care
|
||||
* of. Once / if a buffer has been constructed from the
|
||||
* aggregated buffers, the subclass should call _finish_buffer.
|
||||
* @stop: Optional.
|
||||
* Called when the element goes from PAUSED to READY.
|
||||
* The subclass should free all resources and reset its state.
|
||||
* @start: Optional.
|
||||
* Called when the element goes from READY to PAUSED.
|
||||
* The subclass should get ready to process
|
||||
* aggregated buffers.
|
||||
* @get_next_time: Optional.
|
||||
* Called when the element needs to know the running time of the next
|
||||
* rendered buffer for live pipelines. This causes deadline
|
||||
* based aggregation to occur. Defaults to returning
|
||||
* GST_CLOCK_TIME_NONE causing the element to wait for buffers
|
||||
* on all sink pads before aggregating.
|
||||
* @create_new_pad: Optional.
|
||||
* Called when a new pad needs to be created. Allows subclass that
|
||||
* don't have a single sink pad template to provide a pad based
|
||||
* on the provided information.
|
||||
* @update_src_caps: Lets subclasses update the #GstCaps representing
|
||||
* the src pad caps before usage. The result should end up
|
||||
* in @ret. Return %GST_AGGREGATOR_FLOW_NEED_DATA to indicate that the
|
||||
* element needs more information (caps, a buffer, etc) to
|
||||
* choose the correct caps. Should return ANY caps if the
|
||||
* stream has not caps at all.
|
||||
* @fixate_src_caps: Optional.
|
||||
* Fixate and return the src pad caps provided. The function takes
|
||||
* ownership of @caps and returns a fixated version of
|
||||
* @caps. @caps is not guaranteed to be writable.
|
||||
* @negotiated_src_caps: Optional.
|
||||
* Notifies subclasses what caps format has been negotiated
|
||||
* @decide_allocation: Optional.
|
||||
* Allows the subclass to influence the allocation choices.
|
||||
* Setup the allocation parameters for allocating output
|
||||
* buffers. The passed in query contains the result of the
|
||||
* downstream allocation query.
|
||||
* @propose_allocation: Optional.
|
||||
* Allows the subclass to handle the allocation query from upstream.
|
||||
* @negotiate: Optional.
|
||||
* Negotiate the caps with the peer (Since: 1.18).
|
||||
* @sink_event_pre_queue: Optional.
|
||||
* Called when an event is received on a sink pad before queueing up
|
||||
* serialized events. The subclass should always chain up (Since: 1.18).
|
||||
* @sink_query_pre_queue: Optional.
|
||||
* Called when a query is received on a sink pad before queueing up
|
||||
* serialized queries. The subclass should always chain up (Since: 1.18).
|
||||
*
|
||||
* The aggregator base class will handle in a thread-safe way all manners of
|
||||
* concurrent flushes, seeks, pad additions and removals, leaving to the
|
||||
* subclass the responsibility of clipping buffers, and aggregating buffers in
|
||||
* the way the implementor sees fit.
|
||||
*
|
||||
* It will also take care of event ordering (stream-start, segment, eos).
|
||||
*
|
||||
* Basically, a simple implementation will override @aggregate, and call
|
||||
* _finish_buffer from inside that function.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
struct _GstAggregatorClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
GstFlowReturn (*flush) (GstAggregator * aggregator);
|
||||
|
||||
GstBuffer * (*clip) (GstAggregator * aggregator,
|
||||
GstAggregatorPad * aggregator_pad,
|
||||
GstBuffer * buf);
|
||||
|
||||
GstFlowReturn (*finish_buffer) (GstAggregator * aggregator,
|
||||
GstBuffer * buffer);
|
||||
|
||||
/* sinkpads virtual methods */
|
||||
gboolean (*sink_event) (GstAggregator * aggregator,
|
||||
GstAggregatorPad * aggregator_pad,
|
||||
GstEvent * event);
|
||||
|
||||
gboolean (*sink_query) (GstAggregator * aggregator,
|
||||
GstAggregatorPad * aggregator_pad,
|
||||
GstQuery * query);
|
||||
|
||||
/* srcpad virtual methods */
|
||||
gboolean (*src_event) (GstAggregator * aggregator,
|
||||
GstEvent * event);
|
||||
|
||||
gboolean (*src_query) (GstAggregator * aggregator,
|
||||
GstQuery * query);
|
||||
|
||||
gboolean (*src_activate) (GstAggregator * aggregator,
|
||||
GstPadMode mode,
|
||||
gboolean active);
|
||||
|
||||
GstFlowReturn (*aggregate) (GstAggregator * aggregator,
|
||||
gboolean timeout);
|
||||
|
||||
gboolean (*stop) (GstAggregator * aggregator);
|
||||
|
||||
gboolean (*start) (GstAggregator * aggregator);
|
||||
|
||||
GstClockTime (*get_next_time) (GstAggregator * aggregator);
|
||||
|
||||
GstAggregatorPad * (*create_new_pad) (GstAggregator * self,
|
||||
GstPadTemplate * templ,
|
||||
const gchar * req_name,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* GstAggregatorClass::update_src_caps:
|
||||
* @ret: (out) (allow-none):
|
||||
*/
|
||||
GstFlowReturn (*update_src_caps) (GstAggregator * self,
|
||||
GstCaps * caps,
|
||||
GstCaps ** ret);
|
||||
GstCaps * (*fixate_src_caps) (GstAggregator * self,
|
||||
GstCaps * caps);
|
||||
gboolean (*negotiated_src_caps) (GstAggregator * self,
|
||||
GstCaps * caps);
|
||||
gboolean (*decide_allocation) (GstAggregator * self,
|
||||
GstQuery * query);
|
||||
gboolean (*propose_allocation) (GstAggregator * self,
|
||||
GstAggregatorPad * pad,
|
||||
GstQuery * decide_query,
|
||||
GstQuery * query);
|
||||
|
||||
gboolean (*negotiate) (GstAggregator * self);
|
||||
|
||||
GstFlowReturn (*sink_event_pre_queue) (GstAggregator * aggregator,
|
||||
GstAggregatorPad * aggregator_pad,
|
||||
GstEvent * event);
|
||||
|
||||
gboolean (*sink_query_pre_queue) (GstAggregator * aggregator,
|
||||
GstAggregatorPad * aggregator_pad,
|
||||
GstQuery * query);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE-3];
|
||||
};
|
||||
|
||||
/************************************
|
||||
* GstAggregator convenience macros *
|
||||
***********************************/
|
||||
|
||||
/**
|
||||
* GST_AGGREGATOR_SRC_PAD:
|
||||
* @agg: a #GstAggregator
|
||||
*
|
||||
* Convenience macro to access the source pad of #GstAggregator
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
#define GST_AGGREGATOR_SRC_PAD(agg) (((GstAggregator *)(agg))->srcpad)
|
||||
|
||||
/*************************
|
||||
* GstAggregator methods *
|
||||
************************/
|
||||
|
||||
GST_BASE_API
|
||||
GstFlowReturn gst_aggregator_finish_buffer (GstAggregator * aggregator,
|
||||
GstBuffer * buffer);
|
||||
|
||||
GST_BASE_API
|
||||
void gst_aggregator_set_src_caps (GstAggregator * self,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BASE_API
|
||||
gboolean gst_aggregator_negotiate (GstAggregator * self);
|
||||
|
||||
GST_BASE_API
|
||||
void gst_aggregator_set_latency (GstAggregator * self,
|
||||
GstClockTime min_latency,
|
||||
GstClockTime max_latency);
|
||||
|
||||
GST_BASE_API
|
||||
GType gst_aggregator_get_type(void);
|
||||
|
||||
GST_BASE_API
|
||||
GstClockTime gst_aggregator_get_latency (GstAggregator * self);
|
||||
|
||||
GST_BASE_API
|
||||
GstBufferPool * gst_aggregator_get_buffer_pool (GstAggregator * self);
|
||||
|
||||
GST_BASE_API
|
||||
void gst_aggregator_get_allocator (GstAggregator * self,
|
||||
GstAllocator ** allocator,
|
||||
GstAllocationParams * params);
|
||||
|
||||
GST_BASE_API
|
||||
GstClockTime gst_aggregator_simple_get_next_time (GstAggregator * self);
|
||||
|
||||
GST_BASE_API
|
||||
void gst_aggregator_update_segment (GstAggregator * self,
|
||||
GstSegment * segment);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregator, gst_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregatorPad, gst_object_unref)
|
||||
|
||||
#endif /* __GST_AGGREGATOR_H__ */
|
|
@ -1,26 +0,0 @@
|
|||
#[allow(clippy::unreadable_literal)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[allow(clippy::match_same_arms)]
|
||||
#[allow(clippy::type_complexity)]
|
||||
mod auto;
|
||||
pub use auto::*;
|
||||
|
||||
mod utils;
|
||||
|
||||
mod aggregator;
|
||||
mod aggregator_pad;
|
||||
|
||||
pub mod prelude {
|
||||
pub use gst::glib::prelude::*;
|
||||
pub use gst::prelude::*;
|
||||
|
||||
pub use super::aggregator::AggregatorExtManual;
|
||||
pub use super::aggregator_pad::AggregatorPadExtManual;
|
||||
pub use super::auto::traits::*;
|
||||
}
|
||||
|
||||
pub mod subclass;
|
||||
|
||||
mod ffi;
|
||||
|
||||
pub const AGGREGATOR_FLOW_NEED_DATA: gst::FlowError = gst::FlowError::CustomError;
|
|
@ -1,971 +0,0 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use super::super::ffi;
|
||||
|
||||
use glib::translate::*;
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use super::super::Aggregator;
|
||||
use super::super::AggregatorPad;
|
||||
|
||||
pub trait AggregatorImpl: AggregatorImplExt + ElementImpl {
|
||||
fn flush(&self, aggregator: &Self::Type) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
self.parent_flush(aggregator)
|
||||
}
|
||||
|
||||
fn clip(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
buffer: gst::Buffer,
|
||||
) -> Option<gst::Buffer> {
|
||||
self.parent_clip(aggregator, aggregator_pad, buffer)
|
||||
}
|
||||
|
||||
fn finish_buffer(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
buffer: gst::Buffer,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
self.parent_finish_buffer(aggregator, buffer)
|
||||
}
|
||||
|
||||
fn sink_event(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> bool {
|
||||
self.parent_sink_event(aggregator, aggregator_pad, event)
|
||||
}
|
||||
|
||||
fn sink_event_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
self.parent_sink_event_pre_queue(aggregator, aggregator_pad, event)
|
||||
}
|
||||
|
||||
fn sink_query(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool {
|
||||
self.parent_sink_query(aggregator, aggregator_pad, query)
|
||||
}
|
||||
|
||||
fn sink_query_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool {
|
||||
self.parent_sink_query_pre_queue(aggregator, aggregator_pad, query)
|
||||
}
|
||||
|
||||
fn src_event(&self, aggregator: &Self::Type, event: gst::Event) -> bool {
|
||||
self.parent_src_event(aggregator, event)
|
||||
}
|
||||
|
||||
fn src_query(&self, aggregator: &Self::Type, query: &mut gst::QueryRef) -> bool {
|
||||
self.parent_src_query(aggregator, query)
|
||||
}
|
||||
|
||||
fn src_activate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
mode: gst::PadMode,
|
||||
active: bool,
|
||||
) -> Result<(), gst::LoggableError> {
|
||||
self.parent_src_activate(aggregator, mode, active)
|
||||
}
|
||||
|
||||
fn aggregate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
timeout: bool,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
self.parent_aggregate(aggregator, timeout)
|
||||
}
|
||||
|
||||
fn start(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||
self.parent_start(aggregator)
|
||||
}
|
||||
|
||||
fn stop(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||
self.parent_stop(aggregator)
|
||||
}
|
||||
|
||||
fn next_time(&self, aggregator: &Self::Type) -> Option<gst::ClockTime> {
|
||||
self.parent_next_time(aggregator)
|
||||
}
|
||||
|
||||
fn create_new_pad(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
templ: &gst::PadTemplate,
|
||||
req_name: Option<&str>,
|
||||
caps: Option<&gst::Caps>,
|
||||
) -> Option<AggregatorPad> {
|
||||
self.parent_create_new_pad(aggregator, templ, req_name, caps)
|
||||
}
|
||||
|
||||
fn update_src_caps(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<gst::Caps, gst::FlowError> {
|
||||
self.parent_update_src_caps(aggregator, caps)
|
||||
}
|
||||
|
||||
fn fixate_src_caps(&self, aggregator: &Self::Type, caps: gst::Caps) -> gst::Caps {
|
||||
self.parent_fixate_src_caps(aggregator, caps)
|
||||
}
|
||||
|
||||
fn negotiated_src_caps(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<(), gst::LoggableError> {
|
||||
self.parent_negotiated_src_caps(aggregator, caps)
|
||||
}
|
||||
|
||||
fn negotiate(&self, aggregator: &Self::Type) -> bool {
|
||||
self.parent_negotiate(aggregator)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AggregatorImplExt: ObjectSubclass {
|
||||
fn parent_flush(&self, aggregator: &Self::Type) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
|
||||
fn parent_clip(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
buffer: gst::Buffer,
|
||||
) -> Option<gst::Buffer>;
|
||||
|
||||
fn parent_finish_buffer(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
buffer: gst::Buffer,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
|
||||
fn parent_sink_event(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> bool;
|
||||
|
||||
fn parent_sink_event_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
|
||||
fn parent_sink_query(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool;
|
||||
|
||||
fn parent_sink_query_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool;
|
||||
|
||||
fn parent_src_event(&self, aggregator: &Self::Type, event: gst::Event) -> bool;
|
||||
|
||||
fn parent_src_query(&self, aggregator: &Self::Type, query: &mut gst::QueryRef) -> bool;
|
||||
|
||||
fn parent_src_activate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
mode: gst::PadMode,
|
||||
active: bool,
|
||||
) -> Result<(), gst::LoggableError>;
|
||||
|
||||
fn parent_aggregate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
timeout: bool,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
|
||||
fn parent_start(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage>;
|
||||
|
||||
fn parent_stop(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage>;
|
||||
|
||||
fn parent_next_time(&self, aggregator: &Self::Type) -> Option<gst::ClockTime>;
|
||||
|
||||
fn parent_create_new_pad(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
templ: &gst::PadTemplate,
|
||||
req_name: Option<&str>,
|
||||
caps: Option<&gst::Caps>,
|
||||
) -> Option<AggregatorPad>;
|
||||
|
||||
fn parent_update_src_caps(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<gst::Caps, gst::FlowError>;
|
||||
|
||||
fn parent_fixate_src_caps(&self, aggregator: &Self::Type, caps: gst::Caps) -> gst::Caps;
|
||||
|
||||
fn parent_negotiated_src_caps(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<(), gst::LoggableError>;
|
||||
|
||||
fn parent_negotiate(&self, aggregator: &Self::Type) -> bool;
|
||||
}
|
||||
|
||||
impl<T: AggregatorImpl> AggregatorImplExt for T {
|
||||
fn parent_flush(&self, aggregator: &Self::Type) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.flush
|
||||
.map(|f| {
|
||||
try_from_glib(f(aggregator
|
||||
.unsafe_cast_ref::<Aggregator>()
|
||||
.to_glib_none()
|
||||
.0))
|
||||
})
|
||||
.unwrap_or(Ok(gst::FlowSuccess::Ok))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_clip(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
buffer: gst::Buffer,
|
||||
) -> Option<gst::Buffer> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
match (*parent_class).clip {
|
||||
None => Some(buffer),
|
||||
Some(ref func) => from_glib_full(func(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
aggregator_pad.to_glib_none().0,
|
||||
buffer.into_ptr(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_finish_buffer(
|
||||
&self,
|
||||
aggregator: &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::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.finish_buffer
|
||||
.expect("Missing parent function `finish_buffer`");
|
||||
try_from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
buffer.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_sink_event(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.sink_event
|
||||
.expect("Missing parent function `sink_event`");
|
||||
from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
aggregator_pad.to_glib_none().0,
|
||||
event.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_sink_event_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
event: gst::Event,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.sink_event_pre_queue
|
||||
.expect("Missing parent function `sink_event_pre_queue`");
|
||||
try_from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
aggregator_pad.to_glib_none().0,
|
||||
event.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_sink_query(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
let data = T::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.sink_query
|
||||
.expect("Missing parent function `sink_query`");
|
||||
from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
aggregator_pad.to_glib_none().0,
|
||||
query.as_mut_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_sink_query_pre_queue(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
aggregator_pad: &AggregatorPad,
|
||||
query: &mut gst::QueryRef,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.sink_query_pre_queue
|
||||
.expect("Missing parent function `sink_query`");
|
||||
from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
aggregator_pad.to_glib_none().0,
|
||||
query.as_mut_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_src_event(&self, aggregator: &Self::Type, event: gst::Event) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.src_event
|
||||
.expect("Missing parent function `src_event`");
|
||||
from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
event.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_src_query(&self, aggregator: &Self::Type, query: &mut gst::QueryRef) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.src_query
|
||||
.expect("Missing parent function `src_query`");
|
||||
from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
query.as_mut_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_src_activate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
mode: gst::PadMode,
|
||||
active: bool,
|
||||
) -> Result<(), gst::LoggableError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
match (*parent_class).src_activate {
|
||||
None => Ok(()),
|
||||
Some(f) => gst::result_from_gboolean!(
|
||||
f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
mode.into_glib(),
|
||||
active.into_glib()
|
||||
),
|
||||
gst::CAT_RUST,
|
||||
"Parent function `src_activate` failed"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_aggregate(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
timeout: bool,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.aggregate
|
||||
.expect("Missing parent function `aggregate`");
|
||||
try_from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
timeout.into_glib(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_start(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.start
|
||||
.map(|f| {
|
||||
if from_glib(f(aggregator
|
||||
.unsafe_cast_ref::<Aggregator>()
|
||||
.to_glib_none()
|
||||
.0))
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(gst::error_msg!(
|
||||
gst::CoreError::Failed,
|
||||
["Parent function `start` failed"]
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_stop(&self, aggregator: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.stop
|
||||
.map(|f| {
|
||||
if from_glib(f(aggregator
|
||||
.unsafe_cast_ref::<Aggregator>()
|
||||
.to_glib_none()
|
||||
.0))
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(gst::error_msg!(
|
||||
gst::CoreError::Failed,
|
||||
["Parent function `stop` failed"]
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_next_time(&self, aggregator: &Self::Type) -> Option<gst::ClockTime> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.get_next_time
|
||||
.map(|f| {
|
||||
from_glib(f(aggregator
|
||||
.unsafe_cast_ref::<Aggregator>()
|
||||
.to_glib_none()
|
||||
.0))
|
||||
})
|
||||
.unwrap_or(gst::ClockTime::NONE)
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_create_new_pad(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
templ: &gst::PadTemplate,
|
||||
req_name: Option<&str>,
|
||||
caps: Option<&gst::Caps>,
|
||||
) -> Option<AggregatorPad> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.create_new_pad
|
||||
.expect("Missing parent function `create_new_pad`");
|
||||
from_glib_full(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
templ.to_glib_none().0,
|
||||
req_name.to_glib_none().0,
|
||||
caps.to_glib_none().0,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_update_src_caps(
|
||||
&self,
|
||||
aggregator: &Self::Type,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<gst::Caps, gst::FlowError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
let f = (*parent_class)
|
||||
.update_src_caps
|
||||
.expect("Missing parent function `update_src_caps`");
|
||||
|
||||
let mut out_caps = ptr::null_mut();
|
||||
gst::FlowSuccess::try_from_glib(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
caps.as_mut_ptr(),
|
||||
&mut out_caps,
|
||||
))
|
||||
.map(|_| from_glib_full(out_caps))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_fixate_src_caps(&self, aggregator: &Self::Type, caps: gst::Caps) -> gst::Caps {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
|
||||
let f = (*parent_class)
|
||||
.fixate_src_caps
|
||||
.expect("Missing parent function `fixate_src_caps`");
|
||||
from_glib_full(f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
caps.into_ptr(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_negotiated_src_caps(
|
||||
&self,
|
||||
aggregator: &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::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.negotiated_src_caps
|
||||
.map(|f| {
|
||||
gst::result_from_gboolean!(
|
||||
f(
|
||||
aggregator.unsafe_cast_ref::<Aggregator>().to_glib_none().0,
|
||||
caps.to_glib_none().0
|
||||
),
|
||||
gst::CAT_RUST,
|
||||
"Parent function `negotiated_src_caps` failed"
|
||||
)
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_negotiate(&self, aggregator: &Self::Type) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
|
||||
(*parent_class)
|
||||
.negotiate
|
||||
.map(|f| {
|
||||
from_glib(f(aggregator
|
||||
.unsafe_cast_ref::<Aggregator>()
|
||||
.to_glib_none()
|
||||
.0))
|
||||
})
|
||||
.unwrap_or(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: AggregatorImpl> IsSubclassable<T> for Aggregator {
|
||||
fn class_init(klass: &mut glib::Class<Self>) {
|
||||
<gst::Element as IsSubclassable<T>>::class_init(klass);
|
||||
let klass = klass.as_mut();
|
||||
klass.flush = Some(aggregator_flush::<T>);
|
||||
klass.clip = Some(aggregator_clip::<T>);
|
||||
klass.finish_buffer = Some(aggregator_finish_buffer::<T>);
|
||||
klass.sink_event = Some(aggregator_sink_event::<T>);
|
||||
klass.sink_query = Some(aggregator_sink_query::<T>);
|
||||
klass.src_event = Some(aggregator_src_event::<T>);
|
||||
klass.src_query = Some(aggregator_src_query::<T>);
|
||||
klass.src_activate = Some(aggregator_src_activate::<T>);
|
||||
klass.aggregate = Some(aggregator_aggregate::<T>);
|
||||
klass.start = Some(aggregator_start::<T>);
|
||||
klass.stop = Some(aggregator_stop::<T>);
|
||||
klass.get_next_time = Some(aggregator_get_next_time::<T>);
|
||||
klass.create_new_pad = Some(aggregator_create_new_pad::<T>);
|
||||
klass.update_src_caps = Some(aggregator_update_src_caps::<T>);
|
||||
klass.fixate_src_caps = Some(aggregator_fixate_src_caps::<T>);
|
||||
klass.negotiated_src_caps = Some(aggregator_negotiated_src_caps::<T>);
|
||||
{
|
||||
klass.sink_event_pre_queue = Some(aggregator_sink_event_pre_queue::<T>);
|
||||
klass.sink_query_pre_queue = Some(aggregator_sink_query_pre_queue::<T>);
|
||||
klass.negotiate = Some(aggregator_negotiate::<T>);
|
||||
}
|
||||
}
|
||||
|
||||
fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
|
||||
<gst::Element as IsSubclassable<T>>::instance_init(instance);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_flush<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::FlowReturn::Error, {
|
||||
imp.flush(wrap.unsafe_cast_ref()).into()
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_clip<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
aggregator_pad: *mut ffi::GstAggregatorPad,
|
||||
buffer: *mut gst::ffi::GstBuffer,
|
||||
) -> *mut gst::ffi::GstBuffer {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
let ret = gst::panic_to_error!(&wrap, &imp.panicked(), None, {
|
||||
imp.clip(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator_pad),
|
||||
from_glib_full(buffer),
|
||||
)
|
||||
});
|
||||
|
||||
ret.map(|r| r.into_ptr()).unwrap_or(ptr::null_mut())
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_finish_buffer<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
buffer: *mut gst::ffi::GstBuffer,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::FlowReturn::Error, {
|
||||
imp.finish_buffer(wrap.unsafe_cast_ref(), from_glib_full(buffer))
|
||||
.into()
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_sink_event<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
aggregator_pad: *mut ffi::GstAggregatorPad,
|
||||
event: *mut gst::ffi::GstEvent,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(wrap, &imp.panicked(), false, {
|
||||
imp.sink_event(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator_pad),
|
||||
from_glib_full(event),
|
||||
)
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_sink_event_pre_queue<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
aggregator_pad: *mut ffi::GstAggregatorPad,
|
||||
event: *mut gst::ffi::GstEvent,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::FlowReturn::Error, {
|
||||
imp.sink_event_pre_queue(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator_pad),
|
||||
from_glib_full(event),
|
||||
)
|
||||
.into()
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_sink_query<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
aggregator_pad: *mut ffi::GstAggregatorPad,
|
||||
query: *mut gst::ffi::GstQuery,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
imp.sink_query(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator_pad),
|
||||
gst::QueryRef::from_mut_ptr(query),
|
||||
)
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_sink_query_pre_queue<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
aggregator_pad: *mut ffi::GstAggregatorPad,
|
||||
query: *mut gst::ffi::GstQuery,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
imp.sink_query_pre_queue(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator_pad),
|
||||
gst::QueryRef::from_mut_ptr(query),
|
||||
)
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_src_event<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
event: *mut gst::ffi::GstEvent,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = 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()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_src_query<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
query: *mut gst::ffi::GstQuery,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
imp.src_query(wrap.unsafe_cast_ref(), gst::QueryRef::from_mut_ptr(query))
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_src_activate<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
mode: gst::ffi::GstPadMode,
|
||||
active: glib::ffi::gboolean,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
match imp.src_activate(wrap.unsafe_cast_ref(), from_glib(mode), from_glib(active)) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
err.log_with_object(&*wrap);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_aggregate<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
timeout: glib::ffi::gboolean,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::FlowReturn::Error, {
|
||||
imp.aggregate(wrap.unsafe_cast_ref(), from_glib(timeout))
|
||||
.into()
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_start<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
match imp.start(wrap.unsafe_cast_ref()) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
wrap.post_error_message(err);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_stop<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
match imp.stop(wrap.unsafe_cast_ref()) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
wrap.post_error_message(err);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_get_next_time<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
) -> gst::ffi::GstClockTime {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::ClockTime::NONE, {
|
||||
imp.next_time(wrap.unsafe_cast_ref())
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_create_new_pad<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
templ: *mut gst::ffi::GstPadTemplate,
|
||||
req_name: *const libc::c_char,
|
||||
caps: *const gst::ffi::GstCaps,
|
||||
) -> *mut ffi::GstAggregatorPad {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), None, {
|
||||
let req_name: Borrowed<Option<glib::GString>> = from_glib_borrow(req_name);
|
||||
|
||||
imp.create_new_pad(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(templ),
|
||||
req_name.as_ref().as_ref().map(|s| s.as_str()),
|
||||
Option::<gst::Caps>::from_glib_borrow(caps)
|
||||
.as_ref()
|
||||
.as_ref(),
|
||||
)
|
||||
})
|
||||
.to_glib_full()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_update_src_caps<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
caps: *mut gst::ffi::GstCaps,
|
||||
res: *mut *mut gst::ffi::GstCaps,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
*res = ptr::null_mut();
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::FlowReturn::Error, {
|
||||
match imp.update_src_caps(wrap.unsafe_cast_ref(), &from_glib_borrow(caps)) {
|
||||
Ok(res_caps) => {
|
||||
*res = res_caps.into_ptr();
|
||||
gst::FlowReturn::Ok
|
||||
}
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_fixate_src_caps<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
caps: *mut gst::ffi::GstCaps,
|
||||
) -> *mut gst::ffi::GstCaps {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), gst::Caps::new_empty(), {
|
||||
imp.fixate_src_caps(wrap.unsafe_cast_ref(), from_glib_full(caps))
|
||||
})
|
||||
.into_ptr()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_negotiated_src_caps<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
caps: *mut gst::ffi::GstCaps,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
match imp.negotiated_src_caps(wrap.unsafe_cast_ref(), &from_glib_borrow(caps)) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
err.log_with_object(&*wrap);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_negotiate<T: AggregatorImpl>(
|
||||
ptr: *mut ffi::GstAggregator,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<Aggregator> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, &imp.panicked(), false, {
|
||||
imp.negotiate(wrap.unsafe_cast_ref())
|
||||
})
|
||||
.into_glib()
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use super::super::ffi;
|
||||
|
||||
use glib::translate::*;
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
|
||||
use super::super::Aggregator;
|
||||
use super::super::AggregatorPad;
|
||||
|
||||
pub trait AggregatorPadImpl: AggregatorPadImplExt + PadImpl {
|
||||
fn flush(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
self.parent_flush(aggregator_pad, aggregator)
|
||||
}
|
||||
|
||||
fn skip_buffer(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
buffer: &gst::Buffer,
|
||||
) -> bool {
|
||||
self.parent_skip_buffer(aggregator_pad, aggregator, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AggregatorPadImplExt: ObjectSubclass {
|
||||
fn parent_flush(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
|
||||
fn parent_skip_buffer(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
buffer: &gst::Buffer,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
impl<T: AggregatorPadImpl> AggregatorPadImplExt for T {
|
||||
fn parent_flush(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
|
||||
(*parent_class)
|
||||
.flush
|
||||
.map(|f| {
|
||||
try_from_glib(f(
|
||||
aggregator_pad
|
||||
.unsafe_cast_ref::<AggregatorPad>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
aggregator.to_glib_none().0,
|
||||
))
|
||||
})
|
||||
.unwrap_or(Ok(gst::FlowSuccess::Ok))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_skip_buffer(
|
||||
&self,
|
||||
aggregator_pad: &Self::Type,
|
||||
aggregator: &Aggregator,
|
||||
buffer: &gst::Buffer,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
|
||||
(*parent_class)
|
||||
.skip_buffer
|
||||
.map(|f| {
|
||||
from_glib(f(
|
||||
aggregator_pad
|
||||
.unsafe_cast_ref::<AggregatorPad>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
aggregator.to_glib_none().0,
|
||||
buffer.to_glib_none().0,
|
||||
))
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe impl<T: AggregatorPadImpl> IsSubclassable<T> for AggregatorPad {
|
||||
fn class_init(klass: &mut glib::Class<Self>) {
|
||||
<gst::Pad as IsSubclassable<T>>::class_init(klass);
|
||||
let klass = klass.as_mut();
|
||||
klass.flush = Some(aggregator_pad_flush::<T>);
|
||||
klass.skip_buffer = Some(aggregator_pad_skip_buffer::<T>);
|
||||
}
|
||||
|
||||
fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
|
||||
<gst::Pad as IsSubclassable<T>>::instance_init(instance);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_pad_flush<T: AggregatorPadImpl>(
|
||||
ptr: *mut ffi::GstAggregatorPad,
|
||||
aggregator: *mut ffi::GstAggregator,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<AggregatorPad> = from_glib_borrow(ptr);
|
||||
|
||||
let res: gst::FlowReturn = imp
|
||||
.flush(wrap.unsafe_cast_ref(), &from_glib_borrow(aggregator))
|
||||
.into();
|
||||
res.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn aggregator_pad_skip_buffer<T: AggregatorPadImpl>(
|
||||
ptr: *mut ffi::GstAggregatorPad,
|
||||
aggregator: *mut ffi::GstAggregator,
|
||||
buffer: *mut gst::ffi::GstBuffer,
|
||||
) -> glib::ffi::gboolean {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.impl_();
|
||||
let wrap: Borrowed<AggregatorPad> = from_glib_borrow(ptr);
|
||||
|
||||
imp.skip_buffer(
|
||||
wrap.unsafe_cast_ref(),
|
||||
&from_glib_borrow(aggregator),
|
||||
&from_glib_borrow(buffer),
|
||||
)
|
||||
.into_glib()
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (C) 2016-2018 Sebastian Dröge <sebastian@centricular.com>
|
||||
// 2016 Luis de Bethencourt <luisbg@osg.samsung.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.
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
|
||||
pub mod aggregator;
|
||||
pub mod aggregator_pad;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::aggregator::{AggregatorImpl, AggregatorImplExt};
|
||||
pub use super::aggregator_pad::{AggregatorPadImpl, AggregatorPadImplExt};
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::translate::mut_override;
|
||||
use gst::glib;
|
||||
|
||||
#[must_use = "if unused the Mutex will immediately unlock"]
|
||||
pub struct MutexGuard<'a>(&'a glib::ffi::GMutex);
|
||||
|
||||
impl<'a> MutexGuard<'a> {
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
#[doc(alias = "g_mutex_lock")]
|
||||
pub fn lock(mutex: &'a glib::ffi::GMutex) -> Self {
|
||||
unsafe {
|
||||
glib::ffi::g_mutex_lock(mut_override(mutex));
|
||||
}
|
||||
MutexGuard(mutex)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for MutexGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
glib::ffi::g_mutex_unlock(mut_override(self.0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,22 +17,9 @@
|
|||
|
||||
use gst::glib;
|
||||
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use self::gst_base::prelude::*;
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use self::gst_base::subclass::prelude::*;
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use crate::gst_base_compat as gst_base;
|
||||
|
||||
#[cfg(feature = "v1_18")]
|
||||
use gst_base::prelude::*;
|
||||
#[cfg(feature = "v1_18")]
|
||||
use gst_base::subclass::prelude::*;
|
||||
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use glib::subclass::prelude::*;
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use gst::subclass::prelude::*;
|
||||
use gst::{gst_debug, gst_error, gst_info, gst_log, gst_warning};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
use crate::gst_base_compat as gst_base;
|
||||
|
||||
mod imp;
|
||||
|
||||
glib::wrapper! {
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
|
||||
use gst::glib;
|
||||
|
||||
#[cfg(not(feature = "v1_18"))]
|
||||
#[path = "base/mod.rs"]
|
||||
pub mod gst_base_compat;
|
||||
|
||||
mod fallbacksrc;
|
||||
mod fallbackswitch;
|
||||
|
||||
|
|
Loading…
Reference in a new issue