2017-07-24 08:51:14 +00:00
|
|
|
// 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.
|
|
|
|
|
2017-07-25 12:08:42 +00:00
|
|
|
use Buffer;
|
2017-07-28 18:18:08 +00:00
|
|
|
use BufferList;
|
2018-04-01 08:30:03 +00:00
|
|
|
use Event;
|
2018-10-28 22:57:21 +00:00
|
|
|
use FlowError;
|
2018-04-01 08:30:03 +00:00
|
|
|
use FlowReturn;
|
2019-01-08 16:13:37 +00:00
|
|
|
use FlowSuccess;
|
2017-11-11 10:21:55 +00:00
|
|
|
use Format;
|
2017-12-09 16:20:21 +00:00
|
|
|
use FormattedValue;
|
2018-04-01 08:30:03 +00:00
|
|
|
use GenericFormattedValue;
|
2019-01-24 21:11:43 +00:00
|
|
|
use LoggableError;
|
2018-04-01 08:30:03 +00:00
|
|
|
use Pad;
|
2020-01-06 15:23:39 +00:00
|
|
|
use PadFlags;
|
2019-01-08 16:13:37 +00:00
|
|
|
use PadLinkCheck;
|
|
|
|
use PadLinkError;
|
|
|
|
use PadLinkReturn;
|
|
|
|
use PadLinkSuccess;
|
2018-04-01 08:30:03 +00:00
|
|
|
use PadProbeReturn;
|
|
|
|
use PadProbeType;
|
2017-07-29 15:09:14 +00:00
|
|
|
use Query;
|
2017-07-29 13:04:34 +00:00
|
|
|
use QueryRef;
|
2018-04-01 08:30:03 +00:00
|
|
|
use SpecificFormattedValue;
|
2017-10-15 08:08:56 +00:00
|
|
|
use StaticPadTemplate;
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2018-04-01 08:30:03 +00:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::mem;
|
2020-01-05 02:38:55 +00:00
|
|
|
use std::num::NonZeroU64;
|
2017-07-25 12:21:03 +00:00
|
|
|
use std::ptr;
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2017-09-17 22:53:02 +00:00
|
|
|
use glib;
|
2019-01-30 13:02:03 +00:00
|
|
|
use glib::object::{Cast, IsA};
|
2018-07-27 10:36:40 +00:00
|
|
|
use glib::translate::{
|
2020-06-22 08:48:56 +00:00
|
|
|
from_glib, from_glib_borrow, from_glib_full, FromGlib, FromGlibPtrBorrow, ToGlib, ToGlibPtr,
|
2018-07-27 10:36:40 +00:00
|
|
|
};
|
2019-01-16 11:32:58 +00:00
|
|
|
use glib::StaticType;
|
2019-03-19 07:58:20 +00:00
|
|
|
use glib_sys;
|
|
|
|
use glib_sys::gpointer;
|
2017-07-24 08:51:14 +00:00
|
|
|
|
|
|
|
use libc;
|
|
|
|
|
2019-03-19 07:58:20 +00:00
|
|
|
use gst_sys;
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2018-01-25 19:06:39 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2020-01-05 02:38:55 +00:00
|
|
|
pub struct PadProbeId(NonZeroU64);
|
2017-07-24 22:17:50 +00:00
|
|
|
|
|
|
|
impl ToGlib for PadProbeId {
|
|
|
|
type GlibType = libc::c_ulong;
|
|
|
|
|
|
|
|
fn to_glib(&self) -> libc::c_ulong {
|
2020-01-05 02:38:55 +00:00
|
|
|
self.0.get() as libc::c_ulong
|
2017-07-24 22:17:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromGlib<libc::c_ulong> for PadProbeId {
|
|
|
|
fn from_glib(val: libc::c_ulong) -> PadProbeId {
|
2017-08-30 11:39:09 +00:00
|
|
|
skip_assert_initialized!();
|
2018-01-25 19:06:39 +00:00
|
|
|
assert_ne!(val, 0);
|
2020-01-05 02:38:55 +00:00
|
|
|
PadProbeId(unsafe { NonZeroU64::new_unchecked(val as u64) })
|
2017-07-24 22:17:50 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2017-07-29 15:09:14 +00:00
|
|
|
pub struct PadProbeInfo<'a> {
|
2017-07-24 08:51:14 +00:00
|
|
|
pub mask: PadProbeType,
|
|
|
|
pub id: PadProbeId,
|
|
|
|
pub offset: u64,
|
|
|
|
pub size: u32,
|
2017-07-29 15:09:14 +00:00
|
|
|
pub data: Option<PadProbeData<'a>>,
|
2020-11-18 15:56:23 +00:00
|
|
|
pub flow_res: Result<FlowSuccess, FlowError>,
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2017-07-29 15:09:14 +00:00
|
|
|
pub enum PadProbeData<'a> {
|
2017-07-25 12:08:42 +00:00
|
|
|
Buffer(Buffer),
|
2017-07-28 18:18:08 +00:00
|
|
|
BufferList(BufferList),
|
2017-07-29 15:09:14 +00:00
|
|
|
Query(&'a mut QueryRef),
|
2017-07-30 14:11:47 +00:00
|
|
|
Event(Event),
|
2018-07-26 00:14:04 +00:00
|
|
|
#[doc(hidden)]
|
2019-03-19 07:58:20 +00:00
|
|
|
__Unknown(*mut gst_sys::GstMiniObject),
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 15:04:42 +00:00
|
|
|
unsafe impl<'a> Send for PadProbeData<'a> {}
|
|
|
|
unsafe impl<'a> Sync for PadProbeData<'a> {}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2020-02-28 14:29:48 +00:00
|
|
|
#[must_use = "if unused the StreamLock will immediately unlock"]
|
2020-06-22 08:48:56 +00:00
|
|
|
pub struct StreamLock<'a>(&'a Pad);
|
|
|
|
impl<'a> Drop for StreamLock<'a> {
|
2017-08-03 08:09:39 +00:00
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let pad: *mut gst_sys::GstPad = self.0.to_glib_none().0;
|
|
|
|
glib_sys::g_rec_mutex_unlock(&mut (*pad).stream_rec_lock);
|
2017-08-03 08:09:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-29 17:11:00 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum PadGetRangeSuccess {
|
|
|
|
FilledBuffer,
|
|
|
|
NewBuffer(::Buffer),
|
|
|
|
}
|
|
|
|
|
2018-12-08 09:22:42 +00:00
|
|
|
pub trait PadExtManual: 'static {
|
2018-06-14 12:45:54 +00:00
|
|
|
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId>
|
2017-07-24 08:51:14 +00:00
|
|
|
where
|
2019-01-30 13:02:03 +00:00
|
|
|
F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static;
|
2017-07-24 08:51:14 +00:00
|
|
|
fn remove_probe(&self, id: PadProbeId);
|
2017-07-25 12:21:03 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>;
|
|
|
|
fn push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>;
|
2017-07-25 12:21:03 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>;
|
|
|
|
fn push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>;
|
2017-08-14 19:21:11 +00:00
|
|
|
|
2018-10-28 22:57:21 +00:00
|
|
|
fn pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>;
|
2020-03-28 17:57:49 +00:00
|
|
|
fn pull_range_fill(
|
|
|
|
&self,
|
|
|
|
offset: u64,
|
|
|
|
buffer: &mut ::BufferRef,
|
|
|
|
size: u32,
|
|
|
|
) -> Result<(), FlowError>;
|
2018-10-28 22:57:21 +00:00
|
|
|
fn get_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>;
|
2020-03-28 17:57:49 +00:00
|
|
|
fn get_range_fill(
|
|
|
|
&self,
|
|
|
|
offset: u64,
|
|
|
|
buffer: &mut ::BufferRef,
|
|
|
|
size: u32,
|
|
|
|
) -> Result<(), FlowError>;
|
2017-07-29 13:04:34 +00:00
|
|
|
|
|
|
|
fn peer_query(&self, query: &mut QueryRef) -> bool;
|
|
|
|
fn query(&self, query: &mut QueryRef) -> bool;
|
2019-05-23 18:19:24 +00:00
|
|
|
fn query_default<P: IsA<::Object>>(&self, parent: Option<&P>, query: &mut QueryRef) -> bool;
|
2017-07-29 13:04:34 +00:00
|
|
|
fn proxy_query_caps(&self, query: &mut QueryRef) -> bool;
|
|
|
|
fn proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool;
|
2017-08-01 12:58:50 +00:00
|
|
|
|
2019-05-23 18:19:24 +00:00
|
|
|
fn event_default<P: IsA<::Object>>(&self, parent: Option<&P>, event: Event) -> bool;
|
2017-08-01 12:58:50 +00:00
|
|
|
fn push_event(&self, event: Event) -> bool;
|
|
|
|
fn send_event(&self, event: Event) -> bool;
|
2017-08-03 08:09:39 +00:00
|
|
|
|
2020-11-18 15:56:23 +00:00
|
|
|
fn get_last_flow_result(&self) -> Result<FlowSuccess, FlowError>;
|
2019-01-08 16:13:37 +00:00
|
|
|
|
2017-09-17 21:24:36 +00:00
|
|
|
fn iterate_internal_links(&self) -> ::Iterator<Pad>;
|
2019-05-23 18:19:24 +00:00
|
|
|
fn iterate_internal_links_default<P: IsA<::Object>>(
|
2017-09-17 21:24:36 +00:00
|
|
|
&self,
|
2019-05-23 18:19:24 +00:00
|
|
|
parent: Option<&P>,
|
2017-09-17 21:24:36 +00:00
|
|
|
) -> ::Iterator<Pad>;
|
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn link<P: IsA<Pad>>(&self, sinkpad: &P) -> Result<PadLinkSuccess, PadLinkError>;
|
|
|
|
fn link_full<P: IsA<Pad>>(
|
|
|
|
&self,
|
|
|
|
sinkpad: &P,
|
|
|
|
flags: PadLinkCheck,
|
|
|
|
) -> Result<PadLinkSuccess, PadLinkError>;
|
|
|
|
|
2017-08-03 08:09:39 +00:00
|
|
|
fn stream_lock(&self) -> StreamLock;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_activate_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_activatemode_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError>
|
2019-01-16 20:23:56 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_chain_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_chain_list_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_event_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_event_full_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_getrange_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2020-03-29 17:11:00 +00:00
|
|
|
F: Fn(
|
|
|
|
&Self,
|
|
|
|
Option<&::Object>,
|
|
|
|
u64,
|
|
|
|
Option<&mut ::BufferRef>,
|
|
|
|
u32,
|
|
|
|
) -> Result<PadGetRangeSuccess, ::FlowError>
|
2017-09-16 22:45:21 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_link_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_query_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static;
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_unlink_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static;
|
2017-09-17 21:32:29 +00:00
|
|
|
|
2017-09-17 22:53:02 +00:00
|
|
|
fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>;
|
2017-11-11 10:21:55 +00:00
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
|
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
) -> Option<U>;
|
|
|
|
fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
|
2017-11-11 10:21:55 +00:00
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
dest_format: Format,
|
2017-12-09 16:20:21 +00:00
|
|
|
) -> Option<GenericFormattedValue>;
|
|
|
|
|
|
|
|
fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
|
|
|
|
fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
|
|
|
|
|
|
|
|
fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
|
|
|
|
fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
|
|
|
|
|
|
|
|
fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
|
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
) -> Option<U>;
|
|
|
|
fn query_convert_generic<V: Into<GenericFormattedValue>>(
|
2017-11-11 10:21:55 +00:00
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
dest_format: Format,
|
2017-12-09 16:20:21 +00:00
|
|
|
) -> Option<GenericFormattedValue>;
|
|
|
|
|
|
|
|
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
|
|
|
|
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
|
|
|
|
|
|
|
|
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
|
|
|
|
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
|
2018-08-01 16:28:57 +00:00
|
|
|
|
|
|
|
fn get_mode(&self) -> ::PadMode;
|
2018-08-13 16:58:30 +00:00
|
|
|
|
|
|
|
fn sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>(
|
|
|
|
&self,
|
|
|
|
func: F,
|
|
|
|
);
|
2019-01-08 16:13:37 +00:00
|
|
|
|
|
|
|
fn store_sticky_event(&self, event: &Event) -> Result<FlowSuccess, FlowError>;
|
2019-05-11 10:13:33 +00:00
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn set_pad_flags(&self, flags: PadFlags);
|
2019-05-11 10:13:33 +00:00
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn unset_pad_flags(&self, flags: PadFlags);
|
2019-05-11 12:51:33 +00:00
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn get_pad_flags(&self) -> PadFlags;
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<O: IsA<Pad>> PadExtManual for O {
|
2018-06-14 12:45:54 +00:00
|
|
|
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId>
|
2017-07-24 08:51:14 +00:00
|
|
|
where
|
2019-01-30 13:02:03 +00:00
|
|
|
F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
|
2017-07-24 08:51:14 +00:00
|
|
|
{
|
|
|
|
unsafe {
|
2019-01-30 13:02:03 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
2019-03-19 07:58:20 +00:00
|
|
|
let id = gst_sys::gst_pad_add_probe(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-24 08:51:14 +00:00
|
|
|
mask.to_glib(),
|
2019-01-30 13:02:03 +00:00
|
|
|
Some(trampoline_pad_probe::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
2017-07-24 08:51:14 +00:00
|
|
|
);
|
|
|
|
|
2018-06-14 12:45:54 +00:00
|
|
|
if id == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(from_glib(id))
|
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn remove_probe(&self, id: PadProbeId) {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
gst_sys::gst_pad_remove_probe(self.as_ref().to_glib_none().0, id.to_glib());
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-25 12:21:03 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
FlowReturn::from_glib(gst_sys::gst_pad_chain(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
buffer.into_ptr(),
|
|
|
|
))
|
|
|
|
.into_result()
|
2019-01-08 16:13:37 +00:00
|
|
|
}
|
2017-07-25 12:21:03 +00:00
|
|
|
}
|
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
FlowReturn::from_glib(gst_sys::gst_pad_push(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
buffer.into_ptr(),
|
|
|
|
))
|
|
|
|
.into_result()
|
2019-01-08 16:13:37 +00:00
|
|
|
}
|
2017-07-25 12:21:03 +00:00
|
|
|
}
|
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
|
2017-09-10 11:55:29 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
FlowReturn::from_glib(gst_sys::gst_pad_chain_list(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-09-10 11:55:29 +00:00
|
|
|
list.into_ptr(),
|
|
|
|
))
|
2019-01-08 16:13:37 +00:00
|
|
|
.into_result()
|
2017-09-10 11:55:29 +00:00
|
|
|
}
|
2017-08-14 19:21:11 +00:00
|
|
|
}
|
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
|
2017-09-10 11:55:29 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
FlowReturn::from_glib(gst_sys::gst_pad_push_list(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-09-10 11:55:29 +00:00
|
|
|
list.into_ptr(),
|
|
|
|
))
|
2019-01-08 16:13:37 +00:00
|
|
|
.into_result()
|
2017-09-10 11:55:29 +00:00
|
|
|
}
|
2017-08-14 19:21:11 +00:00
|
|
|
}
|
|
|
|
|
2018-10-28 22:57:21 +00:00
|
|
|
fn get_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError> {
|
2017-07-25 12:21:03 +00:00
|
|
|
unsafe {
|
|
|
|
let mut buffer = ptr::null_mut();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret: FlowReturn = from_glib(gst_sys::gst_pad_get_range(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-25 12:21:03 +00:00
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
&mut buffer,
|
|
|
|
));
|
2018-10-28 22:57:21 +00:00
|
|
|
ret.into_result_value(|| from_glib_full(buffer))
|
2017-07-25 12:21:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-28 17:57:49 +00:00
|
|
|
fn get_range_fill(
|
|
|
|
&self,
|
|
|
|
offset: u64,
|
|
|
|
buffer: &mut ::BufferRef,
|
|
|
|
size: u32,
|
|
|
|
) -> Result<(), FlowError> {
|
|
|
|
assert!(buffer.get_size() >= size as usize);
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let mut buffer_ref = buffer.as_mut_ptr();
|
|
|
|
let ret: FlowReturn = from_glib(gst_sys::gst_pad_get_range(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
&mut buffer_ref,
|
|
|
|
));
|
|
|
|
match ret.into_result_value(|| ()) {
|
|
|
|
Ok(_) => {
|
|
|
|
if buffer.as_mut_ptr() != buffer_ref {
|
|
|
|
gst_sys::gst_mini_object_unref(buffer_ref as *mut _);
|
|
|
|
Err(::FlowError::Error)
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-28 22:57:21 +00:00
|
|
|
fn pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError> {
|
2017-07-25 12:21:03 +00:00
|
|
|
unsafe {
|
|
|
|
let mut buffer = ptr::null_mut();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret: FlowReturn = from_glib(gst_sys::gst_pad_pull_range(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-25 12:21:03 +00:00
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
&mut buffer,
|
|
|
|
));
|
2018-10-28 22:57:21 +00:00
|
|
|
ret.into_result_value(|| from_glib_full(buffer))
|
2017-07-25 12:21:03 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-29 13:04:34 +00:00
|
|
|
|
2020-03-28 17:57:49 +00:00
|
|
|
fn pull_range_fill(
|
|
|
|
&self,
|
|
|
|
offset: u64,
|
|
|
|
buffer: &mut ::BufferRef,
|
|
|
|
size: u32,
|
|
|
|
) -> Result<(), FlowError> {
|
|
|
|
assert!(buffer.get_size() >= size as usize);
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let mut buffer_ref = buffer.as_mut_ptr();
|
|
|
|
let ret: FlowReturn = from_glib(gst_sys::gst_pad_pull_range(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
&mut buffer_ref,
|
|
|
|
));
|
|
|
|
match ret.into_result_value(|| ()) {
|
|
|
|
Ok(_) => {
|
|
|
|
if buffer.as_mut_ptr() != buffer_ref {
|
|
|
|
gst_sys::gst_mini_object_unref(buffer_ref as *mut _);
|
|
|
|
Err(::FlowError::Error)
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-29 13:04:34 +00:00
|
|
|
fn query(&self, query: &mut QueryRef) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_query(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-31 11:16:42 +00:00
|
|
|
query.as_mut_ptr(),
|
|
|
|
))
|
2017-07-29 13:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peer_query(&self, query: &mut QueryRef) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_peer_query(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-31 11:16:42 +00:00
|
|
|
query.as_mut_ptr(),
|
|
|
|
))
|
2017-07-29 13:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-23 18:19:24 +00:00
|
|
|
fn query_default<P: IsA<::Object>>(&self, parent: Option<&P>, query: &mut QueryRef) -> bool {
|
2017-08-30 11:39:09 +00:00
|
|
|
skip_assert_initialized!();
|
2017-07-29 13:04:34 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_query_default(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
parent.map(|p| p.as_ref()).to_glib_none().0,
|
2017-07-31 11:16:42 +00:00
|
|
|
query.as_mut_ptr(),
|
|
|
|
))
|
2017-07-29 13:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_proxy_query_accept_caps(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-31 11:16:42 +00:00
|
|
|
query.as_mut_ptr(),
|
|
|
|
))
|
2017-07-29 13:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn proxy_query_caps(&self, query: &mut QueryRef) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_proxy_query_accept_caps(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-07-31 11:16:42 +00:00
|
|
|
query.as_mut_ptr(),
|
|
|
|
))
|
2017-07-29 13:04:34 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-01 12:58:50 +00:00
|
|
|
|
2019-05-23 18:19:24 +00:00
|
|
|
fn event_default<P: IsA<::Object>>(&self, parent: Option<&P>, event: Event) -> bool {
|
2017-08-30 11:39:09 +00:00
|
|
|
skip_assert_initialized!();
|
2017-08-01 12:58:50 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_event_default(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
parent.map(|p| p.as_ref()).to_glib_none().0,
|
2017-08-01 14:28:36 +00:00
|
|
|
event.into_ptr(),
|
|
|
|
))
|
2017-08-01 12:58:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn push_event(&self, event: Event) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_push_event(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-08-01 14:28:36 +00:00
|
|
|
event.into_ptr(),
|
|
|
|
))
|
2017-08-01 12:58:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn send_event(&self, event: Event) -> bool {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_send_event(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-08-01 14:28:36 +00:00
|
|
|
event.into_ptr(),
|
|
|
|
))
|
2017-08-01 12:58:50 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-03 08:09:39 +00:00
|
|
|
|
2020-11-18 15:56:23 +00:00
|
|
|
fn get_last_flow_result(&self) -> Result<FlowSuccess, FlowError> {
|
2019-01-16 11:32:58 +00:00
|
|
|
let ret: FlowReturn = unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_get_last_flow_return(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
))
|
|
|
|
};
|
2019-01-08 16:13:37 +00:00
|
|
|
ret.into_result()
|
|
|
|
}
|
|
|
|
|
2017-09-17 21:24:36 +00:00
|
|
|
fn iterate_internal_links(&self) -> ::Iterator<Pad> {
|
2019-01-16 11:32:58 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib_full(gst_sys::gst_pad_iterate_internal_links(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
))
|
|
|
|
}
|
2017-09-17 21:24:36 +00:00
|
|
|
}
|
|
|
|
|
2019-05-23 18:19:24 +00:00
|
|
|
fn iterate_internal_links_default<P: IsA<::Object>>(
|
2017-09-17 21:24:36 +00:00
|
|
|
&self,
|
2019-05-23 18:19:24 +00:00
|
|
|
parent: Option<&P>,
|
2017-09-17 21:24:36 +00:00
|
|
|
) -> ::Iterator<Pad> {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib_full(gst_sys::gst_pad_iterate_internal_links_default(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
parent.map(|p| p.as_ref()).to_glib_none().0,
|
2017-09-17 21:24:36 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
fn link<P: IsA<Pad>>(&self, sinkpad: &P) -> Result<PadLinkSuccess, PadLinkError> {
|
|
|
|
let ret: PadLinkReturn = unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_link(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
sinkpad.as_ref().to_glib_none().0,
|
2019-01-08 16:13:37 +00:00
|
|
|
))
|
|
|
|
};
|
|
|
|
ret.into_result()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn link_full<P: IsA<Pad>>(
|
|
|
|
&self,
|
|
|
|
sinkpad: &P,
|
|
|
|
flags: PadLinkCheck,
|
|
|
|
) -> Result<PadLinkSuccess, PadLinkError> {
|
|
|
|
let ret: PadLinkReturn = unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_link_full(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
sinkpad.as_ref().to_glib_none().0,
|
2019-01-08 16:13:37 +00:00
|
|
|
flags.to_glib(),
|
|
|
|
))
|
|
|
|
};
|
|
|
|
ret.into_result()
|
|
|
|
}
|
|
|
|
|
2017-08-03 08:09:39 +00:00
|
|
|
fn stream_lock(&self) -> StreamLock {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let ptr: &mut gst_sys::GstPad = &mut *(self.as_ptr() as *mut _);
|
|
|
|
glib_sys::g_rec_mutex_lock(&mut ptr.stream_rec_lock);
|
2020-06-22 08:48:56 +00:00
|
|
|
StreamLock(self.upcast_ref())
|
2017-08-03 08:09:39 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_activate_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_activate_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_activate_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_activatemode_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError>
|
2019-01-16 20:23:56 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_activatemode_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_activatemode_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_chain_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_chain_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_chain_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_chain_list_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_chain_list_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_chain_list_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_event_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_event_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_event_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_event_full_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_event_full_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_event_full_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_getrange_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2020-03-29 17:11:00 +00:00
|
|
|
F: Fn(
|
|
|
|
&Self,
|
|
|
|
Option<&::Object>,
|
|
|
|
u64,
|
|
|
|
Option<&mut ::BufferRef>,
|
|
|
|
u32,
|
|
|
|
) -> Result<PadGetRangeSuccess, ::FlowError>
|
2017-09-16 22:45:21 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_getrange_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_getrange_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_iterate_internal_links_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_iterate_internal_links_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_link_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
|
2019-01-08 16:13:37 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_link_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_link_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_query_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_query_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_query_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 15:28:04 +00:00
|
|
|
unsafe fn set_unlink_function<F>(&self, func: F)
|
2017-09-16 22:45:21 +00:00
|
|
|
where
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static,
|
2017-09-16 22:45:21 +00:00
|
|
|
{
|
2020-06-21 15:28:04 +00:00
|
|
|
let func_box: Box<F> = Box::new(func);
|
|
|
|
gst_sys::gst_pad_set_unlink_function_full(
|
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline_unlink_function::<Self, F>),
|
|
|
|
Box::into_raw(func_box) as gpointer,
|
|
|
|
Some(destroy_closure::<F>),
|
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
2017-09-17 21:32:29 +00:00
|
|
|
|
2017-09-17 22:53:02 +00:00
|
|
|
fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError> {
|
2017-09-17 21:32:29 +00:00
|
|
|
unsafe {
|
2019-01-04 12:15:58 +00:00
|
|
|
glib_result_from_gboolean!(
|
2019-03-19 07:58:20 +00:00
|
|
|
gst_sys::gst_pad_start_task(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2019-01-30 13:02:03 +00:00
|
|
|
Some(trampoline_pad_task::<F>),
|
2017-09-17 22:53:02 +00:00
|
|
|
into_raw_pad_task(func),
|
2019-03-01 17:49:27 +00:00
|
|
|
Some(destroy_closure_pad_task::<F>),
|
2017-09-17 22:53:02 +00:00
|
|
|
),
|
|
|
|
"Failed to start pad task",
|
|
|
|
)
|
2017-09-17 21:32:29 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-11 10:21:55 +00:00
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
|
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
) -> Option<U> {
|
|
|
|
let src_val = src_val.into();
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut dest_val = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_convert(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
src_val.get_format().to_glib(),
|
2017-12-10 10:10:25 +00:00
|
|
|
src_val.to_raw_value(),
|
2017-12-09 16:20:21 +00:00
|
|
|
U::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
dest_val.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(U::from_raw(U::get_default_format(), dest_val.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
|
2017-11-11 10:21:55 +00:00
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
dest_format: Format,
|
2017-12-09 16:20:21 +00:00
|
|
|
) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
let src_val = src_val.into();
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut dest_val = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_convert(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
src_val.get_format().to_glib(),
|
2017-12-10 10:10:25 +00:00
|
|
|
src_val.to_raw_value(),
|
2017-11-11 10:21:55 +00:00
|
|
|
dest_format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
dest_val.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(
|
|
|
|
dest_format,
|
|
|
|
dest_val.assume_init(),
|
|
|
|
))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut duration = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_duration(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
T::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
duration.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(T::from_raw(T::get_default_format(), duration.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut duration = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_duration(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-11-11 10:21:55 +00:00
|
|
|
format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
duration.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(format, duration.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut cur = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_position(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
T::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
cur.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(T::from_raw(T::get_default_format(), cur.assume_init()))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut cur = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_peer_query_position(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-11-11 10:21:55 +00:00
|
|
|
format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
cur.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(format, cur.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
|
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
) -> Option<U> {
|
|
|
|
let src_val = src_val.into();
|
|
|
|
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut dest_val = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_convert(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
src_val.get_format().to_glib(),
|
2017-12-10 10:10:25 +00:00
|
|
|
src_val.to_raw_value(),
|
2017-12-09 16:20:21 +00:00
|
|
|
U::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
dest_val.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(U::from_raw(U::get_default_format(), dest_val.assume_init()))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn query_convert_generic<V: Into<GenericFormattedValue>>(
|
2017-11-11 10:21:55 +00:00
|
|
|
&self,
|
|
|
|
src_val: V,
|
|
|
|
dest_format: Format,
|
2017-12-09 16:20:21 +00:00
|
|
|
) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
let src_val = src_val.into();
|
|
|
|
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut dest_val = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_convert(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
src_val.get_format().to_glib(),
|
|
|
|
src_val.get_value(),
|
2017-11-11 10:21:55 +00:00
|
|
|
dest_format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
dest_val.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(
|
|
|
|
dest_format,
|
|
|
|
dest_val.assume_init(),
|
|
|
|
))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut duration = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_duration(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
T::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
duration.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(T::from_raw(T::get_default_format(), duration.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut duration = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_duration(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-11-11 10:21:55 +00:00
|
|
|
format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
duration.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(format, duration.assume_init()))
|
2017-12-09 16:20:21 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut cur = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_position(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-12-09 16:20:21 +00:00
|
|
|
T::get_default_format().to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
cur.as_mut_ptr(),
|
2017-12-09 16:20:21 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(T::from_raw(T::get_default_format(), cur.assume_init()))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
|
2017-11-11 10:21:55 +00:00
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut cur = mem::MaybeUninit::uninit();
|
2019-03-19 07:58:20 +00:00
|
|
|
let ret = from_glib(gst_sys::gst_pad_query_position(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2017-11-11 10:21:55 +00:00
|
|
|
format.to_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
cur.as_mut_ptr(),
|
2017-11-11 10:21:55 +00:00
|
|
|
));
|
|
|
|
if ret {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some(GenericFormattedValue::new(format, cur.assume_init()))
|
2017-11-11 10:21:55 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-08-01 16:28:57 +00:00
|
|
|
|
|
|
|
fn get_mode(&self) -> ::PadMode {
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let ptr: &gst_sys::GstPad = &*(self.as_ptr() as *const _);
|
2018-08-01 16:28:57 +00:00
|
|
|
from_glib(ptr.mode)
|
|
|
|
}
|
|
|
|
}
|
2018-08-13 16:58:30 +00:00
|
|
|
|
|
|
|
fn sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>(
|
|
|
|
&self,
|
|
|
|
func: F,
|
|
|
|
) {
|
|
|
|
unsafe extern "C" fn trampoline(
|
2019-03-19 07:58:20 +00:00
|
|
|
_pad: *mut gst_sys::GstPad,
|
|
|
|
event: *mut *mut gst_sys::GstEvent,
|
|
|
|
user_data: glib_sys::gpointer,
|
|
|
|
) -> glib_sys::gboolean {
|
2018-08-13 16:58:30 +00:00
|
|
|
let func =
|
2019-06-06 06:09:34 +00:00
|
|
|
user_data as *mut &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>);
|
2018-08-13 16:58:30 +00:00
|
|
|
let res = (*func)(from_glib_full(*event));
|
|
|
|
|
|
|
|
match res {
|
|
|
|
Ok(Some(ev)) => {
|
|
|
|
*event = ev.into_ptr();
|
2019-03-19 07:58:20 +00:00
|
|
|
glib_sys::GTRUE
|
2018-08-13 16:58:30 +00:00
|
|
|
}
|
|
|
|
Err(Some(ev)) => {
|
|
|
|
*event = ev.into_ptr();
|
2019-03-19 07:58:20 +00:00
|
|
|
glib_sys::GFALSE
|
2018-08-13 16:58:30 +00:00
|
|
|
}
|
|
|
|
Ok(None) => {
|
|
|
|
*event = ptr::null_mut();
|
2019-03-19 07:58:20 +00:00
|
|
|
glib_sys::GTRUE
|
2018-08-13 16:58:30 +00:00
|
|
|
}
|
|
|
|
Err(None) => {
|
|
|
|
*event = ptr::null_mut();
|
2019-03-19 07:58:20 +00:00
|
|
|
glib_sys::GFALSE
|
2018-08-13 16:58:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let mut func = func;
|
2019-06-06 06:09:34 +00:00
|
|
|
let func_obj: &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>) =
|
|
|
|
&mut func;
|
2018-08-13 16:58:30 +00:00
|
|
|
let func_ptr = &func_obj
|
2019-06-06 06:09:34 +00:00
|
|
|
as *const &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>)
|
2019-03-19 07:58:20 +00:00
|
|
|
as glib_sys::gpointer;
|
2018-08-13 16:58:30 +00:00
|
|
|
|
2019-03-19 07:58:20 +00:00
|
|
|
gst_sys::gst_pad_sticky_events_foreach(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
|
|
|
Some(trampoline),
|
|
|
|
func_ptr,
|
|
|
|
);
|
2018-08-13 16:58:30 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-08 16:13:37 +00:00
|
|
|
|
|
|
|
fn store_sticky_event(&self, event: &Event) -> Result<FlowSuccess, FlowError> {
|
|
|
|
let ret: FlowReturn = unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
from_glib(gst_sys::gst_pad_store_sticky_event(
|
2019-01-16 11:32:58 +00:00
|
|
|
self.as_ref().to_glib_none().0,
|
2019-01-08 16:13:37 +00:00
|
|
|
event.to_glib_none().0,
|
|
|
|
))
|
|
|
|
};
|
|
|
|
ret.into_result()
|
|
|
|
}
|
2019-05-11 10:13:33 +00:00
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn set_pad_flags(&self, flags: PadFlags) {
|
2019-05-11 10:13:33 +00:00
|
|
|
unsafe {
|
|
|
|
let ptr: *mut gst_sys::GstObject = self.as_ptr() as *mut _;
|
|
|
|
let _guard = ::utils::MutexGuard::lock(&(*ptr).lock);
|
|
|
|
(*ptr).flags |= flags.to_glib();
|
2019-05-11 12:51:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn unset_pad_flags(&self, flags: PadFlags) {
|
2019-05-11 12:51:33 +00:00
|
|
|
unsafe {
|
|
|
|
let ptr: *mut gst_sys::GstObject = self.as_ptr() as *mut _;
|
|
|
|
let _guard = ::utils::MutexGuard::lock(&(*ptr).lock);
|
|
|
|
(*ptr).flags &= !flags.to_glib();
|
2019-05-11 10:13:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 15:23:39 +00:00
|
|
|
fn get_pad_flags(&self) -> PadFlags {
|
2019-05-11 10:13:33 +00:00
|
|
|
unsafe {
|
|
|
|
let ptr: *mut gst_sys::GstObject = self.as_ptr() as *mut _;
|
|
|
|
let _guard = ::utils::MutexGuard::lock(&(*ptr).lock);
|
|
|
|
from_glib((*ptr).flags)
|
|
|
|
}
|
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
2020-08-05 07:30:05 +00:00
|
|
|
unsafe fn create_probe_info<'a>(
|
2019-03-19 07:58:20 +00:00
|
|
|
info: *mut gst_sys::GstPadProbeInfo,
|
2020-08-05 07:30:05 +00:00
|
|
|
) -> (PadProbeInfo<'a>, Option<glib::Type>) {
|
2017-07-25 12:08:42 +00:00
|
|
|
let mut data_type = None;
|
2020-11-18 15:56:23 +00:00
|
|
|
let flow_ret: FlowReturn = from_glib((*info).ABI.abi.flow_ret);
|
2020-08-05 07:30:05 +00:00
|
|
|
let info = PadProbeInfo {
|
2017-07-24 08:51:14 +00:00
|
|
|
mask: from_glib((*info).type_),
|
2020-01-09 09:55:55 +00:00
|
|
|
id: PadProbeId(NonZeroU64::new_unchecked((*info).id as u64)),
|
2017-07-24 08:51:14 +00:00
|
|
|
offset: (*info).offset,
|
|
|
|
size: (*info).size,
|
|
|
|
data: if (*info).data.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
2019-03-19 07:58:20 +00:00
|
|
|
let data = (*info).data as *mut gst_sys::GstMiniObject;
|
2018-07-26 00:14:04 +00:00
|
|
|
(*info).data = ptr::null_mut();
|
2017-07-25 12:08:42 +00:00
|
|
|
if (*data).type_ == Buffer::static_type().to_glib() {
|
|
|
|
data_type = Some(Buffer::static_type());
|
2018-07-26 00:14:04 +00:00
|
|
|
Some(PadProbeData::Buffer(from_glib_full(
|
2019-03-19 07:58:20 +00:00
|
|
|
data as *const gst_sys::GstBuffer,
|
2017-12-20 17:30:14 +00:00
|
|
|
)))
|
2017-07-28 18:18:08 +00:00
|
|
|
} else if (*data).type_ == BufferList::static_type().to_glib() {
|
|
|
|
data_type = Some(BufferList::static_type());
|
2018-07-26 00:14:04 +00:00
|
|
|
Some(PadProbeData::BufferList(from_glib_full(
|
2019-03-19 07:58:20 +00:00
|
|
|
data as *const gst_sys::GstBufferList,
|
2017-12-20 17:30:14 +00:00
|
|
|
)))
|
2017-07-29 15:09:14 +00:00
|
|
|
} else if (*data).type_ == Query::static_type().to_glib() {
|
|
|
|
data_type = Some(Query::static_type());
|
2017-12-20 17:30:14 +00:00
|
|
|
Some(PadProbeData::Query(QueryRef::from_mut_ptr(
|
2019-03-19 07:58:20 +00:00
|
|
|
data as *mut gst_sys::GstQuery,
|
2017-12-20 17:30:14 +00:00
|
|
|
)))
|
2017-07-30 14:11:47 +00:00
|
|
|
} else if (*data).type_ == Event::static_type().to_glib() {
|
|
|
|
data_type = Some(Event::static_type());
|
2018-07-26 00:14:04 +00:00
|
|
|
Some(PadProbeData::Event(from_glib_full(
|
2019-03-19 07:58:20 +00:00
|
|
|
data as *const gst_sys::GstEvent,
|
2017-12-20 17:30:14 +00:00
|
|
|
)))
|
2017-07-25 12:08:42 +00:00
|
|
|
} else {
|
2018-07-26 00:14:04 +00:00
|
|
|
Some(PadProbeData::__Unknown(data))
|
2017-07-25 12:08:42 +00:00
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
},
|
2020-11-18 15:56:23 +00:00
|
|
|
flow_res: flow_ret.into_result(),
|
2017-07-24 08:51:14 +00:00
|
|
|
};
|
2020-08-05 07:30:05 +00:00
|
|
|
(info, data_type)
|
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2020-08-05 07:30:05 +00:00
|
|
|
unsafe fn update_probe_info(
|
|
|
|
ret: PadProbeReturn,
|
|
|
|
probe_info: PadProbeInfo,
|
|
|
|
data_type: Option<glib::Type>,
|
|
|
|
info: *mut gst_sys::GstPadProbeInfo,
|
|
|
|
) {
|
2019-05-12 13:03:16 +00:00
|
|
|
if ret == PadProbeReturn::Handled {
|
|
|
|
// Handled queries need to be returned
|
|
|
|
// Handled buffers are consumed
|
|
|
|
// No other types can safely be used here
|
|
|
|
|
|
|
|
match probe_info.data {
|
|
|
|
Some(PadProbeData::Query(query)) => {
|
|
|
|
assert_eq!(data_type, Some(Query::static_type()));
|
|
|
|
(*info).data = query.as_mut_ptr() as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
Some(PadProbeData::Buffer(_)) => {
|
|
|
|
assert_eq!(data_type, Some(Buffer::static_type()));
|
|
|
|
// Buffer not consumed by probe; consume it here
|
|
|
|
}
|
2020-11-18 13:16:59 +00:00
|
|
|
Some(PadProbeData::Event(_)) => {
|
|
|
|
assert_eq!(data_type, Some(Event::static_type()));
|
|
|
|
// Event not consumed by probe; consume it here
|
|
|
|
}
|
|
|
|
None if data_type == Some(Buffer::static_type())
|
|
|
|
|| data_type == Some(Event::static_type()) =>
|
|
|
|
{
|
|
|
|
// Buffer or Event consumed by probe
|
2019-05-12 13:03:16 +00:00
|
|
|
}
|
|
|
|
other => panic!(
|
|
|
|
"Bad data for {:?} pad probe returning Handled: {:?}",
|
|
|
|
data_type, other
|
|
|
|
),
|
2017-07-30 14:11:47 +00:00
|
|
|
}
|
2019-05-12 13:03:16 +00:00
|
|
|
} else {
|
|
|
|
match probe_info.data {
|
|
|
|
Some(PadProbeData::Buffer(buffer)) => {
|
|
|
|
assert_eq!(data_type, Some(Buffer::static_type()));
|
|
|
|
(*info).data = buffer.into_ptr() as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
Some(PadProbeData::BufferList(bufferlist)) => {
|
|
|
|
assert_eq!(data_type, Some(BufferList::static_type()));
|
|
|
|
(*info).data = bufferlist.into_ptr() as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
Some(PadProbeData::Event(event)) => {
|
|
|
|
assert_eq!(data_type, Some(Event::static_type()));
|
|
|
|
(*info).data = event.into_ptr() as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
Some(PadProbeData::Query(query)) => {
|
|
|
|
assert_eq!(data_type, Some(Query::static_type()));
|
|
|
|
(*info).data = query.as_mut_ptr() as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
Some(PadProbeData::__Unknown(ptr)) => {
|
|
|
|
assert_eq!(data_type, None);
|
|
|
|
(*info).data = ptr as *mut libc::c_void;
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
assert_eq!(data_type, None);
|
|
|
|
}
|
2017-07-25 12:08:42 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-24 08:51:14 +00:00
|
|
|
|
2020-11-18 15:56:23 +00:00
|
|
|
let flow_ret: FlowReturn = probe_info.flow_res.into();
|
|
|
|
(*info).ABI.abi.flow_ret = flow_ret.to_glib();
|
2020-08-05 07:30:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe extern "C" fn trampoline_pad_probe<
|
|
|
|
T,
|
|
|
|
F: Fn(&T, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
|
|
|
|
>(
|
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
info: *mut gst_sys::GstPadProbeInfo,
|
|
|
|
func: gpointer,
|
|
|
|
) -> gst_sys::GstPadProbeReturn
|
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
|
|
|
let func: &F = &*(func as *const F);
|
|
|
|
|
|
|
|
let (mut probe_info, data_type) = create_probe_info(info);
|
|
|
|
|
|
|
|
let ret = func(
|
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
&mut probe_info,
|
|
|
|
);
|
|
|
|
|
|
|
|
update_probe_info(ret, probe_info, data_type, info);
|
2019-05-12 09:59:59 +00:00
|
|
|
|
2019-05-12 13:03:16 +00:00
|
|
|
ret.to_glib()
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_activate_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
) -> glib_sys::gboolean
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).activatedata as *const F);
|
2019-01-16 20:23:56 +00:00
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
match func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2019-01-30 13:02:03 +00:00
|
|
|
) {
|
2019-01-16 20:23:56 +00:00
|
|
|
Ok(()) => true,
|
|
|
|
Err(err) => {
|
2020-04-05 14:52:56 +00:00
|
|
|
err.log_with_object(&*Pad::from_glib_borrow(pad));
|
2019-01-16 20:23:56 +00:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_activatemode_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
mode: gst_sys::GstPadMode,
|
|
|
|
active: glib_sys::gboolean,
|
|
|
|
) -> glib_sys::gboolean
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).activatemodedata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-24 21:11:43 +00:00
|
|
|
match func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
from_glib(mode),
|
|
|
|
from_glib(active),
|
2019-01-24 21:11:43 +00:00
|
|
|
) {
|
|
|
|
Ok(()) => true,
|
|
|
|
Err(err) => {
|
2020-04-05 14:52:56 +00:00
|
|
|
err.log_with_object(&*Pad::from_glib_borrow(pad));
|
2019-01-24 21:11:43 +00:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
2018-10-08 12:02:23 +00:00
|
|
|
.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_chain_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
buffer: *mut gst_sys::GstBuffer,
|
|
|
|
) -> gst_sys::GstFlowReturn
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).chaindata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
let res: FlowReturn = func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
from_glib_full(buffer),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
2019-01-08 16:13:37 +00:00
|
|
|
.into();
|
|
|
|
res.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_chain_list_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
|
2019-01-30 13:02:03 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
list: *mut gst_sys::GstBufferList,
|
|
|
|
) -> gst_sys::GstFlowReturn
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).chainlistdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
let res: FlowReturn = func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
from_glib_full(list),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
2019-01-08 16:13:37 +00:00
|
|
|
.into();
|
|
|
|
res.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_event_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
event: *mut gst_sys::GstEvent,
|
|
|
|
) -> glib_sys::gboolean
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).eventdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
|
|
|
func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
from_glib_full(event),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
|
|
|
.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_event_full_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
event: *mut gst_sys::GstEvent,
|
|
|
|
) -> gst_sys::GstFlowReturn
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).eventdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
let res: FlowReturn = func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
from_glib_full(event),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
2019-01-08 16:13:37 +00:00
|
|
|
.into();
|
|
|
|
res.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_getrange_function<
|
|
|
|
T,
|
2020-03-29 17:11:00 +00:00
|
|
|
F: Fn(
|
|
|
|
&T,
|
|
|
|
Option<&::Object>,
|
|
|
|
u64,
|
|
|
|
Option<&mut ::BufferRef>,
|
|
|
|
u32,
|
|
|
|
) -> Result<PadGetRangeSuccess, ::FlowError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
2017-09-16 22:45:21 +00:00
|
|
|
offset: u64,
|
|
|
|
length: u32,
|
2019-03-19 07:58:20 +00:00
|
|
|
buffer: *mut *mut gst_sys::GstBuffer,
|
|
|
|
) -> gst_sys::GstFlowReturn
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).getrangedata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-03-29 17:11:00 +00:00
|
|
|
assert!(!buffer.is_null());
|
|
|
|
|
2020-04-05 14:52:56 +00:00
|
|
|
let pad = Pad::from_glib_borrow(pad);
|
|
|
|
let pad = pad.unsafe_cast_ref();
|
2020-03-29 17:11:00 +00:00
|
|
|
let mut passed_buffer = if (*buffer).is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(::BufferRef::from_mut_ptr(*buffer))
|
|
|
|
};
|
|
|
|
|
2017-09-16 22:45:21 +00:00
|
|
|
match func(
|
2020-03-29 17:11:00 +00:00
|
|
|
&pad,
|
2020-04-05 14:52:56 +00:00
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
offset,
|
2020-04-20 15:16:23 +00:00
|
|
|
passed_buffer.as_deref_mut(),
|
2017-09-16 22:45:21 +00:00
|
|
|
length,
|
|
|
|
) {
|
2020-03-29 17:11:00 +00:00
|
|
|
Ok(PadGetRangeSuccess::NewBuffer(new_buffer)) => {
|
|
|
|
if let Some(passed_buffer) = passed_buffer {
|
|
|
|
gst_debug!(
|
|
|
|
::CAT_PERFORMANCE,
|
|
|
|
obj: pad.unsafe_cast_ref::<glib::Object>(),
|
|
|
|
"Returned new buffer from getrange function, copying into passed buffer"
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut map = match passed_buffer.map_writable() {
|
|
|
|
Ok(map) => map,
|
|
|
|
Err(_) => {
|
|
|
|
gst_error!(
|
|
|
|
::CAT_RUST,
|
|
|
|
obj: pad.unsafe_cast_ref::<glib::Object>(),
|
|
|
|
"Failed to map passed buffer writable"
|
|
|
|
);
|
|
|
|
return gst_sys::GST_FLOW_ERROR;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let copied_size = new_buffer.copy_to_slice(0, &mut *map);
|
|
|
|
drop(map);
|
|
|
|
|
|
|
|
if let Err(copied_size) = copied_size {
|
|
|
|
passed_buffer.set_size(copied_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
match new_buffer.copy_into(passed_buffer, ::BUFFER_COPY_METADATA, 0, None) {
|
|
|
|
Ok(_) => FlowReturn::Ok.to_glib(),
|
|
|
|
Err(_) => {
|
|
|
|
gst_error!(
|
|
|
|
::CAT_RUST,
|
|
|
|
obj: pad.unsafe_cast_ref::<glib::Object>(),
|
|
|
|
"Failed to copy buffer metadata"
|
|
|
|
);
|
|
|
|
|
|
|
|
FlowReturn::Error.to_glib()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*buffer = new_buffer.into_ptr();
|
|
|
|
FlowReturn::Ok.to_glib()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(PadGetRangeSuccess::FilledBuffer) => {
|
|
|
|
assert!(passed_buffer.is_some());
|
2019-01-08 16:13:37 +00:00
|
|
|
FlowReturn::Ok.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
2019-01-08 16:13:37 +00:00
|
|
|
Err(ret) => FlowReturn::from_error(ret).to_glib(),
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_iterate_internal_links_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
) -> *mut gst_sys::GstIterator
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).iterintlinkdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
|
|
|
// Steal the iterator and return it
|
2019-01-30 13:02:03 +00:00
|
|
|
let ret = func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2019-01-30 13:02:03 +00:00
|
|
|
);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2020-03-09 10:55:14 +00:00
|
|
|
ret.into_ptr()
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_link_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, &::Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
|
2019-01-30 13:02:03 +00:00
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
peer: *mut gst_sys::GstPad,
|
|
|
|
) -> gst_sys::GstPadLinkReturn
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).linkdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
let res: ::PadLinkReturn = func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
&from_glib_borrow(peer),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
2019-01-08 16:13:37 +00:00
|
|
|
.into();
|
|
|
|
res.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_query_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
|
|
|
query: *mut gst_sys::GstQuery,
|
|
|
|
) -> glib_sys::gboolean
|
2019-01-30 13:02:03 +00:00
|
|
|
where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).querydata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
|
|
|
func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2017-09-16 22:45:21 +00:00
|
|
|
::QueryRef::from_mut_ptr(query),
|
2018-10-08 12:02:23 +00:00
|
|
|
)
|
|
|
|
.to_glib()
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_unlink_function<
|
|
|
|
T,
|
2019-05-22 20:27:13 +00:00
|
|
|
F: Fn(&T, Option<&::Object>) + Send + Sync + 'static,
|
2019-01-30 13:02:03 +00:00
|
|
|
>(
|
2019-03-19 07:58:20 +00:00
|
|
|
pad: *mut gst_sys::GstPad,
|
|
|
|
parent: *mut gst_sys::GstObject,
|
2019-01-30 13:02:03 +00:00
|
|
|
) where
|
|
|
|
T: IsA<Pad>,
|
|
|
|
{
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &F = &*((*pad).unlinkdata as *const F);
|
2017-09-16 22:45:21 +00:00
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
func(
|
2020-04-05 14:52:56 +00:00
|
|
|
&Pad::from_glib_borrow(pad).unsafe_cast_ref(),
|
|
|
|
Option::<::Object>::from_glib_borrow(parent)
|
|
|
|
.as_ref()
|
|
|
|
.as_ref(),
|
2019-01-30 13:02:03 +00:00
|
|
|
)
|
2017-09-16 22:45:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn destroy_closure<F>(ptr: gpointer) {
|
|
|
|
Box::<F>::from_raw(ptr as *mut _);
|
2017-07-24 08:51:14 +00:00
|
|
|
}
|
2017-09-17 21:32:29 +00:00
|
|
|
|
2019-01-30 13:02:03 +00:00
|
|
|
unsafe extern "C" fn trampoline_pad_task<F: FnMut() + Send + 'static>(func: gpointer) {
|
2019-02-21 17:30:36 +00:00
|
|
|
let func: &RefCell<F> = &*(func as *const RefCell<F>);
|
2017-09-17 21:32:29 +00:00
|
|
|
(&mut *func.borrow_mut())()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn into_raw_pad_task<F: FnMut() + Send + 'static>(func: F) -> gpointer {
|
2019-02-28 08:32:13 +00:00
|
|
|
#[allow(clippy::type_complexity)]
|
2019-01-30 13:02:03 +00:00
|
|
|
let func: Box<RefCell<F>> = Box::new(RefCell::new(func));
|
2017-09-17 21:32:29 +00:00
|
|
|
Box::into_raw(func) as gpointer
|
|
|
|
}
|
2017-09-17 22:45:39 +00:00
|
|
|
|
2019-03-01 17:49:27 +00:00
|
|
|
unsafe extern "C" fn destroy_closure_pad_task<F>(ptr: gpointer) {
|
|
|
|
Box::<RefCell<F>>::from_raw(ptr as *mut _);
|
|
|
|
}
|
|
|
|
|
2020-06-21 16:43:21 +00:00
|
|
|
impl Pad {
|
|
|
|
pub fn new(name: Option<&str>, direction: ::PadDirection) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
Self::builder(name, direction).build()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn builder(name: Option<&str>, direction: ::PadDirection) -> PadBuilder<Self> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
PadBuilder::new(name, direction)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self {
|
|
|
|
skip_assert_initialized!();
|
2020-06-22 08:26:24 +00:00
|
|
|
Self::builder_with_static_template(templ, name).build()
|
2020-06-21 16:43:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-22 08:26:24 +00:00
|
|
|
pub fn builder_with_static_template(
|
2020-06-21 16:43:21 +00:00
|
|
|
templ: &StaticPadTemplate,
|
|
|
|
name: Option<&str>,
|
|
|
|
) -> PadBuilder<Self> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
PadBuilder::from_static_template(templ, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_template(templ: &::PadTemplate, name: Option<&str>) -> Self {
|
|
|
|
skip_assert_initialized!();
|
2020-06-22 08:26:24 +00:00
|
|
|
Self::builder_with_template(templ, name).build()
|
2020-06-21 16:43:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-22 08:26:24 +00:00
|
|
|
pub fn builder_with_template(templ: &::PadTemplate, name: Option<&str>) -> PadBuilder<Self> {
|
2020-06-21 16:43:21 +00:00
|
|
|
skip_assert_initialized!();
|
|
|
|
PadBuilder::from_template(templ, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 12:04:23 +00:00
|
|
|
pub struct PadBuilder<T>(pub(crate) T);
|
2020-06-21 16:43:21 +00:00
|
|
|
|
|
|
|
impl<T: IsA<Pad> + IsA<glib::Object>> PadBuilder<T> {
|
|
|
|
pub fn new(name: Option<&str>, direction: ::PadDirection) -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
|
|
|
let pad = glib::Object::new(
|
|
|
|
T::static_type(),
|
|
|
|
&[("name", &name), ("direction", &direction)],
|
|
|
|
)
|
|
|
|
.expect("Failed to create pad")
|
|
|
|
.downcast::<T>()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Ghost pads are a bit special
|
|
|
|
if let Some(pad) = pad.dynamic_cast_ref::<::GhostPad>() {
|
|
|
|
unsafe {
|
|
|
|
let res = gst_sys::gst_ghost_pad_construct(pad.to_glib_none().0);
|
|
|
|
// This can't really fail...
|
|
|
|
assert_ne!(res, glib_sys::GFALSE, "Failed to construct ghost pad");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PadBuilder(pad)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
|
|
|
let templ = templ.get();
|
|
|
|
Self::from_template(&templ, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_template(templ: &::PadTemplate, name: Option<&str>) -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
|
|
|
use glib::ObjectExt;
|
|
|
|
|
|
|
|
let mut type_ = T::static_type();
|
|
|
|
|
|
|
|
// Since 1.14 templates can keep a pad GType with them, so we need to do some
|
|
|
|
// additional checks here now
|
|
|
|
if templ.has_property("gtype", Some(glib::Type::static_type())) {
|
|
|
|
let gtype = templ
|
|
|
|
.get_property("gtype")
|
|
|
|
.unwrap()
|
|
|
|
.get_some::<glib::Type>()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
if gtype == glib::Type::Unit {
|
|
|
|
// Nothing to be done, we can create any kind of pad
|
|
|
|
} else if gtype.is_a(&type_) {
|
|
|
|
// We were asked to create a parent type of the template type, e.g. a gst::Pad for
|
|
|
|
// a template that wants a gst_base::AggregatorPad. Not a problem: update the type
|
|
|
|
type_ = gtype;
|
|
|
|
} else {
|
|
|
|
// Otherwise the requested type must be a subclass of the template pad type
|
|
|
|
assert!(type_.is_a(>ype));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let pad = glib::Object::new(
|
|
|
|
type_,
|
|
|
|
&[
|
|
|
|
("name", &name),
|
|
|
|
("direction", &templ.get_property_direction()),
|
|
|
|
("template", templ),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
.expect("Failed to create pad")
|
|
|
|
.downcast::<T>()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Ghost pads are a bit special
|
|
|
|
if let Some(pad) = pad.dynamic_cast_ref::<::GhostPad>() {
|
|
|
|
unsafe {
|
|
|
|
let res = gst_sys::gst_ghost_pad_construct(pad.to_glib_none().0);
|
|
|
|
// This can't really fail...
|
|
|
|
assert_ne!(res, glib_sys::GFALSE, "Failed to construct ghost pad");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PadBuilder(pad)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn activate_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_activate_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn activatemode_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_activatemode_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn chain_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_chain_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn chain_list_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_chain_list_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn event_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_event_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn event_full_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_event_full_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn getrange_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(
|
|
|
|
&T,
|
|
|
|
Option<&::Object>,
|
|
|
|
u64,
|
|
|
|
Option<&mut ::BufferRef>,
|
|
|
|
u32,
|
|
|
|
) -> Result<PadGetRangeSuccess, ::FlowError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_getrange_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iterate_internal_links_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_iterate_internal_links_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn link_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
|
|
|
|
+ Send
|
|
|
|
+ Sync
|
|
|
|
+ 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_link_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn query_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_query_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unlink_function<F>(self, func: F) -> Self
|
|
|
|
where
|
|
|
|
F: Fn(&T, Option<&::Object>) + Send + Sync + 'static,
|
|
|
|
{
|
|
|
|
unsafe {
|
|
|
|
self.0.set_unlink_function(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn flags(self, flags: PadFlags) -> Self {
|
|
|
|
self.0.set_pad_flags(flags);
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn build(self) -> T {
|
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-17 22:45:39 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use prelude::*;
|
2017-09-17 22:53:02 +00:00
|
|
|
use std::sync::mpsc::channel;
|
2018-04-01 08:30:03 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2017-09-17 22:45:39 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_event_chain_functions() {
|
|
|
|
::init().unwrap();
|
|
|
|
|
|
|
|
let events = Arc::new(Mutex::new(Vec::new()));
|
|
|
|
let events_clone = events.clone();
|
|
|
|
let buffers = Arc::new(Mutex::new(Vec::new()));
|
|
|
|
let buffers_clone = buffers.clone();
|
2020-06-21 16:43:21 +00:00
|
|
|
let pad = ::Pad::builder(Some("sink"), ::PadDirection::Sink)
|
|
|
|
.event_function(move |_, _, event| {
|
|
|
|
let mut events = events_clone.lock().unwrap();
|
|
|
|
events.push(event);
|
|
|
|
|
|
|
|
true
|
|
|
|
})
|
|
|
|
.chain_function(move |_, _, buffer| {
|
|
|
|
let mut buffers = buffers_clone.lock().unwrap();
|
|
|
|
buffers.push(buffer);
|
2017-09-17 22:45:39 +00:00
|
|
|
|
2020-06-21 16:43:21 +00:00
|
|
|
Ok(FlowSuccess::Ok)
|
|
|
|
})
|
|
|
|
.build();
|
2017-09-17 22:45:39 +00:00
|
|
|
|
|
|
|
pad.set_active(true).unwrap();
|
|
|
|
|
2020-06-23 15:52:51 +00:00
|
|
|
assert!(pad.send_event(::event::StreamStart::new("test")));
|
2017-12-09 16:20:21 +00:00
|
|
|
let segment = ::FormattedSegment::<::ClockTime>::new();
|
2020-06-23 15:52:51 +00:00
|
|
|
assert!(pad.send_event(::event::Segment::new(segment.as_ref())));
|
2017-09-17 22:45:39 +00:00
|
|
|
|
2019-01-08 16:13:37 +00:00
|
|
|
assert_eq!(pad.chain(::Buffer::new()), Ok(FlowSuccess::Ok));
|
2017-09-17 22:45:39 +00:00
|
|
|
|
|
|
|
let events = events.lock().unwrap();
|
|
|
|
let buffers = buffers.lock().unwrap();
|
|
|
|
assert_eq!(events.len(), 2);
|
|
|
|
assert_eq!(buffers.len(), 1);
|
|
|
|
|
|
|
|
match events[0].view() {
|
|
|
|
::EventView::StreamStart(..) => (),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
|
|
|
|
match events[1].view() {
|
|
|
|
::EventView::Segment(..) => (),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
2017-09-17 22:53:02 +00:00
|
|
|
|
2020-03-28 18:00:11 +00:00
|
|
|
#[test]
|
|
|
|
fn test_getrange_function() {
|
|
|
|
::init().unwrap();
|
|
|
|
|
2020-06-21 16:43:21 +00:00
|
|
|
let pad = ::Pad::builder(Some("src"), ::PadDirection::Src)
|
|
|
|
.activate_function(|pad, _parent| {
|
|
|
|
pad.activate_mode(::PadMode::Pull, true)
|
|
|
|
.map_err(|err| err.into())
|
|
|
|
})
|
|
|
|
.getrange_function(|_pad, _parent, offset, _buffer, size| {
|
|
|
|
assert_eq!(offset, 0);
|
|
|
|
assert_eq!(size, 5);
|
|
|
|
let buffer = ::Buffer::from_slice(b"abcde");
|
|
|
|
Ok(PadGetRangeSuccess::NewBuffer(buffer))
|
|
|
|
})
|
|
|
|
.build();
|
2020-03-28 18:00:11 +00:00
|
|
|
pad.set_active(true).unwrap();
|
|
|
|
|
|
|
|
let buffer = pad.get_range(0, 5).unwrap();
|
|
|
|
let map = buffer.map_readable().unwrap();
|
|
|
|
assert_eq!(&*map, b"abcde");
|
|
|
|
|
|
|
|
let mut buffer = ::Buffer::with_size(5).unwrap();
|
|
|
|
pad.get_range_fill(0, buffer.get_mut().unwrap(), 5).unwrap();
|
|
|
|
let map = buffer.map_readable().unwrap();
|
|
|
|
assert_eq!(&*map, b"abcde");
|
|
|
|
|
|
|
|
pad.set_active(false).unwrap();
|
|
|
|
drop(pad);
|
|
|
|
|
2020-06-21 16:43:21 +00:00
|
|
|
let pad = ::Pad::builder(Some("src"), ::PadDirection::Src)
|
|
|
|
.activate_function(|pad, _parent| {
|
|
|
|
pad.activate_mode(::PadMode::Pull, true)
|
|
|
|
.map_err(|err| err.into())
|
|
|
|
})
|
|
|
|
.getrange_function(|_pad, _parent, offset, buffer, size| {
|
|
|
|
assert_eq!(offset, 0);
|
|
|
|
assert_eq!(size, 5);
|
|
|
|
if let Some(buffer) = buffer {
|
|
|
|
buffer.copy_from_slice(0, b"fghij").unwrap();
|
|
|
|
Ok(PadGetRangeSuccess::FilledBuffer)
|
|
|
|
} else {
|
|
|
|
let buffer = ::Buffer::from_slice(b"abcde");
|
|
|
|
Ok(PadGetRangeSuccess::NewBuffer(buffer))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.build();
|
2020-03-28 18:00:11 +00:00
|
|
|
pad.set_active(true).unwrap();
|
|
|
|
|
|
|
|
let buffer = pad.get_range(0, 5).unwrap();
|
|
|
|
let map = buffer.map_readable().unwrap();
|
|
|
|
assert_eq!(&*map, b"abcde");
|
|
|
|
|
|
|
|
let mut buffer = ::Buffer::with_size(5).unwrap();
|
|
|
|
pad.get_range_fill(0, buffer.get_mut().unwrap(), 5).unwrap();
|
|
|
|
let map = buffer.map_readable().unwrap();
|
|
|
|
assert_eq!(&*map, b"fghij");
|
|
|
|
}
|
|
|
|
|
2017-09-17 22:53:02 +00:00
|
|
|
#[test]
|
|
|
|
fn test_task() {
|
|
|
|
::init().unwrap();
|
|
|
|
|
2019-03-19 07:58:20 +00:00
|
|
|
let pad = ::Pad::new(Some("sink"), ::PadDirection::Sink);
|
2017-09-17 22:53:02 +00:00
|
|
|
let (sender, receiver) = channel();
|
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
let pad_clone = pad.clone();
|
|
|
|
pad.start_task(move || {
|
|
|
|
i += 1;
|
|
|
|
if i == 3 {
|
|
|
|
sender.send(i).unwrap();
|
|
|
|
pad_clone.pause_task().unwrap();
|
|
|
|
}
|
2018-10-08 12:02:23 +00:00
|
|
|
})
|
|
|
|
.unwrap();
|
2017-09-17 22:53:02 +00:00
|
|
|
|
|
|
|
assert_eq!(receiver.recv().unwrap(), 3);
|
|
|
|
}
|
2019-05-12 14:48:46 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_probe() {
|
|
|
|
::init().unwrap();
|
|
|
|
|
|
|
|
let (major, minor, micro, _) = ::version();
|
|
|
|
let pad = ::Pad::new(Some("src"), ::PadDirection::Src);
|
|
|
|
let events = Arc::new(Mutex::new(Vec::new()));
|
|
|
|
let buffers = Arc::new(Mutex::new(Vec::new()));
|
|
|
|
|
|
|
|
let flow_override = if (major, minor, micro) >= (1, 16, 1) {
|
2020-11-18 15:56:23 +00:00
|
|
|
Err(FlowError::Eos)
|
2019-05-12 14:48:46 +00:00
|
|
|
} else {
|
|
|
|
// Broken on 1.16.0
|
|
|
|
// https://gitlab.freedesktop.org/gstreamer/gstreamer/merge_requests/151
|
2020-11-18 15:56:23 +00:00
|
|
|
Ok(FlowSuccess::Ok)
|
2019-05-12 14:48:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
let events = events.clone();
|
|
|
|
pad.add_probe(::PadProbeType::EVENT_DOWNSTREAM, move |_, info| {
|
|
|
|
if let Some(PadProbeData::Event(event)) = &info.data {
|
|
|
|
let mut events = events.lock().unwrap();
|
|
|
|
events.push(event.clone());
|
|
|
|
} else {
|
|
|
|
unreachable!();
|
|
|
|
}
|
|
|
|
::PadProbeReturn::Ok
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-11-18 13:16:59 +00:00
|
|
|
{
|
|
|
|
let events = events.clone();
|
|
|
|
pad.add_probe(::PadProbeType::EVENT_UPSTREAM, move |_, info| {
|
|
|
|
if let Some(PadProbeData::Event(event)) = info.data.take() {
|
|
|
|
let mut events = events.lock().unwrap();
|
|
|
|
events.push(event);
|
|
|
|
} else {
|
|
|
|
unreachable!();
|
|
|
|
}
|
|
|
|
::PadProbeReturn::Handled
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-05-12 14:48:46 +00:00
|
|
|
{
|
|
|
|
let buffers = buffers.clone();
|
|
|
|
let flow_override = flow_override;
|
|
|
|
pad.add_probe(::PadProbeType::BUFFER, move |_, info| {
|
|
|
|
if let Some(PadProbeData::Buffer(buffer)) = info.data.take() {
|
|
|
|
let mut buffers = buffers.lock().unwrap();
|
2020-11-18 15:56:23 +00:00
|
|
|
info.flow_res = if buffers.is_empty() {
|
|
|
|
Ok(FlowSuccess::Ok)
|
2019-05-12 14:48:46 +00:00
|
|
|
} else {
|
|
|
|
flow_override
|
|
|
|
};
|
|
|
|
buffers.push(buffer);
|
|
|
|
} else {
|
|
|
|
unreachable!();
|
|
|
|
}
|
|
|
|
::PadProbeReturn::Handled
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pad.set_active(true).unwrap();
|
|
|
|
|
2020-11-18 13:16:59 +00:00
|
|
|
assert!(pad.send_event(::event::Latency::new(::ClockTime::from_nseconds(10))));
|
2020-06-23 15:52:51 +00:00
|
|
|
assert!(pad.push_event(::event::StreamStart::new("test")));
|
2019-05-12 14:48:46 +00:00
|
|
|
let segment = ::FormattedSegment::<::ClockTime>::new();
|
2020-06-23 15:52:51 +00:00
|
|
|
assert!(pad.push_event(::event::Segment::new(segment.as_ref())));
|
2019-05-12 14:48:46 +00:00
|
|
|
|
|
|
|
assert_eq!(pad.push(::Buffer::new()), Ok(FlowSuccess::Ok));
|
2020-11-18 15:56:23 +00:00
|
|
|
assert_eq!(pad.push(::Buffer::new()), flow_override);
|
2019-05-12 14:48:46 +00:00
|
|
|
|
|
|
|
let events = events.lock().unwrap();
|
|
|
|
let buffers = buffers.lock().unwrap();
|
2020-11-18 13:16:59 +00:00
|
|
|
assert_eq!(events.len(), 3);
|
2019-05-12 14:48:46 +00:00
|
|
|
assert_eq!(buffers.len(), 2);
|
|
|
|
|
2020-11-18 13:16:59 +00:00
|
|
|
assert_eq!(events[0].get_type(), ::EventType::Latency);
|
|
|
|
assert_eq!(events[1].get_type(), ::EventType::StreamStart);
|
|
|
|
assert_eq!(events[2].get_type(), ::EventType::Segment);
|
2019-05-12 14:48:46 +00:00
|
|
|
|
|
|
|
assert!(
|
|
|
|
buffers.iter().all(|b| b.is_writable()),
|
|
|
|
"A buffer ref leaked!"
|
|
|
|
);
|
|
|
|
|
|
|
|
drop(pad); // Need to drop the pad first to unref sticky events
|
|
|
|
assert!(
|
|
|
|
events.iter().all(|e| e.is_writable()),
|
|
|
|
"An event ref leaked!"
|
|
|
|
);
|
|
|
|
}
|
2017-09-17 22:45:39 +00:00
|
|
|
}
|