mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2025-01-09 00:35:41 +00:00
parent
e9fbbc2b40
commit
c774bd8114
10 changed files with 879 additions and 2 deletions
|
@ -18,6 +18,7 @@ external_libraries = [
|
|||
|
||||
generate = [
|
||||
"GstBase.PushSrc",
|
||||
"GstBase.BaseParseFrameFlags",
|
||||
]
|
||||
|
||||
manual = [
|
||||
|
@ -32,6 +33,8 @@ manual = [
|
|||
"Gst.Format",
|
||||
"Gst.Pad",
|
||||
"Gst.TypeFindProbability",
|
||||
"Gst.TagMergeMode",
|
||||
"GstBase.BaseParseFrame",
|
||||
]
|
||||
|
||||
[[object]]
|
||||
|
@ -196,3 +199,33 @@ ref_mode = "ref"
|
|||
name = "Gst.ClockTime"
|
||||
status = "manual"
|
||||
conversion_type = "scalar"
|
||||
|
||||
[[object]]
|
||||
name = "Gst.TagList"
|
||||
status = "manual"
|
||||
ref_mode = "ref"
|
||||
|
||||
[[object]]
|
||||
name = "GstBase.BaseParse"
|
||||
subclassing = true
|
||||
status = "generate"
|
||||
[[object.function]]
|
||||
name = "finish_frame"
|
||||
ignore = true
|
||||
|
||||
[[object.function]]
|
||||
name = "set_duration"
|
||||
ignore = true
|
||||
|
||||
[[object.function]]
|
||||
name = "convert_default"
|
||||
ignore = true
|
||||
|
||||
[[object.function]]
|
||||
name = "set_frame_rate"
|
||||
ignore = true
|
||||
|
||||
# Didn't bind gst_base_parse_frame_{new,init} so not needed
|
||||
[[object.function]]
|
||||
name = "push_frame"
|
||||
ignore = true
|
||||
|
|
166
gstreamer-base/src/auto/base_parse.rs
Normal file
166
gstreamer-base/src/auto/base_parse.rs
Normal file
|
@ -0,0 +1,166 @@
|
|||
// This file was generated by gir (https://github.com/gtk-rs/gir)
|
||||
// from gir-files (https://github.com/gtk-rs/gir-files)
|
||||
// DO NOT EDIT
|
||||
|
||||
use glib::StaticType;
|
||||
use glib::Value;
|
||||
use glib::object::Cast;
|
||||
use glib::object::IsA;
|
||||
use glib::signal::SignalHandlerId;
|
||||
use glib::signal::connect_raw;
|
||||
use glib::translate::*;
|
||||
use glib_sys;
|
||||
use gobject_sys;
|
||||
use gst;
|
||||
use gst_base_sys;
|
||||
use std::boxed::Box as Box_;
|
||||
use std::mem::transmute;
|
||||
|
||||
glib_wrapper! {
|
||||
pub struct BaseParse(Object<gst_base_sys::GstBaseParse, gst_base_sys::GstBaseParseClass, BaseParseClass>) @extends gst::Element, gst::Object;
|
||||
|
||||
match fn {
|
||||
get_type => || gst_base_sys::gst_base_parse_get_type(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for BaseParse {}
|
||||
unsafe impl Sync for BaseParse {}
|
||||
|
||||
pub const NONE_BASE_PARSE: Option<&BaseParse> = None;
|
||||
|
||||
pub trait BaseParseExt: 'static {
|
||||
fn add_index_entry(&self, offset: u64, ts: gst::ClockTime, key: bool, force: bool) -> bool;
|
||||
|
||||
#[cfg(any(feature = "v1_12", feature = "dox"))]
|
||||
fn drain(&self);
|
||||
|
||||
fn merge_tags(&self, tags: Option<&gst::TagList>, mode: gst::TagMergeMode);
|
||||
|
||||
fn set_average_bitrate(&self, bitrate: u32);
|
||||
|
||||
fn set_has_timing_info(&self, has_timing: bool);
|
||||
|
||||
fn set_infer_ts(&self, infer_ts: bool);
|
||||
|
||||
fn set_latency(&self, min_latency: gst::ClockTime, max_latency: gst::ClockTime);
|
||||
|
||||
fn set_min_frame_size(&self, min_size: u32);
|
||||
|
||||
fn set_passthrough(&self, passthrough: bool);
|
||||
|
||||
fn set_pts_interpolation(&self, pts_interpolate: bool);
|
||||
|
||||
fn set_syncable(&self, syncable: bool);
|
||||
|
||||
fn set_ts_at_offset(&self, offset: usize);
|
||||
|
||||
fn get_property_disable_passthrough(&self) -> bool;
|
||||
|
||||
fn set_property_disable_passthrough(&self, disable_passthrough: bool);
|
||||
|
||||
fn connect_property_disable_passthrough_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<BaseParse>> BaseParseExt for O {
|
||||
fn add_index_entry(&self, offset: u64, ts: gst::ClockTime, key: bool, force: bool) -> bool {
|
||||
unsafe {
|
||||
from_glib(gst_base_sys::gst_base_parse_add_index_entry(self.as_ref().to_glib_none().0, offset, ts.to_glib(), key.to_glib(), force.to_glib()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "v1_12", feature = "dox"))]
|
||||
fn drain(&self) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_drain(self.as_ref().to_glib_none().0);
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_tags(&self, tags: Option<&gst::TagList>, mode: gst::TagMergeMode) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_merge_tags(self.as_ref().to_glib_none().0, tags.to_glib_none().0, mode.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_average_bitrate(&self, bitrate: u32) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_average_bitrate(self.as_ref().to_glib_none().0, bitrate);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_has_timing_info(&self, has_timing: bool) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_has_timing_info(self.as_ref().to_glib_none().0, has_timing.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_infer_ts(&self, infer_ts: bool) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_infer_ts(self.as_ref().to_glib_none().0, infer_ts.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_latency(&self, min_latency: gst::ClockTime, max_latency: gst::ClockTime) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_latency(self.as_ref().to_glib_none().0, min_latency.to_glib(), max_latency.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_min_frame_size(&self, min_size: u32) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_min_frame_size(self.as_ref().to_glib_none().0, min_size);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_passthrough(&self, passthrough: bool) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_passthrough(self.as_ref().to_glib_none().0, passthrough.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_pts_interpolation(&self, pts_interpolate: bool) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_pts_interpolation(self.as_ref().to_glib_none().0, pts_interpolate.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_syncable(&self, syncable: bool) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_syncable(self.as_ref().to_glib_none().0, syncable.to_glib());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_ts_at_offset(&self, offset: usize) {
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_ts_at_offset(self.as_ref().to_glib_none().0, offset);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property_disable_passthrough(&self) -> bool {
|
||||
unsafe {
|
||||
let mut value = Value::from_type(<bool as StaticType>::static_type());
|
||||
gobject_sys::g_object_get_property(self.to_glib_none().0 as *mut gobject_sys::GObject, b"disable-passthrough\0".as_ptr() as *const _, value.to_glib_none_mut().0);
|
||||
value.get().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn set_property_disable_passthrough(&self, disable_passthrough: bool) {
|
||||
unsafe {
|
||||
gobject_sys::g_object_set_property(self.to_glib_none().0 as *mut gobject_sys::GObject, b"disable-passthrough\0".as_ptr() as *const _, Value::from(&disable_passthrough).to_glib_none().0);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_property_disable_passthrough_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(self.as_ptr() as *mut _, b"notify::disable-passthrough\0".as_ptr() as *const _,
|
||||
Some(transmute(notify_disable_passthrough_trampoline::<Self, F> as usize)), Box_::into_raw(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn notify_disable_passthrough_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(this: *mut gst_base_sys::GstBaseParse, _param_spec: glib_sys::gpointer, f: glib_sys::gpointer)
|
||||
where P: IsA<BaseParse> {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(&BaseParse::from_glib_borrow(this).unsafe_cast())
|
||||
}
|
|
@ -2,6 +2,34 @@
|
|||
// from gir-files (https://github.com/gtk-rs/gir-files)
|
||||
// DO NOT EDIT
|
||||
|
||||
use gst_base_sys;
|
||||
use glib::translate::*;
|
||||
use gst_base_sys;
|
||||
|
||||
bitflags! {
|
||||
pub struct BaseParseFrameFlags: u32 {
|
||||
const NONE = 0;
|
||||
const NEW_FRAME = 1;
|
||||
const NO_FRAME = 2;
|
||||
const CLIP = 4;
|
||||
const DROP = 8;
|
||||
const QUEUE = 16;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ToGlib for BaseParseFrameFlags {
|
||||
type GlibType = gst_base_sys::GstBaseParseFrameFlags;
|
||||
|
||||
fn to_glib(&self) -> gst_base_sys::GstBaseParseFrameFlags {
|
||||
self.bits()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromGlib<gst_base_sys::GstBaseParseFrameFlags> for BaseParseFrameFlags {
|
||||
fn from_glib(value: gst_base_sys::GstBaseParseFrameFlags) -> BaseParseFrameFlags {
|
||||
skip_assert_initialized!();
|
||||
BaseParseFrameFlags::from_bits_truncate(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ pub use self::aggregator_pad::{AggregatorPad, AggregatorPadClass, NONE_AGGREGATO
|
|||
#[cfg(any(feature = "v1_14", feature = "dox"))]
|
||||
pub use self::aggregator_pad::AggregatorPadExt;
|
||||
|
||||
mod base_parse;
|
||||
pub use self::base_parse::{BaseParse, BaseParseClass, NONE_BASE_PARSE};
|
||||
pub use self::base_parse::BaseParseExt;
|
||||
|
||||
mod base_sink;
|
||||
pub use self::base_sink::{BaseSink, BaseSinkClass, NONE_BASE_SINK};
|
||||
pub use self::base_sink::BaseSinkExt;
|
||||
|
@ -34,6 +38,9 @@ pub use self::base_transform::BaseTransformExt;
|
|||
mod push_src;
|
||||
pub use self::push_src::{PushSrc, PushSrcClass, NONE_PUSH_SRC};
|
||||
|
||||
mod flags;
|
||||
pub use self::flags::BaseParseFrameFlags;
|
||||
|
||||
pub mod functions;
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -42,6 +49,7 @@ pub mod traits {
|
|||
pub use super::AggregatorExt;
|
||||
#[cfg(any(feature = "v1_14", feature = "dox"))]
|
||||
pub use super::AggregatorPadExt;
|
||||
pub use super::BaseParseExt;
|
||||
pub use super::BaseSinkExt;
|
||||
pub use super::BaseSrcExt;
|
||||
pub use super::BaseTransformExt;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
Generated by gir (https://github.com/gtk-rs/gir @ 58cffd4)
|
||||
Generated by gir (https://github.com/gtk-rs/gir @ f511aae)
|
||||
from gir-files (https://github.com/gtk-rs/gir-files @ ???)
|
||||
|
|
142
gstreamer-base/src/base_parse.rs
Normal file
142
gstreamer-base/src/base_parse.rs
Normal file
|
@ -0,0 +1,142 @@
|
|||
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use glib::object::IsA;
|
||||
use glib::translate::*;
|
||||
use gst;
|
||||
use gst::FormattedValue;
|
||||
use gst_base_sys;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
use BaseParse;
|
||||
use BaseParseFrame;
|
||||
|
||||
pub trait BaseParseExtManual: 'static {
|
||||
fn get_sink_pad(&self) -> gst::Pad;
|
||||
fn get_src_pad(&self) -> gst::Pad;
|
||||
|
||||
fn set_duration<V: Into<gst::GenericFormattedValue>>(&self, duration: V, interval: u32);
|
||||
fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32);
|
||||
|
||||
fn convert_default<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
|
||||
&self,
|
||||
src_val: V,
|
||||
) -> Option<U>;
|
||||
fn convert_default_generic<V: Into<gst::GenericFormattedValue>>(
|
||||
&self,
|
||||
src_val: V,
|
||||
dest_format: gst::Format,
|
||||
) -> Option<gst::GenericFormattedValue>;
|
||||
|
||||
fn finish_frame(
|
||||
&self,
|
||||
frame: BaseParseFrame,
|
||||
size: u32,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError>;
|
||||
}
|
||||
|
||||
impl<O: IsA<BaseParse>> BaseParseExtManual for O {
|
||||
fn get_sink_pad(&self) -> gst::Pad {
|
||||
unsafe {
|
||||
let elt: &gst_base_sys::GstBaseParse = &*(self.as_ptr() as *const _);
|
||||
from_glib_none(elt.sinkpad)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_src_pad(&self) -> gst::Pad {
|
||||
unsafe {
|
||||
let elt: &gst_base_sys::GstBaseParse = &*(self.as_ptr() as *const _);
|
||||
from_glib_none(elt.srcpad)
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration<V: Into<gst::GenericFormattedValue>>(&self, duration: V, interval: u32) {
|
||||
let duration = duration.into();
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_duration(
|
||||
self.as_ref().to_glib_none().0,
|
||||
duration.get_format().to_glib(),
|
||||
duration.get_value(),
|
||||
interval as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32) {
|
||||
let (fps_num, fps_den) = fps.into();
|
||||
unsafe {
|
||||
gst_base_sys::gst_base_parse_set_frame_rate(
|
||||
self.as_ref().to_glib_none().0,
|
||||
fps_num as u32,
|
||||
fps_den as u32,
|
||||
lead_in,
|
||||
lead_out,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_default<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
|
||||
&self,
|
||||
src_val: V,
|
||||
) -> Option<U> {
|
||||
let src_val = src_val.into();
|
||||
unsafe {
|
||||
let mut dest_val = mem::uninitialized();
|
||||
let ret = from_glib(gst_base_sys::gst_base_parse_convert_default(
|
||||
self.as_ref().to_glib_none().0,
|
||||
src_val.get_format().to_glib(),
|
||||
src_val.to_raw_value(),
|
||||
U::get_default_format().to_glib(),
|
||||
&mut dest_val,
|
||||
));
|
||||
if ret {
|
||||
Some(U::from_raw(U::get_default_format(), dest_val))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_default_generic<V: Into<gst::GenericFormattedValue>>(
|
||||
&self,
|
||||
src_val: V,
|
||||
dest_format: gst::Format,
|
||||
) -> Option<gst::GenericFormattedValue> {
|
||||
let src_val = src_val.into();
|
||||
unsafe {
|
||||
let mut dest_val = mem::uninitialized();
|
||||
let ret = from_glib(gst_base_sys::gst_base_parse_convert_default(
|
||||
self.as_ref().to_glib_none().0,
|
||||
src_val.get_format().to_glib(),
|
||||
src_val.to_raw_value(),
|
||||
dest_format.to_glib(),
|
||||
&mut dest_val,
|
||||
));
|
||||
if ret {
|
||||
Some(gst::GenericFormattedValue::new(dest_format, dest_val))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_frame(
|
||||
&self,
|
||||
frame: BaseParseFrame,
|
||||
size: u32,
|
||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
unsafe {
|
||||
gst::FlowReturn::from_glib(gst_base_sys::gst_base_parse_finish_frame(
|
||||
self.as_ref().to_glib_none().0,
|
||||
frame.to_glib_none().0,
|
||||
i32::try_from(size).expect("size higher than i32::MAX"),
|
||||
))
|
||||
.into_result()
|
||||
}
|
||||
}
|
||||
}
|
175
gstreamer-base/src/base_parse_frame.rs
Normal file
175
gstreamer-base/src/base_parse_frame.rs
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use glib::translate::*;
|
||||
use gst;
|
||||
use gst::MiniObject;
|
||||
use gst_base_sys;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
use BaseParse;
|
||||
use BaseParseFrameFlags;
|
||||
|
||||
pub struct BaseParseFrame<'a>(
|
||||
ptr::NonNull<gst_base_sys::GstBaseParseFrame>,
|
||||
PhantomData<&'a BaseParse>,
|
||||
);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Overhead {
|
||||
None,
|
||||
Frame,
|
||||
Bytes(u32),
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ToGlib for Overhead {
|
||||
type GlibType = i32;
|
||||
|
||||
fn to_glib(&self) -> i32 {
|
||||
match *self {
|
||||
Overhead::None => 0,
|
||||
Overhead::Frame => -1,
|
||||
Overhead::Bytes(b) => i32::try_from(b).expect("overhead is higher than i32::MAX"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromGlib<i32> for Overhead {
|
||||
#[inline]
|
||||
fn from_glib(val: i32) -> Overhead {
|
||||
match val {
|
||||
0 => Overhead::None,
|
||||
1 => Overhead::Frame,
|
||||
b if b > 0 => Overhead::Bytes(val as u32),
|
||||
_ => panic!("overheader is lower than -1"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'a> ::glib::translate::ToGlibPtr<'a, *mut gst_base_sys::GstBaseParseFrame>
|
||||
for BaseParseFrame<'a>
|
||||
{
|
||||
type Storage = &'a Self;
|
||||
|
||||
fn to_glib_none(
|
||||
&'a self,
|
||||
) -> ::glib::translate::Stash<*mut gst_base_sys::GstBaseParseFrame, Self> {
|
||||
Stash(self.0.as_ptr(), self)
|
||||
}
|
||||
|
||||
fn to_glib_full(&self) -> *mut gst_base_sys::GstBaseParseFrame {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for BaseParseFrame<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let mut b = f.debug_struct("BaseParseFrame");
|
||||
|
||||
b.field("buffer", &self.get_buffer())
|
||||
.field("output_buffer", &self.get_output_buffer())
|
||||
.field("flags", &self.get_flags())
|
||||
.field("offset", &self.get_offset())
|
||||
.field("overhead", &self.get_overhead());
|
||||
|
||||
b.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BaseParseFrame<'a> {
|
||||
#[cfg(feature = "subclassing")]
|
||||
pub(crate) unsafe fn new(
|
||||
frame: *mut gst_base_sys::GstBaseParseFrame,
|
||||
_parse: &'a BaseParse,
|
||||
) -> BaseParseFrame<'a> {
|
||||
assert!(!frame.is_null());
|
||||
BaseParseFrame(ptr::NonNull::new_unchecked(frame), PhantomData)
|
||||
}
|
||||
|
||||
pub fn get_buffer(&self) -> Option<&mut gst::BufferRef> {
|
||||
unsafe {
|
||||
let ptr = (*self.to_glib_none().0).buffer;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
|
||||
ptr as *const gst_sys::GstMiniObject,
|
||||
));
|
||||
assert!(writable);
|
||||
|
||||
Some(gst::BufferRef::from_mut_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_output_buffer(&self) -> Option<&mut gst::BufferRef> {
|
||||
unsafe {
|
||||
let ptr = (*self.to_glib_none().0).out_buffer;
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
|
||||
ptr as *const gst_sys::GstMiniObject,
|
||||
));
|
||||
assert!(writable);
|
||||
|
||||
Some(gst::BufferRef::from_mut_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_output_buffer(&self, output_buffer: gst::Buffer) {
|
||||
unsafe {
|
||||
let prev = (*self.to_glib_none().0).out_buffer;
|
||||
|
||||
if !prev.is_null() {
|
||||
gst_sys::gst_mini_object_unref(prev as *mut gst_sys::GstMiniObject);
|
||||
}
|
||||
|
||||
let ptr = output_buffer.into_ptr();
|
||||
let writable: bool = from_glib(gst_sys::gst_mini_object_is_writable(
|
||||
ptr as *const gst_sys::GstMiniObject,
|
||||
));
|
||||
assert!(writable);
|
||||
|
||||
(*self.to_glib_none().0).out_buffer = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_flags(&self) -> BaseParseFrameFlags {
|
||||
let flags = unsafe { (*self.to_glib_none().0).flags };
|
||||
BaseParseFrameFlags::from_bits_truncate(flags)
|
||||
}
|
||||
|
||||
pub fn set_flags(&self, flags: BaseParseFrameFlags) {
|
||||
unsafe { (*self.to_glib_none().0).flags |= flags.bits() }
|
||||
}
|
||||
|
||||
pub fn unset_flags(&self, flags: BaseParseFrameFlags) {
|
||||
unsafe { (*self.to_glib_none().0).flags &= !flags.bits() }
|
||||
}
|
||||
|
||||
pub fn get_offset(&self) -> u64 {
|
||||
unsafe { (*self.to_glib_none().0).offset }
|
||||
}
|
||||
|
||||
pub fn get_overhead(&self) -> Overhead {
|
||||
unsafe { from_glib((*self.to_glib_none().0).overhead) }
|
||||
}
|
||||
|
||||
pub fn set_overhead(&self, overhead: Overhead) {
|
||||
unsafe {
|
||||
(*self.to_glib_none().0).overhead = overhead.to_glib();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@ extern crate gstreamer_base_sys as gst_base_sys;
|
|||
extern crate gstreamer_sys as gst_sys;
|
||||
|
||||
extern crate libc;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
#[macro_use]
|
||||
extern crate glib;
|
||||
|
@ -26,6 +28,10 @@ macro_rules! assert_initialized_main_thread {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! skip_assert_initialized {
|
||||
() => {};
|
||||
}
|
||||
|
||||
pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value};
|
||||
|
||||
#[allow(clippy::unreadable_literal)]
|
||||
|
@ -48,10 +54,14 @@ pub use flow_combiner::*;
|
|||
mod aggregator;
|
||||
#[cfg(any(feature = "v1_14", feature = "dox"))]
|
||||
mod aggregator_pad;
|
||||
mod base_parse;
|
||||
mod base_sink;
|
||||
mod base_src;
|
||||
mod base_transform;
|
||||
|
||||
pub mod base_parse_frame;
|
||||
pub use base_parse_frame::BaseParseFrame;
|
||||
|
||||
// Re-export all the traits in a prelude module, so that applications
|
||||
// can always "use gst::prelude::*" without getting conflicts
|
||||
pub mod prelude {
|
||||
|
@ -63,6 +73,8 @@ pub mod prelude {
|
|||
#[cfg(any(feature = "v1_14", feature = "dox"))]
|
||||
pub use aggregator_pad::AggregatorPadExtManual;
|
||||
pub use auto::traits::*;
|
||||
pub use base_parse::BaseParseExtManual;
|
||||
pub use base_parse_frame::BaseParseFrame;
|
||||
pub use base_sink::BaseSinkExtManual;
|
||||
pub use base_src::BaseSrcExtManual;
|
||||
pub use base_transform::BaseTransformExtManual;
|
||||
|
|
311
gstreamer-base/src/subclass/base_parse.rs
Normal file
311
gstreamer-base/src/subclass/base_parse.rs
Normal file
|
@ -0,0 +1,311 @@
|
|||
// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use glib_sys;
|
||||
use gst_base_sys;
|
||||
use gst_sys;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem;
|
||||
|
||||
use glib::translate::*;
|
||||
use prelude::*;
|
||||
|
||||
use glib::subclass::prelude::*;
|
||||
use gst;
|
||||
use gst::subclass::prelude::*;
|
||||
|
||||
use BaseParse;
|
||||
use BaseParseClass;
|
||||
|
||||
pub trait BaseParseImpl: BaseParseImplExt + ElementImpl + Send + Sync + 'static {
|
||||
fn start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage> {
|
||||
self.parent_start(element)
|
||||
}
|
||||
|
||||
fn set_sink_caps(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<(), gst::ErrorMessage> {
|
||||
self.parent_set_sink_caps(element, caps)
|
||||
}
|
||||
|
||||
fn handle_frame<'a>(
|
||||
&'a self,
|
||||
element: &BaseParse,
|
||||
frame: BaseParseFrame,
|
||||
) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
|
||||
self.parent_handle_frame(element, frame)
|
||||
}
|
||||
|
||||
fn convert<V: Into<gst::GenericFormattedValue>>(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
src_val: V,
|
||||
dest_format: gst::Format,
|
||||
) -> Option<gst::GenericFormattedValue>;
|
||||
}
|
||||
|
||||
pub trait BaseParseImplExt {
|
||||
fn parent_start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage>;
|
||||
|
||||
fn parent_set_sink_caps(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<(), gst::ErrorMessage>;
|
||||
|
||||
fn parent_handle_frame<'a>(
|
||||
&'a self,
|
||||
element: &BaseParse,
|
||||
frame: BaseParseFrame,
|
||||
) -> Result<(gst::FlowSuccess, u32), gst::FlowError>;
|
||||
|
||||
fn parent_convert<V: Into<gst::GenericFormattedValue>>(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
src_val: V,
|
||||
dest_format: gst::Format,
|
||||
) -> Option<gst::GenericFormattedValue>;
|
||||
}
|
||||
|
||||
impl<T: BaseParseImpl + ObjectImpl> BaseParseImplExt for T {
|
||||
fn parent_start(&self, element: &BaseParse) -> Result<(), gst::ErrorMessage> {
|
||||
unsafe {
|
||||
let data = self.get_type_data();
|
||||
let parent_class =
|
||||
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
|
||||
(*parent_class)
|
||||
.start
|
||||
.map(|f| {
|
||||
if from_glib(f(element.to_glib_none().0)) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(gst_error_msg!(
|
||||
gst::CoreError::StateChange,
|
||||
["Parent function `start` failed"]
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_set_sink_caps(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
caps: &gst::Caps,
|
||||
) -> Result<(), gst::ErrorMessage> {
|
||||
unsafe {
|
||||
let data = self.get_type_data();
|
||||
let parent_class =
|
||||
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
|
||||
(*parent_class)
|
||||
.set_sink_caps
|
||||
.map(|f| {
|
||||
if from_glib(f(element.to_glib_none().0, caps.to_glib_none().0)) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(gst_error_msg!(
|
||||
gst::CoreError::StateChange,
|
||||
["Parent function `set_sink_caps` failed"]
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_handle_frame<'a>(
|
||||
&'a self,
|
||||
element: &'a BaseParse,
|
||||
frame: BaseParseFrame,
|
||||
) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
|
||||
unsafe {
|
||||
let data = self.get_type_data();
|
||||
let parent_class =
|
||||
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
|
||||
let mut skipsize = 0;
|
||||
let res = (*parent_class).handle_frame.map(|f| {
|
||||
let res = gst::FlowReturn::from_glib(f(
|
||||
element.to_glib_none().0,
|
||||
frame.to_glib_none().0,
|
||||
&mut skipsize,
|
||||
));
|
||||
(res, skipsize as u32)
|
||||
});
|
||||
|
||||
match res {
|
||||
Some((res, skipsize)) => {
|
||||
let res = res.into_result();
|
||||
Ok((res.unwrap(), skipsize))
|
||||
}
|
||||
None => Err(gst::FlowError::Error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_convert<V: Into<gst::GenericFormattedValue>>(
|
||||
&self,
|
||||
element: &BaseParse,
|
||||
src_val: V,
|
||||
dest_format: gst::Format,
|
||||
) -> Option<gst::GenericFormattedValue> {
|
||||
unsafe {
|
||||
let data = self.get_type_data();
|
||||
let parent_class =
|
||||
data.as_ref().get_parent_class() as *mut gst_base_sys::GstBaseParseClass;
|
||||
let src_val = src_val.into();
|
||||
let res = (*parent_class).convert.map(|f| {
|
||||
let mut dest_val = mem::uninitialized();
|
||||
|
||||
let res = from_glib(f(
|
||||
element.to_glib_none().0,
|
||||
src_val.get_format().to_glib(),
|
||||
src_val.to_raw_value(),
|
||||
dest_format.to_glib(),
|
||||
&mut dest_val,
|
||||
));
|
||||
(res, dest_val)
|
||||
});
|
||||
|
||||
match res {
|
||||
Some((true, dest_val)) => {
|
||||
Some(gst::GenericFormattedValue::new(dest_format, dest_val))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: ObjectSubclass + BaseParseImpl> IsSubclassable<T> for BaseParseClass
|
||||
where
|
||||
<T as ObjectSubclass>::Instance: PanicPoison,
|
||||
{
|
||||
fn override_vfuncs(&mut self) {
|
||||
<gst::ElementClass as IsSubclassable<T>>::override_vfuncs(self);
|
||||
unsafe {
|
||||
let klass = &mut *(self as *mut Self as *mut gst_base_sys::GstBaseParseClass);
|
||||
klass.start = Some(base_parse_start::<T>);
|
||||
klass.set_sink_caps = Some(base_parse_set_sink_caps::<T>);
|
||||
klass.handle_frame = Some(base_parse_handle_frame::<T>);
|
||||
klass.convert = Some(base_parse_convert::<T>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn base_parse_start<T: ObjectSubclass>(
|
||||
ptr: *mut gst_base_sys::GstBaseParse,
|
||||
) -> glib_sys::gboolean
|
||||
where
|
||||
T: BaseParseImpl,
|
||||
T::Instance: PanicPoison,
|
||||
{
|
||||
glib_floating_reference_guard!(ptr);
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.get_impl();
|
||||
let wrap: BaseParse = from_glib_borrow(ptr);
|
||||
|
||||
gst_panic_to_error!(&wrap, &instance.panicked(), false, {
|
||||
match imp.start(&wrap) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
wrap.post_error_message(&err);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.to_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn base_parse_set_sink_caps<T: ObjectSubclass>(
|
||||
ptr: *mut gst_base_sys::GstBaseParse,
|
||||
caps: *mut gst_sys::GstCaps,
|
||||
) -> glib_sys::gboolean
|
||||
where
|
||||
T: BaseParseImpl,
|
||||
T::Instance: PanicPoison,
|
||||
{
|
||||
glib_floating_reference_guard!(ptr);
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.get_impl();
|
||||
let wrap: BaseParse = from_glib_borrow(ptr);
|
||||
let caps: gst::Caps = from_glib_none(caps);
|
||||
|
||||
gst_panic_to_error!(&wrap, &instance.panicked(), false, {
|
||||
match imp.set_sink_caps(&wrap, &caps) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
wrap.post_error_message(&err);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.to_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn base_parse_handle_frame<T: ObjectSubclass>(
|
||||
ptr: *mut gst_base_sys::GstBaseParse,
|
||||
frame: *mut gst_base_sys::GstBaseParseFrame,
|
||||
skipsize: *mut i32,
|
||||
) -> gst_sys::GstFlowReturn
|
||||
where
|
||||
T: BaseParseImpl,
|
||||
T::Instance: PanicPoison,
|
||||
{
|
||||
glib_floating_reference_guard!(ptr);
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.get_impl();
|
||||
let wrap: BaseParse = from_glib_borrow(ptr);
|
||||
let wrap_frame = BaseParseFrame::new(frame, &wrap);
|
||||
|
||||
let res = gst_panic_to_error!(&wrap, &instance.panicked(), Err(gst::FlowError::Error), {
|
||||
imp.handle_frame(&wrap, wrap_frame)
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok((flow, skip)) => {
|
||||
*skipsize = i32::try_from(skip).expect("skip is higher than i32::MAX");
|
||||
gst::FlowReturn::from_ok(flow)
|
||||
}
|
||||
Err(flow) => gst::FlowReturn::from_error(flow),
|
||||
}
|
||||
.to_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn base_parse_convert<T: ObjectSubclass>(
|
||||
ptr: *mut gst_base_sys::GstBaseParse,
|
||||
source_format: gst_sys::GstFormat,
|
||||
source_value: i64,
|
||||
dest_format: gst_sys::GstFormat,
|
||||
dest_value: *mut i64,
|
||||
) -> glib_sys::gboolean
|
||||
where
|
||||
T: BaseParseImpl,
|
||||
T::Instance: PanicPoison,
|
||||
{
|
||||
glib_floating_reference_guard!(ptr);
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.get_impl();
|
||||
let wrap: BaseParse = from_glib_borrow(ptr);
|
||||
let source = gst::GenericFormattedValue::new(from_glib(source_format), source_value);
|
||||
|
||||
let res = gst_panic_to_error!(&wrap, &instance.panicked(), None, {
|
||||
imp.convert(&wrap, source, from_glib(dest_format))
|
||||
});
|
||||
|
||||
match res {
|
||||
Some(dest) => {
|
||||
*dest_value = dest.to_raw_value();
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
.to_glib()
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
// except according to those terms.
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
|
||||
pub mod base_parse;
|
||||
pub mod base_sink;
|
||||
pub mod base_src;
|
||||
pub mod base_transform;
|
||||
|
@ -24,6 +25,7 @@ pub mod prelude {
|
|||
pub use super::aggregator::{AggregatorImpl, AggregatorImplExt};
|
||||
#[cfg(any(feature = "v1_14", feature = "dox"))]
|
||||
pub use super::aggregator_pad::{AggregatorPadImpl, AggregatorPadImplExt};
|
||||
pub use super::base_parse::{BaseParseImpl, BaseParseImplExt};
|
||||
pub use super::base_sink::{BaseSinkImpl, BaseSinkImplExt};
|
||||
pub use super::base_src::{BaseSrcImpl, BaseSrcImplExt};
|
||||
pub use super::base_transform::{
|
||||
|
|
Loading…
Reference in a new issue