diff --git a/Cargo.toml b/Cargo.toml index e85b0958..07d37d8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,6 @@ [workspace] members = [ - "gst-plugin", - "gst-plugin-simple", "gst-plugin-file", "gst-plugin-http", "gst-plugin-flv", diff --git a/gst-plugin-simple/Cargo.toml b/gst-plugin-simple/Cargo.toml deleted file mode 100644 index 064581f0..00000000 --- a/gst-plugin-simple/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "gst-plugin-simple" -version = "0.4.0" -authors = ["Sebastian Dröge "] -repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs" -license = "MIT/Apache-2.0" - -[dependencies] -url = "1.1" -glib = { git = "https://github.com/gtk-rs/glib" } -gobject-subclass = { git = "https://github.com/gtk-rs/gobject-subclass" } -gst-plugin = { path="../gst-plugin" } -gstreamer = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } -gstreamer-base = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } - -[lib] -name = "gst_plugin_simple" -path = "src/lib.rs" diff --git a/gst-plugin-simple/src/demuxer.rs b/gst-plugin-simple/src/demuxer.rs deleted file mode 100644 index 4fb75958..00000000 --- a/gst-plugin-simple/src/demuxer.rs +++ /dev/null @@ -1,689 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::sync::Mutex; - -use std::collections::BTreeMap; -use std::u32; -use std::u64; - -use glib; -use gobject_subclass::object::*; -use gst_plugin::element::*; -use gst_plugin::error::*; - -use gst; -use gst::prelude::*; -use gst_base; - -pub type StreamIndex = u32; - -#[derive(Debug)] -pub enum SeekResult { - TooEarly, - Ok(u64), - Eos, -} - -#[derive(Debug)] -pub enum HandleBufferResult { - NeedMoreData, - Again, - // NeedDataFromOffset(u64), - StreamAdded(Stream), - HaveAllStreams, - StreamChanged(Stream), - // StreamsAdded(Vec), // Implies HaveAllStreams - StreamsChanged(Vec), - // TODO need something to replace/add new streams - // TODO should probably directly implement the GstStreams new world order - BufferForStream(StreamIndex, gst::Buffer), - Eos(Option), -} - -pub trait DemuxerImpl: Send + 'static { - fn start( - &mut self, - demuxer: &Element, - upstream_size: Option, - random_access: bool, - ) -> Result<(), gst::ErrorMessage>; - fn stop(&mut self, demuxer: &Element) -> Result<(), gst::ErrorMessage>; - - fn seek( - &mut self, - demuxer: &Element, - start: gst::ClockTime, - stop: gst::ClockTime, - ) -> Result; - fn handle_buffer( - &mut self, - demuxer: &Element, - buffer: Option, - ) -> Result; - fn end_of_stream(&mut self, demuxer: &Element) -> Result<(), gst::ErrorMessage>; - - fn is_seekable(&self, demuxer: &Element) -> bool; - fn get_position(&self, demuxer: &Element) -> gst::ClockTime; - fn get_duration(&self, demuxer: &Element) -> gst::ClockTime; -} - -#[derive(Debug)] -pub struct Stream { - pub index: StreamIndex, - pub caps: gst::Caps, - pub stream_id: String, -} - -impl Stream { - pub fn new(index: StreamIndex, caps: gst::Caps, stream_id: String) -> Stream { - Stream { - index, - caps, - stream_id, - } - } -} - -pub struct DemuxerInfo { - pub name: String, - pub long_name: String, - pub description: String, - pub classification: String, - pub author: String, - pub rank: u32, - pub create_instance: fn(&Element) -> Box, - pub input_caps: gst::Caps, - pub output_caps: gst::Caps, -} - -pub struct Demuxer { - cat: gst::DebugCategory, - sinkpad: gst::Pad, - flow_combiner: Mutex, - group_id: Mutex, - srcpads: Mutex>, - imp: Mutex>, -} - -#[derive(Default)] -pub struct UniqueFlowCombiner(gst_base::FlowCombiner); - -impl UniqueFlowCombiner { - fn add_pad(&mut self, pad: &gst::Pad) { - self.0.add_pad(pad); - } - - fn clear(&mut self) { - self.0.clear(); - } - - fn update_flow(&mut self, flow_ret: gst::FlowReturn) -> gst::FlowReturn { - self.0.update_flow(flow_ret) - } -} - -unsafe impl Send for UniqueFlowCombiner {} -unsafe impl Sync for UniqueFlowCombiner {} - -impl Demuxer { - fn new(element: &Element, sinkpad: gst::Pad, demuxer_info: &DemuxerInfo) -> Self { - Self { - cat: gst::DebugCategory::new( - "rsdemux", - gst::DebugColorFlags::empty(), - "Rust demuxer base class", - ), - sinkpad, - flow_combiner: Mutex::new(Default::default()), - group_id: Mutex::new(gst::util_group_id_next()), - srcpads: Mutex::new(BTreeMap::new()), - imp: Mutex::new((demuxer_info.create_instance)(element)), - } - } - - fn class_init(klass: &mut ElementClass, demuxer_info: &DemuxerInfo) { - klass.set_metadata( - &demuxer_info.long_name, - &demuxer_info.classification, - &demuxer_info.description, - &demuxer_info.author, - ); - - let pad_template = gst::PadTemplate::new( - "sink", - gst::PadDirection::Sink, - gst::PadPresence::Always, - &demuxer_info.input_caps, - ); - klass.add_pad_template(pad_template); - - let pad_template = gst::PadTemplate::new( - "src_%u", - gst::PadDirection::Src, - gst::PadPresence::Sometimes, - &demuxer_info.output_caps, - ); - klass.add_pad_template(pad_template); - } - - fn init(element: &Element, demuxer_info: &DemuxerInfo) -> Box> { - let templ = element.get_pad_template("sink").unwrap(); - let sinkpad = gst::Pad::new_from_template(&templ, "sink"); - sinkpad.set_activate_function(Demuxer::sink_activate); - sinkpad.set_activatemode_function(Demuxer::sink_activatemode); - sinkpad.set_chain_function(Demuxer::sink_chain); - sinkpad.set_event_function(Demuxer::sink_event); - element.add_pad(&sinkpad).unwrap(); - - let imp = Self::new(element, sinkpad, demuxer_info); - Box::new(imp) - } - - fn add_stream(&self, element: &Element, index: u32, caps: gst::Caps, stream_id: &str) { - let mut srcpads = self.srcpads.lock().unwrap(); - assert!(!srcpads.contains_key(&index)); - - let templ = element.get_pad_template("src_%u").unwrap(); - let name = format!("src_{}", index); - let pad = gst::Pad::new_from_template(&templ, Some(name.as_str())); - pad.set_query_function(Demuxer::src_query); - pad.set_event_function(Demuxer::src_event); - - pad.set_active(true).unwrap(); - - let full_stream_id = pad.create_stream_id(element, stream_id).unwrap(); - pad.push_event( - gst::Event::new_stream_start(&full_stream_id) - .group_id(*self.group_id.lock().unwrap()) - .build(), - ); - pad.push_event(gst::Event::new_caps(&caps).build()); - - let segment = gst::FormattedSegment::::default(); - pad.push_event(gst::Event::new_segment(&segment).build()); - - self.flow_combiner.lock().unwrap().add_pad(&pad); - element.add_pad(&pad).unwrap(); - - srcpads.insert(index, pad); - } - - fn added_all_streams(&self, element: &Element) { - element.no_more_pads(); - *self.group_id.lock().unwrap() = gst::util_group_id_next(); - } - - fn stream_format_changed(&self, _element: &Element, index: u32, caps: gst::Caps) { - let srcpads = self.srcpads.lock().unwrap(); - - if let Some(pad) = srcpads.get(&index) { - pad.push_event(gst::Event::new_caps(&caps).build()); - } - } - - fn stream_eos(&self, _element: &Element, index: Option) { - let srcpads = self.srcpads.lock().unwrap(); - - let event = gst::Event::new_eos().build(); - match index { - Some(index) => { - if let Some(pad) = srcpads.get(&index) { - pad.push_event(event); - } - } - None => { - for (_, pad) in srcpads.iter().by_ref() { - pad.push_event(event.clone()); - } - } - }; - } - - fn stream_push_buffer( - &self, - _element: &Element, - index: u32, - buffer: gst::Buffer, - ) -> gst::FlowReturn { - let srcpads = self.srcpads.lock().unwrap(); - - if let Some(pad) = srcpads.get(&index) { - self.flow_combiner - .lock() - .unwrap() - .update_flow(pad.push(buffer)) - } else { - gst::FlowReturn::Error - } - } - - fn remove_all_streams(&self, element: &Element) { - self.flow_combiner.lock().unwrap().clear(); - let mut srcpads = self.srcpads.lock().unwrap(); - for (_, pad) in srcpads.iter().by_ref() { - element.remove_pad(pad).unwrap(); - } - srcpads.clear(); - } - - fn sink_activate(pad: &gst::Pad, _parent: &Option) -> bool { - let mode = { - let mut query = gst::Query::new_scheduling(); - if !pad.peer_query(&mut query) { - return false; - } - - // TODO - //if (gst_query_has_scheduling_mode_with_flags (query, GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) { - // GST_DEBUG_OBJECT (demuxer, "Activating in PULL mode"); - // mode = GST_PAD_MODE_PULL; - //} else { - //GST_DEBUG_OBJECT (demuxer, "Activating in PUSH mode"); - //} - gst::PadMode::Push - }; - - match pad.activate_mode(mode, true) { - Ok(_) => true, - Err(_) => false, - } - } - - fn start(&self, element: &Element, upstream_size: Option, random_access: bool) -> bool { - let demuxer_impl = &mut self.imp.lock().unwrap(); - - gst_debug!( - self.cat, - obj: element, - "Starting with upstream size {:?} and random access {}", - upstream_size, - random_access - ); - - match demuxer_impl.start(element, upstream_size, random_access) { - Ok(..) => { - gst_trace!(self.cat, obj: element, "Successfully started",); - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: element, "Failed to start: {:?}", msg); - element.post_error_message(msg); - false - } - } - } - - fn stop(&self, element: &Element) -> bool { - let demuxer_impl = &mut self.imp.lock().unwrap(); - - gst_debug!(self.cat, obj: element, "Stopping"); - - match demuxer_impl.stop(element) { - Ok(..) => { - gst_trace!(self.cat, obj: element, "Successfully stop"); - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: element, "Failed to stop: {:?}", msg); - element.post_error_message(msg); - false - } - } - } - - fn sink_activatemode( - _pad: &gst::Pad, - parent: &Option, - mode: gst::PadMode, - active: bool, - ) -> bool { - let element = parent.as_ref().unwrap().downcast_ref::().unwrap(); - let demuxer = element.get_impl().downcast_ref::().unwrap(); - - if active { - let upstream_size = demuxer - .sinkpad - .peer_query_duration::() - .and_then(|v| v.0); - - if !demuxer.start(element, upstream_size, mode == gst::PadMode::Pull) { - return false; - } - - if mode == gst::PadMode::Pull { - // TODO - // demuxer.sinkpad.start_task(...) - } - - true - } else { - if mode == gst::PadMode::Pull { - let _ = demuxer.sinkpad.stop_task(); - } - - demuxer.stop(element) - } - } - - fn sink_chain( - _pad: &gst::Pad, - parent: &Option, - buffer: gst::Buffer, - ) -> gst::FlowReturn { - let element = parent.as_ref().unwrap().downcast_ref::().unwrap(); - let demuxer = element.get_impl().downcast_ref::().unwrap(); - - let mut res = { - let demuxer_impl = &mut demuxer.imp.lock().unwrap(); - - gst_trace!(demuxer.cat, obj: element, "Handling buffer {:?}", buffer); - - match demuxer_impl.handle_buffer(element, Some(buffer)) { - Ok(res) => res, - Err(flow_error) => { - gst_error!( - demuxer.cat, - obj: element, - "Failed handling buffer: {:?}", - flow_error - ); - match flow_error { - FlowError::NotNegotiated(ref msg) | FlowError::Error(ref msg) => { - element.post_error_message(msg); - } - _ => (), - } - return flow_error.into(); - } - } - }; - - // Loop until AllEos, NeedMoreData or error when pushing downstream - loop { - gst_trace!(demuxer.cat, obj: element, "Handled {:?}", res); - - match res { - HandleBufferResult::NeedMoreData => { - return gst::FlowReturn::Ok; - } - HandleBufferResult::StreamAdded(stream) => { - demuxer.add_stream(element, stream.index, stream.caps, &stream.stream_id); - } - HandleBufferResult::HaveAllStreams => { - demuxer.added_all_streams(element); - } - HandleBufferResult::StreamChanged(stream) => { - demuxer.stream_format_changed(element, stream.index, stream.caps); - } - HandleBufferResult::StreamsChanged(streams) => { - for stream in streams { - demuxer.stream_format_changed(element, stream.index, stream.caps); - } - } - HandleBufferResult::BufferForStream(index, buffer) => { - let flow_ret = demuxer.stream_push_buffer(element, index, buffer); - - if flow_ret != gst::FlowReturn::Ok { - return flow_ret; - } - } - HandleBufferResult::Eos(index) => { - demuxer.stream_eos(element, index); - return gst::FlowReturn::Eos; - } - HandleBufferResult::Again => { - // nothing, just call again - } - }; - - gst_trace!(demuxer.cat, obj: element, "Calling again"); - - res = { - let demuxer_impl = &mut demuxer.imp.lock().unwrap(); - match demuxer_impl.handle_buffer(element, None) { - Ok(res) => res, - Err(flow_error) => { - gst_error!( - demuxer.cat, - obj: element, - "Failed calling again: {:?}", - flow_error - ); - match flow_error { - FlowError::NotNegotiated(ref msg) | FlowError::Error(ref msg) => { - element.post_error_message(msg); - } - _ => (), - } - return flow_error.into(); - } - } - } - } - } - - fn sink_event(pad: &gst::Pad, parent: &Option, event: gst::Event) -> bool { - use gst::EventView; - - let element = parent.as_ref().unwrap().downcast_ref::().unwrap(); - let demuxer = element.get_impl().downcast_ref::().unwrap(); - - match event.view() { - EventView::Eos(..) => { - let demuxer_impl = &mut demuxer.imp.lock().unwrap(); - - gst_debug!(demuxer.cat, obj: element, "End of stream"); - match demuxer_impl.end_of_stream(element) { - Ok(_) => (), - Err(ref msg) => { - gst_error!(demuxer.cat, obj: element, "Failed end of stream: {:?}", msg); - element.post_error_message(msg); - } - } - pad.event_default(parent.as_ref(), event) - } - EventView::Segment(..) => pad.event_default(parent.as_ref(), event), - _ => pad.event_default(parent.as_ref(), event), - } - } - - fn src_query(pad: &gst::Pad, parent: &Option, query: &mut gst::QueryRef) -> bool { - use gst::QueryView; - - let element = parent.as_ref().unwrap().downcast_ref::().unwrap(); - let demuxer = element.get_impl().downcast_ref::().unwrap(); - - match query.view_mut() { - QueryView::Position(ref mut q) => { - let fmt = q.get_format(); - if fmt == gst::Format::Time { - let demuxer_impl = &demuxer.imp.lock().unwrap(); - - let position = demuxer_impl.get_position(&element); - gst_trace!( - demuxer.cat, - obj: element, - "Returning position {:?}", - position - ); - - match *position { - None => return false, - Some(_) => { - q.set(position); - return true; - } - } - } else { - return false; - } - } - QueryView::Duration(ref mut q) => { - let fmt = q.get_format(); - if fmt == gst::Format::Time { - let demuxer_impl = &demuxer.imp.lock().unwrap(); - - let duration = demuxer_impl.get_duration(&element); - gst_trace!( - demuxer.cat, - obj: element, - "Returning duration {:?}", - duration - ); - - match *duration { - None => return false, - Some(_) => { - q.set(duration); - return true; - } - } - } else { - return false; - } - } - _ => (), - } - - // FIXME: Have to do it outside the match because otherwise query is already mutably - // borrowed by the query view. - pad.query_default(parent.as_ref(), query) - } - - fn src_event(pad: &gst::Pad, parent: &Option, event: gst::Event) -> bool { - use gst::EventView; - - match event.view() { - EventView::Seek(..) => { - // TODO: Implement - false - } - _ => pad.event_default(parent.as_ref(), event), - } - } - - fn seek( - &self, - element: &Element, - start: gst::ClockTime, - stop: gst::ClockTime, - offset: &mut u64, - ) -> bool { - gst_debug!(self.cat, obj: element, "Seeking to {:?}-{:?}", start, stop); - - let res = { - let demuxer_impl = &mut self.imp.lock().unwrap(); - - match demuxer_impl.seek(element, start, stop) { - Ok(res) => res, - Err(ref msg) => { - gst_error!(self.cat, obj: element, "Failed to seek: {:?}", msg); - element.post_error_message(msg); - return false; - } - } - }; - - match res { - SeekResult::TooEarly => { - gst_debug!(self.cat, obj: element, "Seeked too early"); - false - } - SeekResult::Ok(off) => { - gst_trace!(self.cat, obj: element, "Seeked successfully"); - *offset = off; - true - } - SeekResult::Eos => { - gst_debug!(self.cat, obj: element, "Seeked after EOS"); - *offset = u64::MAX; - - self.stream_eos(element, None); - - true - } - } - } -} - -impl ObjectImpl for Demuxer {} - -impl ElementImpl for Demuxer { - fn change_state( - &self, - element: &Element, - transition: gst::StateChange, - ) -> gst::StateChangeReturn { - let mut ret = gst::StateChangeReturn::Success; - - gst_trace!(self.cat, obj: element, "Changing state {:?}", transition); - - match transition { - gst::StateChange::ReadyToPaused => { - // TODO - *self.group_id.lock().unwrap() = gst::util_group_id_next(); - } - _ => (), - } - - ret = element.parent_change_state(transition); - if ret == gst::StateChangeReturn::Failure { - return ret; - } - - match transition { - gst::StateChange::PausedToReady => { - self.flow_combiner.lock().unwrap().clear(); - let mut srcpads = self.srcpads.lock().unwrap(); - for (_, pad) in srcpads.iter().by_ref() { - element.remove_pad(pad).unwrap(); - } - srcpads.clear(); - } - _ => (), - } - - ret - } -} - -struct DemuxerStatic { - name: String, - demuxer_info: DemuxerInfo, -} - -impl ImplTypeStatic for DemuxerStatic { - fn get_name(&self) -> &str { - self.name.as_str() - } - - fn new(&self, element: &Element) -> Box> { - Demuxer::init(element, &self.demuxer_info) - } - - fn class_init(&self, klass: &mut ElementClass) { - Demuxer::class_init(klass, &self.demuxer_info); - } -} - -pub fn demuxer_register( - plugin: &gst::Plugin, - demuxer_info: DemuxerInfo, -) -> Result<(), glib::BoolError> { - let name = demuxer_info.name.clone(); - let rank = demuxer_info.rank; - - let demuxer_static = DemuxerStatic { - name: format!("Demuxer-{}", name), - demuxer_info, - }; - - let type_ = register_type(demuxer_static); - gst::Element::register(plugin, &name, rank, type_) -} diff --git a/gst-plugin-simple/src/error.rs b/gst-plugin-simple/src/error.rs deleted file mode 100644 index 69707ebd..00000000 --- a/gst-plugin-simple/src/error.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::error::Error; -use std::fmt::Error as FmtError; -use std::fmt::{Display, Formatter}; - -use glib; -use gst; - -#[derive(Debug, PartialEq, Eq)] -pub struct UriError { - error: gst::URIError, - message: String, -} - -impl UriError { - pub fn new>(error: gst::URIError, message: T) -> UriError { - UriError { - error, - message: message.into(), - } - } - - pub fn message(&self) -> &str { - &self.message - } - - pub fn error(&self) -> gst::URIError { - self.error - } -} - -impl Into for UriError { - fn into(self) -> glib::Error { - (&self).into() - } -} - -impl<'a> Into for &'a UriError { - fn into(self) -> glib::Error { - glib::Error::new(self.error, &self.message) - } -} - -impl Display for UriError { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - f.write_fmt(format_args!("{}: {}", self.description(), self.message)) - } -} - -impl Error for UriError { - fn description(&self) -> &str { - match self.error { - gst::URIError::UnsupportedProtocol => "Unsupported protocol", - gst::URIError::BadUri => "Bad URI", - gst::URIError::BadState => "Bad State", - gst::URIError::BadReference => "Bad Reference", - _ => "Unknown", - } - } -} diff --git a/gst-plugin-simple/src/lib.rs b/gst-plugin-simple/src/lib.rs deleted file mode 100644 index 0ca4cec8..00000000 --- a/gst-plugin-simple/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate glib; -extern crate gobject_subclass; -extern crate gst_plugin; -#[macro_use] -extern crate gstreamer as gst; -extern crate gstreamer_base as gst_base; - -extern crate url; - -pub mod demuxer; -pub mod error; -pub mod sink; -pub mod source; - -pub type UriValidator = Fn(&url::Url) -> Result<(), error::UriError> + Send + Sync + 'static; diff --git a/gst-plugin-simple/src/sink.rs b/gst-plugin-simple/src/sink.rs deleted file mode 100644 index 66f21ac1..00000000 --- a/gst-plugin-simple/src/sink.rs +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::sync::Mutex; - -use url::Url; - -use glib; -use gst; -use gst::prelude::*; -use gst_base::prelude::*; - -use gobject_subclass::object::*; - -use gst_plugin::base_sink::*; -use gst_plugin::element::*; -use gst_plugin::error::*; -use gst_plugin::uri_handler::*; - -pub use gst_plugin::base_sink::BaseSink; - -use error::*; - -use UriValidator; - -pub trait SinkImpl: Send + 'static { - fn uri_validator(&self) -> Box; - - fn start(&mut self, sink: &BaseSink, uri: Url) -> Result<(), gst::ErrorMessage>; - fn stop(&mut self, sink: &BaseSink) -> Result<(), gst::ErrorMessage>; - fn render(&mut self, sink: &BaseSink, buffer: &gst::BufferRef) -> Result<(), FlowError>; -} - -struct Sink { - cat: gst::DebugCategory, - uri: Mutex<(Option, bool)>, - uri_validator: Box, - imp: Mutex>, -} - -static PROPERTIES: [Property; 1] = [Property::String( - "uri", - "URI", - "URI to read from", - None, - PropertyMutability::ReadWrite, -)]; - -impl Sink { - fn new(sink: &BaseSink, sink_info: &SinkInfo) -> Self { - let sink_impl = (sink_info.create_instance)(sink); - - Self { - cat: gst::DebugCategory::new( - "rssink", - gst::DebugColorFlags::empty(), - "Rust sink base class", - ), - uri: Mutex::new((None, false)), - uri_validator: sink_impl.uri_validator(), - imp: Mutex::new(sink_impl), - } - } - - fn class_init(klass: &mut BaseSinkClass, sink_info: &SinkInfo) { - klass.set_metadata( - &sink_info.long_name, - &sink_info.classification, - &sink_info.description, - &sink_info.author, - ); - - let caps = gst::Caps::new_any(); - let pad_template = gst::PadTemplate::new( - "sink", - gst::PadDirection::Sink, - gst::PadPresence::Always, - &caps, - ); - klass.add_pad_template(pad_template); - - klass.install_properties(&PROPERTIES); - } - - fn init(element: &BaseSink, sink_info: &SinkInfo) -> Box> { - element.set_blocksize(4096); - - let imp = Self::new(element, sink_info); - Box::new(imp) - } - - fn get_uri(&self, _element: &glib::Object) -> Option { - let uri_storage = &self.uri.lock().unwrap(); - uri_storage.0.as_ref().map(|uri| String::from(uri.as_str())) - } - - fn set_uri(&self, element: &glib::Object, uri_str: Option) -> Result<(), glib::Error> { - let sink = element.clone().dynamic_cast::().unwrap(); - - let uri_storage = &mut self.uri.lock().unwrap(); - - gst_debug!(self.cat, obj: &sink, "Setting URI {:?}", uri_str); - - if uri_storage.1 { - return Err( - UriError::new(gst::URIError::BadState, "Already started".to_string()).into(), - ); - } - - uri_storage.0 = None; - - if let Some(uri_str) = uri_str { - match Url::parse(uri_str.as_str()) { - Ok(uri) => { - try!((self.uri_validator)(&uri).map_err(|e| e.into())); - uri_storage.0 = Some(uri); - Ok(()) - } - Err(err) => Err(UriError::new( - gst::URIError::BadUri, - format!("Failed to parse URI '{}': {}", uri_str, err), - ) - .into()), - } - } else { - Ok(()) - } - } -} - -impl ObjectImpl for Sink { - fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { - let prop = &PROPERTIES[id as usize]; - - match *prop { - Property::String("uri", ..) => { - self.set_uri(obj, value.get()).unwrap(); - } - _ => unimplemented!(), - } - } - - fn get_property(&self, obj: &glib::Object, id: u32) -> Result { - let prop = &PROPERTIES[id as usize]; - - match *prop { - Property::String("uri", ..) => Ok(self.get_uri(obj).to_value()), - _ => unimplemented!(), - } - } -} - -impl ElementImpl for Sink {} - -impl BaseSinkImpl for Sink { - fn start(&self, sink: &BaseSink) -> bool { - gst_debug!(self.cat, obj: sink, "Starting"); - - // Don't keep the URI locked while we call start later - let uri = match *self.uri.lock().unwrap() { - (Some(ref uri), ref mut started) => { - *started = true; - uri.clone() - } - (None, _) => { - gst_error!(self.cat, obj: sink, "No URI given"); - gst_element_error!(sink, gst::ResourceError::OpenRead, ["No URI given"]); - return false; - } - }; - - let sink_impl = &mut self.imp.lock().unwrap(); - match sink_impl.start(sink, uri) { - Ok(..) => { - gst_trace!(self.cat, obj: sink, "Started successfully"); - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: sink, "Failed to start: {:?}", msg); - - self.uri.lock().unwrap().1 = false; - sink.post_error_message(msg); - false - } - } - } - - fn stop(&self, sink: &BaseSink) -> bool { - let sink_impl = &mut self.imp.lock().unwrap(); - - gst_debug!(self.cat, obj: sink, "Stopping"); - - match sink_impl.stop(sink) { - Ok(..) => { - gst_trace!(self.cat, obj: sink, "Stopped successfully"); - self.uri.lock().unwrap().1 = false; - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: sink, "Failed to stop: {:?}", msg); - - sink.post_error_message(msg); - false - } - } - } - - fn render(&self, sink: &BaseSink, buffer: &gst::BufferRef) -> gst::FlowReturn { - let sink_impl = &mut self.imp.lock().unwrap(); - - gst_trace!(self.cat, obj: sink, "Rendering buffer {:?}", buffer,); - - match sink_impl.render(sink, buffer) { - Ok(()) => gst::FlowReturn::Ok, - Err(flow_error) => { - gst_error!(self.cat, obj: sink, "Failed to render: {:?}", flow_error); - match flow_error { - FlowError::NotNegotiated(ref msg) | FlowError::Error(ref msg) => { - sink.post_error_message(msg); - } - _ => (), - } - flow_error.into() - } - } - } -} - -impl URIHandlerImpl for Sink { - fn get_uri(&self, element: &gst::URIHandler) -> Option { - Sink::get_uri(self, &element.clone().upcast()) - } - - fn set_uri(&self, element: &gst::URIHandler, uri: Option) -> Result<(), glib::Error> { - Sink::set_uri(self, &element.clone().upcast(), uri) - } -} - -pub struct SinkInfo { - pub name: String, - pub long_name: String, - pub description: String, - pub classification: String, - pub author: String, - pub rank: u32, - pub create_instance: fn(&BaseSink) -> Box, - pub protocols: Vec, -} - -struct SinkStatic { - name: String, - sink_info: SinkInfo, -} - -impl ImplTypeStatic for SinkStatic { - fn get_name(&self) -> &str { - self.name.as_str() - } - - fn new(&self, element: &BaseSink) -> Box> { - Sink::init(element, &self.sink_info) - } - - fn class_init(&self, klass: &mut BaseSinkClass) { - Sink::class_init(klass, &self.sink_info); - } - - fn type_init(&self, token: &TypeInitToken, type_: glib::Type) { - register_uri_handler(token, type_, self); - } -} - -impl URIHandlerImplStatic for SinkStatic { - fn get_impl<'a>(&self, imp: &'a Box>) -> &'a URIHandlerImpl { - imp.downcast_ref::().unwrap() - } - - fn get_type(&self) -> gst::URIType { - gst::URIType::Sink - } - - fn get_protocols(&self) -> Vec { - self.sink_info.protocols.clone() - } -} - -pub fn sink_register(plugin: &gst::Plugin, sink_info: SinkInfo) -> Result<(), glib::BoolError> { - let name = sink_info.name.clone(); - let rank = sink_info.rank; - - let sink_static = SinkStatic { - name: format!("Sink-{}", name), - sink_info, - }; - - let type_ = register_type(sink_static); - gst::Element::register(plugin, &name, rank, type_) -} diff --git a/gst-plugin-simple/src/source.rs b/gst-plugin-simple/src/source.rs deleted file mode 100644 index 94512efb..00000000 --- a/gst-plugin-simple/src/source.rs +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::u64; - -use std::sync::Mutex; - -use url::Url; - -use glib; -use gst; -use gst::prelude::*; -use gst_base::prelude::*; - -use gobject_subclass::object::*; - -use gst_plugin::base_src::*; -use gst_plugin::element::*; -use gst_plugin::error::*; -use gst_plugin::uri_handler::*; - -pub use gst_plugin::base_src::BaseSrc; - -use error::*; - -use UriValidator; - -pub trait SourceImpl: Send + 'static { - fn uri_validator(&self) -> Box; - - fn is_seekable(&self, src: &BaseSrc) -> bool; - fn get_size(&self, src: &BaseSrc) -> Option; - - fn start(&mut self, src: &BaseSrc, uri: Url) -> Result<(), gst::ErrorMessage>; - fn stop(&mut self, src: &BaseSrc) -> Result<(), gst::ErrorMessage>; - fn fill( - &mut self, - src: &BaseSrc, - offset: u64, - length: u32, - buffer: &mut gst::BufferRef, - ) -> Result<(), FlowError>; - fn seek( - &mut self, - src: &BaseSrc, - start: u64, - stop: Option, - ) -> Result<(), gst::ErrorMessage>; -} - -struct Source { - cat: gst::DebugCategory, - uri: Mutex<(Option, bool)>, - uri_validator: Box, - imp: Mutex>, - push_only: bool, -} - -static PROPERTIES: [Property; 1] = [Property::String( - "uri", - "URI", - "URI to read from", - None, - PropertyMutability::ReadWrite, -)]; - -impl Source { - fn new(source: &BaseSrc, source_info: &SourceInfo) -> Self { - let source_impl = (source_info.create_instance)(source); - - Self { - cat: gst::DebugCategory::new( - "rssource", - gst::DebugColorFlags::empty(), - "Rust source base class", - ), - uri: Mutex::new((None, false)), - uri_validator: source_impl.uri_validator(), - imp: Mutex::new(source_impl), - push_only: source_info.push_only, - } - } - - fn class_init(klass: &mut BaseSrcClass, source_info: &SourceInfo) { - klass.set_metadata( - &source_info.long_name, - &source_info.classification, - &source_info.description, - &source_info.author, - ); - - let caps = gst::Caps::new_any(); - let pad_template = gst::PadTemplate::new( - "src", - gst::PadDirection::Src, - gst::PadPresence::Always, - &caps, - ); - klass.add_pad_template(pad_template); - - klass.install_properties(&PROPERTIES); - } - - fn init(element: &BaseSrc, source_info: &SourceInfo) -> Box> { - element.set_blocksize(4096); - - let imp = Self::new(element, source_info); - Box::new(imp) - } - - fn get_uri(&self, _element: &glib::Object) -> Option { - let uri_storage = &self.uri.lock().unwrap(); - uri_storage.0.as_ref().map(|uri| String::from(uri.as_str())) - } - - fn set_uri(&self, element: &glib::Object, uri_str: Option) -> Result<(), glib::Error> { - let src = element.clone().dynamic_cast::().unwrap(); - - let uri_storage = &mut self.uri.lock().unwrap(); - - gst_debug!(self.cat, obj: &src, "Setting URI {:?}", uri_str); - - if uri_storage.1 { - return Err( - UriError::new(gst::URIError::BadState, "Already started".to_string()).into(), - ); - } - - uri_storage.0 = None; - - if let Some(uri_str) = uri_str { - match Url::parse(uri_str.as_str()) { - Ok(uri) => { - try!((self.uri_validator)(&uri).map_err(|e| e.into())); - uri_storage.0 = Some(uri); - Ok(()) - } - Err(err) => Err(UriError::new( - gst::URIError::BadUri, - format!("Failed to parse URI '{}': {}", uri_str, err), - ) - .into()), - } - } else { - Ok(()) - } - } -} - -impl ObjectImpl for Source { - fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { - let prop = &PROPERTIES[id as usize]; - - match *prop { - Property::String("uri", ..) => { - self.set_uri(obj, value.get()).unwrap(); - } - _ => unimplemented!(), - } - } - - fn get_property(&self, obj: &glib::Object, id: u32) -> Result { - let prop = &PROPERTIES[id as usize]; - - match *prop { - Property::String("uri", ..) => Ok(self.get_uri(obj).to_value()), - _ => unimplemented!(), - } - } -} - -impl ElementImpl for Source {} - -impl BaseSrcImpl for Source { - fn start(&self, src: &BaseSrc) -> bool { - gst_debug!(self.cat, obj: src, "Starting"); - - // Don't keep the URI locked while we call start later - let uri = match *self.uri.lock().unwrap() { - (Some(ref uri), ref mut started) => { - *started = true; - uri.clone() - } - (None, _) => { - gst_error!(self.cat, obj: src, "No URI given"); - gst_element_error!(src, gst::ResourceError::OpenRead, ["No URI given"]); - return false; - } - }; - - let source_impl = &mut self.imp.lock().unwrap(); - match source_impl.start(src, uri) { - Ok(..) => { - gst_trace!(self.cat, obj: src, "Started successfully"); - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: src, "Failed to start: {:?}", msg); - - self.uri.lock().unwrap().1 = false; - src.post_error_message(msg); - false - } - } - } - - fn stop(&self, src: &BaseSrc) -> bool { - let source_impl = &mut self.imp.lock().unwrap(); - - gst_debug!(self.cat, obj: src, "Stopping"); - - match source_impl.stop(src) { - Ok(..) => { - gst_trace!(self.cat, obj: src, "Stopped successfully"); - self.uri.lock().unwrap().1 = false; - true - } - Err(ref msg) => { - gst_error!(self.cat, obj: src, "Failed to stop: {:?}", msg); - - src.post_error_message(msg); - false - } - } - } - - fn query(&self, src: &BaseSrc, query: &mut gst::QueryRef) -> bool { - use gst::QueryView; - - match query.view_mut() { - QueryView::Scheduling(ref mut q) if self.push_only => { - q.set(gst::SchedulingFlags::SEQUENTIAL, 1, -1, 0); - q.add_scheduling_modes(&[gst::PadMode::Push]); - return true; - } - _ => (), - } - - BaseSrcBase::parent_query(src, query) - } - - fn fill( - &self, - src: &BaseSrc, - offset: u64, - length: u32, - buffer: &mut gst::BufferRef, - ) -> gst::FlowReturn { - let source_impl = &mut self.imp.lock().unwrap(); - - gst_trace!( - self.cat, - obj: src, - "Filling buffer {:?} with offset {} and length {}", - buffer, - offset, - length - ); - - match source_impl.fill(src, offset, length, buffer) { - Ok(()) => gst::FlowReturn::Ok, - Err(flow_error) => { - gst_error!(self.cat, obj: src, "Failed to fill: {:?}", flow_error); - match flow_error { - FlowError::NotNegotiated(ref msg) | FlowError::Error(ref msg) => { - src.post_error_message(msg); - } - _ => (), - } - flow_error.into() - } - } - } - - fn do_seek(&self, src: &BaseSrc, segment: &mut gst::Segment) -> bool { - let source_impl = &mut self.imp.lock().unwrap(); - - let segment = match segment.downcast_ref::() { - None => return false, - Some(segment) => segment, - }; - - let start = match segment.get_start().0 { - None => return false, - Some(start) => start, - }; - let stop = segment.get_stop().0; - - gst_debug!(self.cat, obj: src, "Seeking to {:?}-{:?}", start, stop); - - match source_impl.seek(src, start, stop) { - Ok(..) => true, - Err(ref msg) => { - gst_error!(self.cat, obj: src, "Failed to seek {:?}", msg); - src.post_error_message(msg); - false - } - } - } - - fn is_seekable(&self, src: &BaseSrc) -> bool { - let source_impl = &self.imp.lock().unwrap(); - source_impl.is_seekable(src) - } - - fn get_size(&self, src: &BaseSrc) -> Option { - let source_impl = &self.imp.lock().unwrap(); - source_impl.get_size(src) - } -} - -impl URIHandlerImpl for Source { - fn get_uri(&self, element: &gst::URIHandler) -> Option { - Source::get_uri(self, &element.clone().upcast()) - } - - fn set_uri(&self, element: &gst::URIHandler, uri: Option) -> Result<(), glib::Error> { - Source::set_uri(self, &element.clone().upcast(), uri) - } -} - -pub struct SourceInfo { - pub name: String, - pub long_name: String, - pub description: String, - pub classification: String, - pub author: String, - pub rank: u32, - pub create_instance: fn(&BaseSrc) -> Box, - pub protocols: Vec, - pub push_only: bool, -} - -struct SourceStatic { - name: String, - source_info: SourceInfo, -} - -impl ImplTypeStatic for SourceStatic { - fn get_name(&self) -> &str { - self.name.as_str() - } - - fn new(&self, element: &BaseSrc) -> Box> { - Source::init(element, &self.source_info) - } - - fn class_init(&self, klass: &mut BaseSrcClass) { - Source::class_init(klass, &self.source_info); - } - - fn type_init(&self, token: &TypeInitToken, type_: glib::Type) { - register_uri_handler(token, type_, self); - } -} - -impl URIHandlerImplStatic for SourceStatic { - fn get_impl<'a>(&self, imp: &'a Box>) -> &'a URIHandlerImpl { - imp.downcast_ref::().unwrap() - } - - fn get_type(&self) -> gst::URIType { - gst::URIType::Src - } - - fn get_protocols(&self) -> Vec { - self.source_info.protocols.clone() - } -} - -pub fn source_register( - plugin: &gst::Plugin, - source_info: SourceInfo, -) -> Result<(), glib::BoolError> { - let name = source_info.name.clone(); - let rank = source_info.rank; - - let source_static = SourceStatic { - name: format!("Source-{}", name), - source_info, - }; - - let type_ = register_type(source_static); - gst::Element::register(plugin, &name, rank, type_) -} diff --git a/gst-plugin/CHANGELOG.md b/gst-plugin/CHANGELOG.md deleted file mode 100644 index 4aaf7d53..00000000 --- a/gst-plugin/CHANGELOG.md +++ /dev/null @@ -1,79 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html), -specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field). - -## [0.3.2] - 2018-11-26 -### Changed -- Fix various links in the README.md -- Link to the correct location for the documentation - -## [0.3.1] - 2018-11-19 -### Fixed -- Override vfuncs of all parent classes correctly. - -## [0.3.0] - 2018-09-08 -### Added -- Support for subclassing pads, ghost pads, aggregator and aggregator pads -- Support for implementing child proxy interface -- Generic catch_panic_pad_function() that allows wrapping around pad functions - for catching their panics and converting them into error messages -- More Rust-like FlowError enum that can be used to simplify implementations - -### Changed -- Use ptr::NonNull in various places -- Move to standalone gobject-subclass crate and refactor for its API changes -- Removed CallbackGuard as unwinding across FFI boundaries is not undefined - behaviour anymore and will cause an immediate panic instead -- Use new Object::downcast_ref() to prevent some unneeded clones - -## [0.2.1] - 2018-05-09 -### Fixed -- Fix memory leak in ElementClass::add_pad_template() related to floating - reference handling. - -## [0.2.0] - 2018-03-20 -### Changed -- Update to gstreamer-rs 0.11 -- BaseTransform::transform_caps() takes caps by reference instead of value - -### Added -- Send+Sync impls for all wrapper types - -## [0.1.4] - 2018-02-12 -### Fixed -- Fix BaseSrc::unlock_stop() and the same in BaseSink. It was calling unlock() - instead of unlock_stop() before, making it rather useless. - -## [0.1.3] - 2018-01-15 -### Fixed -- Only require GStreamer >= 1.8, not >= 1.10. We didn't use any 1.10 API - anymore since quite a while -- Don't call BaseTransform::transform_ip in passthrough mode with a mutable - reference, but call a new transform_ip_passthrough with an immutable - reference. The mutable reference would've failed all mutable operations. - -## [0.1.2] - 2018-01-03 -### Fixed -- BaseTransform::transform_caps() caps parameter is not owned when chainging - to the parent class' implementation either - -## [0.1.1] - 2018-01-03 -### Fixed -- BaseTransform::transform_caps() caps parameter is not owned - -## [0.1.0] - 2017-12-22 -- Initial release of the `gst-plugin` crate. - -[Unreleased]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.3.2...HEAD -[0.3.2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.3.1...0.3.2 -[0.3.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.3.0...0.3.1 -[0.3.0]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.2.1...0.3.0 -[0.2.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.2.0...0.2.1 -[0.2.0]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.1.4...0.2.0 -[0.1.4]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.1.3...0.1.4 -[0.1.3]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.1.2...0.1.3 -[0.1.2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.1.1...0.1.2 -[0.1.1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/compare/0.1.0...0.1.1 diff --git a/gst-plugin/Cargo.toml b/gst-plugin/Cargo.toml deleted file mode 100644 index 8d0d175a..00000000 --- a/gst-plugin/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "gst-plugin" -version = "0.4.0" -authors = ["Sebastian Dröge "] -categories = ["multimedia", "api-bindings"] -description = "Infrastructure for writing GStreamer plugins in Rust" -documentation = "https://slomo.pages.freedesktop.org/rustdocs/gst-plugin/gst_plugin" -repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/tree/master/gst-plugin" -license = "MIT/Apache-2.0" -readme = "README.md" -homepage = "https://gstreamer.freedesktop.org" -keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] - -[dependencies] -libc = "0.2" -lazy_static = "1.0" -byteorder = "1.0" -gobject-subclass = { git = "https://github.com/gtk-rs/gobject-subclass" } -glib-sys = { git = "https://github.com/gtk-rs/sys" } -gobject-sys = { git = "https://github.com/gtk-rs/sys" } -gstreamer-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys" } -gstreamer-base-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys" } -glib = { git = "https://github.com/gtk-rs/glib" } -gstreamer = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } -gstreamer-base = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } - -[lib] -name = "gst_plugin" -path = "src/lib.rs" - -[features] -v1_10 = ["gstreamer/v1_10", "gstreamer-base/v1_10"] -v1_12 = ["gstreamer/v1_12", "gstreamer-base/v1_12", "v1_10"] -v1_14 = ["gstreamer/v1_14", "gstreamer-base/v1_14", "v1_12"] - diff --git a/gst-plugin/README.md b/gst-plugin/README.md deleted file mode 100644 index 1057b171..00000000 --- a/gst-plugin/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# NOTE: The canonical repository for gst-plugins-rs has moved to [freedesktop.org GitLab](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs)! - -# gst-plugins-rs [![crates.io](https://img.shields.io/crates/v/gst-plugin.svg)](https://crates.io/crates/gst-plugin) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/badges/master/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/commits/master) - -Infrastructure for writing [GStreamer](https://gstreamer.freedesktop.org/) -plugins and elements in the [Rust programming -language](https://www.rust-lang.org/), and a collection of various GStreamer -plugins. - -Documentation for the crate containing the infrastructure for writing -GStreamer plugins in Rust, [`gst-plugin`](gst-plugin), can be found -[here](https://slomo.pages.freedesktop.org/rustdocs/gst-plugin/gst_plugin). The whole -API builds upon the [application-side GStreamer bindings](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs). -Check the README.md of that repository also for details about how to set-up -your development environment. - -Various example plugins can be found in the [GIT repository](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/). A blog post series about writing GStreamer plugins/elements can be found [here](https://coaxion.net/blog/2018/01/how-to-write-gstreamer-elements-in-rust-part-1-a-video-filter-for-converting-rgb-to-grayscale/)[2](https://coaxion.net/blog/2018/02/how-to-write-gstreamer-elements-in-rust-part-2-a-raw-audio-sine-wave-source/). - -For background and motivation, see the [announcement -blogpost](https://coaxion.net/blog/2016/05/writing-gstreamer-plugins-and-elements-in-rust/) -and the follow-up blogposts -[1](https://coaxion.net/blog/2016/09/writing-gstreamer-elements-in-rust-part-2-dont-panic-we-have-better-assertions-now-and-other-updates/), -[2](https://coaxion.net/blog/2016/11/writing-gstreamer-elements-in-rust-part-3-parsing-data-from-untrusted-sources-like-its-2016/), -[3](https://coaxion.net/blog/2017/03/writing-gstreamer-elements-in-rust-part-4-logging-cows-and-plugins/). -Note that the overall implementation has changed completely since those -blogposts were written. - -## LICENSE - -gst-plugins-rs and all crates contained in here that are not listed below are -licensed under either of - - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) - -at your option. - -gst-plugin-togglerecord is licensed under the Lesser General Public License -([LICENSE-LGPLv2](LICENSE-LGPLv2)) version 2.1 or (at your option) any later -version. - -GStreamer itself is licensed under the Lesser General Public License version -2.1 or (at your option) any later version: -https://www.gnu.org/licenses/lgpl-2.1.html - -## Contribution - -Any kinds of contributions are welcome as a pull request. - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in gst-plugins-rs by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. diff --git a/gst-plugin/src/adapter.rs b/gst-plugin/src/adapter.rs deleted file mode 100644 index d0be2c3c..00000000 --- a/gst-plugin/src/adapter.rs +++ /dev/null @@ -1,334 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::cmp; -use std::collections::VecDeque; -use std::error::Error; -use std::fmt; -use std::io; - -use gst; - -lazy_static! { - static ref CAT: gst::DebugCategory = { - gst::DebugCategory::new( - "rsadapter", - gst::DebugColorFlags::empty(), - "Rust buffer adapter", - ) - }; -} - -#[derive(Default, Debug)] -pub struct Adapter { - deque: VecDeque>, - size: usize, - skip: usize, - scratch: Vec, -} - -#[derive(Debug, PartialEq, Eq)] -pub enum AdapterError { - NotEnoughData, -} - -impl fmt::Display for AdapterError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Not enough data") - } -} - -impl Error for AdapterError { - fn description(&self) -> &str { - "Not enough data" - } -} - -impl Adapter { - pub fn new() -> Adapter { - Adapter { - deque: VecDeque::new(), - size: 0, - skip: 0, - scratch: Vec::new(), - } - } - - pub fn push(&mut self, buffer: gst::Buffer) { - let size = buffer.get_size(); - - self.size += size; - gst_trace!( - CAT, - "Storing {:?} of size {}, now have size {}", - buffer, - size, - self.size - ); - self.deque - .push_back(buffer.into_mapped_buffer_readable().unwrap()); - } - - pub fn clear(&mut self) { - self.deque.clear(); - self.size = 0; - self.skip = 0; - self.scratch.clear(); - gst_trace!(CAT, "Cleared adapter"); - } - - pub fn get_available(&self) -> usize { - self.size - } - - fn copy_data( - deque: &VecDeque>, - skip: usize, - data: &mut [u8], - size: usize, - ) { - let mut skip = skip; - let mut left = size; - let mut idx = 0; - - gst_trace!(CAT, "Copying {} bytes", size); - - for item in deque { - let data_item = item.as_slice(); - - let to_copy = cmp::min(left, data_item.len() - skip); - gst_trace!( - CAT, - "Copying {} bytes from {:?}, {} more to go", - to_copy, - item.get_buffer(), - left - to_copy - ); - - data[idx..idx + to_copy].copy_from_slice(&data_item[skip..skip + to_copy]); - skip = 0; - idx += to_copy; - left -= to_copy; - if left == 0 { - break; - } - } - assert_eq!(left, 0); - } - - pub fn peek_into(&self, data: &mut [u8]) -> Result<(), AdapterError> { - let size = data.len(); - - if self.size < size { - gst_debug!( - CAT, - "Peeking {} bytes into, not enough data: have {}", - size, - self.size - ); - return Err(AdapterError::NotEnoughData); - } - - gst_trace!(CAT, "Peeking {} bytes into", size); - if size == 0 { - return Ok(()); - } - - Self::copy_data(&self.deque, self.skip, data, size); - Ok(()) - } - - pub fn peek(&mut self, size: usize) -> Result<&[u8], AdapterError> { - if self.size < size { - gst_debug!( - CAT, - "Peeking {} bytes, not enough data: have {}", - size, - self.size - ); - return Err(AdapterError::NotEnoughData); - } - - if size == 0 { - return Ok(&[]); - } - - if let Some(front) = self.deque.front() { - gst_trace!(CAT, "Peeking {} bytes, subbuffer of first", size); - if front.get_size() - self.skip >= size { - return Ok(&front.as_slice()[self.skip..self.skip + size]); - } - } - - gst_trace!(CAT, "Peeking {} bytes, copy to scratch", size); - - self.scratch.truncate(0); - self.scratch.reserve(size); - { - let data = self.scratch.as_mut_slice(); - Self::copy_data(&self.deque, self.skip, data, size); - } - - Ok(self.scratch.as_slice()) - } - - pub fn get_buffer(&mut self, size: usize) -> Result { - if self.size < size { - gst_debug!( - CAT, - "Get buffer of {} bytes, not enough data: have {}", - size, - self.size - ); - return Err(AdapterError::NotEnoughData); - } - - if size == 0 { - return Ok(gst::Buffer::new()); - } - - let sub = self.deque.front().and_then(|front| { - if front.get_size() - self.skip >= size { - gst_trace!(CAT, "Get buffer of {} bytes, subbuffer of first", size); - let new = front - .get_buffer() - .copy_region(*gst::BUFFER_COPY_ALL, self.skip, Some(size)) - .unwrap(); - Some(new) - } else { - None - } - }); - - if let Some(s) = sub { - self.flush(size).unwrap(); - return Ok(s); - } - - gst_trace!(CAT, "Get buffer of {} bytes, copy into new buffer", size); - let mut new = gst::Buffer::with_size(size).unwrap(); - { - let mut map = new.get_mut().unwrap().map_writable().unwrap(); - let data = map.as_mut_slice(); - Self::copy_data(&self.deque, self.skip, data, size); - } - self.flush(size).unwrap(); - Ok(new) - } - - pub fn flush(&mut self, size: usize) -> Result<(), AdapterError> { - if self.size < size { - gst_debug!( - CAT, - "Flush {} bytes, not enough data: have {}", - size, - self.size - ); - return Err(AdapterError::NotEnoughData); - } - - if size == 0 { - return Ok(()); - } - - gst_trace!(CAT, "Flushing {} bytes, have {}", size, self.size); - - let mut left = size; - while left > 0 { - let front_size = self.deque.front().unwrap().get_size() - self.skip; - - if front_size <= left { - gst_trace!( - CAT, - "Flushing whole {:?}, {} more to go", - self.deque.front().map(|b| b.get_buffer()), - left - front_size - ); - self.deque.pop_front(); - self.size -= front_size; - self.skip = 0; - left -= front_size; - } else { - gst_trace!( - CAT, - "Flushing partial {:?}, {} more left", - self.deque.front().map(|b| b.get_buffer()), - front_size - left - ); - self.skip += left; - self.size -= left; - left = 0; - } - } - - Ok(()) - } -} - -impl io::Read for Adapter { - fn read(&mut self, buf: &mut [u8]) -> Result { - let mut len = self.size; - - if len == 0 { - return Err(io::Error::new( - io::ErrorKind::WouldBlock, - format!( - "Missing data: requesting {} but only got {}.", - buf.len(), - len - ), - )); - } - - if buf.len() < len { - len = buf.len(); - } - - Self::copy_data(&self.deque, self.skip, buf, len); - self.flush(len).unwrap(); - Ok(len) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use gst; - - #[test] - fn test_push_get() { - gst::init().unwrap(); - - let mut a = Adapter::new(); - - a.push(gst::Buffer::with_size(100).unwrap()); - assert_eq!(a.get_available(), 100); - a.push(gst::Buffer::with_size(20).unwrap()); - assert_eq!(a.get_available(), 120); - - let b = a.get_buffer(20).unwrap(); - assert_eq!(a.get_available(), 100); - assert_eq!(b.get_size(), 20); - let b = a.get_buffer(90).unwrap(); - assert_eq!(a.get_available(), 10); - assert_eq!(b.get_size(), 90); - - a.push(gst::Buffer::with_size(20).unwrap()); - assert_eq!(a.get_available(), 30); - - let b = a.get_buffer(20).unwrap(); - assert_eq!(a.get_available(), 10); - assert_eq!(b.get_size(), 20); - let b = a.get_buffer(10).unwrap(); - assert_eq!(a.get_available(), 0); - assert_eq!(b.get_size(), 10); - - let b = a.get_buffer(1); - assert_eq!(b.err().unwrap(), AdapterError::NotEnoughData); - } -} diff --git a/gst-plugin/src/aggregator.rs b/gst-plugin/src/aggregator.rs deleted file mode 100644 index 48938816..00000000 --- a/gst-plugin/src/aggregator.rs +++ /dev/null @@ -1,867 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use libc; - -use glib_ffi; -use gobject_ffi; -use gst_base_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; -use gst_base; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use element::*; -use object::*; - -pub trait AggregatorImpl: - AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn flush(&self, aggregator: &T) -> gst::FlowReturn { - aggregator.parent_flush() - } - - fn clip( - &self, - aggregator: &T, - aggregator_pad: &gst_base::AggregatorPad, - buffer: gst::Buffer, - ) -> Option { - aggregator.parent_clip(aggregator_pad, buffer) - } - - fn finish_buffer(&self, aggregator: &T, buffer: gst::Buffer) -> gst::FlowReturn { - aggregator.parent_finish_buffer(buffer) - } - - fn sink_event( - &self, - aggregator: &T, - aggregator_pad: &gst_base::AggregatorPad, - event: gst::Event, - ) -> bool { - aggregator.parent_sink_event(aggregator_pad, event) - } - - fn sink_query( - &self, - aggregator: &T, - aggregator_pad: &gst_base::AggregatorPad, - query: &mut gst::QueryRef, - ) -> bool { - aggregator.parent_sink_query(aggregator_pad, query) - } - - fn src_event(&self, aggregator: &T, event: gst::Event) -> bool { - aggregator.parent_src_event(event) - } - - fn src_query(&self, aggregator: &T, query: &mut gst::QueryRef) -> bool { - aggregator.parent_src_query(query) - } - - fn src_activate(&self, aggregator: &T, mode: gst::PadMode, active: bool) -> bool { - aggregator.parent_src_activate(mode, active) - } - - fn aggregate(&self, aggregator: &T, timeout: bool) -> gst::FlowReturn; - - fn start(&self, aggregator: &T) -> bool { - aggregator.parent_start() - } - - fn stop(&self, aggregator: &T) -> bool { - aggregator.parent_stop() - } - - fn get_next_time(&self, aggregator: &T) -> gst::ClockTime { - aggregator.parent_get_next_time() - } - - fn create_new_pad( - &self, - aggregator: &T, - templ: &gst::PadTemplate, - req_name: Option<&str>, - caps: Option<&gst::CapsRef>, - ) -> Option { - aggregator.parent_create_new_pad(templ, req_name, caps) - } - - fn update_src_caps( - &self, - aggregator: &T, - caps: &gst::CapsRef, - ) -> Result { - aggregator.parent_update_src_caps(caps) - } - - fn fixate_src_caps(&self, aggregator: &T, caps: gst::Caps) -> gst::Caps { - aggregator.parent_fixate_src_caps(caps) - } - - fn negotiated_src_caps(&self, aggregator: &T, caps: &gst::CapsRef) -> bool { - aggregator.parent_negotiated_src_caps(caps) - } -} - -any_impl!(AggregatorBase, AggregatorImpl, PanicPoison); - -pub unsafe trait AggregatorBase: - IsA + IsA + ObjectType -{ - fn parent_flush(&self) -> gst::FlowReturn { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .flush - .map(|f| from_glib(f(self.to_glib_none().0))) - .unwrap_or(gst::FlowReturn::Ok) - } - } - - fn parent_clip( - &self, - aggregator_pad: &gst_base::AggregatorPad, - buffer: gst::Buffer, - ) -> Option { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - match (*parent_klass).clip { - None => Some(buffer), - Some(ref func) => from_glib_full(func( - self.to_glib_none().0, - aggregator_pad.to_glib_none().0, - buffer.into_ptr(), - )), - } - } - } - - fn parent_finish_buffer(&self, buffer: gst::Buffer) -> gst::FlowReturn { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .finish_buffer - .map(|f| from_glib(f(self.to_glib_none().0, buffer.into_ptr()))) - .unwrap_or(gst::FlowReturn::Ok) - } - } - - fn parent_sink_event( - &self, - aggregator_pad: &gst_base::AggregatorPad, - event: gst::Event, - ) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .sink_event - .map(|f| { - from_glib(f( - self.to_glib_none().0, - aggregator_pad.to_glib_none().0, - event.into_ptr(), - )) - }) - .unwrap_or(false) - } - } - - fn parent_sink_query( - &self, - aggregator_pad: &gst_base::AggregatorPad, - query: &mut gst::QueryRef, - ) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .sink_query - .map(|f| { - from_glib(f( - self.to_glib_none().0, - aggregator_pad.to_glib_none().0, - query.as_mut_ptr(), - )) - }) - .unwrap_or(false) - } - } - - fn parent_src_event(&self, event: gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .src_event - .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr()))) - .unwrap_or(false) - } - } - - fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .src_query - .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr()))) - .unwrap_or(false) - } - } - - fn parent_src_activate(&self, mode: gst::PadMode, active: bool) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .src_activate - .map(|f| from_glib(f(self.to_glib_none().0, mode.to_glib(), active.to_glib()))) - .unwrap_or(false) - } - } - - fn parent_aggregate(&self, timeout: bool) -> gst::FlowReturn { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .aggregate - .map(|f| from_glib(f(self.to_glib_none().0, timeout.to_glib()))) - .unwrap_or(gst::FlowReturn::Error) - } - } - - fn parent_start(&self) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .start - .map(|f| from_glib(f(self.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_stop(&self) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .stop - .map(|f| from_glib(f(self.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_get_next_time(&self) -> gst::ClockTime { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .get_next_time - .map(|f| from_glib(f(self.to_glib_none().0))) - .unwrap_or(gst::CLOCK_TIME_NONE) - } - } - - fn parent_create_new_pad( - &self, - templ: &gst::PadTemplate, - req_name: Option<&str>, - caps: Option<&gst::CapsRef>, - ) -> Option { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .create_new_pad - .map(|f| { - from_glib_full(f( - self.to_glib_none().0, - templ.to_glib_none().0, - req_name.to_glib_none().0, - caps.map(|c| c.as_ptr()).unwrap_or(ptr::null()), - )) - }) - .unwrap_or(None) - } - } - - fn parent_update_src_caps(&self, caps: &gst::CapsRef) -> Result { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .update_src_caps - .map(|f| { - let mut out_caps = ptr::null_mut(); - let flow_ret = - from_glib(f(self.to_glib_none().0, caps.as_mut_ptr(), &mut out_caps)); - flow_ret.into_result_value(|| from_glib_full(out_caps)) - }) - .unwrap_or(Err(gst::FlowError::Error)) - } - } - - fn parent_fixate_src_caps(&self, caps: gst::Caps) -> gst::Caps { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - - match (*parent_klass).fixate_src_caps { - Some(ref f) => from_glib_full(f(self.to_glib_none().0, caps.into_ptr())), - None => caps, - } - } - } - - fn parent_negotiated_src_caps(&self, caps: &gst::CapsRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorClass; - (*parent_klass) - .negotiated_src_caps - .map(|f| from_glib(f(self.to_glib_none().0, caps.as_mut_ptr()))) - .unwrap_or(false) - } - } -} - -pub unsafe trait AggregatorClassExt -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstAggregatorClass); - klass.flush = Some(aggregator_flush::); - klass.clip = Some(aggregator_clip::); - klass.finish_buffer = Some(aggregator_finish_buffer::); - klass.sink_event = Some(aggregator_sink_event::); - klass.sink_query = Some(aggregator_sink_query::); - klass.src_event = Some(aggregator_src_event::); - klass.src_query = Some(aggregator_src_query::); - klass.src_activate = Some(aggregator_src_activate::); - klass.aggregate = Some(aggregator_aggregate::); - klass.start = Some(aggregator_start::); - klass.stop = Some(aggregator_stop::); - klass.get_next_time = Some(aggregator_get_next_time::); - klass.create_new_pad = Some(aggregator_create_new_pad::); - klass.update_src_caps = Some(aggregator_update_src_caps::); - klass.fixate_src_caps = Some(aggregator_fixate_src_caps::); - klass.negotiated_src_caps = Some(aggregator_negotiated_src_caps::); - } - } -} - -glib_wrapper! { - pub struct Aggregator(Object>): - [gst_base::Aggregator => gst_base_ffi::GstAggregator, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> AggregatorBase for T {} -pub type AggregatorClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl AggregatorClassExt for AggregatorClass {} -unsafe impl ElementClassExt for AggregatorClass {} -unsafe impl ObjectClassExt for AggregatorClass {} - -unsafe impl Send for Aggregator {} -unsafe impl Sync for Aggregator {} - -#[macro_export] -macro_rules! box_aggregator_impl( - ($name:ident) => { - box_element_impl!($name); - - impl AggregatorImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn flush(&self, aggregator: &T) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.flush(aggregator) - } - - fn clip(&self, aggregator: &T, aggregator_pad: &gst_base::AggregatorPad, buffer: gst::Buffer) -> Option { - let imp: &$name = self.as_ref(); - imp.clip(aggregator, aggregator_pad, buffer) - } - - fn finish_buffer(&self, aggregator: &T, buffer: gst::Buffer) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.finish_buffer(aggregator, buffer) - } - - fn sink_event(&self, aggregator: &T, aggregator_pad: &gst_base::AggregatorPad, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.sink_event(aggregator, aggregator_pad, event) - } - - fn sink_query(&self, aggregator: &T, aggregator_pad: &gst_base::AggregatorPad, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - imp.sink_query(aggregator, aggregator_pad, query) - } - - fn src_event(&self, aggregator: &T, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.src_event(aggregator, event) - } - - fn src_query(&self, aggregator: &T, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - imp.src_query(aggregator, query) - } - - fn src_activate(&self, aggregator: &T, mode: gst::PadMode, active: bool) -> bool { - let imp: &$name = self.as_ref(); - imp.src_activate(aggregator, mode, active) - } - - fn aggregate(&self, aggregator: &T, timeout: bool) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.aggregate(aggregator, timeout) - } - - fn start(&self, aggregator: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.start(aggregator) - } - - fn stop(&self, aggregator: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.stop(aggregator) - } - - fn get_next_time(&self, aggregator: &T) -> gst::ClockTime { - let imp: &$name = self.as_ref(); - imp.get_next_time(aggregator) - } - - fn create_new_pad(&self, aggregator: &T, templ: &gst::PadTemplate, req_name: Option<&str>, caps: Option<&gst::CapsRef>) -> Option { - let imp: &$name = self.as_ref(); - imp.create_new_pad(aggregator, templ, req_name, caps) - } - - fn update_src_caps(&self, aggregator: &T, caps: &gst::CapsRef) -> Result { - let imp: &$name = self.as_ref(); - imp.update_src_caps(aggregator, caps) - } - - fn fixate_src_caps(&self, aggregator: &T, caps: gst::Caps) -> gst::Caps { - let imp: &$name = self.as_ref(); - imp.fixate_src_caps(aggregator, caps) - } - - fn negotiated_src_caps(&self, aggregator: &T, caps: &gst::CapsRef) -> bool { - let imp: &$name = self.as_ref(); - imp.negotiated_src_caps(aggregator, caps) - } - } - }; -); -box_aggregator_impl!(AggregatorImpl); - -impl ObjectType for Aggregator { - const NAME: &'static str = "RsAggregator"; - type ParentType = gst_base::Aggregator; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut AggregatorClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - AggregatorClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn aggregator_flush( - ptr: *mut gst_base_ffi::GstAggregator, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::FlowReturn::Error, { - imp.flush(&wrap) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_clip( - ptr: *mut gst_base_ffi::GstAggregator, - aggregator_pad: *mut gst_base_ffi::GstAggregatorPad, - buffer: *mut gst_ffi::GstBuffer, -) -> *mut gst_ffi::GstBuffer -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - let ret = panic_to_error!(&wrap, &aggregator.panicked(), None, { - imp.clip( - &wrap, - &from_glib_borrow(aggregator_pad), - from_glib_full(buffer), - ) - }); - - ret.map(|r| r.into_ptr()).unwrap_or(ptr::null_mut()) -} - -unsafe extern "C" fn aggregator_finish_buffer( - ptr: *mut gst_base_ffi::GstAggregator, - buffer: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::FlowReturn::Error, { - imp.finish_buffer(&wrap, from_glib_full(buffer)) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_sink_event( - ptr: *mut gst_base_ffi::GstAggregator, - aggregator_pad: *mut gst_base_ffi::GstAggregatorPad, - event: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.sink_event( - &wrap, - &from_glib_borrow(aggregator_pad), - from_glib_full(event), - ) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_sink_query( - ptr: *mut gst_base_ffi::GstAggregator, - aggregator_pad: *mut gst_base_ffi::GstAggregatorPad, - query: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.sink_query( - &wrap, - &from_glib_borrow(aggregator_pad), - gst::QueryRef::from_mut_ptr(query), - ) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_src_event( - ptr: *mut gst_base_ffi::GstAggregator, - event: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.src_event(&wrap, from_glib_full(event)) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_src_query( - ptr: *mut gst_base_ffi::GstAggregator, - query: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.src_query(&wrap, gst::QueryRef::from_mut_ptr(query)) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_src_activate( - ptr: *mut gst_base_ffi::GstAggregator, - mode: gst_ffi::GstPadMode, - active: glib_ffi::gboolean, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.src_activate(&wrap, from_glib(mode), from_glib(active)) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_aggregate( - ptr: *mut gst_base_ffi::GstAggregator, - timeout: glib_ffi::gboolean, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::FlowReturn::Error, { - imp.aggregate(&wrap, from_glib(timeout)) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_start( - ptr: *mut gst_base_ffi::GstAggregator, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { imp.start(&wrap) }).to_glib() -} - -unsafe extern "C" fn aggregator_stop( - ptr: *mut gst_base_ffi::GstAggregator, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { imp.stop(&wrap) }).to_glib() -} - -unsafe extern "C" fn aggregator_get_next_time( - ptr: *mut gst_base_ffi::GstAggregator, -) -> gst_ffi::GstClockTime -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::CLOCK_TIME_NONE, { - imp.get_next_time(&wrap) - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_create_new_pad( - ptr: *mut gst_base_ffi::GstAggregator, - templ: *mut gst_ffi::GstPadTemplate, - req_name: *const libc::c_char, - caps: *const gst_ffi::GstCaps, -) -> *mut gst_base_ffi::GstAggregatorPad -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), None, { - let req_name: Option = from_glib_none(req_name); - - // FIXME: Easier way to convert Option to Option<&str>? - let mut _tmp = String::new(); - let req_name = match req_name { - Some(n) => { - _tmp = n; - Some(_tmp.as_str()) - } - None => None, - }; - - imp.create_new_pad( - &wrap, - &from_glib_borrow(templ), - req_name, - if caps.is_null() { - None - } else { - Some(gst::CapsRef::from_ptr(caps)) - }, - ) - }) - .to_glib_full() -} - -unsafe extern "C" fn aggregator_update_src_caps( - ptr: *mut gst_base_ffi::GstAggregator, - caps: *mut gst_ffi::GstCaps, - res: *mut *mut gst_ffi::GstCaps, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - *res = ptr::null_mut(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::FlowReturn::Error, { - match imp.update_src_caps(&wrap, gst::CapsRef::from_ptr(caps)) { - Ok(res_caps) => { - *res = res_caps.into_ptr(); - gst::FlowReturn::Ok - } - Err(err) => err, - } - }) - .to_glib() -} - -unsafe extern "C" fn aggregator_fixate_src_caps( - ptr: *mut gst_base_ffi::GstAggregator, - caps: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), gst::Caps::new_empty(), { - imp.fixate_src_caps(&wrap, from_glib_full(caps)) - }) - .into_ptr() -} - -unsafe extern "C" fn aggregator_negotiated_src_caps( - ptr: *mut gst_base_ffi::GstAggregator, - caps: *mut gst_ffi::GstCaps, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let aggregator = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator.get_impl(); - - panic_to_error!(&wrap, &aggregator.panicked(), false, { - imp.negotiated_src_caps(&wrap, gst::CapsRef::from_ptr(caps)) - }) - .to_glib() -} diff --git a/gst-plugin/src/aggregator_pad.rs b/gst-plugin/src/aggregator_pad.rs deleted file mode 100644 index 35270f55..00000000 --- a/gst-plugin/src/aggregator_pad.rs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (C) 2018 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_base_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; -use gst_base; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use pad::*; - -pub trait AggregatorPadImpl: - AnyImpl + ObjectImpl + PadImpl + Send + Sync + 'static -{ - fn flush(&self, aggregator_pad: &T, aggregator: &gst_base::Aggregator) -> gst::FlowReturn { - aggregator_pad.parent_flush(aggregator) - } - - fn skip_buffer( - &self, - aggregator_pad: &T, - aggregator: &gst_base::Aggregator, - buffer: &gst::BufferRef, - ) -> bool { - aggregator_pad.parent_skip_buffer(aggregator, buffer) - } -} - -any_impl!(AggregatorPadBase, AggregatorPadImpl); - -pub unsafe trait AggregatorPadBase: - IsA + IsA + ObjectType -{ - fn parent_flush(&self, aggregator: &gst_base::Aggregator) -> gst::FlowReturn { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorPadClass; - (*parent_klass) - .flush - .map(|f| from_glib(f(self.to_glib_none().0, aggregator.to_glib_none().0))) - .unwrap_or(gst::FlowReturn::Ok) - } - } - - fn parent_skip_buffer( - &self, - aggregator: &gst_base::Aggregator, - buffer: &gst::BufferRef, - ) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstAggregatorPadClass; - (*parent_klass) - .skip_buffer - .map(|f| { - from_glib(f( - self.to_glib_none().0, - aggregator.to_glib_none().0, - buffer.as_mut_ptr(), - )) - }) - .unwrap_or(false) - } - } -} - -pub unsafe trait AggregatorPadClassExt -where - T::ImplType: AggregatorPadImpl, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstAggregatorPadClass); - klass.flush = Some(aggregator_pad_flush::); - klass.skip_buffer = Some(aggregator_pad_skip_buffer::); - } - } -} - -glib_wrapper! { - pub struct AggregatorPad(Object>): - [gst_base::AggregatorPad => gst_base_ffi::GstAggregatorPad, - gst::Pad => gst_ffi::GstPad, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> AggregatorPadBase for T {} -pub type AggregatorPadClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl AggregatorPadClassExt for AggregatorPadClass {} -unsafe impl PadClassExt for AggregatorPadClass {} -unsafe impl ObjectClassExt for AggregatorPadClass {} - -unsafe impl Send for AggregatorPad {} -unsafe impl Sync for AggregatorPad {} - -#[macro_export] -macro_rules! box_aggregator_pad_impl( - ($name:ident) => { - box_pad_impl!($name); - - impl AggregatorPadImpl for Box<$name> - { - fn flush(&self, aggregator_pad: &T, aggregator: &gst_base::Aggregator) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.flush(aggregator_pad, aggregator) - } - - fn skip_buffer(&self, aggregator_pad: &T, aggregator: &gst_base::Aggregator, buffer: &gst::BufferRef) -> bool { - let imp: &$name = self.as_ref(); - imp.skip_buffer(aggregator_pad, aggregator, buffer) - } - } - }; -); -box_aggregator_pad_impl!(AggregatorPadImpl); - -impl ObjectType for AggregatorPad { - const NAME: &'static str = "RsAggregatorPad"; - type ParentType = gst_base::AggregatorPad; - type ImplType = Box>; - type InstanceStructType = InstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut AggregatorPadClass) { - ObjectClassExt::override_vfuncs(klass, token); - PadClassExt::override_vfuncs(klass, token); - AggregatorPadClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn aggregator_pad_flush( - ptr: *mut gst_base_ffi::GstAggregatorPad, - aggregator: *mut gst_base_ffi::GstAggregator, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: AggregatorPadImpl, -{ - floating_reference_guard!(ptr); - let aggregator_pad = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator_pad.get_impl(); - - imp.flush(&wrap, &from_glib_borrow(aggregator)).to_glib() -} - -unsafe extern "C" fn aggregator_pad_skip_buffer( - ptr: *mut gst_base_ffi::GstAggregatorPad, - aggregator: *mut gst_base_ffi::GstAggregator, - buffer: *mut gst_ffi::GstBuffer, -) -> glib_ffi::gboolean -where - T::ImplType: AggregatorPadImpl, -{ - floating_reference_guard!(ptr); - let aggregator_pad = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = aggregator_pad.get_impl(); - - imp.skip_buffer( - &wrap, - &from_glib_borrow(aggregator), - gst::BufferRef::from_ptr(buffer), - ) - .to_glib() -} diff --git a/gst-plugin/src/base_sink.rs b/gst-plugin/src/base_sink.rs deleted file mode 100644 index 56bc4bec..00000000 --- a/gst-plugin/src/base_sink.rs +++ /dev/null @@ -1,553 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_base_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; -use gst_base; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use element::*; -use object::*; - -pub trait BaseSinkImpl: - AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn start(&self, _element: &T) -> bool { - true - } - - fn stop(&self, _element: &T) -> bool { - true - } - - fn render(&self, element: &T, buffer: &gst::BufferRef) -> gst::FlowReturn; - - fn prepare(&self, _element: &T, _buffer: &gst::BufferRef) -> gst::FlowReturn { - gst::FlowReturn::Ok - } - - fn render_list(&self, element: &T, list: &gst::BufferListRef) -> gst::FlowReturn { - for buffer in list.iter() { - let ret = self.render(element, buffer); - if ret != gst::FlowReturn::Ok { - return ret; - } - } - - gst::FlowReturn::Ok - } - - fn prepare_list(&self, element: &T, list: &gst::BufferListRef) -> gst::FlowReturn { - for buffer in list.iter() { - let ret = self.prepare(element, buffer); - if ret != gst::FlowReturn::Ok { - return ret; - } - } - - gst::FlowReturn::Ok - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - element.parent_query(query) - } - - fn event(&self, element: &T, event: gst::Event) -> bool { - element.parent_event(event) - } - - fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option { - element.parent_get_caps(filter) - } - - fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool { - element.parent_set_caps(caps) - } - - fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps { - element.parent_fixate(caps) - } - - fn unlock(&self, _element: &T) -> bool { - true - } - - fn unlock_stop(&self, _element: &T) -> bool { - true - } -} - -any_impl!(BaseSinkBase, BaseSinkImpl, PanicPoison); - -pub unsafe trait BaseSinkBase: - IsA + IsA + ObjectType -{ - fn parent_query(&self, query: &mut gst::QueryRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSinkClass; - (*parent_klass) - .query - .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr()))) - .unwrap_or(false) - } - } - - fn parent_event(&self, event: gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSinkClass; - (*parent_klass) - .event - .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr()))) - .unwrap_or(false) - } - } - - fn parent_get_caps(&self, filter: Option<&gst::CapsRef>) -> Option { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSinkClass; - let filter_ptr = if let Some(filter) = filter { - filter.as_mut_ptr() - } else { - ptr::null_mut() - }; - - (*parent_klass) - .get_caps - .map(|f| from_glib_full(f(self.to_glib_none().0, filter_ptr))) - .unwrap_or(None) - } - } - - fn parent_set_caps(&self, caps: &gst::CapsRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSinkClass; - (*parent_klass) - .set_caps - .map(|f| from_glib(f(self.to_glib_none().0, caps.as_mut_ptr()))) - .unwrap_or(true) - } - } - - fn parent_fixate(&self, caps: gst::Caps) -> gst::Caps { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSinkClass; - - match (*parent_klass).fixate { - Some(fixate) => from_glib_full(fixate(self.to_glib_none().0, caps.into_ptr())), - None => caps, - } - } - } -} - -pub unsafe trait BaseSinkClassExt -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseSinkClass); - klass.start = Some(base_sink_start::); - klass.stop = Some(base_sink_stop::); - klass.render = Some(base_sink_render::); - klass.render_list = Some(base_sink_render_list::); - klass.prepare = Some(base_sink_prepare::); - klass.prepare_list = Some(base_sink_prepare_list::); - klass.query = Some(base_sink_query::); - klass.event = Some(base_sink_event::); - klass.get_caps = Some(base_sink_get_caps::); - klass.set_caps = Some(base_sink_set_caps::); - klass.fixate = Some(base_sink_fixate::); - klass.unlock = Some(base_sink_unlock::); - klass.unlock_stop = Some(base_sink_unlock_stop::); - } - } -} - -glib_wrapper! { - pub struct BaseSink(Object>): - [gst_base::BaseSink => gst_base_ffi::GstBaseSink, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> BaseSinkBase for T {} -pub type BaseSinkClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl BaseSinkClassExt for BaseSinkClass {} -unsafe impl ElementClassExt for BaseSinkClass {} -unsafe impl ObjectClassExt for BaseSinkClass {} - -unsafe impl Send for BaseSink {} -unsafe impl Sync for BaseSink {} - -#[macro_export] -macro_rules! box_base_sink_impl( - ($name:ident) => { - box_element_impl!($name); - - impl BaseSinkImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn start(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.start(element) - } - - fn stop(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.stop(element) - } - - fn render(&self, element: &T, buffer: &gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.render(element, buffer) - } - - fn prepare(&self, element: &T, buffer: &gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.prepare(element, buffer) - } - - fn render_list(&self, element: &T, list: &gst::BufferListRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.render_list(element, list) - } - - fn prepare_list(&self, element: &T, list: &gst::BufferListRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.prepare_list(element, list) - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - BaseSinkImpl::query(imp, element, query) - } - - fn event(&self, element: &T, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.event(element, event) - } - - fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option { - let imp: &$name = self.as_ref(); - imp.get_caps(element, filter) - } - - fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool { - let imp: &$name = self.as_ref(); - imp.set_caps(element, caps) - } - - fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps { - let imp: &$name = self.as_ref(); - imp.fixate(element, caps) - } - - fn unlock(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.unlock(element) - } - - fn unlock_stop(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.unlock_stop(element) - } - } - }; -); - -box_base_sink_impl!(BaseSinkImpl); - -impl ObjectType for BaseSink { - const NAME: &'static str = "RsBaseSink"; - type ParentType = gst_base::BaseSink; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut BaseSinkClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - BaseSinkClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn base_sink_start( - ptr: *mut gst_base_ffi::GstBaseSink, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_sink_stop( - ptr: *mut gst_base_ffi::GstBaseSink, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_sink_render( - ptr: *mut gst_base_ffi::GstBaseSink, - buffer: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let buffer = gst::BufferRef::from_ptr(buffer); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.render(&wrap, buffer) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_prepare( - ptr: *mut gst_base_ffi::GstBaseSink, - buffer: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let buffer = gst::BufferRef::from_ptr(buffer); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.prepare(&wrap, buffer) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_render_list( - ptr: *mut gst_base_ffi::GstBaseSink, - list: *mut gst_ffi::GstBufferList, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let list = gst::BufferListRef::from_ptr(list); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.render_list(&wrap, list) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_prepare_list( - ptr: *mut gst_base_ffi::GstBaseSink, - list: *mut gst_ffi::GstBufferList, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let list = gst::BufferListRef::from_ptr(list); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.prepare_list(&wrap, list) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_query( - ptr: *mut gst_base_ffi::GstBaseSink, - query_ptr: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let query = gst::QueryRef::from_mut_ptr(query_ptr); - - panic_to_error!(&wrap, &element.panicked(), false, { - BaseSinkImpl::query(imp, &wrap, query) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_event( - ptr: *mut gst_base_ffi::GstBaseSink, - event_ptr: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.event(&wrap, from_glib_full(event_ptr)) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_get_caps( - ptr: *mut gst_base_ffi::GstBaseSink, - filter: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let filter = if filter.is_null() { - None - } else { - Some(gst::CapsRef::from_ptr(filter)) - }; - - panic_to_error!(&wrap, &element.panicked(), None, { - imp.get_caps(&wrap, filter) - }) - .map(|caps| caps.into_ptr()) - .unwrap_or(ptr::null_mut()) -} - -unsafe extern "C" fn base_sink_set_caps( - ptr: *mut gst_base_ffi::GstBaseSink, - caps: *mut gst_ffi::GstCaps, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let caps = gst::CapsRef::from_ptr(caps); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.set_caps(&wrap, caps) - }) - .to_glib() -} - -unsafe extern "C" fn base_sink_fixate( - ptr: *mut gst_base_ffi::GstBaseSink, - caps: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let caps = from_glib_full(caps); - - panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { - imp.fixate(&wrap, caps) - }) - .into_ptr() -} - -unsafe extern "C" fn base_sink_unlock( - ptr: *mut gst_base_ffi::GstBaseSink, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_sink_unlock_stop( - ptr: *mut gst_base_ffi::GstBaseSink, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSinkImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.unlock_stop(&wrap) - }) - .to_glib() -} diff --git a/gst-plugin/src/base_src.rs b/gst-plugin/src/base_src.rs deleted file mode 100644 index bae4b6d9..00000000 --- a/gst-plugin/src/base_src.rs +++ /dev/null @@ -1,668 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_base_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; -use gst_base; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use element::*; -use object::*; - -pub trait BaseSrcImpl: - AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn start(&self, _element: &T) -> bool { - true - } - - fn stop(&self, _element: &T) -> bool { - true - } - - fn is_seekable(&self, _element: &T) -> bool { - false - } - - fn get_size(&self, _element: &T) -> Option { - None - } - - fn fill( - &self, - _element: &T, - _offset: u64, - _length: u32, - _buffer: &mut gst::BufferRef, - ) -> gst::FlowReturn { - unimplemented!() - } - - fn create(&self, element: &T, offset: u64, length: u32) -> Result { - element.parent_create(offset, length) - } - - fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool { - element.parent_do_seek(segment) - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - element.parent_query(query) - } - - fn event(&self, element: &T, event: &gst::Event) -> bool { - element.parent_event(event) - } - - fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option { - element.parent_get_caps(filter) - } - - fn negotiate(&self, element: &T) -> bool { - element.parent_negotiate() - } - - fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool { - element.parent_set_caps(caps) - } - - fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps { - element.parent_fixate(caps) - } - - fn unlock(&self, _element: &T) -> bool { - true - } - - fn unlock_stop(&self, _element: &T) -> bool { - true - } -} - -any_impl!(BaseSrcBase, BaseSrcImpl, PanicPoison); - -pub unsafe trait BaseSrcBase: - IsA + IsA + ObjectType -{ - fn parent_create(&self, offset: u64, length: u32) -> Result { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .create - .map(|f| { - let mut buffer: *mut gst_ffi::GstBuffer = ptr::null_mut(); - // FIXME: Wrong signature in -sys bindings - // https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3 - let buffer_ref = &mut buffer as *mut _ as *mut gst_ffi::GstBuffer; - let ret: gst::FlowReturn = - from_glib(f(self.to_glib_none().0, offset, length, buffer_ref)); - - ret.into_result_value(|| from_glib_full(buffer)) - }) - .unwrap_or(Err(gst::FlowError::Error)) - } - } - - fn parent_do_seek(&self, segment: &mut gst::Segment) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .do_seek - .map(|f| from_glib(f(self.to_glib_none().0, segment.to_glib_none_mut().0))) - .unwrap_or(false) - } - } - - fn parent_query(&self, query: &mut gst::QueryRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .query - .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr()))) - .unwrap_or(false) - } - } - - fn parent_event(&self, event: &gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .event - .map(|f| from_glib(f(self.to_glib_none().0, event.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_get_caps(&self, filter: Option<&gst::CapsRef>) -> Option { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - let filter_ptr = if let Some(filter) = filter { - filter.as_mut_ptr() - } else { - ptr::null_mut() - }; - - (*parent_klass) - .get_caps - .map(|f| from_glib_full(f(self.to_glib_none().0, filter_ptr))) - .unwrap_or(None) - } - } - - fn parent_negotiate(&self) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .negotiate - .map(|f| from_glib(f(self.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_set_caps(&self, caps: &gst::CapsRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - (*parent_klass) - .set_caps - .map(|f| from_glib(f(self.to_glib_none().0, caps.as_mut_ptr()))) - .unwrap_or(true) - } - } - - fn parent_fixate(&self, caps: gst::Caps) -> gst::Caps { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass; - - match (*parent_klass).fixate { - Some(fixate) => from_glib_full(fixate(self.to_glib_none().0, caps.into_ptr())), - None => caps, - } - } - } -} - -pub unsafe trait BaseSrcClassExt -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseSrcClass); - klass.start = Some(base_src_start::); - klass.stop = Some(base_src_stop::); - klass.is_seekable = Some(base_src_is_seekable::); - klass.get_size = Some(base_src_get_size::); - klass.fill = Some(base_src_fill::); - klass.create = Some(base_src_create::); - klass.do_seek = Some(base_src_do_seek::); - klass.query = Some(base_src_query::); - klass.event = Some(base_src_event::); - klass.get_caps = Some(base_src_get_caps::); - klass.negotiate = Some(base_src_negotiate::); - klass.set_caps = Some(base_src_set_caps::); - klass.fixate = Some(base_src_fixate::); - klass.unlock = Some(base_src_unlock::); - klass.unlock_stop = Some(base_src_unlock_stop::); - } - } -} - -glib_wrapper! { - pub struct BaseSrc(Object>): - [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> BaseSrcBase for T {} -pub type BaseSrcClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl BaseSrcClassExt for BaseSrcClass {} -unsafe impl ElementClassExt for BaseSrcClass {} -unsafe impl ObjectClassExt for BaseSrcClass {} - -unsafe impl Send for BaseSrc {} -unsafe impl Sync for BaseSrc {} - -#[macro_export] -macro_rules! box_base_src_impl( - ($name:ident) => { - box_element_impl!($name); - - impl BaseSrcImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn start(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.start(element) - } - - fn stop(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.stop(element) - } - - fn is_seekable(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.is_seekable(element) - } - - fn get_size(&self, element: &T) -> Option { - let imp: &$name = self.as_ref(); - imp.get_size(element) - } - - fn fill( - &self, - element: &T, - offset: u64, - length: u32, - buffer: &mut gst::BufferRef, - ) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.fill(element, offset, length, buffer) - } - - fn create( - &self, - element: &T, - offset: u64, - length: u32, - ) -> Result { - let imp: &$name = self.as_ref(); - imp.create(element, offset, length) - } - - fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool { - let imp: &$name = self.as_ref(); - imp.do_seek(element, segment) - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - BaseSrcImpl::query(imp, element, query) - } - - fn event(&self, element: &T, event: &gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.event(element, event) - } - - fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option { - let imp: &$name = self.as_ref(); - imp.get_caps(element, filter) - } - - fn negotiate(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.negotiate(element) - } - - fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool { - let imp: &$name = self.as_ref(); - imp.set_caps(element, caps) - } - - fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps { - let imp: &$name = self.as_ref(); - imp.fixate(element, caps) - } - - fn unlock(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.unlock(element) - } - - fn unlock_stop(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.unlock_stop(element) - } - } - }; -); -box_base_src_impl!(BaseSrcImpl); - -impl ObjectType for BaseSrc { - const NAME: &'static str = "RsBaseSrc"; - type ParentType = gst_base::BaseSrc; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut BaseSrcClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - BaseSrcClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn base_src_start( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_src_stop( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_src_is_seekable( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.is_seekable(&wrap) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_get_size( - ptr: *mut gst_base_ffi::GstBaseSrc, - size: *mut u64, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - match imp.get_size(&wrap) { - Some(s) => { - *size = s; - true - } - None => false, - } - }) - .to_glib() -} - -unsafe extern "C" fn base_src_fill( - ptr: *mut gst_base_ffi::GstBaseSrc, - offset: u64, - length: u32, - buffer: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let buffer = gst::BufferRef::from_mut_ptr(buffer); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.fill(&wrap, offset, length, buffer) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_create( - ptr: *mut gst_base_ffi::GstBaseSrc, - offset: u64, - length: u32, - buffer_ptr: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - // FIXME: Wrong signature in -sys bindings - // https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3 - let buffer_ptr = buffer_ptr as *mut *mut gst_ffi::GstBuffer; - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - match imp.create(&wrap, offset, length) { - Ok(buffer) => { - *buffer_ptr = buffer.into_ptr(); - gst::FlowReturn::Ok - } - Err(err) => gst::FlowReturn::from(err), - } - }) - .to_glib() -} - -unsafe extern "C" fn base_src_do_seek( - ptr: *mut gst_base_ffi::GstBaseSrc, - segment: *mut gst_ffi::GstSegment, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.do_seek(&wrap, &mut from_glib_borrow(segment)) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_query( - ptr: *mut gst_base_ffi::GstBaseSrc, - query_ptr: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let query = gst::QueryRef::from_mut_ptr(query_ptr); - - panic_to_error!(&wrap, &element.panicked(), false, { - BaseSrcImpl::query(imp, &wrap, query) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_event( - ptr: *mut gst_base_ffi::GstBaseSrc, - event_ptr: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.event(&wrap, &from_glib_borrow(event_ptr)) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_get_caps( - ptr: *mut gst_base_ffi::GstBaseSrc, - filter: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let filter = if filter.is_null() { - None - } else { - Some(gst::CapsRef::from_ptr(filter)) - }; - - panic_to_error!(&wrap, &element.panicked(), None, { - imp.get_caps(&wrap, filter) - }) - .map(|caps| caps.into_ptr()) - .unwrap_or(ptr::null_mut()) -} - -unsafe extern "C" fn base_src_negotiate( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.negotiate(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_src_set_caps( - ptr: *mut gst_base_ffi::GstBaseSrc, - caps: *mut gst_ffi::GstCaps, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let caps = gst::CapsRef::from_ptr(caps); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.set_caps(&wrap, caps) - }) - .to_glib() -} - -unsafe extern "C" fn base_src_fixate( - ptr: *mut gst_base_ffi::GstBaseSrc, - caps: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let caps = from_glib_full(caps); - - panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { - imp.fixate(&wrap, caps) - }) - .into_ptr() -} - -unsafe extern "C" fn base_src_unlock( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_src_unlock_stop( - ptr: *mut gst_base_ffi::GstBaseSrc, -) -> glib_ffi::gboolean -where - T::ImplType: BaseSrcImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.unlock_stop(&wrap) - }) - .to_glib() -} diff --git a/gst-plugin/src/base_transform.rs b/gst-plugin/src/base_transform.rs deleted file mode 100644 index ace3bf99..00000000 --- a/gst-plugin/src/base_transform.rs +++ /dev/null @@ -1,741 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_base_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; -use gst_base; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use element::*; -use object::*; - -pub trait BaseTransformImpl: - AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn start(&self, _element: &T) -> bool { - true - } - - fn stop(&self, _element: &T) -> bool { - true - } - - fn transform_caps( - &self, - element: &T, - direction: gst::PadDirection, - caps: &gst::Caps, - filter: Option<&gst::Caps>, - ) -> gst::Caps { - element.parent_transform_caps(direction, caps, filter) - } - - fn fixate_caps( - &self, - element: &T, - direction: gst::PadDirection, - caps: &gst::Caps, - othercaps: gst::Caps, - ) -> gst::Caps { - element.parent_fixate_caps(direction, caps, othercaps) - } - - fn set_caps(&self, _element: &T, _incaps: &gst::Caps, _outcaps: &gst::Caps) -> bool { - true - } - - fn accept_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps) -> bool { - element.parent_accept_caps(direction, caps) - } - - fn query(&self, element: &T, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool { - element.parent_query(direction, query) - } - - fn transform_size( - &self, - element: &T, - direction: gst::PadDirection, - caps: &gst::Caps, - size: usize, - othercaps: &gst::Caps, - ) -> Option { - element.parent_transform_size(direction, caps, size, othercaps) - } - - fn get_unit_size(&self, _element: &T, _caps: &gst::Caps) -> Option { - unimplemented!(); - } - - fn sink_event(&self, element: &T, event: gst::Event) -> bool { - element.parent_sink_event(event) - } - - fn src_event(&self, element: &T, event: gst::Event) -> bool { - element.parent_src_event(event) - } - - fn transform( - &self, - _element: &T, - _inbuf: &gst::Buffer, - _outbuf: &mut gst::BufferRef, - ) -> gst::FlowReturn { - unimplemented!(); - } - - fn transform_ip(&self, _element: &T, _buf: &mut gst::BufferRef) -> gst::FlowReturn { - unimplemented!(); - } - - fn transform_ip_passthrough(&self, _element: &T, _buf: &gst::BufferRef) -> gst::FlowReturn { - unimplemented!(); - } -} - -any_impl!(BaseTransformBase, BaseTransformImpl, PanicPoison); - -pub unsafe trait BaseTransformBase: - IsA + IsA + ObjectType -where - Self::InstanceStructType: PanicPoison, -{ - fn parent_transform_caps( - &self, - direction: gst::PadDirection, - caps: &gst::Caps, - filter: Option<&gst::Caps>, - ) -> gst::Caps { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - match (*parent_klass).transform_caps { - Some(f) => from_glib_full(f( - self.to_glib_none().0, - direction.to_glib(), - caps.to_glib_none().0, - filter.to_glib_none().0, - )), - None => caps.clone(), - } - } - } - - fn parent_fixate_caps( - &self, - direction: gst::PadDirection, - caps: &gst::Caps, - othercaps: gst::Caps, - ) -> gst::Caps { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - match (*parent_klass).fixate_caps { - Some(f) => from_glib_full(f( - self.to_glib_none().0, - direction.to_glib(), - caps.to_glib_none().0, - othercaps.into_ptr(), - )), - None => othercaps, - } - } - } - - fn parent_accept_caps(&self, direction: gst::PadDirection, caps: &gst::Caps) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - (*parent_klass) - .accept_caps - .map(|f| { - from_glib(f( - self.to_glib_none().0, - direction.to_glib(), - caps.to_glib_none().0, - )) - }) - .unwrap_or(false) - } - } - - fn parent_query(&self, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - (*parent_klass) - .query - .map(|f| { - from_glib(f( - self.to_glib_none().0, - direction.to_glib(), - query.as_mut_ptr(), - )) - }) - .unwrap_or(false) - } - } - - fn parent_transform_size( - &self, - direction: gst::PadDirection, - caps: &gst::Caps, - size: usize, - othercaps: &gst::Caps, - ) -> Option { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - (*parent_klass) - .transform_size - .map(|f| { - let mut othersize = 0; - let res: bool = from_glib(f( - self.to_glib_none().0, - direction.to_glib(), - caps.to_glib_none().0, - size, - othercaps.to_glib_none().0, - &mut othersize, - )); - if res { - Some(othersize) - } else { - None - } - }) - .unwrap_or(None) - } - } - - fn parent_sink_event(&self, event: gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - (*parent_klass) - .sink_event - .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr()))) - .unwrap_or(false) - } - } - - fn parent_src_event(&self, event: gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = - (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass; - (*parent_klass) - .src_event - .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr()))) - .unwrap_or(false) - } - } -} - -pub enum BaseTransformMode { - AlwaysInPlace, - NeverInPlace, - Both, -} - -pub unsafe trait BaseTransformClassExt -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - fn configure( - &mut self, - mode: BaseTransformMode, - passthrough_on_same_caps: bool, - transform_ip_on_passthrough: bool, - ) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseTransformClass); - - klass.passthrough_on_same_caps = passthrough_on_same_caps.to_glib(); - klass.transform_ip_on_passthrough = transform_ip_on_passthrough.to_glib(); - - match mode { - BaseTransformMode::AlwaysInPlace => { - klass.transform_ip = Some(base_transform_transform_ip::); - } - BaseTransformMode::NeverInPlace => { - klass.transform = Some(base_transform_transform::); - } - BaseTransformMode::Both => { - klass.transform = Some(base_transform_transform::); - klass.transform_ip = Some(base_transform_transform_ip::); - } - } - } - } - - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseTransformClass); - klass.start = Some(base_transform_start::); - klass.stop = Some(base_transform_stop::); - klass.transform_caps = Some(base_transform_transform_caps::); - klass.fixate_caps = Some(base_transform_fixate_caps::); - klass.set_caps = Some(base_transform_set_caps::); - klass.accept_caps = Some(base_transform_accept_caps::); - klass.query = Some(base_transform_query::); - klass.transform_size = Some(base_transform_transform_size::); - klass.get_unit_size = Some(base_transform_get_unit_size::); - klass.sink_event = Some(base_transform_sink_event::); - klass.src_event = Some(base_transform_src_event::); - } - } -} - -glib_wrapper! { - pub struct BaseTransform(Object>): - [gst_base::BaseTransform => gst_base_ffi::GstBaseTransform, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> BaseTransformBase - for T -where - T::InstanceStructType: PanicPoison, -{ -} -pub type BaseTransformClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl BaseTransformClassExt for BaseTransformClass {} -unsafe impl ElementClassExt for BaseTransformClass {} -unsafe impl ObjectClassExt for BaseTransformClass {} - -unsafe impl Send for BaseTransform {} -unsafe impl Sync for BaseTransform {} - -#[macro_export] -macro_rules! box_base_transform_impl( - ($name:ident) => { - box_element_impl!($name); - - impl BaseTransformImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn start(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.start(element) - } - - fn stop(&self, element: &T) -> bool { - let imp: &$name = self.as_ref(); - imp.stop(element) - } - - fn transform_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, filter: Option<&gst::Caps>) -> gst::Caps { - let imp: &$name = self.as_ref(); - imp.transform_caps(element, direction, caps, filter) - } - - fn fixate_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, othercaps: gst::Caps) -> gst::Caps { - let imp: &$name = self.as_ref(); - imp.fixate_caps(element, direction, caps, othercaps) - } - - fn set_caps(&self, element: &T, incaps: &gst::Caps, outcaps: &gst::Caps) -> bool { - let imp: &$name = self.as_ref(); - imp.set_caps(element, incaps, outcaps) - } - - fn accept_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps) -> bool { - let imp: &$name = self.as_ref(); - imp.accept_caps(element, direction, caps) - } - - fn query(&self, element: &T, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - BaseTransformImpl::query(imp, element, direction, query) - } - - fn transform_size(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, size: usize, othercaps: &gst::Caps) -> Option { - let imp: &$name = self.as_ref(); - imp.transform_size(element, direction, caps, size, othercaps) - } - - fn get_unit_size(&self, element: &T, caps: &gst::Caps) -> Option { - let imp: &$name = self.as_ref(); - imp.get_unit_size(element, caps) - } - - fn sink_event(&self, element: &T, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.sink_event(element, event) - } - - fn src_event(&self, element: &T, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.src_event(element, event) - } - - fn transform(&self, element: &T, inbuf: &gst::Buffer, outbuf: &mut gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.transform(element, inbuf, outbuf) - } - - fn transform_ip(&self, element: &T, buf: &mut gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.transform_ip(element, buf) - } - - fn transform_ip_passthrough(&self, element: &T, buf: &gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); - imp.transform_ip_passthrough(element, buf) - } - } - }; -); -box_base_transform_impl!(BaseTransformImpl); - -impl ObjectType for BaseTransform { - const NAME: &'static str = "RsBaseTransform"; - type ParentType = gst_base::BaseTransform; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut BaseTransformClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - BaseTransformClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn base_transform_start( - ptr: *mut gst_base_ffi::GstBaseTransform, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_transform_stop( - ptr: *mut gst_base_ffi::GstBaseTransform, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() -} - -unsafe extern "C" fn base_transform_transform_caps( - ptr: *mut gst_base_ffi::GstBaseTransform, - direction: gst_ffi::GstPadDirection, - caps: *mut gst_ffi::GstCaps, - filter: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { - let filter = if filter.is_null() { - None - } else { - Some(from_glib_borrow(filter)) - }; - - imp.transform_caps( - &wrap, - from_glib(direction), - &from_glib_borrow(caps), - filter.as_ref(), - ) - }) - .into_ptr() -} - -unsafe extern "C" fn base_transform_fixate_caps( - ptr: *mut gst_base_ffi::GstBaseTransform, - direction: gst_ffi::GstPadDirection, - caps: *mut gst_ffi::GstCaps, - othercaps: *mut gst_ffi::GstCaps, -) -> *mut gst_ffi::GstCaps -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { - imp.fixate_caps( - &wrap, - from_glib(direction), - &from_glib_borrow(caps), - from_glib_full(othercaps), - ) - }) - .into_ptr() -} - -unsafe extern "C" fn base_transform_set_caps( - ptr: *mut gst_base_ffi::GstBaseTransform, - incaps: *mut gst_ffi::GstCaps, - outcaps: *mut gst_ffi::GstCaps, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.set_caps(&wrap, &from_glib_borrow(incaps), &from_glib_borrow(outcaps)) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_accept_caps( - ptr: *mut gst_base_ffi::GstBaseTransform, - direction: gst_ffi::GstPadDirection, - caps: *mut gst_ffi::GstCaps, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.accept_caps(&wrap, from_glib(direction), &from_glib_borrow(caps)) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_query( - ptr: *mut gst_base_ffi::GstBaseTransform, - direction: gst_ffi::GstPadDirection, - query: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - BaseTransformImpl::query( - imp, - &wrap, - from_glib(direction), - gst::QueryRef::from_mut_ptr(query), - ) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_transform_size( - ptr: *mut gst_base_ffi::GstBaseTransform, - direction: gst_ffi::GstPadDirection, - caps: *mut gst_ffi::GstCaps, - size: usize, - othercaps: *mut gst_ffi::GstCaps, - othersize: *mut usize, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - match imp.transform_size( - &wrap, - from_glib(direction), - &from_glib_borrow(caps), - size, - &from_glib_borrow(othercaps), - ) { - Some(s) => { - *othersize = s; - true - } - None => false, - } - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_get_unit_size( - ptr: *mut gst_base_ffi::GstBaseTransform, - caps: *mut gst_ffi::GstCaps, - size: *mut usize, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - match imp.get_unit_size(&wrap, &from_glib_borrow(caps)) { - Some(s) => { - *size = s; - true - } - None => false, - } - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_sink_event( - ptr: *mut gst_base_ffi::GstBaseTransform, - event: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.sink_event(&wrap, from_glib_full(event)) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_src_event( - ptr: *mut gst_base_ffi::GstBaseTransform, - event: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.src_event(&wrap, from_glib_full(event)) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_transform( - ptr: *mut gst_base_ffi::GstBaseTransform, - inbuf: *mut gst_ffi::GstBuffer, - outbuf: *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - imp.transform( - &wrap, - &from_glib_borrow(inbuf), - gst::BufferRef::from_mut_ptr(outbuf), - ) - }) - .to_glib() -} - -unsafe extern "C" fn base_transform_transform_ip( - ptr: *mut gst_base_ffi::GstBaseTransform, - buf: *mut *mut gst_ffi::GstBuffer, -) -> gst_ffi::GstFlowReturn -where - T::ImplType: BaseTransformImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - // FIXME: Wrong signature in FFI - let buf = buf as *mut gst_ffi::GstBuffer; - - panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { - if from_glib(gst_base_ffi::gst_base_transform_is_passthrough(ptr)) { - imp.transform_ip_passthrough(&wrap, gst::BufferRef::from_ptr(buf)) - } else { - imp.transform_ip(&wrap, gst::BufferRef::from_mut_ptr(buf)) - } - }) - .to_glib() -} diff --git a/gst-plugin/src/bin.rs b/gst-plugin/src/bin.rs deleted file mode 100644 index 841f17e7..00000000 --- a/gst-plugin/src/bin.rs +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use element::*; -use object::*; - -pub trait BinImpl: - AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn add_element(&self, bin: &T, element: &gst::Element) -> bool { - bin.parent_add_element(element) - } - - fn remove_element(&self, bin: &T, element: &gst::Element) -> bool { - bin.parent_remove_element(element) - } - - fn handle_message(&self, bin: &T, message: gst::Message) { - bin.parent_handle_message(message) - } -} - -any_impl!(BinBase, BinImpl, PanicPoison); - -pub unsafe trait BinBase: IsA + IsA + ObjectType { - fn parent_add_element(&self, element: &gst::Element) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstBinClass; - (*parent_klass) - .add_element - .map(|f| from_glib(f(self.to_glib_none().0, element.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_remove_element(&self, element: &gst::Element) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstBinClass; - (*parent_klass) - .remove_element - .map(|f| from_glib(f(self.to_glib_none().0, element.to_glib_none().0))) - .unwrap_or(false) - } - } - - fn parent_handle_message(&self, message: gst::Message) { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstBinClass; - (*parent_klass) - .handle_message - .map(move |f| f(self.to_glib_none().0, message.into_ptr())); - } - } -} - -pub unsafe trait BinClassExt -where - T::ImplType: BinImpl, - T::InstanceStructType: PanicPoison, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_ffi::GstBinClass); - klass.add_element = Some(bin_add_element::); - klass.remove_element = Some(bin_remove_element::); - klass.handle_message = Some(bin_handle_message::); - } - } -} - -glib_wrapper! { - pub struct Bin(Object>): - [gst::Bin => gst_ffi::GstBin, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject, - gst::ChildProxy => gst_ffi::GstChildProxy]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> BinBase for T {} -pub type BinClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl BinClassExt for BinClass {} -unsafe impl ElementClassExt for BinClass {} -unsafe impl ObjectClassExt for BinClass {} - -unsafe impl Send for Bin {} -unsafe impl Sync for Bin {} - -#[macro_export] -macro_rules! box_bin_impl( - ($name:ident) => { - box_element_impl!($name); - - impl BinImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn add_element(&self, bin: &T, element: &gst::Element) -> bool { - let imp: &$name = self.as_ref(); - imp.add_element(bin, element) - } - - fn remove_element(&self, bin: &T, element: &gst::Element) -> bool { - let imp: &$name = self.as_ref(); - imp.remove_element(bin, element) - } - - fn handle_message(&self, bin: &T, message: gst::Message) { - let imp: &$name = self.as_ref(); - imp.handle_message(bin, message) - } - } - }; -); -box_bin_impl!(BinImpl); - -impl ObjectType for Bin { - const NAME: &'static str = "RsBin"; - type ParentType = gst::Bin; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut BinClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - BinClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn bin_add_element( - ptr: *mut gst_ffi::GstBin, - element: *mut gst_ffi::GstElement, -) -> glib_ffi::gboolean -where - T::ImplType: BinImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let bin = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = bin.get_impl(); - - panic_to_error!(&wrap, &bin.panicked(), false, { - imp.add_element(&wrap, &from_glib_borrow(element)) - }) - .to_glib() -} - -unsafe extern "C" fn bin_remove_element( - ptr: *mut gst_ffi::GstBin, - element: *mut gst_ffi::GstElement, -) -> glib_ffi::gboolean -where - T::ImplType: BinImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let bin = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = bin.get_impl(); - - panic_to_error!(&wrap, &bin.panicked(), false, { - imp.remove_element(&wrap, &from_glib_borrow(element)) - }) - .to_glib() -} - -unsafe extern "C" fn bin_handle_message( - ptr: *mut gst_ffi::GstBin, - message: *mut gst_ffi::GstMessage, -) where - T::ImplType: BinImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let bin = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = bin.get_impl(); - - panic_to_error!(&wrap, &bin.panicked(), (), { - imp.handle_message(&wrap, from_glib_full(message)) - }); -} diff --git a/gst-plugin/src/bytes.rs b/gst-plugin/src/bytes.rs deleted file mode 100644 index d16be1d1..00000000 --- a/gst-plugin/src/bytes.rs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; -use std::io; - -pub trait ReadBytesExtShort: io::Read { - fn read_u16le(&mut self) -> io::Result { - self.read_u16::() - } - fn read_i16le(&mut self) -> io::Result { - self.read_i16::() - } - fn read_u32le(&mut self) -> io::Result { - self.read_u32::() - } - fn read_i32le(&mut self) -> io::Result { - self.read_i32::() - } - fn read_u64le(&mut self) -> io::Result { - self.read_u64::() - } - fn read_i64le(&mut self) -> io::Result { - self.read_i64::() - } - fn read_uintle(&mut self, nbytes: usize) -> io::Result { - self.read_uint::(nbytes) - } - fn read_intle(&mut self, nbytes: usize) -> io::Result { - self.read_int::(nbytes) - } - fn read_f32le(&mut self) -> io::Result { - self.read_f32::() - } - fn read_f64le(&mut self) -> io::Result { - self.read_f64::() - } - fn read_u16be(&mut self) -> io::Result { - self.read_u16::() - } - fn read_i16be(&mut self) -> io::Result { - self.read_i16::() - } - fn read_u32be(&mut self) -> io::Result { - self.read_u32::() - } - fn read_i32be(&mut self) -> io::Result { - self.read_i32::() - } - fn read_u64be(&mut self) -> io::Result { - self.read_u64::() - } - fn read_i64be(&mut self) -> io::Result { - self.read_i64::() - } - fn read_uintbe(&mut self, nbytes: usize) -> io::Result { - self.read_uint::(nbytes) - } - fn read_intbe(&mut self, nbytes: usize) -> io::Result { - self.read_int::(nbytes) - } - fn read_f32be(&mut self) -> io::Result { - self.read_f32::() - } - fn read_f64be(&mut self) -> io::Result { - self.read_f64::() - } -} - -impl ReadBytesExtShort for T where T: ReadBytesExt {} - -pub trait WriteBytesExtShort: WriteBytesExt { - fn write_u16le(&mut self, n: u16) -> io::Result<()> { - self.write_u16::(n) - } - fn write_i16le(&mut self, n: i16) -> io::Result<()> { - self.write_i16::(n) - } - fn write_u32le(&mut self, n: u32) -> io::Result<()> { - self.write_u32::(n) - } - fn write_i32le(&mut self, n: i32) -> io::Result<()> { - self.write_i32::(n) - } - fn write_u64le(&mut self, n: u64) -> io::Result<()> { - self.write_u64::(n) - } - fn write_i64le(&mut self, n: i64) -> io::Result<()> { - self.write_i64::(n) - } - fn write_uintle(&mut self, n: u64, nbytes: usize) -> io::Result<()> { - self.write_uint::(n, nbytes) - } - fn write_intle(&mut self, n: i64, nbytes: usize) -> io::Result<()> { - self.write_int::(n, nbytes) - } - fn write_f32le(&mut self, n: f32) -> io::Result<()> { - self.write_f32::(n) - } - fn write_f64le(&mut self, n: f64) -> io::Result<()> { - self.write_f64::(n) - } - fn write_u16be(&mut self, n: u16) -> io::Result<()> { - self.write_u16::(n) - } - fn write_i16be(&mut self, n: i16) -> io::Result<()> { - self.write_i16::(n) - } - fn write_u32be(&mut self, n: u32) -> io::Result<()> { - self.write_u32::(n) - } - fn write_i32be(&mut self, n: i32) -> io::Result<()> { - self.write_i32::(n) - } - fn write_u64be(&mut self, n: u64) -> io::Result<()> { - self.write_u64::(n) - } - fn write_i64be(&mut self, n: i64) -> io::Result<()> { - self.write_i64::(n) - } - fn write_uintbe(&mut self, n: u64, nbytes: usize) -> io::Result<()> { - self.write_uint::(n, nbytes) - } - fn write_intbe(&mut self, n: i64, nbytes: usize) -> io::Result<()> { - self.write_int::(n, nbytes) - } - fn write_f32be(&mut self, n: f32) -> io::Result<()> { - self.write_f32::(n) - } - fn write_f64be(&mut self, n: f64) -> io::Result<()> { - self.write_f64::(n) - } -} - -impl WriteBytesExtShort for T where T: WriteBytesExt {} diff --git a/gst-plugin/src/child_proxy.rs b/gst-plugin/src/child_proxy.rs deleted file mode 100644 index 2218c102..00000000 --- a/gst-plugin/src/child_proxy.rs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2018 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use libc; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -pub trait ChildProxyImpl: AnyImpl + Send + Sync + 'static { - fn get_child_by_name(&self, object: &gst::ChildProxy, name: &str) -> Option { - unsafe { - let type_ = gst_ffi::gst_child_proxy_get_type(); - let iface = gobject_ffi::g_type_default_interface_ref(type_) - as *mut gst_ffi::GstChildProxyInterface; - assert!(!iface.is_null()); - - let ret = ((*iface).get_child_by_name.as_ref().unwrap())( - object.to_glib_none().0, - name.to_glib_none().0, - ); - - gobject_ffi::g_type_default_interface_unref(iface as glib_ffi::gpointer); - - from_glib_full(ret) - } - } - - fn get_child_by_index(&self, object: &gst::ChildProxy, index: u32) -> Option; - fn get_children_count(&self, object: &gst::ChildProxy) -> u32; - - fn child_added(&self, object: &gst::ChildProxy, child: &glib::Object, name: &str); - fn child_removed(&self, object: &gst::ChildProxy, child: &glib::Object, name: &str); -} - -any_impl!(ChildProxyImpl); - -pub trait ChildProxyImplStatic: Send + Sync + 'static { - fn get_impl<'a>(&self, imp: &'a T::ImplType) -> &'a ChildProxyImpl; -} - -struct ChildProxyStatic { - imp_static: *const ChildProxyImplStatic, -} - -unsafe extern "C" fn child_proxy_get_child_by_name( - child_proxy: *mut gst_ffi::GstChildProxy, - name: *const libc::c_char, -) -> *mut gobject_ffi::GObject { - floating_reference_guard!(child_proxy); - - let klass = &**(child_proxy as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_child_proxy_get_type()) - as *const ChildProxyStatic; - - let instance = &*(child_proxy as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.get_child_by_name( - &from_glib_borrow(child_proxy), - String::from_glib_none(name).as_str(), - ) - .to_glib_full() -} - -unsafe extern "C" fn child_proxy_get_child_by_index( - child_proxy: *mut gst_ffi::GstChildProxy, - index: u32, -) -> *mut gobject_ffi::GObject { - floating_reference_guard!(child_proxy); - - let klass = &**(child_proxy as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_child_proxy_get_type()) - as *const ChildProxyStatic; - - let instance = &*(child_proxy as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.get_child_by_index(&from_glib_borrow(child_proxy), index) - .to_glib_full() -} - -unsafe extern "C" fn child_proxy_get_children_count( - child_proxy: *mut gst_ffi::GstChildProxy, -) -> u32 { - floating_reference_guard!(child_proxy); - - let klass = &**(child_proxy as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_child_proxy_get_type()) - as *const ChildProxyStatic; - - let instance = &*(child_proxy as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.get_children_count(&from_glib_borrow(child_proxy)) -} - -unsafe extern "C" fn child_proxy_child_added( - child_proxy: *mut gst_ffi::GstChildProxy, - child: *mut gobject_ffi::GObject, - name: *const libc::c_char, -) { - floating_reference_guard!(child_proxy); - - let klass = &**(child_proxy as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_child_proxy_get_type()) - as *const ChildProxyStatic; - - let instance = &*(child_proxy as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.child_added( - &from_glib_borrow(child_proxy), - &from_glib_borrow(child), - String::from_glib_none(name).as_str(), - ) -} - -unsafe extern "C" fn child_proxy_child_removed( - child_proxy: *mut gst_ffi::GstChildProxy, - child: *mut gobject_ffi::GObject, - name: *const libc::c_char, -) { - floating_reference_guard!(child_proxy); - - let klass = &**(child_proxy as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_child_proxy_get_type()) - as *const ChildProxyStatic; - - let instance = &*(child_proxy as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.child_removed( - &from_glib_borrow(child_proxy), - &from_glib_borrow(child), - String::from_glib_none(name).as_str(), - ) -} - -unsafe extern "C" fn child_proxy_init( - iface: glib_ffi::gpointer, - iface_data: glib_ffi::gpointer, -) { - let child_proxy_iface = &mut *(iface as *mut gst_ffi::GstChildProxyInterface); - - let iface_type = (*(iface as *const gobject_ffi::GTypeInterface)).g_type; - let type_ = (*(iface as *const gobject_ffi::GTypeInterface)).g_instance_type; - let klass = &mut *(gobject_ffi::g_type_class_ref(type_) as *mut ClassStruct); - let interfaces_static = &mut *(klass.interfaces_static as *mut Vec<_>); - interfaces_static.push((iface_type, iface_data)); - - child_proxy_iface.get_child_by_name = Some(child_proxy_get_child_by_name::); - child_proxy_iface.get_child_by_index = Some(child_proxy_get_child_by_index::); - child_proxy_iface.get_children_count = Some(child_proxy_get_children_count::); - child_proxy_iface.child_added = Some(child_proxy_child_added::); - child_proxy_iface.child_removed = Some(child_proxy_child_removed::); -} - -pub fn register_child_proxy>( - _: &TypeInitToken, - type_: glib::Type, - imp: &I, -) { - unsafe { - let imp = imp as &ChildProxyImplStatic as *const ChildProxyImplStatic; - let interface_static = Box::new(ChildProxyStatic { imp_static: imp }); - - let iface_info = gobject_ffi::GInterfaceInfo { - interface_init: Some(child_proxy_init::), - interface_finalize: None, - interface_data: Box::into_raw(interface_static) as glib_ffi::gpointer, - }; - gobject_ffi::g_type_add_interface_static( - type_.to_glib(), - gst_ffi::gst_child_proxy_get_type(), - &iface_info, - ); - } -} diff --git a/gst-plugin/src/element.rs b/gst-plugin/src/element.rs deleted file mode 100644 index ba3c77fe..00000000 --- a/gst-plugin/src/element.rs +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::any::Any; -use std::mem; -use std::ptr; - -use libc; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use object::*; - -pub trait ElementImpl: ObjectImpl + AnyImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ - fn change_state(&self, element: &T, transition: gst::StateChange) -> gst::StateChangeReturn { - element.parent_change_state(transition) - } - - fn request_new_pad( - &self, - _element: &T, - _templ: &gst::PadTemplate, - _name: Option, - _caps: Option<&gst::CapsRef>, - ) -> Option { - None - } - - fn release_pad(&self, _element: &T, _pad: &gst::Pad) {} - - fn send_event(&self, element: &T, event: gst::Event) -> bool { - element.parent_send_event(event) - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - element.parent_query(query) - } - - fn set_context(&self, element: &T, context: &gst::Context) { - element.parent_set_context(context) - } -} - -pub trait ElementImplExt { - fn catch_panic_pad_function R, G: FnOnce() -> R>( - parent: &Option, - fallback: G, - f: F, - ) -> R; -} - -impl, T: ObjectType + glib::IsA + glib::IsA> - ElementImplExt for S -where - T::InstanceStructType: PanicPoison, -{ - fn catch_panic_pad_function R, G: FnOnce() -> R>( - parent: &Option, - fallback: G, - f: F, - ) -> R { - // FIXME: Does this work for element subclasses? - let element = parent.as_ref().unwrap().downcast_ref::().unwrap(); - let imp = element.get_impl(); - let imp = Any::downcast_ref:: + 'static>>(imp).unwrap(); - let imp = imp.downcast_ref::().unwrap(); - element.catch_panic(fallback, |element| f(imp, element)) - } -} - -any_impl!(ElementBase, ElementImpl, PanicPoison); - -pub unsafe trait ElementBase: IsA + ObjectType -where - Self::InstanceStructType: PanicPoison, -{ - fn parent_change_state(&self, transition: gst::StateChange) -> gst::StateChangeReturn { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstElementClass; - (*parent_klass) - .change_state - .map(|f| from_glib(f(self.to_glib_none().0, transition.to_glib()))) - .unwrap_or(gst::StateChangeReturn::Success) - } - } - - fn parent_send_event(&self, event: gst::Event) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstElementClass; - (*parent_klass) - .send_event - .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr()))) - .unwrap_or(false) - } - } - - fn parent_query(&self, query: &mut gst::QueryRef) -> bool { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstElementClass; - (*parent_klass) - .query - .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr()))) - .unwrap_or(false) - } - } - - fn parent_set_context(&self, context: &gst::Context) { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstElementClass; - (*parent_klass) - .set_context - .map(|f| f(self.to_glib_none().0, context.to_glib_none().0)) - .unwrap_or(()) - } - } - - fn catch_panic T, G: FnOnce() -> T>(&self, fallback: G, f: F) -> T { - let panicked = unsafe { &(*self.get_instance()).panicked() }; - panic_to_error!(self, panicked, fallback(), { f(self) }) - } -} - -pub unsafe trait ElementClassExt -where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - fn add_pad_template(&mut self, pad_template: gst::PadTemplate) { - unsafe { - gst_ffi::gst_element_class_add_pad_template( - self as *const Self as *mut gst_ffi::GstElementClass, - pad_template.to_glib_none().0, - ); - } - } - - fn set_metadata( - &mut self, - long_name: &str, - classification: &str, - description: &str, - author: &str, - ) { - unsafe { - gst_ffi::gst_element_class_set_metadata( - self as *const Self as *mut gst_ffi::GstElementClass, - long_name.to_glib_none().0, - classification.to_glib_none().0, - description.to_glib_none().0, - author.to_glib_none().0, - ); - } - } - - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_ffi::GstElementClass); - klass.change_state = Some(element_change_state::); - klass.request_new_pad = Some(element_request_new_pad::); - klass.release_pad = Some(element_release_pad::); - klass.send_event = Some(element_send_event::); - klass.query = Some(element_query::); - klass.set_context = Some(element_set_context::); - } - } -} - -glib_wrapper! { - pub struct Element(Object>): - [gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + ObjectType> ElementBase for T where - Self::InstanceStructType: PanicPoison -{ -} - -pub type ElementClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl ElementClassExt for ElementClass {} -unsafe impl ObjectClassExt for ElementClass {} - -unsafe impl Send for Element {} -unsafe impl Sync for Element {} - -#[macro_export] -macro_rules! box_element_impl( - ($name:ident) => { - box_object_impl!($name, PanicPoison); - - impl ElementImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - fn change_state( - &self, - element: &T, - transition: gst::StateChange, - ) -> gst::StateChangeReturn { - let imp: &$name = self.as_ref(); - imp.change_state(element, transition) - } - - fn request_new_pad(&self, element: &T, templ: &gst::PadTemplate, name: Option, caps: Option<&gst::CapsRef>) -> Option { - let imp: &$name = self.as_ref(); - imp.request_new_pad(element, templ, name, caps) - } - - fn release_pad(&self, element: &T, pad: &gst::Pad) { - let imp: &$name = self.as_ref(); - imp.release_pad(element, pad) - } - - fn send_event(&self, element: &T, event: gst::Event) -> bool { - let imp: &$name = self.as_ref(); - imp.send_event(element, event) - } - - fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); - ElementImpl::query(imp, element, query) - } - - fn set_context(&self, element: &T, context: &gst::Context) { - let imp: &$name = self.as_ref(); - imp.set_context(element, context) - } - } - }; -); - -box_element_impl!(ElementImpl); - -impl ObjectType for Element { - const NAME: &'static str = "RsElement"; - type ParentType = gst::Element; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut ElementClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn element_change_state( - ptr: *mut gst_ffi::GstElement, - transition: gst_ffi::GstStateChange, -) -> gst_ffi::GstStateChangeReturn -where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - // *Never* fail downwards state changes, this causes bugs in GStreamer - // and leads to crashes and deadlocks. - let transition = from_glib(transition); - let fallback = match transition { - gst::StateChange::PlayingToPaused - | gst::StateChange::PausedToReady - | gst::StateChange::ReadyToNull => gst::StateChangeReturn::Success, - _ => gst::StateChangeReturn::Failure, - }; - - panic_to_error!(&wrap, &element.panicked(), fallback, { - imp.change_state(&wrap, transition) - }) - .to_glib() -} - -unsafe extern "C" fn element_request_new_pad( - ptr: *mut gst_ffi::GstElement, - templ: *mut gst_ffi::GstPadTemplate, - name: *const libc::c_char, - caps: *const gst_ffi::GstCaps, -) -> *mut gst_ffi::GstPad -where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let caps = if caps.is_null() { - None - } else { - Some(gst::CapsRef::from_ptr(caps)) - }; - - // XXX: This is effectively unsafe but the best we can do - // See https://bugzilla.gnome.org/show_bug.cgi?id=791193 - let pad = panic_to_error!(&wrap, &element.panicked(), None, { - imp.request_new_pad(&wrap, &from_glib_borrow(templ), from_glib_none(name), caps) - }); - - // Ensure that the pad is owned by the element now, if a pad was returned - if let Some(ref pad) = pad { - assert_eq!( - pad.get_parent(), - Some(gst::Object::from_glib_borrow( - ptr as *mut gst_ffi::GstObject - )) - ); - } - - pad.to_glib_none().0 -} - -unsafe extern "C" fn element_release_pad( - ptr: *mut gst_ffi::GstElement, - pad: *mut gst_ffi::GstPad, -) where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), (), { - imp.release_pad(&wrap, &from_glib_borrow(pad)) - }) -} - -unsafe extern "C" fn element_send_event( - ptr: *mut gst_ffi::GstElement, - event: *mut gst_ffi::GstEvent, -) -> glib_ffi::gboolean -where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.send_event(&wrap, from_glib_full(event)) - }) - .to_glib() -} - -unsafe extern "C" fn element_query( - ptr: *mut gst_ffi::GstElement, - query: *mut gst_ffi::GstQuery, -) -> glib_ffi::gboolean -where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - let query = gst::QueryRef::from_mut_ptr(query); - - panic_to_error!(&wrap, &element.panicked(), false, { - imp.query(&wrap, query) - }) - .to_glib() -} - -unsafe extern "C" fn element_set_context( - ptr: *mut gst_ffi::GstElement, - context: *mut gst_ffi::GstContext, -) where - T::ImplType: ElementImpl, - T::InstanceStructType: PanicPoison, -{ - floating_reference_guard!(ptr); - let element = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = element.get_impl(); - - panic_to_error!(&wrap, &element.panicked(), (), { - imp.set_context(&wrap, &from_glib_borrow(context)) - }) -} diff --git a/gst-plugin/src/error.rs b/gst-plugin/src/error.rs deleted file mode 100644 index 4b70ac69..00000000 --- a/gst-plugin/src/error.rs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::error::Error; -use std::fmt::Error as FmtError; -use std::fmt::{Display, Formatter}; - -use gst; - -#[macro_export] -macro_rules! panic_to_error( - ($element:expr, $panicked:expr, $ret:expr, $code:block) => {{ - use std::panic::{self, AssertUnwindSafe}; - use std::sync::atomic::Ordering; - - if $panicked.load(Ordering::Relaxed) { - $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked"])); - $ret - } else { - let result = panic::catch_unwind(AssertUnwindSafe(|| $code)); - - match result { - Ok(result) => result, - Err(err) => { - $panicked.store(true, Ordering::Relaxed); - if let Some(cause) = err.downcast_ref::<&str>() { - $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked: {}", cause])); - } else if let Some(cause) = err.downcast_ref::() { - $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked: {}", cause])); - } else { - $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked"])); - } - $ret - } - } - } - }}; -); - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum FlowError { - Flushing, - Eos, - NotNegotiated(gst::ErrorMessage), - Error(gst::ErrorMessage), -} - -impl From for gst::FlowReturn { - fn from(err: FlowError) -> Self { - gst::FlowReturn::from(&err) - } -} - -impl<'a> From<&'a FlowError> for gst::FlowReturn { - fn from(err: &FlowError) -> gst::FlowReturn { - match *err { - FlowError::Flushing => gst::FlowReturn::Flushing, - FlowError::Eos => gst::FlowReturn::Eos, - FlowError::NotNegotiated(..) => gst::FlowReturn::NotNegotiated, - FlowError::Error(..) => gst::FlowReturn::Error, - } - } -} - -impl Display for FlowError { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - match *self { - FlowError::Flushing | FlowError::Eos => f.write_str(self.description()), - FlowError::NotNegotiated(ref m) => { - f.write_fmt(format_args!("{}: {}", self.description(), m)) - } - FlowError::Error(ref m) => f.write_fmt(format_args!("{}: {}", self.description(), m)), - } - } -} - -impl Error for FlowError { - fn description(&self) -> &str { - match *self { - FlowError::Flushing => "Flushing", - FlowError::Eos => "Eos", - FlowError::NotNegotiated(..) => "Not Negotiated", - FlowError::Error(..) => "Error", - } - } -} diff --git a/gst-plugin/src/ghost_pad.rs b/gst-plugin/src/ghost_pad.rs deleted file mode 100644 index 9679b718..00000000 --- a/gst-plugin/src/ghost_pad.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2018 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use pad::*; - -pub trait GhostPadImpl: - AnyImpl + ObjectImpl + PadImpl + Send + Sync + 'static -{ -} - -any_impl!(GhostPadBase, GhostPadImpl); - -pub unsafe trait GhostPadBase: IsA + IsA + ObjectType {} - -pub unsafe trait GhostPadClassExt -where - T::ImplType: GhostPadImpl, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) {} -} - -glib_wrapper! { - pub struct GhostPad(Object>): - [gst::GhostPad => gst_ffi::GstGhostPad, - gst::ProxyPad => gst_ffi::GstProxyPad, - gst::Pad => gst_ffi::GstPad, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + ObjectType> GhostPadBase for T {} -pub type GhostPadClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl GhostPadClassExt for GhostPadClass {} -unsafe impl PadClassExt for GhostPadClass {} -unsafe impl ObjectClassExt for GhostPadClass {} - -unsafe impl Send for GhostPad {} -unsafe impl Sync for GhostPad {} - -#[macro_export] -macro_rules! box_ghost_pad_impl( - ($name:ident) => { - box_pad_impl!($name); - - impl GhostPadImpl for Box<$name> - { - } - }; -); -box_ghost_pad_impl!(GhostPadImpl); - -impl ObjectType for GhostPad { - const NAME: &'static str = "RsGhostPad"; - type ParentType = gst::GhostPad; - type ImplType = Box>; - type InstanceStructType = InstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut GhostPadClass) { - ObjectClassExt::override_vfuncs(klass, token); - PadClassExt::override_vfuncs(klass, token); - GhostPadClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} diff --git a/gst-plugin/src/lib.rs b/gst-plugin/src/lib.rs deleted file mode 100644 index 49d08125..00000000 --- a/gst-plugin/src/lib.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// 2016 Luis de Bethencourt -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -#![cfg_attr(feature = "cargo-clippy", allow(cast_ptr_alignment))] - -extern crate byteorder; - -pub extern crate glib_sys as glib_ffi; -pub extern crate gobject_sys as gobject_ffi; -extern crate gstreamer_base_sys as gst_base_ffi; -pub extern crate gstreamer_sys as gst_ffi; - -#[macro_use] -extern crate lazy_static; -extern crate libc; - -#[macro_use] -pub extern crate glib; -#[macro_use] -pub extern crate gstreamer as gst; -extern crate gstreamer_base as gst_base; - -#[macro_use] -extern crate gobject_subclass; - -pub mod object; - -#[macro_use] -pub mod error; -pub mod adapter; -#[macro_use] -pub mod plugin; -pub mod bytes; - -#[macro_use] -pub mod element; -#[macro_use] -pub mod bin; -#[macro_use] -pub mod pipeline; -#[macro_use] -pub mod base_src; -#[macro_use] -pub mod base_sink; -#[macro_use] -pub mod base_transform; -#[cfg(any(feature = "v1_14", feature = "dox"))] -#[macro_use] -pub mod aggregator; - -#[macro_use] -pub mod pad; -#[macro_use] -pub mod ghost_pad; -#[cfg(any(feature = "v1_14", feature = "dox"))] -#[macro_use] -pub mod aggregator_pad; - -pub mod child_proxy; -pub mod uri_handler; diff --git a/gst-plugin/src/object.rs b/gst-plugin/src/object.rs deleted file mode 100644 index 293903ff..00000000 --- a/gst-plugin/src/object.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::ptr; -use std::sync::atomic::AtomicBool; - -use glib::wrapper::Wrapper; -use gobject_subclass::object::*; - -#[repr(C)] -pub struct ElementInstanceStruct { - _parent: ::GlibType, - _imp: ptr::NonNull, - - _panicked: AtomicBool, -} - -pub trait PanicPoison { - fn panicked(&self) -> &AtomicBool; -} - -unsafe impl Instance for ElementInstanceStruct { - fn parent(&self) -> &::GlibType { - &self._parent - } - - fn get_impl(&self) -> &T::ImplType { - unsafe { self._imp.as_ref() } - } - - unsafe fn set_impl(&mut self, imp: ptr::NonNull) { - self._imp = imp; - } - - unsafe fn get_class(&self) -> *const ClassStruct { - *(self as *const _ as *const *const ClassStruct) - } -} - -impl PanicPoison for ElementInstanceStruct { - fn panicked(&self) -> &AtomicBool { - &self._panicked - } -} diff --git a/gst-plugin/src/pad.rs b/gst-plugin/src/pad.rs deleted file mode 100644 index 1ddbc1a9..00000000 --- a/gst-plugin/src/pad.rs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2018 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -pub trait PadImpl: AnyImpl + ObjectImpl + Send + Sync + 'static { - fn linked(&self, pad: &T, peer: &gst::Pad) { - pad.parent_linked(peer) - } - - fn unlinked(&self, pad: &T, peer: &gst::Pad) { - pad.parent_unlinked(peer) - } -} - -any_impl!(PadBase, PadImpl); - -pub unsafe trait PadBase: IsA + ObjectType { - fn parent_linked(&self, peer: &gst::Pad) { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass; - (*parent_klass) - .linked - .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0)) - .unwrap_or(()) - } - } - - fn parent_unlinked(&self, peer: &gst::Pad) { - unsafe { - let klass = self.get_class(); - let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass; - (*parent_klass) - .unlinked - .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0)) - .unwrap_or(()) - } - } -} - -pub unsafe trait PadClassExt -where - T::ImplType: PadImpl, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) { - unsafe { - let klass = &mut *(self as *const Self as *mut gst_ffi::GstPadClass); - klass.linked = Some(pad_linked::); - klass.unlinked = Some(pad_unlinked::); - } - } -} - -glib_wrapper! { - pub struct Pad(Object>): - [gst::Pad => gst_ffi::GstPad, - gst::Object => gst_ffi::GstObject]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + ObjectType> PadBase for T {} -pub type PadClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl PadClassExt for PadClass {} -unsafe impl ObjectClassExt for PadClass {} - -unsafe impl Send for Pad {} -unsafe impl Sync for Pad {} - -#[macro_export] -macro_rules! box_pad_impl( - ($name:ident) => { - box_object_impl!($name); - - impl PadImpl for Box<$name> - { - fn linked(&self, pad: &T, peer: &gst::Pad) { - let imp: &$name = self.as_ref(); - imp.linked(pad, peer) - } - - fn unlinked(&self, pad: &T, peer: &gst::Pad) { - let imp: &$name = self.as_ref(); - imp.unlinked(pad, peer) - } - } - }; -); -box_pad_impl!(PadImpl); - -impl ObjectType for Pad { - const NAME: &'static str = "RsPad"; - type ParentType = gst::Pad; - type ImplType = Box>; - type InstanceStructType = InstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut PadClass) { - ObjectClassExt::override_vfuncs(klass, token); - PadClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} - -unsafe extern "C" fn pad_linked(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad) -where - T::ImplType: PadImpl, -{ - floating_reference_guard!(ptr); - let pad = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = pad.get_impl(); - - imp.linked(&wrap, &from_glib_borrow(peer)) -} - -unsafe extern "C" fn pad_unlinked(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad) -where - T::ImplType: PadImpl, -{ - floating_reference_guard!(ptr); - let pad = &*(ptr as *mut T::InstanceStructType); - let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); - let imp = pad.get_impl(); - - imp.unlinked(&wrap, &from_glib_borrow(peer)) -} diff --git a/gst-plugin/src/pipeline.rs b/gst-plugin/src/pipeline.rs deleted file mode 100644 index 813ecec4..00000000 --- a/gst-plugin/src/pipeline.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use gst::prelude::*; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -use bin::*; -use element::*; -use object::*; - -pub trait PipelineImpl: - AnyImpl + ObjectImpl + ElementImpl + BinImpl + Send + Sync + 'static -where - T::InstanceStructType: PanicPoison, -{ -} - -any_impl!(PipelineBase, PipelineImpl, PanicPoison); - -pub unsafe trait PipelineBase: - IsA + IsA + IsA + ObjectType -{ -} - -pub unsafe trait PipelineClassExt -where - T::ImplType: PipelineImpl, - T::InstanceStructType: PanicPoison, -{ - fn override_vfuncs(&mut self, _: &ClassInitToken) {} -} - -glib_wrapper! { - pub struct Pipeline(Object>): - [gst::Pipeline => gst_ffi::GstPipeline, - gst::Bin => gst_ffi::GstBin, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject, - gst::ChildProxy => gst_ffi::GstChildProxy]; - - match fn { - get_type => || get_type::(), - } -} - -unsafe impl + IsA + IsA + ObjectType> PipelineBase - for T -{ -} -pub type PipelineClass = ClassStruct; - -// FIXME: Boilerplate -unsafe impl PipelineClassExt for PipelineClass {} -unsafe impl BinClassExt for PipelineClass {} -unsafe impl ElementClassExt for PipelineClass {} -unsafe impl ObjectClassExt for PipelineClass {} - -unsafe impl Send for Pipeline {} -unsafe impl Sync for Pipeline {} - -#[macro_export] -macro_rules! box_pipeline_impl( - ($name:ident) => { - box_bin_impl!($name); - - impl PipelineImpl for Box<$name> - where - T::InstanceStructType: PanicPoison - { - } - }; -); -box_pipeline_impl!(PipelineImpl); - -impl ObjectType for Pipeline { - const NAME: &'static str = "RsPipeline"; - type ParentType = gst::Pipeline; - type ImplType = Box>; - type InstanceStructType = ElementInstanceStruct; - - fn class_init(token: &ClassInitToken, klass: &mut PipelineClass) { - ObjectClassExt::override_vfuncs(klass, token); - ElementClassExt::override_vfuncs(klass, token); - BinClassExt::override_vfuncs(klass, token); - PipelineClassExt::override_vfuncs(klass, token); - } - - object_type_fns!(); -} diff --git a/gst-plugin/src/plugin.rs b/gst-plugin/src/plugin.rs deleted file mode 100644 index 8ed213b1..00000000 --- a/gst-plugin/src/plugin.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2016-2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[macro_export] -macro_rules! plugin_define( - ($name:expr, $description:expr, $plugin_init:ident, - $version:expr, $license:expr, $source:expr, - $package:expr, $origin:expr, $release_datetime:expr) => { - pub mod plugin_desc { - use $crate::glib::translate::{from_glib_borrow, ToGlib, from_glib}; - - const MAJOR_VERSION: i32 = 1; - const MINOR_VERSION: i32 = 8; - - // Not using c_char here because it requires the libc crate - #[allow(non_camel_case_types)] - type c_char = i8; - - #[repr(C)] - pub struct GstPluginDesc($crate::gst_ffi::GstPluginDesc); - unsafe impl Sync for GstPluginDesc {} - - #[no_mangle] - #[allow(non_upper_case_globals)] - pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc($crate::gst_ffi::GstPluginDesc { - major_version: MAJOR_VERSION, - minor_version: MINOR_VERSION, - name: $name as *const u8 as *const c_char, - description: $description as *const u8 as *const c_char, - plugin_init: Some(plugin_init_trampoline), - version: $version as *const u8 as *const c_char, - license: $license as *const u8 as *const c_char, - source: $source as *const u8 as *const c_char, - package: $package as *const u8 as *const c_char, - origin: $origin as *const u8 as *const c_char, - release_datetime: $release_datetime as *const u8 as *const c_char, - _gst_reserved: [0 as $crate::glib_ffi::gpointer; 4], - }); - - pub fn plugin_register_static() -> bool { - unsafe { - from_glib($crate::gst_ffi::gst_plugin_register_static( - MAJOR_VERSION, - MINOR_VERSION, - $name as *const u8 as *const c_char, - $description as *const u8 as *const c_char, - Some(plugin_init_trampoline), - $version as *const u8 as *const c_char, - $license as *const u8 as *const c_char, - $source as *const u8 as *const c_char, - $package as *const u8 as *const c_char, - $origin as *const u8 as *const c_char, - )) - } - } - - unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::gst_ffi::GstPlugin) -> $crate::glib_ffi::gboolean { - use std::panic::{self, AssertUnwindSafe}; - - let panic_result = panic::catch_unwind(AssertUnwindSafe(|| super::$plugin_init(&from_glib_borrow(plugin)))); - match panic_result { - Ok(register_result) => match register_result { - Ok(_) => $crate::glib_ffi::GTRUE, - Err(err) => { - let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap(); - gst_error!(cat, "Failed to register plugin: {}", err); - $crate::glib_ffi::GFALSE - } - } - Err(err) => { - let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap(); - if let Some(cause) = err.downcast_ref::<&str>() { - gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause); - } else if let Some(cause) = err.downcast_ref::() { - gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause); - } else { - gst_error!(cat, "Failed to initialize plugin due to panic"); - } - - $crate::glib_ffi::GFALSE - } - } - } - } - pub use plugin_desc::plugin_register_static; - }; -); diff --git a/gst-plugin/src/uri_handler.rs b/gst-plugin/src/uri_handler.rs deleted file mode 100644 index 07abd615..00000000 --- a/gst-plugin/src/uri_handler.rs +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -use std::ptr; - -use glib_ffi; -use gobject_ffi; -use gst_ffi; - -use glib; -use glib::translate::*; -use gst; -use libc; - -use gobject_subclass::anyimpl::*; -use gobject_subclass::object::*; - -pub trait URIHandlerImpl: AnyImpl + Send + Sync + 'static { - fn get_uri(&self, element: &gst::URIHandler) -> Option; - fn set_uri(&self, element: &gst::URIHandler, uri: Option) -> Result<(), glib::Error>; -} - -any_impl!(URIHandlerImpl); - -pub trait URIHandlerImplStatic: Send + Sync + 'static { - fn get_impl<'a>(&self, imp: &'a T::ImplType) -> &'a URIHandlerImpl; - fn get_type(&self) -> gst::URIType; - fn get_protocols(&self) -> Vec; -} - -struct URIHandlerStatic { - imp_static: *const URIHandlerImplStatic, - protocols: *const Vec<*const libc::c_char>, -} - -unsafe extern "C" fn uri_handler_get_type( - type_: glib_ffi::GType, -) -> gst_ffi::GstURIType { - let klass = gobject_ffi::g_type_class_peek(type_); - let klass = &*(klass as *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) - as *const URIHandlerStatic; - (*(*interface_static).imp_static).get_type().to_glib() -} - -unsafe extern "C" fn uri_handler_get_protocols( - type_: glib_ffi::GType, -) -> *const *const libc::c_char { - let klass = gobject_ffi::g_type_class_peek(type_); - let klass = &*(klass as *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) - as *const URIHandlerStatic; - (*(*interface_static).protocols).as_ptr() -} - -unsafe extern "C" fn uri_handler_get_uri( - uri_handler: *mut gst_ffi::GstURIHandler, -) -> *mut libc::c_char { - floating_reference_guard!(uri_handler); - - let klass = &**(uri_handler as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) - as *const URIHandlerStatic; - - let instance = &*(uri_handler as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - imp.get_uri(&from_glib_borrow(uri_handler)).to_glib_full() -} - -unsafe extern "C" fn uri_handler_set_uri( - uri_handler: *mut gst_ffi::GstURIHandler, - uri: *const libc::c_char, - err: *mut *mut glib_ffi::GError, -) -> glib_ffi::gboolean { - floating_reference_guard!(uri_handler); - - let klass = &**(uri_handler as *const *const ClassStruct); - let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) - as *const URIHandlerStatic; - - let instance = &*(uri_handler as *const T::InstanceStructType); - let imp = instance.get_impl(); - let imp = (*(*interface_static).imp_static).get_impl(imp); - - match imp.set_uri(&from_glib_borrow(uri_handler), from_glib_none(uri)) { - Ok(()) => true.to_glib(), - Err(error) => { - *err = error.to_glib_full() as *mut _; - false.to_glib() - } - } -} - -unsafe extern "C" fn uri_handler_init( - iface: glib_ffi::gpointer, - iface_data: glib_ffi::gpointer, -) { - let uri_handler_iface = &mut *(iface as *mut gst_ffi::GstURIHandlerInterface); - - let iface_type = (*(iface as *const gobject_ffi::GTypeInterface)).g_type; - let type_ = (*(iface as *const gobject_ffi::GTypeInterface)).g_instance_type; - let klass = &mut *(gobject_ffi::g_type_class_ref(type_) as *mut ClassStruct); - let interfaces_static = &mut *(klass.interfaces_static as *mut Vec<_>); - interfaces_static.push((iface_type, iface_data)); - - uri_handler_iface.get_type = Some(uri_handler_get_type::); - uri_handler_iface.get_protocols = Some(uri_handler_get_protocols::); - uri_handler_iface.get_uri = Some(uri_handler_get_uri::); - uri_handler_iface.set_uri = Some(uri_handler_set_uri::); -} - -pub fn register_uri_handler>( - _: &TypeInitToken, - type_: glib::Type, - imp: &I, -) { - unsafe { - let mut protocols: Vec<_> = imp - .get_protocols() - .iter() - .map(|s| s.to_glib_full()) - .collect(); - protocols.push(ptr::null()); - - let imp = imp as &URIHandlerImplStatic as *const URIHandlerImplStatic; - let interface_static = Box::new(URIHandlerStatic { - imp_static: imp, - protocols: Box::into_raw(Box::new(protocols)), - }); - - let iface_info = gobject_ffi::GInterfaceInfo { - interface_init: Some(uri_handler_init::), - interface_finalize: None, - interface_data: Box::into_raw(interface_static) as glib_ffi::gpointer, - }; - gobject_ffi::g_type_add_interface_static( - type_.to_glib(), - gst_ffi::gst_uri_handler_get_type(), - &iface_info, - ); - } -}