Add ClockId and related waiting API, and SystemClock

Fixes https://github.com/sdroege/gstreamer-rs/issues/23
This commit is contained in:
Sebastian Dröge 2017-08-14 01:40:43 +03:00
parent d6c869b691
commit 77cb4da32a
34 changed files with 497 additions and 37 deletions

View file

@ -15,6 +15,7 @@ external_libraries = [
generate = [ generate = [
"Gst.ClockTime", "Gst.ClockTime",
"Gst.ClockTimeDiff",
"Gst.Pipeline", "Gst.Pipeline",
"Gst.State", "Gst.State",
"Gst.StateChangeReturn", "Gst.StateChangeReturn",
@ -64,6 +65,8 @@ generate = [
"Gst.TocEntryType", "Gst.TocEntryType",
"Gst.TocLoopType", "Gst.TocLoopType",
"Gst.TocSetter", "Gst.TocSetter",
"Gst.ClockType",
"Gst.ClockReturn",
] ]
manual = [ manual = [
@ -193,6 +196,14 @@ status = "generate"
[object.function.return] [object.function.return]
bool_return_is_error = "Timed out waiting for sync" bool_return_is_error = "Timed out waiting for sync"
[[object]]
name = "Gst.SystemClock"
status = "generate"
[[object.function]]
name = "obtain"
[object.function.return]
nullable = false
[[object]] [[object]]
name = "Gst.Element" name = "Gst.Element"
status = "generate" status = "generate"

View file

@ -1,8 +1,9 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
#[allow(unused_imports)] #[allow(unused_imports)]
use auto::*; use auto::*;
pub type ClockTime = u64; pub type ClockTime = u64;
pub type ClockTimeDiff = i64;
pub type ElementFactoryListType = u64; pub type ElementFactoryListType = u64;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ChildProxy; use ChildProxy;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ClockTime; use ClockTime;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ffi; use ffi;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ClockTime; use ClockTime;
@ -46,11 +46,11 @@ impl Clock {
// unsafe { TODO: call ffi::gst_clock_id_unschedule() } // unsafe { TODO: call ffi::gst_clock_id_unschedule() }
//} //}
//pub fn id_wait(id: /*Unimplemented*/ClockID) -> (/*Ignored*/ClockReturn, ClockTimeDiff) { //pub fn id_wait(id: /*Unimplemented*/ClockID) -> (ClockReturn, ClockTimeDiff) {
// unsafe { TODO: call ffi::gst_clock_id_wait() } // unsafe { TODO: call ffi::gst_clock_id_wait() }
//} //}
//pub fn id_wait_async<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(id: /*Unimplemented*/ClockID, func: /*Unknown conversion*//*Unimplemented*/ClockCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> /*Ignored*/ClockReturn { //pub fn id_wait_async<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(id: /*Unimplemented*/ClockID, func: /*Unknown conversion*//*Unimplemented*/ClockCallback, user_data: P, destroy_data: /*Unknown conversion*//*Unimplemented*/DestroyNotify) -> ClockReturn {
// unsafe { TODO: call ffi::gst_clock_id_wait_async() } // unsafe { TODO: call ffi::gst_clock_id_wait_async() }
//} //}
} }

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ffi; use ffi;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Caps; use Caps;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Bus; use Bus;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Bus; use Bus;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use DeviceProvider; use DeviceProvider;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Bus; use Bus;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Caps; use Caps;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ffi; use ffi;
@ -191,6 +191,141 @@ impl SetValue for CapsIntersectMode {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum ClockReturn {
Ok,
Early,
Unscheduled,
Busy,
Badtime,
Error,
Unsupported,
Done,
#[doc(hidden)]
__Unknown(i32),
}
#[doc(hidden)]
impl ToGlib for ClockReturn {
type GlibType = ffi::GstClockReturn;
fn to_glib(&self) -> ffi::GstClockReturn {
match *self {
ClockReturn::Ok => ffi::GST_CLOCK_OK,
ClockReturn::Early => ffi::GST_CLOCK_EARLY,
ClockReturn::Unscheduled => ffi::GST_CLOCK_UNSCHEDULED,
ClockReturn::Busy => ffi::GST_CLOCK_BUSY,
ClockReturn::Badtime => ffi::GST_CLOCK_BADTIME,
ClockReturn::Error => ffi::GST_CLOCK_ERROR,
ClockReturn::Unsupported => ffi::GST_CLOCK_UNSUPPORTED,
ClockReturn::Done => ffi::GST_CLOCK_DONE,
ClockReturn::__Unknown(value) => unsafe{std::mem::transmute(value)}
}
}
}
#[doc(hidden)]
impl FromGlib<ffi::GstClockReturn> for ClockReturn {
fn from_glib(value: ffi::GstClockReturn) -> Self {
skip_assert_initialized!();
match value as i32 {
0 => ClockReturn::Ok,
1 => ClockReturn::Early,
2 => ClockReturn::Unscheduled,
3 => ClockReturn::Busy,
4 => ClockReturn::Badtime,
5 => ClockReturn::Error,
6 => ClockReturn::Unsupported,
7 => ClockReturn::Done,
value => ClockReturn::__Unknown(value),
}
}
}
impl StaticType for ClockReturn {
fn static_type() -> Type {
unsafe { from_glib(ffi::gst_clock_return_get_type()) }
}
}
impl<'a> FromValueOptional<'a> for ClockReturn {
unsafe fn from_value_optional(value: &Value) -> Option<Self> {
Some(FromValue::from_value(value))
}
}
impl<'a> FromValue<'a> for ClockReturn {
unsafe fn from_value(value: &Value) -> Self {
from_glib(std::mem::transmute::<i32, ffi::GstClockReturn>(gobject_ffi::g_value_get_enum(value.to_glib_none().0)))
}
}
impl SetValue for ClockReturn {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum ClockType {
Realtime,
Monotonic,
Other,
#[doc(hidden)]
__Unknown(i32),
}
#[doc(hidden)]
impl ToGlib for ClockType {
type GlibType = ffi::GstClockType;
fn to_glib(&self) -> ffi::GstClockType {
match *self {
ClockType::Realtime => ffi::GST_CLOCK_TYPE_REALTIME,
ClockType::Monotonic => ffi::GST_CLOCK_TYPE_MONOTONIC,
ClockType::Other => ffi::GST_CLOCK_TYPE_OTHER,
ClockType::__Unknown(value) => unsafe{std::mem::transmute(value)}
}
}
}
#[doc(hidden)]
impl FromGlib<ffi::GstClockType> for ClockType {
fn from_glib(value: ffi::GstClockType) -> Self {
skip_assert_initialized!();
match value as i32 {
0 => ClockType::Realtime,
1 => ClockType::Monotonic,
2 => ClockType::Other,
value => ClockType::__Unknown(value),
}
}
}
impl StaticType for ClockType {
fn static_type() -> Type {
unsafe { from_glib(ffi::gst_clock_type_get_type()) }
}
}
impl<'a> FromValueOptional<'a> for ClockType {
unsafe fn from_value_optional(value: &Value) -> Option<Self> {
Some(FromValue::from_value(value))
}
}
impl<'a> FromValue<'a> for ClockType {
unsafe fn from_value(value: &Value) -> Self {
from_glib(std::mem::transmute::<i32, ffi::GstClockType>(gobject_ffi::g_value_get_enum(value.to_glib_none().0)))
}
}
impl SetValue for ClockType {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum CoreError { pub enum CoreError {
Failed, Failed,

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ffi; use ffi;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Bin; use Bin;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Object; use Object;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
mod bin; mod bin;
@ -84,6 +84,10 @@ pub use self::stream_collection::StreamCollection;
#[cfg(feature = "v1_10")] #[cfg(feature = "v1_10")]
pub use self::stream_collection::StreamCollectionExt; pub use self::stream_collection::StreamCollectionExt;
mod system_clock;
pub use self::system_clock::SystemClock;
pub use self::system_clock::SystemClockExt;
mod tag_setter; mod tag_setter;
pub use self::tag_setter::TagSetter; pub use self::tag_setter::TagSetter;
pub use self::tag_setter::TagSetterExt; pub use self::tag_setter::TagSetterExt;
@ -103,6 +107,8 @@ mod enums;
pub use self::enums::BufferingMode; pub use self::enums::BufferingMode;
pub use self::enums::BusSyncReply; pub use self::enums::BusSyncReply;
pub use self::enums::CapsIntersectMode; pub use self::enums::CapsIntersectMode;
pub use self::enums::ClockReturn;
pub use self::enums::ClockType;
pub use self::enums::CoreError; pub use self::enums::CoreError;
pub use self::enums::EventType; pub use self::enums::EventType;
pub use self::enums::FlowReturn; pub use self::enums::FlowReturn;
@ -210,6 +216,7 @@ pub use self::flags::STREAM_TYPE_TEXT;
mod alias; mod alias;
pub use self::alias::ClockTime; pub use self::alias::ClockTime;
pub use self::alias::ClockTimeDiff;
pub use self::alias::ElementFactoryListType; pub use self::alias::ElementFactoryListType;
pub mod functions; pub mod functions;
@ -235,6 +242,7 @@ pub mod traits {
pub use super::StreamExt; pub use super::StreamExt;
#[cfg(feature = "v1_10")] #[cfg(feature = "v1_10")]
pub use super::StreamCollectionExt; pub use super::StreamCollectionExt;
pub use super::SystemClockExt;
pub use super::TagSetterExt; pub use super::TagSetterExt;
pub use super::TocSetterExt; pub use super::TocSetterExt;
pub use super::URIHandlerExt; pub use super::URIHandlerExt;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ClockTime; use ClockTime;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Caps; use Caps;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Caps; use Caps;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Bin; use Bin;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Error; use Error;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use ffi; use ffi;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Iterator; use Iterator;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
#[cfg(feature = "v1_10")] #[cfg(feature = "v1_10")]

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Object; use Object;

View file

@ -0,0 +1,66 @@
// This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT
use Clock;
use ClockType;
use Object;
use ffi;
use glib;
use glib::Value;
use glib::object::IsA;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use std::mem;
use std::mem::transmute;
use std::ptr;
glib_wrapper! {
pub struct SystemClock(Object<ffi::GstSystemClock>): Clock, Object;
match fn {
get_type => || ffi::gst_system_clock_get_type(),
}
}
impl SystemClock {
pub fn obtain() -> Clock {
assert_initialized_main_thread!();
unsafe {
from_glib_full(ffi::gst_system_clock_obtain())
}
}
pub fn set_default<P: IsA<Clock>>(new_clock: &P) {
skip_assert_initialized!();
unsafe {
ffi::gst_system_clock_set_default(new_clock.to_glib_none().0);
}
}
}
unsafe impl Send for SystemClock {}
unsafe impl Sync for SystemClock {}
pub trait SystemClockExt {
fn get_property_clock_type(&self) -> ClockType;
fn set_property_clock_type(&self, clock_type: ClockType);
}
impl<O: IsA<SystemClock> + IsA<glib::object::Object>> SystemClockExt for O {
fn get_property_clock_type(&self) -> ClockType {
let mut value = Value::from(&0);
unsafe {
gobject_ffi::g_object_get_property(self.to_glib_none().0, "clock-type".to_glib_none().0, value.to_glib_none_mut().0);
from_glib(transmute(value.get::<i32>().unwrap()))
}
}
fn set_property_clock_type(&self, clock_type: ClockType) {
let clock_type = clock_type.to_glib() as i32;
unsafe {
gobject_ffi::g_object_set_property(self.to_glib_none().0, "clock-type".to_glib_none().0, Value::from(&clock_type).to_glib_none().0);
}
}
}

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Element; use Element;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Element; use Element;

View file

@ -1,4 +1,4 @@
// This file was generated by gir (3294959) from gir-files (???) // This file was generated by gir (cf27827) from gir-files (???)
// DO NOT EDIT // DO NOT EDIT
use Error; use Error;

View file

@ -26,13 +26,15 @@ unsafe extern "C" fn trampoline_watch(
func: gpointer, func: gpointer,
) -> gboolean { ) -> gboolean {
let _guard = CallbackGuard::new(); let _guard = CallbackGuard::new();
let func: &RefCell<Box<FnMut(&Bus, &Message) -> Continue + 'static>> = transmute(func); let func: &RefCell<Box<FnMut(&Bus, &Message) -> Continue + Send + 'static>> = transmute(func);
(&mut *func.borrow_mut())(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib() (&mut *func.borrow_mut())(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib()
} }
unsafe extern "C" fn destroy_closure_watch(ptr: gpointer) { unsafe extern "C" fn destroy_closure_watch(ptr: gpointer) {
let _guard = CallbackGuard::new(); let _guard = CallbackGuard::new();
Box::<RefCell<Box<FnMut(&Bus, &Message) -> Continue + 'static>>>::from_raw(ptr as *mut _); Box::<RefCell<Box<FnMut(&Bus, &Message) -> Continue + Send + 'static>>>::from_raw(
ptr as *mut _,
);
} }
fn into_raw_watch<F: FnMut(&Bus, &Message) -> Continue + Send + 'static>(func: F) -> gpointer { fn into_raw_watch<F: FnMut(&Bus, &Message) -> Continue + Send + 'static>(func: F) -> gpointer {
@ -47,17 +49,19 @@ unsafe extern "C" fn trampoline_sync(
func: gpointer, func: gpointer,
) -> ffi::GstBusSyncReply { ) -> ffi::GstBusSyncReply {
let _guard = CallbackGuard::new(); let _guard = CallbackGuard::new();
let f: &&(Fn(&Bus, &Message) -> BusSyncReply + 'static) = transmute(func); let f: &&(Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static) = transmute(func);
f(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib() f(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib()
} }
unsafe extern "C" fn destroy_closure_sync(ptr: gpointer) { unsafe extern "C" fn destroy_closure_sync(ptr: gpointer) {
let _guard = CallbackGuard::new(); let _guard = CallbackGuard::new();
Box::<Box<Fn(&Bus, &Message) -> BusSyncReply + 'static>>::from_raw(ptr as *mut _); Box::<Box<Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static>>::from_raw(ptr as *mut _);
} }
fn into_raw_sync<F: Fn(&Bus, &Message) -> BusSyncReply + Send + 'static>(func: F) -> gpointer { fn into_raw_sync<F: Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static>(
let func: Box<Box<Fn(&Bus, &Message) -> BusSyncReply + Send + 'static>> = func: F,
) -> gpointer {
let func: Box<Box<Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static>> =
Box::new(Box::new(func)); Box::new(Box::new(func));
Box::into_raw(func) as gpointer Box::into_raw(func) as gpointer
} }

232
gstreamer/src/clock.rs Normal file
View file

@ -0,0 +1,232 @@
// Copyright (C) 2017 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 Clock;
use ClockTime;
use ClockTimeDiff;
use ClockReturn;
use std::mem;
use std::cmp;
use std::ptr;
use std::mem::transmute;
use ffi;
use glib;
use glib::IsA;
use glib::translate::*;
use glib::source::CallbackGuard;
use glib_ffi;
use glib_ffi::{gboolean, gpointer};
use libc::c_void;
glib_wrapper! {
pub struct ClockId(Shared<c_void>);
match fn {
ref => |ptr| ffi::gst_clock_id_ref(ptr),
unref => |ptr| ffi::gst_clock_id_unref(ptr),
}
}
unsafe extern "C" fn trampoline_wait_async(
clock: *mut ffi::GstClock,
time: ClockTime,
id: gpointer,
func: gpointer,
) -> gboolean {
let _guard = CallbackGuard::new();
let f: &&(Fn(&Clock, ClockTime, &ClockId) -> bool + Send + 'static) = transmute(func);
f(&from_glib_none(clock), time, &from_glib_none(id)).to_glib()
}
unsafe extern "C" fn destroy_closure_wait_async(ptr: gpointer) {
let _guard = CallbackGuard::new();
Box::<Box<Fn(&Clock, ClockTime, &ClockId) -> bool + Send + 'static>>::from_raw(ptr as *mut _);
}
fn into_raw_wait_async<F: Fn(&Clock, ClockTime, &ClockId) -> bool + Send + 'static>(
func: F,
) -> gpointer {
let func: Box<Box<Fn(&Clock, ClockTime, &ClockId) -> bool + Send + 'static>> =
Box::new(Box::new(func));
Box::into_raw(func) as gpointer
}
impl ClockId {
pub fn get_time(&self) -> ClockTime {
unsafe { ffi::gst_clock_id_get_time(self.to_glib_none().0) }
}
pub fn unschedule(&self) {
unsafe { ffi::gst_clock_id_unschedule(self.to_glib_none().0) }
}
pub fn wait(&self) -> (ClockReturn, ClockTimeDiff) {
unsafe {
let mut jitter = mem::uninitialized();
let res = ffi::gst_clock_id_wait(self.to_glib_none().0, &mut jitter);
(from_glib(res), jitter)
}
}
pub fn wait_async<F>(&self, func: F) -> ClockReturn
where
F: Fn(&Clock, ClockTime, &ClockId) -> bool + Send + 'static,
{
unsafe {
from_glib(ffi::gst_clock_id_wait_async(
self.to_glib_none().0,
Some(trampoline_wait_async),
into_raw_wait_async(func),
Some(destroy_closure_wait_async),
))
}
}
}
impl PartialOrd for ClockId {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ClockId {
fn cmp(&self, other: &Self) -> cmp::Ordering {
unsafe {
let res = ffi::gst_clock_id_compare_func(self.to_glib_none().0, other.to_glib_none().0);
if res < 0 {
cmp::Ordering::Less
} else if res > 0 {
cmp::Ordering::Greater
} else {
cmp::Ordering::Equal
}
}
}
}
impl PartialEq for ClockId {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == cmp::Ordering::Equal
}
}
impl Eq for ClockId {}
unsafe impl Send for ClockId {}
unsafe impl Sync for ClockId {}
pub trait ClockExtManual {
fn new_periodic_id(&self, start_time: ClockTime, interval: ClockTime) -> Option<ClockId>;
fn periodic_id_reinit(
&self,
id: &ClockId,
start_time: ClockTime,
interval: ClockTime,
) -> Result<(), glib::BoolError>;
fn new_single_shot_id(&self, time: ClockTime) -> Option<ClockId>;
fn single_shot_id_reinit(&self, id: &ClockId, time: ClockTime) -> Result<(), glib::BoolError>;
}
impl<O: IsA<Clock> + IsA<glib::object::Object>> ClockExtManual for O {
fn new_periodic_id(&self, start_time: ClockTime, interval: ClockTime) -> Option<ClockId> {
unsafe {
from_glib_full(ffi::gst_clock_new_periodic_id(
self.to_glib_none().0,
start_time,
interval,
))
}
}
fn periodic_id_reinit(
&self,
id: &ClockId,
start_time: ClockTime,
interval: ClockTime,
) -> Result<(), glib::BoolError> {
unsafe {
let res: bool = from_glib(ffi::gst_clock_periodic_id_reinit(
self.to_glib_none().0,
id.to_glib_none().0,
start_time,
interval,
));
if res {
Ok(())
} else {
Err(glib::BoolError("Failed to reinit periodic clock id"))
}
}
}
fn new_single_shot_id(&self, time: ClockTime) -> Option<ClockId> {
unsafe {
from_glib_full(ffi::gst_clock_new_single_shot_id(
self.to_glib_none().0,
time,
))
}
}
fn single_shot_id_reinit(&self, id: &ClockId, time: ClockTime) -> Result<(), glib::BoolError> {
unsafe {
let res: bool = from_glib(ffi::gst_clock_single_shot_id_reinit(
self.to_glib_none().0,
id.to_glib_none().0,
time,
));
if res {
Ok(())
} else {
Err(glib::BoolError("Failed to reinit single shot clock id"))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use super::super::*;
use std::sync::mpsc::channel;
#[test]
fn test_wait() {
::init().unwrap();
let clock = SystemClock::obtain();
let now = clock.get_time();
let id = clock.new_single_shot_id(now + 20_000_000).unwrap();
let (res, _) = id.wait();
assert!(res == ClockReturn::Ok || res == ClockReturn::Early);
}
#[test]
fn test_wait_async() {
::init().unwrap();
let (sender, receiver) = channel();
let clock = SystemClock::obtain();
let now = clock.get_time();
let id = clock.new_single_shot_id(now + 20_000_000).unwrap();
let res = id.wait_async(move |_, _, _| {
sender.send(()).unwrap();
true
});
assert!(res == ClockReturn::Ok);
assert_eq!(receiver.recv(), Ok(()));
}
}

View file

@ -102,6 +102,9 @@ pub use segment::*;
pub mod toc; pub mod toc;
pub use toc::{Toc, TocEntry, TocEntryRef, TocRef}; pub use toc::{Toc, TocEntry, TocEntryRef, TocRef};
mod clock;
pub use clock::{ClockId, ClockExtManual};
use std::ptr; use std::ptr;
pub fn init() -> Result<(), glib::Error> { pub fn init() -> Result<(), glib::Error> {