diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2020-11-15 16:50:12 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2020-11-15 19:50:31 +0300 |
commit | 717477fd36f00c5f1b8dbb64ec4dadc602d5fc22 (patch) | |
tree | 7387cf91d55c71afa125a6891579045fa6de5197 /video/closedcaption | |
parent | b021a8bf100bbd7bbb35c28a7fc9fff78afad28f (diff) |
video: Update for subclassing API changes
Diffstat (limited to 'video/closedcaption')
-rw-r--r-- | video/closedcaption/src/caption_frame.rs | 2 | ||||
-rw-r--r-- | video/closedcaption/src/ccdetect/imp.rs (renamed from video/closedcaption/src/ccdetect.rs) | 28 | ||||
-rw-r--r-- | video/closedcaption/src/ccdetect/mod.rs | 38 | ||||
-rw-r--r-- | video/closedcaption/src/cea608overlay/imp.rs (renamed from video/closedcaption/src/cea608overlay.rs) | 45 | ||||
-rw-r--r-- | video/closedcaption/src/cea608overlay/mod.rs | 44 | ||||
-rw-r--r-- | video/closedcaption/src/cea608tott/imp.rs (renamed from video/closedcaption/src/cea608tott.rs) | 30 | ||||
-rw-r--r-- | video/closedcaption/src/cea608tott/mod.rs | 29 | ||||
-rw-r--r-- | video/closedcaption/src/ffi.rs (renamed from video/closedcaption/src/cea608tott_ffi.rs) | 0 | ||||
-rw-r--r-- | video/closedcaption/src/lib.rs | 16 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_enc/headers.rs (renamed from video/closedcaption/src/mcc_enc_headers.rs) | 0 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_enc/imp.rs (renamed from video/closedcaption/src/mcc_enc.rs) | 48 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_enc/mod.rs | 39 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_parse/imp.rs (renamed from video/closedcaption/src/mcc_parse.rs) | 70 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_parse/mod.rs | 39 | ||||
-rw-r--r-- | video/closedcaption/src/mcc_parse/parser.rs (renamed from video/closedcaption/src/mcc_parser.rs) | 2 | ||||
-rw-r--r-- | video/closedcaption/src/scc_enc/imp.rs (renamed from video/closedcaption/src/scc_enc.rs) | 43 | ||||
-rw-r--r-- | video/closedcaption/src/scc_enc/mod.rs | 39 | ||||
-rw-r--r-- | video/closedcaption/src/scc_parse/imp.rs (renamed from video/closedcaption/src/scc_parse.rs) | 51 | ||||
-rw-r--r-- | video/closedcaption/src/scc_parse/mod.rs | 40 | ||||
-rw-r--r-- | video/closedcaption/src/scc_parse/parser.rs (renamed from video/closedcaption/src/scc_parser.rs) | 2 | ||||
-rw-r--r-- | video/closedcaption/src/tttocea608/imp.rs (renamed from video/closedcaption/src/tttocea608.rs) | 55 | ||||
-rw-r--r-- | video/closedcaption/src/tttocea608/mod.rs | 49 |
22 files changed, 479 insertions, 230 deletions
diff --git a/video/closedcaption/src/caption_frame.rs b/video/closedcaption/src/caption_frame.rs index ac5aad5df..724757500 100644 --- a/video/closedcaption/src/caption_frame.rs +++ b/video/closedcaption/src/caption_frame.rs @@ -6,7 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::cea608tott_ffi as ffi; +use super::ffi; use std::mem; #[derive(Copy, Clone, Debug)] diff --git a/video/closedcaption/src/ccdetect.rs b/video/closedcaption/src/ccdetect/imp.rs index 6c51c538d..488c1b16e 100644 --- a/video/closedcaption/src/ccdetect.rs +++ b/video/closedcaption/src/ccdetect/imp.rs @@ -69,7 +69,7 @@ struct State { last_cc708_change: gst::ClockTime, } -struct CCDetect { +pub struct CCDetect { settings: Mutex<Settings>, state: Mutex<Option<State>>, } @@ -321,7 +321,7 @@ impl CCDetect { fn maybe_update_properties( &self, - element: &gst_base::BaseTransform, + element: &super::CCDetect, ts: gst::ClockTime, cc_packet: CCPacketContents, ) -> Result<(), gst::FlowError> { @@ -382,6 +382,7 @@ impl CCDetect { impl ObjectSubclass for CCDetect { const NAME: &'static str = "CCDetect"; + type Type = super::CCDetect; type ParentType = gst_base::BaseTransform; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; @@ -395,7 +396,7 @@ impl ObjectSubclass for CCDetect { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Closed Caption Detect", "Filter/Video/ClosedCaption/Detect", @@ -441,7 +442,7 @@ impl ObjectSubclass for CCDetect { } impl ObjectImpl for CCDetect { - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { @@ -453,7 +454,7 @@ impl ObjectImpl for CCDetect { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result<glib::Value, ()> { let prop = &PROPERTIES[id]; match *prop { @@ -479,7 +480,7 @@ impl ElementImpl for CCDetect {} impl BaseTransformImpl for CCDetect { fn transform_ip_passthrough( &self, - element: &gst_base::BaseTransform, + element: &Self::Type, buf: &gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { let map = buf.map_readable().map_err(|_| gst::FlowError::Error)?; @@ -517,7 +518,7 @@ impl BaseTransformImpl for CCDetect { Ok(gst::FlowSuccess::Ok) } - fn sink_event(&self, element: &gst_base::BaseTransform, event: gst::Event) -> bool { + fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool { match event.view() { gst::event::EventView::Gap(gap) => { let _ = self.maybe_update_properties( @@ -536,7 +537,7 @@ impl BaseTransformImpl for CCDetect { fn set_caps( &self, - _element: &gst_base::BaseTransform, + _element: &Self::Type, incaps: &gst::Caps, outcaps: &gst::Caps, ) -> Result<(), gst::LoggableError> { @@ -569,19 +570,10 @@ impl BaseTransformImpl for CCDetect { Ok(()) } - fn stop(&self, _element: &gst_base::BaseTransform) -> Result<(), gst::ErrorMessage> { + fn stop(&self, _element: &Self::Type) -> Result<(), gst::ErrorMessage> { // Drop state let _ = self.state.lock().unwrap().take(); Ok(()) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "ccdetect", - gst::Rank::None, - CCDetect::get_type(), - ) -} diff --git a/video/closedcaption/src/ccdetect/mod.rs b/video/closedcaption/src/ccdetect/mod.rs new file mode 100644 index 000000000..11a82b86b --- /dev/null +++ b/video/closedcaption/src/ccdetect/mod.rs @@ -0,0 +1,38 @@ +// Copyright (C) 2020 Matthew Waters <matthew@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct CCDetect(ObjectSubclass<imp::CCDetect>) @extends gst_base::BaseTransform, gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for CCDetect {} +unsafe impl Sync for CCDetect {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "ccdetect", + gst::Rank::None, + CCDetect::static_type(), + ) +} diff --git a/video/closedcaption/src/cea608overlay.rs b/video/closedcaption/src/cea608overlay/imp.rs index 0df857c78..e55c16c8c 100644 --- a/video/closedcaption/src/cea608overlay.rs +++ b/video/closedcaption/src/cea608overlay/imp.rs @@ -15,13 +15,6 @@ // Free Software Foundation, Inc., 51 Franklin Street, Suite 500, // Boston, MA 02110-1335, USA. -// Example command-line: -// -// gst-launch-1.0 cccombiner name=ccc ! cea608overlay ! autovideosink \ -// videotestsrc ! video/x-raw, width=1280, height=720 ! queue ! ccc.sink \ -// filesrc location=input.srt ! subparse ! tttocea608 ! queue ! ccc.caption - -use glib::prelude::*; use glib::subclass; use glib::subclass::prelude::*; use gst::prelude::*; @@ -68,7 +61,7 @@ impl Default for State { unsafe impl Send for State {} -struct Cea608Overlay { +pub struct Cea608Overlay { srcpad: gst::Pad, sinkpad: gst::Pad, state: Mutex<State>, @@ -86,7 +79,7 @@ impl Cea608Overlay { // TODO: switch to the API presented in this post once it's been exposed fn recalculate_layout( &self, - element: &gst::Element, + element: &super::Cea608Overlay, state: &mut State, ) -> Result<gst::FlowSuccess, gst::FlowError> { let video_info = state.video_info.as_ref().unwrap(); @@ -242,7 +235,7 @@ impl Cea608Overlay { fn negotiate( &self, - element: &gst::Element, + element: &super::Cea608Overlay, state: &mut State, ) -> Result<gst::FlowSuccess, gst::FlowError> { let video_info = match state.video_info.as_ref() { @@ -294,7 +287,7 @@ impl Cea608Overlay { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::Cea608Overlay, mut buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -358,7 +351,12 @@ impl Cea608Overlay { self.srcpad.push(buffer) } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event( + &self, + pad: &gst::Pad, + element: &super::Cea608Overlay, + event: gst::Event, + ) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -388,13 +386,14 @@ impl Cea608Overlay { impl ObjectSubclass for Cea608Overlay { const NAME: &'static str = "RsCea608Overlay"; + type Type = super::Cea608Overlay; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -426,7 +425,7 @@ impl ObjectSubclass for Cea608Overlay { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Cea 608 overlay", "Video/Overlay/Subtitle", @@ -460,19 +459,18 @@ impl ObjectSubclass for Cea608Overlay { } impl ObjectImpl for Cea608Overlay { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for Cea608Overlay { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -489,12 +487,3 @@ impl ElementImpl for Cea608Overlay { self.parent_change_state(element, transition) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "cea608overlay", - gst::Rank::Primary, - Cea608Overlay::get_type(), - ) -} diff --git a/video/closedcaption/src/cea608overlay/mod.rs b/video/closedcaption/src/cea608overlay/mod.rs new file mode 100644 index 000000000..54669bf3e --- /dev/null +++ b/video/closedcaption/src/cea608overlay/mod.rs @@ -0,0 +1,44 @@ +// Copyright (C) 2020 Mathieu Duponchelle <mathieu@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +// Example command-line: +// +// gst-launch-1.0 cccombiner name=ccc ! cea608overlay ! autovideosink \ +// videotestsrc ! video/x-raw, width=1280, height=720 ! queue ! ccc.sink \ +// filesrc location=input.srt ! subparse ! tttocea608 ! queue ! ccc.caption + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct Cea608Overlay(ObjectSubclass<imp::Cea608Overlay>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for Cea608Overlay {} +unsafe impl Sync for Cea608Overlay {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "cea608overlay", + gst::Rank::Primary, + Cea608Overlay::static_type(), + ) +} diff --git a/video/closedcaption/src/cea608tott.rs b/video/closedcaption/src/cea608tott/imp.rs index edcb8002f..6dbc36ace 100644 --- a/video/closedcaption/src/cea608tott.rs +++ b/video/closedcaption/src/cea608tott/imp.rs @@ -6,7 +6,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use glib::prelude::*; use glib::subclass; use glib::subclass::prelude::*; use gst::prelude::*; @@ -42,7 +41,7 @@ impl Default for State { } } -struct Cea608ToTt { +pub struct Cea608ToTt { srcpad: gst::Pad, sinkpad: gst::Pad, @@ -61,7 +60,7 @@ impl Cea608ToTt { fn sink_chain( &self, pad: &gst::Pad, - _element: &gst::Element, + _element: &super::Cea608ToTt, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -271,7 +270,7 @@ impl Cea608ToTt { buffer } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::Cea608ToTt, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -371,13 +370,14 @@ impl Cea608ToTt { impl ObjectSubclass for Cea608ToTt { const NAME: &'static str = "Cea608ToTt"; + type Type = super::Cea608ToTt; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -409,7 +409,7 @@ impl ObjectSubclass for Cea608ToTt { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "CEA-608 to TT", "Generic", @@ -461,19 +461,18 @@ impl ObjectSubclass for Cea608ToTt { } impl ObjectImpl for Cea608ToTt { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for Cea608ToTt { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -499,12 +498,3 @@ impl ElementImpl for Cea608ToTt { Ok(ret) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "cea608tott", - gst::Rank::None, - Cea608ToTt::get_type(), - ) -} diff --git a/video/closedcaption/src/cea608tott/mod.rs b/video/closedcaption/src/cea608tott/mod.rs new file mode 100644 index 000000000..51b23dc8a --- /dev/null +++ b/video/closedcaption/src/cea608tott/mod.rs @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Sebastian Dröge <sebastian@centricular.com> +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct Cea608ToTt(ObjectSubclass<imp::Cea608ToTt>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for Cea608ToTt {} +unsafe impl Sync for Cea608ToTt {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "cea608tott", + gst::Rank::None, + Cea608ToTt::static_type(), + ) +} diff --git a/video/closedcaption/src/cea608tott_ffi.rs b/video/closedcaption/src/ffi.rs index a59e87fca..a59e87fca 100644 --- a/video/closedcaption/src/cea608tott_ffi.rs +++ b/video/closedcaption/src/ffi.rs diff --git a/video/closedcaption/src/lib.rs b/video/closedcaption/src/lib.rs index 9ba22abf8..65690d40c 100644 --- a/video/closedcaption/src/lib.rs +++ b/video/closedcaption/src/lib.rs @@ -17,11 +17,6 @@ #![recursion_limit = "128"] -// These macros are in weird paths currently, -// and extern crate is used to avoid the explicit imports -// should not be needed ideally in the upcoming releases. -// https://github.com/gtk-rs/glib/issues/420 -// https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/issues/170 #[macro_use] extern crate glib; #[macro_use] @@ -33,21 +28,20 @@ extern crate lazy_static; #[macro_use] extern crate pretty_assertions; +#[allow(non_camel_case_types, non_upper_case_globals, unused)] +#[allow(clippy::redundant_static_lifetimes, clippy::unreadable_literal)] +#[allow(clippy::useless_transmute, clippy::trivially_copy_pass_by_ref)] +mod ffi; + mod caption_frame; mod ccdetect; mod cea608overlay; mod cea608tott; -#[allow(non_camel_case_types, non_upper_case_globals)] -#[allow(clippy::redundant_static_lifetimes, clippy::unreadable_literal)] -#[allow(clippy::useless_transmute, clippy::trivially_copy_pass_by_ref)] -pub mod cea608tott_ffi; mod line_reader; mod mcc_enc; mod mcc_parse; -mod mcc_parser; mod scc_enc; mod scc_parse; -mod scc_parser; mod tttocea608; fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { diff --git a/video/closedcaption/src/mcc_enc_headers.rs b/video/closedcaption/src/mcc_enc/headers.rs index 6995c99c3..6995c99c3 100644 --- a/video/closedcaption/src/mcc_enc_headers.rs +++ b/video/closedcaption/src/mcc_enc/headers.rs diff --git a/video/closedcaption/src/mcc_enc.rs b/video/closedcaption/src/mcc_enc/imp.rs index 6acfb3aab..9dac0fe28 100644 --- a/video/closedcaption/src/mcc_enc.rs +++ b/video/closedcaption/src/mcc_enc/imp.rs @@ -28,9 +28,7 @@ use uuid::Uuid; use std::io::Write; use std::sync::Mutex; -#[path = "mcc_enc_headers.rs"] -mod mcc_enc_headers; -use self::mcc_enc_headers::*; +use super::headers::*; #[derive(Clone, Copy, Debug, PartialEq, Eq)] enum Format { @@ -89,7 +87,7 @@ static PROPERTIES: [subclass::Property; 2] = [ }), ]; -struct MccEnc { +pub struct MccEnc { srcpad: gst::Pad, sinkpad: gst::Pad, state: Mutex<State>, @@ -291,7 +289,7 @@ impl MccEnc { fn generate_caption( &self, - element: &gst::Element, + element: &super::MccEnc, state: &State, buffer: &gst::Buffer, outbuf: &mut Vec<u8>, @@ -359,7 +357,7 @@ impl MccEnc { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::MccEnc, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -383,7 +381,7 @@ impl MccEnc { self.srcpad.push(buf) } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::MccEnc, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -426,7 +424,7 @@ impl MccEnc { } } - fn src_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn src_event(&self, pad: &gst::Pad, element: &super::MccEnc, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -439,7 +437,12 @@ impl MccEnc { } } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::MccEnc, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -462,13 +465,14 @@ impl MccEnc { impl ObjectSubclass for MccEnc { const NAME: &'static str = "RsMccEnc"; + type Type = super::MccEnc; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -513,7 +517,7 @@ impl ObjectSubclass for MccEnc { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Mcc Encoder", "Encoder/ClosedCaption", @@ -571,7 +575,7 @@ impl ObjectSubclass for MccEnc { } impl ObjectImpl for MccEnc { - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { @@ -587,7 +591,7 @@ impl ObjectImpl for MccEnc { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result<glib::Value, ()> { let prop = &PROPERTIES[id]; match *prop { @@ -603,19 +607,18 @@ impl ObjectImpl for MccEnc { } } - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for MccEnc { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -632,12 +635,3 @@ impl ElementImpl for MccEnc { self.parent_change_state(element, transition) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "mccenc", - gst::Rank::Primary, - MccEnc::get_type(), - ) -} diff --git a/video/closedcaption/src/mcc_enc/mod.rs b/video/closedcaption/src/mcc_enc/mod.rs new file mode 100644 index 000000000..f3c1f0d30 --- /dev/null +++ b/video/closedcaption/src/mcc_enc/mod.rs @@ -0,0 +1,39 @@ +// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; + +mod headers; +mod imp; + +glib_wrapper! { + pub struct MccEnc(ObjectSubclass<imp::MccEnc>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for MccEnc {} +unsafe impl Sync for MccEnc {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "mccenc", + gst::Rank::Primary, + MccEnc::static_type(), + ) +} diff --git a/video/closedcaption/src/mcc_parse.rs b/video/closedcaption/src/mcc_parse/imp.rs index 90304b2f7..1f93db5e8 100644 --- a/video/closedcaption/src/mcc_parse.rs +++ b/video/closedcaption/src/mcc_parse/imp.rs @@ -26,8 +26,8 @@ use std::cmp; use std::convert::TryInto; use std::sync::{Mutex, MutexGuard}; +use super::parser::{MccLine, MccParser, TimeCode}; use crate::line_reader::LineReader; -use crate::mcc_parser::{MccLine, MccParser, TimeCode}; lazy_static! { static ref CAT: gst::DebugCategory = { @@ -54,7 +54,7 @@ struct PullState { } impl PullState { - fn new(element: &gst::Element, pad: &gst::Pad) -> Self { + fn new(element: &super::MccParse, pad: &gst::Pad) -> Self { Self { need_stream_start: true, stream_id: pad @@ -180,7 +180,7 @@ impl State { fn handle_timecode( &mut self, - element: &gst::Element, + element: &super::MccParse, framerate: gst::Fraction, drop_frame: bool, tc: TimeCode, @@ -219,7 +219,7 @@ impl State { /// not produce timestamps jumping backwards fn update_timestamp( &mut self, - element: &gst::Element, + element: &super::MccParse, timecode: &gst_video::ValidVideoTimeCode, ) { let nsecs = gst::ClockTime::from(timecode.nsec_since_daily_jam()); @@ -255,7 +255,7 @@ impl State { fn add_buffer_metadata( &mut self, - element: &gst::Element, + element: &super::MccParse, buffer: &mut gst::buffer::Buffer, timecode: &gst_video::ValidVideoTimeCode, framerate: gst::Fraction, @@ -281,7 +281,7 @@ impl State { fn create_events( &mut self, - element: &gst::Element, + element: &super::MccParse, format: Option<Format>, framerate: gst::Fraction, ) -> Vec<gst::Event> { @@ -341,7 +341,7 @@ impl State { } } -struct MccParse { +pub struct MccParse { srcpad: gst::Pad, sinkpad: gst::Pad, state: Mutex<State>, @@ -369,7 +369,7 @@ impl AsMut<[u8]> for OffsetVec { impl MccParse { fn handle_buffer( &self, - element: &gst::Element, + element: &super::MccParse, buffer: Option<gst::Buffer>, scan_tc_rate: bool, ) -> Result<gst::FlowSuccess, gst::FlowError> { @@ -513,7 +513,7 @@ impl MccParse { fn handle_skipped_line( &self, - element: &gst::Element, + element: &super::MccParse, tc: TimeCode, mut state: MutexGuard<State>, ) -> Result<MutexGuard<State>, gst::FlowError> { @@ -537,7 +537,7 @@ impl MccParse { fn handle_line( &self, - element: &gst::Element, + element: &super::MccParse, tc: TimeCode, data: Vec<u8>, format: Format, @@ -587,7 +587,7 @@ impl MccParse { fn sink_activate( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::MccParse, ) -> Result<(), gst::LoggableError> { let mode = { let mut query = gst::query::Scheduling::new(); @@ -616,7 +616,7 @@ impl MccParse { Ok(()) } - fn start_task(&self, element: &gst::Element) -> Result<(), gst::LoggableError> { + fn start_task(&self, element: &super::MccParse) -> Result<(), gst::LoggableError> { let element_weak = element.downgrade(); let pad_weak = self.sinkpad.downgrade(); let res = self.sinkpad.start_task(move || { @@ -642,7 +642,7 @@ impl MccParse { fn sink_activatemode( &self, _pad: &gst::Pad, - element: &gst::Element, + element: &super::MccParse, mode: gst::PadMode, active: bool, ) -> Result<(), gst::LoggableError> { @@ -659,7 +659,7 @@ impl MccParse { fn scan_duration( &self, - element: &gst::Element, + element: &super::MccParse, ) -> Result<Option<ValidVideoTimeCode>, gst::LoggableError> { gst_debug!(CAT, obj: element, "Scanning duration"); @@ -748,7 +748,7 @@ impl MccParse { } } - fn push_eos(&self, element: &gst::Element) { + fn push_eos(&self, element: &super::MccParse) { let mut state = self.state.lock().unwrap(); if state.seeking { @@ -784,7 +784,7 @@ impl MccParse { } } - fn loop_fn(&self, element: &gst::Element) { + fn loop_fn(&self, element: &super::MccParse) { let mut state = self.state.lock().unwrap(); let State { timecode_rate: ref tc_rate, @@ -882,7 +882,7 @@ impl MccParse { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::MccParse, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -910,7 +910,7 @@ impl MccParse { self.state.lock().unwrap() } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::MccParse, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -956,7 +956,7 @@ impl MccParse { } } - fn perform_seek(&self, event: &gst::event::Seek, element: &gst::Element) -> bool { + fn perform_seek(&self, event: &gst::event::Seek, element: &super::MccParse) -> bool { let mut state = self.state.lock().unwrap(); if state.pull.is_none() { @@ -1049,7 +1049,7 @@ impl MccParse { } } - fn src_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn src_event(&self, pad: &gst::Pad, element: &super::MccParse, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -1059,7 +1059,12 @@ impl MccParse { } } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::MccParse, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -1120,13 +1125,14 @@ impl MccParse { impl ObjectSubclass for MccParse { const NAME: &'static str = "RsMccParse"; + type Type = super::MccParse; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .activate_function(|pad, parent| { @@ -1189,7 +1195,7 @@ impl ObjectSubclass for MccParse { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Mcc Parse", "Parser/ClosedCaption", @@ -1241,19 +1247,18 @@ impl ObjectSubclass for MccParse { } impl ObjectImpl for MccParse { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for MccParse { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -1270,12 +1275,3 @@ impl ElementImpl for MccParse { self.parent_change_state(element, transition) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "mccparse", - gst::Rank::Primary, - MccParse::get_type(), - ) -} diff --git a/video/closedcaption/src/mcc_parse/mod.rs b/video/closedcaption/src/mcc_parse/mod.rs new file mode 100644 index 000000000..d3ee283e0 --- /dev/null +++ b/video/closedcaption/src/mcc_parse/mod.rs @@ -0,0 +1,39 @@ +// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; + +mod imp; +mod parser; + +glib_wrapper! { + pub struct MccParse(ObjectSubclass<imp::MccParse>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for MccParse {} +unsafe impl Sync for MccParse {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "mccparse", + gst::Rank::Primary, + MccParse::static_type(), + ) +} diff --git a/video/closedcaption/src/mcc_parser.rs b/video/closedcaption/src/mcc_parse/parser.rs index c2ec97069..b57e95e44 100644 --- a/video/closedcaption/src/mcc_parser.rs +++ b/video/closedcaption/src/mcc_parse/parser.rs @@ -752,7 +752,7 @@ mod tests { #[test] fn test_parser() { - let mcc_file = include_bytes!("../tests/captions-test_708.mcc"); + let mcc_file = include_bytes!("../../tests/captions-test_708.mcc"); let mut reader = crate::line_reader::LineReader::new(); let mut parser = MccParser::new(); let mut line_cnt = 0; diff --git a/video/closedcaption/src/scc_enc.rs b/video/closedcaption/src/scc_enc/imp.rs index 00b3bf85e..c9c473931 100644 --- a/video/closedcaption/src/scc_enc.rs +++ b/video/closedcaption/src/scc_enc/imp.rs @@ -16,7 +16,6 @@ // Free Software Foundation, Inc., 51 Franklin Street, Suite 500, // Boston, MA 02110-1335, USA. -use glib::prelude::*; use glib::subclass; use glib::subclass::prelude::*; use gst::prelude::*; @@ -70,7 +69,7 @@ impl State { fn generate_caption( &mut self, - element: &gst::Element, + element: &super::SccEnc, buffer: gst::Buffer, ) -> Result<Option<gst::Buffer>, gst::FlowError> { // Arbitrary number that was chosen to keep in order @@ -141,7 +140,7 @@ impl State { // Flush the internal buffers into a line fn write_line( &mut self, - element: &gst::Element, + element: &super::SccEnc, ) -> Result<Option<gst::Buffer>, gst::FlowError> { let mut outbuf = Vec::new(); let mut line_start = true; @@ -218,7 +217,7 @@ impl State { } } -struct SccEnc { +pub struct SccEnc { srcpad: gst::Pad, sinkpad: gst::Pad, state: Mutex<State>, @@ -228,7 +227,7 @@ impl SccEnc { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::SccEnc, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -246,7 +245,7 @@ impl SccEnc { Ok(gst::FlowSuccess::Ok) } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::SccEnc, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -294,7 +293,7 @@ impl SccEnc { } } - fn src_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn src_event(&self, pad: &gst::Pad, element: &super::SccEnc, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -307,7 +306,12 @@ impl SccEnc { } } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::SccEnc, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -330,13 +334,14 @@ impl SccEnc { impl ObjectSubclass for SccEnc { const NAME: &'static str = "RsSccEnc"; + type Type = super::SccEnc; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -380,7 +385,7 @@ impl ObjectSubclass for SccEnc { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Scc Encoder", "Encoder/ClosedCaption", @@ -416,19 +421,18 @@ impl ObjectSubclass for SccEnc { } impl ObjectImpl for SccEnc { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for SccEnc { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -445,12 +449,3 @@ impl ElementImpl for SccEnc { self.parent_change_state(element, transition) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "sccenc", - gst::Rank::Primary, - SccEnc::get_type(), - ) -} diff --git a/video/closedcaption/src/scc_enc/mod.rs b/video/closedcaption/src/scc_enc/mod.rs new file mode 100644 index 000000000..46998d753 --- /dev/null +++ b/video/closedcaption/src/scc_enc/mod.rs @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com> +// Copyright (C) 2019 Jordan Petridis <jordan@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; + +mod imp; + +glib_wrapper! { + pub struct SccEnc(ObjectSubclass<imp::SccEnc>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for SccEnc {} +unsafe impl Sync for SccEnc {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "sccenc", + gst::Rank::Primary, + SccEnc::static_type(), + ) +} diff --git a/video/closedcaption/src/scc_parse.rs b/video/closedcaption/src/scc_parse/imp.rs index 1b70bc015..5e2781ec3 100644 --- a/video/closedcaption/src/scc_parse.rs +++ b/video/closedcaption/src/scc_parse/imp.rs @@ -16,7 +16,6 @@ // Free Software Foundation, Inc., 51 Franklin Street, Suite 500, // Boston, MA 02110-1335, USA. -use glib::prelude::*; use glib::subclass; use glib::subclass::prelude::*; use gst::prelude::*; @@ -24,8 +23,8 @@ use gst::subclass::prelude::*; use std::sync::{Mutex, MutexGuard}; +use super::parser::{SccLine, SccParser, TimeCode}; use crate::line_reader::LineReader; -use crate::scc_parser::{SccLine, SccParser, TimeCode}; lazy_static! { static ref CAT: gst::DebugCategory = { @@ -83,7 +82,7 @@ impl State { &mut self, tc: TimeCode, framerate: gst::Fraction, - element: &gst::Element, + element: &super::SccParse, ) -> Result<gst_video::ValidVideoTimeCode, gst::FlowError> { use std::convert::TryInto; @@ -137,7 +136,7 @@ impl State { fn update_timestamp( &mut self, timecode: &gst_video::ValidVideoTimeCode, - element: &gst::Element, + element: &super::SccParse, ) { let nsecs = gst::ClockTime::from(timecode.nsec_since_daily_jam()); @@ -159,7 +158,7 @@ impl State { buffer: &mut gst::buffer::Buffer, timecode: &gst_video::ValidVideoTimeCode, framerate: gst::Fraction, - element: &gst::Element, + element: &super::SccParse, ) { let buffer = buffer.get_mut().unwrap(); gst_video::VideoTimeCodeMeta::add(buffer, &timecode); @@ -175,7 +174,7 @@ impl State { } } -struct SccParse { +pub struct SccParse { srcpad: gst::Pad, sinkpad: gst::Pad, state: Mutex<State>, @@ -184,7 +183,7 @@ struct SccParse { impl SccParse { fn handle_buffer( &self, - element: &gst::Element, + element: &super::SccParse, buffer: Option<gst::Buffer>, ) -> Result<gst::FlowSuccess, gst::FlowError> { let mut state = self.state.lock().unwrap(); @@ -234,7 +233,7 @@ impl SccParse { &self, tc: TimeCode, data: Vec<u8>, - element: &gst::Element, + element: &super::SccParse, mut state: MutexGuard<State>, ) -> Result<MutexGuard<State>, gst::FlowError> { gst_trace!( @@ -309,7 +308,7 @@ impl SccParse { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::SccParse, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { gst_log!(CAT, obj: pad, "Handling buffer {:?}", buffer); @@ -317,7 +316,7 @@ impl SccParse { self.handle_buffer(element, Some(buffer)) } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::SccParse, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -367,7 +366,7 @@ impl SccParse { } } - fn src_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn src_event(&self, pad: &gst::Pad, element: &super::SccParse, event: gst::Event) -> bool { use gst::EventView; gst_log!(CAT, obj: pad, "Handling event {:?}", event); @@ -380,7 +379,12 @@ impl SccParse { } } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::SccParse, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -413,13 +417,14 @@ impl SccParse { impl ObjectSubclass for SccParse { const NAME: &'static str = "RsSccParse"; + type Type = super::SccParse; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -463,7 +468,7 @@ impl ObjectSubclass for SccParse { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "Scc Parse", "Parser/ClosedCaption", @@ -500,19 +505,18 @@ impl ObjectSubclass for SccParse { } impl ObjectImpl for SccParse { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } } impl ElementImpl for SccParse { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -529,12 +533,3 @@ impl ElementImpl for SccParse { self.parent_change_state(element, transition) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "sccparse", - gst::Rank::Primary, - SccParse::get_type(), - ) -} diff --git a/video/closedcaption/src/scc_parse/mod.rs b/video/closedcaption/src/scc_parse/mod.rs new file mode 100644 index 000000000..19cf93f87 --- /dev/null +++ b/video/closedcaption/src/scc_parse/mod.rs @@ -0,0 +1,40 @@ +// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com> +// Copyright (C) 2019 Jordan Petridis <jordan@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; + +mod imp; +mod parser; + +glib_wrapper! { + pub struct SccParse(ObjectSubclass<imp::SccParse>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for SccParse {} +unsafe impl Sync for SccParse {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "sccparse", + gst::Rank::Primary, + SccParse::static_type(), + ) +} diff --git a/video/closedcaption/src/scc_parser.rs b/video/closedcaption/src/scc_parse/parser.rs index bd02f3e94..7aff8848a 100644 --- a/video/closedcaption/src/scc_parser.rs +++ b/video/closedcaption/src/scc_parse/parser.rs @@ -455,7 +455,7 @@ mod tests { #[test] fn test_parser() { - let scc_file = include_bytes!("../tests/dn2018-1217.scc"); + let scc_file = include_bytes!("../../tests/dn2018-1217.scc"); let mut reader = crate::line_reader::LineReader::new(); let mut parser = SccParser::new(); let mut line_cnt = 0; diff --git a/video/closedcaption/src/tttocea608.rs b/video/closedcaption/src/tttocea608/imp.rs index 935f04ea6..beb05e82a 100644 --- a/video/closedcaption/src/tttocea608.rs +++ b/video/closedcaption/src/tttocea608/imp.rs @@ -18,13 +18,14 @@ use glib::prelude::*; use glib::subclass; use glib::subclass::prelude::*; -use glib::GEnum; use gst::prelude::*; use gst::subclass::prelude::*; -use super::cea608tott_ffi as ffi; +use crate::ffi; use std::sync::Mutex; +use super::Mode; + fn decrement_pts( min_frame_no: u64, frame_no: &mut u64, @@ -208,16 +209,6 @@ const DEFAULT_FPS_D: i32 = 1; */ const LATENCY_BUFFERS: u64 = 74; -#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, GEnum)] -#[repr(u32)] -#[genum(type_name = "GstTtToCea608Mode")] -enum Mode { - PopOn, - RollUp2, - RollUp3, - RollUp4, -} - const DEFAULT_MODE: Mode = Mode::RollUp2; static PROPERTIES: [subclass::Property; 1] = [subclass::Property("mode", |name| { @@ -264,7 +255,7 @@ impl Default for State { } } -struct TtToCea608 { +pub struct TtToCea608 { srcpad: gst::Pad, sinkpad: gst::Pad, @@ -346,7 +337,7 @@ impl TtToCea608 { fn sink_chain( &self, pad: &gst::Pad, - element: &gst::Element, + element: &super::TtToCea608, buffer: gst::Buffer, ) -> Result<gst::FlowSuccess, gst::FlowError> { let pts = match buffer.get_pts() { @@ -628,7 +619,12 @@ impl TtToCea608 { } } - fn src_query(&self, pad: &gst::Pad, element: &gst::Element, query: &mut gst::QueryRef) -> bool { + fn src_query( + &self, + pad: &gst::Pad, + element: &super::TtToCea608, + query: &mut gst::QueryRef, + ) -> bool { use gst::QueryView; gst_log!(CAT, obj: pad, "Handling query {:?}", query); @@ -671,7 +667,7 @@ impl TtToCea608 { } } - fn sink_event(&self, pad: &gst::Pad, element: &gst::Element, event: gst::Event) -> bool { + fn sink_event(&self, pad: &gst::Pad, element: &super::TtToCea608, event: gst::Event) -> bool { gst_log!(CAT, obj: pad, "Handling event {:?}", event); use gst::EventView; @@ -785,13 +781,14 @@ impl TtToCea608 { impl ObjectSubclass for TtToCea608 { const NAME: &'static str = "TtToCea608"; + type Type = super::TtToCea608; type ParentType = gst::Element; type Instance = gst::subclass::ElementInstanceStruct<Self>; type Class = subclass::simple::ClassStruct<Self>; glib_object_subclass!(); - fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self { + fn with_class(klass: &Self::Class) -> Self { let templ = klass.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::builder_with_template(&templ, Some("sink")) .chain_function(|pad, parent, buffer| { @@ -831,7 +828,7 @@ impl ObjectSubclass for TtToCea608 { } } - fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) { + fn class_init(klass: &mut Self::Class) { klass.set_metadata( "TT to CEA-608", "Generic", @@ -874,15 +871,14 @@ impl ObjectSubclass for TtToCea608 { } impl ObjectImpl for TtToCea608 { - fn constructed(&self, obj: &glib::Object) { + fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); - let element = obj.downcast_ref::<gst::Element>().unwrap(); - element.add_pad(&self.sinkpad).unwrap(); - element.add_pad(&self.srcpad).unwrap(); + obj.add_pad(&self.sinkpad).unwrap(); + obj.add_pad(&self.srcpad).unwrap(); } - fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) { + fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) { let prop = &PROPERTIES[id]; match *prop { @@ -894,7 +890,7 @@ impl ObjectImpl for TtToCea608 { } } - fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> { + fn get_property(&self, _obj: &Self::Type, id: usize) -> Result<glib::Value, ()> { let prop = &PROPERTIES[id]; match *prop { @@ -910,7 +906,7 @@ impl ObjectImpl for TtToCea608 { impl ElementImpl for TtToCea608 { fn change_state( &self, - element: &gst::Element, + element: &Self::Type, transition: gst::StateChange, ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { gst_trace!(CAT, obj: element, "Changing state {:?}", transition); @@ -941,12 +937,3 @@ impl ElementImpl for TtToCea608 { Ok(ret) } } - -pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { - gst::Element::register( - Some(plugin), - "tttocea608", - gst::Rank::None, - TtToCea608::get_type(), - ) -} diff --git a/video/closedcaption/src/tttocea608/mod.rs b/video/closedcaption/src/tttocea608/mod.rs new file mode 100644 index 000000000..790e71511 --- /dev/null +++ b/video/closedcaption/src/tttocea608/mod.rs @@ -0,0 +1,49 @@ +// Copyright (C) 2020 Mathieu Duponchelle <mathieu@centricular.com> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, Suite 500, +// Boston, MA 02110-1335, USA. + +use glib::prelude::*; +use glib::GEnum; + +mod imp; + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, GEnum)] +#[repr(u32)] +#[genum(type_name = "GstTtToCea608Mode")] +enum Mode { + PopOn, + RollUp2, + RollUp3, + RollUp4, +} + +glib_wrapper! { + pub struct TtToCea608(ObjectSubclass<imp::TtToCea608>) @extends gst::Element, gst::Object; +} + +// GStreamer elements need to be thread-safe. For the private implementation this is automatically +// enforced but for the public wrapper type we need to specify this manually. +unsafe impl Send for TtToCea608 {} +unsafe impl Sync for TtToCea608 {} + +pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { + gst::Element::register( + Some(plugin), + "tttocea608", + gst::Rank::None, + TtToCea608::static_type(), + ) +} |