forked from mirrors/gstreamer-rs
gstreamer: Add support for subclassing gst::Clock
This commit is contained in:
parent
74b05f0272
commit
1c8b2c671b
2 changed files with 308 additions and 0 deletions
305
gstreamer/src/subclass/clock.rs
Normal file
305
gstreamer/src/subclass/clock.rs
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.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 gst_sys;
|
||||||
|
|
||||||
|
use glib;
|
||||||
|
use glib::translate::*;
|
||||||
|
|
||||||
|
use glib::subclass::prelude::*;
|
||||||
|
|
||||||
|
use Clock;
|
||||||
|
use ClockClass;
|
||||||
|
use ClockError;
|
||||||
|
use ClockId;
|
||||||
|
use ClockReturn;
|
||||||
|
use ClockSuccess;
|
||||||
|
use ClockTime;
|
||||||
|
use ClockTimeDiff;
|
||||||
|
|
||||||
|
pub trait ClockImpl: ClockImplExt + ObjectImpl + Send + Sync + 'static {
|
||||||
|
fn change_resolution(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
old_resolution: ClockTime,
|
||||||
|
new_resolution: ClockTime,
|
||||||
|
) -> ClockTime {
|
||||||
|
self.parent_change_resolution(clock, old_resolution, new_resolution)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_resolution(&self, clock: &Clock) -> ClockTime {
|
||||||
|
self.parent_get_resolution(clock)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_internal_time(&self, clock: &Clock) -> ClockTime {
|
||||||
|
self.parent_get_internal_time(clock)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
id: &ClockId,
|
||||||
|
) -> (Result<ClockSuccess, ClockError>, ClockTimeDiff) {
|
||||||
|
self.parent_wait(clock, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_async(&self, clock: &Clock, id: &ClockId) -> Result<ClockSuccess, ClockError> {
|
||||||
|
self.parent_wait_async(clock, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unschedule(&self, clock: &Clock, id: &ClockId) {
|
||||||
|
self.parent_unschedule(clock, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ClockImplExt {
|
||||||
|
fn parent_change_resolution(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
old_resolution: ClockTime,
|
||||||
|
new_resolution: ClockTime,
|
||||||
|
) -> ClockTime;
|
||||||
|
|
||||||
|
fn parent_get_resolution(&self, clock: &Clock) -> ClockTime;
|
||||||
|
|
||||||
|
fn parent_get_internal_time(&self, clock: &Clock) -> ClockTime;
|
||||||
|
|
||||||
|
fn parent_wait(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
id: &ClockId,
|
||||||
|
) -> (Result<ClockSuccess, ClockError>, ClockTimeDiff);
|
||||||
|
|
||||||
|
fn parent_wait_async(&self, clock: &Clock, id: &ClockId) -> Result<ClockSuccess, ClockError>;
|
||||||
|
|
||||||
|
fn parent_unschedule(&self, clock: &Clock, id: &ClockId);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ClockImpl + ObjectImpl> ClockImplExt for T {
|
||||||
|
fn parent_change_resolution(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
old_resolution: ClockTime,
|
||||||
|
new_resolution: ClockTime,
|
||||||
|
) -> ClockTime {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
|
||||||
|
if let Some(func) = (*parent_class).change_resolution {
|
||||||
|
from_glib(func(
|
||||||
|
clock.to_glib_none().0,
|
||||||
|
old_resolution.to_glib(),
|
||||||
|
new_resolution.to_glib(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
self.get_resolution(clock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_get_resolution(&self, clock: &Clock) -> ClockTime {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
|
||||||
|
from_glib(
|
||||||
|
(*parent_class)
|
||||||
|
.get_resolution
|
||||||
|
.map(|f| f(clock.to_glib_none().0))
|
||||||
|
.unwrap_or(1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_get_internal_time(&self, clock: &Clock) -> ClockTime {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
|
||||||
|
from_glib(
|
||||||
|
(*parent_class)
|
||||||
|
.get_internal_time
|
||||||
|
.map(|f| f(clock.to_glib_none().0))
|
||||||
|
.unwrap_or(0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_wait(
|
||||||
|
&self,
|
||||||
|
clock: &Clock,
|
||||||
|
id: &ClockId,
|
||||||
|
) -> (Result<ClockSuccess, ClockError>, ClockTimeDiff) {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
let mut jitter = 0;
|
||||||
|
|
||||||
|
(
|
||||||
|
ClockReturn::from_glib(
|
||||||
|
(*parent_class)
|
||||||
|
.wait
|
||||||
|
.map(|f| {
|
||||||
|
f(
|
||||||
|
clock.to_glib_none().0,
|
||||||
|
id.to_glib_none().0 as *mut gst_sys::GstClockEntry,
|
||||||
|
&mut jitter,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or(gst_sys::GST_CLOCK_UNSUPPORTED),
|
||||||
|
)
|
||||||
|
.into_result(),
|
||||||
|
jitter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_wait_async(&self, clock: &Clock, id: &ClockId) -> Result<ClockSuccess, ClockError> {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
ClockReturn::from_glib(
|
||||||
|
(*parent_class)
|
||||||
|
.wait_async
|
||||||
|
.map(|f| {
|
||||||
|
f(
|
||||||
|
clock.to_glib_none().0,
|
||||||
|
id.to_glib_none().0 as *mut gst_sys::GstClockEntry,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or(gst_sys::GST_CLOCK_UNSUPPORTED),
|
||||||
|
)
|
||||||
|
.into_result()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_unschedule(&self, clock: &Clock, id: &ClockId) {
|
||||||
|
unsafe {
|
||||||
|
let data = self.get_type_data();
|
||||||
|
let parent_class = data.as_ref().get_parent_class() as *mut gst_sys::GstClockClass;
|
||||||
|
if let Some(func) = (*parent_class).unschedule {
|
||||||
|
func(
|
||||||
|
clock.to_glib_none().0,
|
||||||
|
id.to_glib_none().0 as *mut gst_sys::GstClockEntry,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: ObjectSubclass + ClockImpl> IsSubclassable<T> for ClockClass {
|
||||||
|
fn override_vfuncs(&mut self) {
|
||||||
|
<glib::ObjectClass as IsSubclassable<T>>::override_vfuncs(self);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let klass = &mut *(self as *mut Self as *mut gst_sys::GstClockClass);
|
||||||
|
klass.change_resolution = Some(clock_change_resolution::<T>);
|
||||||
|
klass.get_resolution = Some(clock_get_resolution::<T>);
|
||||||
|
klass.get_internal_time = Some(clock_get_internal_time::<T>);
|
||||||
|
klass.wait = Some(clock_wait::<T>);
|
||||||
|
klass.wait_async = Some(clock_wait_async::<T>);
|
||||||
|
klass.unschedule = Some(clock_unschedule::<T>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_change_resolution<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
old_resolution: gst_sys::GstClockTime,
|
||||||
|
new_resolution: gst_sys::GstClockTime,
|
||||||
|
) -> gst_sys::GstClockTime
|
||||||
|
where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
imp.change_resolution(&wrap, from_glib(old_resolution), from_glib(new_resolution))
|
||||||
|
.to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_get_resolution<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
) -> gst_sys::GstClockTime
|
||||||
|
where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
imp.get_resolution(&wrap).to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_get_internal_time<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
) -> gst_sys::GstClockTime
|
||||||
|
where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
imp.get_internal_time(&wrap).to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_wait<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
id: *mut gst_sys::GstClockEntry,
|
||||||
|
jitter: *mut gst_sys::GstClockTimeDiff,
|
||||||
|
) -> gst_sys::GstClockReturn
|
||||||
|
where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
let (res, j) = imp.wait(&wrap, &from_glib_borrow(id as gst_sys::GstClockID));
|
||||||
|
if !jitter.is_null() {
|
||||||
|
*jitter = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClockReturn::from(res).to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_wait_async<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
id: *mut gst_sys::GstClockEntry,
|
||||||
|
) -> gst_sys::GstClockReturn
|
||||||
|
where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
ClockReturn::from(imp.wait_async(&wrap, &from_glib_borrow(id as gst_sys::GstClockID))).to_glib()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn clock_unschedule<T: ObjectSubclass>(
|
||||||
|
ptr: *mut gst_sys::GstClock,
|
||||||
|
id: *mut gst_sys::GstClockEntry,
|
||||||
|
) where
|
||||||
|
T: ClockImpl,
|
||||||
|
{
|
||||||
|
glib_floating_reference_guard!(ptr);
|
||||||
|
let instance = &*(ptr as *mut T::Instance);
|
||||||
|
let imp = instance.get_impl();
|
||||||
|
let wrap: Clock = from_glib_borrow(ptr);
|
||||||
|
|
||||||
|
imp.unschedule(&wrap, &from_glib_borrow(id as gst_sys::GstClockID));
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ pub mod pipeline;
|
||||||
pub mod device;
|
pub mod device;
|
||||||
pub mod device_provider;
|
pub mod device_provider;
|
||||||
|
|
||||||
|
pub mod clock;
|
||||||
|
|
||||||
pub mod preset;
|
pub mod preset;
|
||||||
pub mod tag_setter;
|
pub mod tag_setter;
|
||||||
pub mod uri_handler;
|
pub mod uri_handler;
|
||||||
|
@ -38,6 +40,7 @@ pub mod uri_handler;
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use super::bin::{BinImpl, BinImplExt};
|
pub use super::bin::{BinImpl, BinImplExt};
|
||||||
pub use super::child_proxy::ChildProxyImpl;
|
pub use super::child_proxy::ChildProxyImpl;
|
||||||
|
pub use super::clock::{ClockImpl, ClockImplExt};
|
||||||
pub use super::device::{DeviceImpl, DeviceImplExt};
|
pub use super::device::{DeviceImpl, DeviceImplExt};
|
||||||
pub use super::device_provider::{
|
pub use super::device_provider::{
|
||||||
DeviceProviderClassSubclassExt, DeviceProviderImpl, DeviceProviderImplExt,
|
DeviceProviderClassSubclassExt, DeviceProviderImpl, DeviceProviderImplExt,
|
||||||
|
|
Loading…
Reference in a new issue