Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/video/cdg
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2020-11-15 16:50:12 +0300
committerSebastian Dröge <sebastian@centricular.com>2020-11-15 19:50:31 +0300
commit717477fd36f00c5f1b8dbb64ec4dadc602d5fc22 (patch)
tree7387cf91d55c71afa125a6891579045fa6de5197 /video/cdg
parentb021a8bf100bbd7bbb35c28a7fc9fff78afad28f (diff)
video: Update for subclassing API changes
Diffstat (limited to 'video/cdg')
-rw-r--r--video/cdg/src/cdgdec/imp.rs (renamed from video/cdg/src/cdgdec.rs)32
-rw-r--r--video/cdg/src/cdgdec/mod.rs29
-rw-r--r--video/cdg/src/cdgparse/imp.rs (renamed from video/cdg/src/cdgparse.rs)20
-rw-r--r--video/cdg/src/cdgparse/mod.rs29
-rw-r--r--video/cdg/src/lib.rs83
-rw-r--r--video/cdg/src/typefind.rs87
6 files changed, 165 insertions, 115 deletions
diff --git a/video/cdg/src/cdgdec.rs b/video/cdg/src/cdgdec/imp.rs
index 92d1a34ad..2a2365d1c 100644
--- a/video/cdg/src/cdgdec.rs
+++ b/video/cdg/src/cdgdec/imp.rs
@@ -17,18 +17,19 @@ use std::sync::Mutex;
use crate::constants::{CDG_HEIGHT, CDG_WIDTH};
-struct CdgDec {
- cdg_inter: Mutex<Box<cdg_renderer::CdgInterpreter>>,
- output_info: Mutex<Option<gst_video::VideoInfo>>,
-}
-
lazy_static! {
static ref CAT: gst::DebugCategory =
gst::DebugCategory::new("cdgdec", gst::DebugColorFlags::empty(), Some("CDG decoder"),);
}
+pub struct CdgDec {
+ cdg_inter: Mutex<Box<cdg_renderer::CdgInterpreter>>,
+ output_info: Mutex<Option<gst_video::VideoInfo>>,
+}
+
impl ObjectSubclass for CdgDec {
const NAME: &'static str = "CdgDec";
+ type Type = super::CdgDec;
type ParentType = gst_video::VideoDecoder;
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
@@ -42,7 +43,7 @@ impl ObjectSubclass for CdgDec {
}
}
- fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
+ fn class_init(klass: &mut Self::Class) {
klass.set_metadata(
"CDG decoder",
"Decoder/Video",
@@ -85,14 +86,14 @@ impl ObjectImpl for CdgDec {}
impl ElementImpl for CdgDec {}
impl VideoDecoderImpl for CdgDec {
- fn start(&self, element: &gst_video::VideoDecoder) -> Result<(), gst::ErrorMessage> {
+ fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
let mut out_info = self.output_info.lock().unwrap();
*out_info = None;
self.parent_start(element)
}
- fn stop(&self, element: &gst_video::VideoDecoder) -> Result<(), gst::ErrorMessage> {
+ fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
{
let mut cdg_inter = self.cdg_inter.lock().unwrap();
cdg_inter.reset(true);
@@ -102,7 +103,7 @@ impl VideoDecoderImpl for CdgDec {
fn handle_frame(
&self,
- element: &gst_video::VideoDecoder,
+ element: &Self::Type,
mut frame: gst_video::VideoCodecFrame,
) -> Result<gst::FlowSuccess, gst::FlowError> {
{
@@ -192,7 +193,7 @@ impl VideoDecoderImpl for CdgDec {
fn decide_allocation(
&self,
- element: &gst_video::VideoDecoder,
+ element: &Self::Type,
query: &mut gst::QueryRef,
) -> Result<(), gst::ErrorMessage> {
if let gst::query::QueryView::Allocation(allocation) = query.view() {
@@ -216,7 +217,7 @@ impl VideoDecoderImpl for CdgDec {
self.parent_decide_allocation(element, query)
}
- fn flush(&self, element: &gst_video::VideoDecoder) -> bool {
+ fn flush(&self, element: &Self::Type) -> bool {
gst_debug!(CAT, obj: element, "flushing, reset CDG interpreter");
let mut cdg_inter = self.cdg_inter.lock().unwrap();
@@ -224,12 +225,3 @@ impl VideoDecoderImpl for CdgDec {
true
}
}
-
-pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
- gst::Element::register(
- Some(plugin),
- "cdgdec",
- gst::Rank::Primary,
- CdgDec::get_type(),
- )
-}
diff --git a/video/cdg/src/cdgdec/mod.rs b/video/cdg/src/cdgdec/mod.rs
new file mode 100644
index 000000000..daf17cb42
--- /dev/null
+++ b/video/cdg/src/cdgdec/mod.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use glib::prelude::*;
+
+mod imp;
+
+glib_wrapper! {
+ pub struct CdgDec(ObjectSubclass<imp::CdgDec>) @extends gst_video::VideoDecoder, 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 CdgDec {}
+unsafe impl Sync for CdgDec {}
+
+pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
+ gst::Element::register(
+ Some(plugin),
+ "cdgdec",
+ gst::Rank::Primary,
+ CdgDec::static_type(),
+ )
+}
diff --git a/video/cdg/src/cdgparse.rs b/video/cdg/src/cdgparse/imp.rs
index 50b46072b..7b564a5a1 100644
--- a/video/cdg/src/cdgparse.rs
+++ b/video/cdg/src/cdgparse/imp.rs
@@ -23,7 +23,7 @@ const CDG_CMD_MEMORY_PRESET: u8 = 1;
const CDG_CMD_MEMORY_LOAD_COLOR_TABLE_1: u8 = 30;
const CDG_CMD_MEMORY_LOAD_COLOR_TABLE_2: u8 = 31;
-struct CdgParse;
+pub struct CdgParse;
lazy_static! {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new(
@@ -35,6 +35,7 @@ lazy_static! {
impl ObjectSubclass for CdgParse {
const NAME: &'static str = "CdgParse";
+ type Type = super::CdgParse;
type ParentType = gst_base::BaseParse;
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
@@ -45,7 +46,7 @@ impl ObjectSubclass for CdgParse {
Self
}
- fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
+ fn class_init(klass: &mut Self::Class) {
klass.set_metadata(
"CDG parser",
"Codec/Parser/Video",
@@ -108,7 +109,7 @@ fn time_to_bytes(time: gst::ClockTime) -> Bytes {
}
impl BaseParseImpl for CdgParse {
- fn start(&self, element: &gst_base::BaseParse) -> Result<(), gst::ErrorMessage> {
+ fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
element.set_min_frame_size(CDG_PACKET_SIZE as u32);
/* Set duration */
@@ -125,7 +126,7 @@ impl BaseParseImpl for CdgParse {
fn handle_frame(
&self,
- element: &gst_base::BaseParse,
+ element: &Self::Type,
mut frame: gst_base::BaseParseFrame,
) -> Result<(gst::FlowSuccess, u32), gst::FlowError> {
let pad = element.get_src_pad();
@@ -212,7 +213,7 @@ impl BaseParseImpl for CdgParse {
fn convert<V: Into<gst::GenericFormattedValue>>(
&self,
- _element: &gst_base::BaseParse,
+ _element: &Self::Type,
src_val: V,
dest_format: gst::Format,
) -> Option<gst::GenericFormattedValue> {
@@ -229,12 +230,3 @@ impl BaseParseImpl for CdgParse {
}
}
}
-
-pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
- gst::Element::register(
- Some(plugin),
- "cdgparse",
- gst::Rank::Primary,
- CdgParse::get_type(),
- )
-}
diff --git a/video/cdg/src/cdgparse/mod.rs b/video/cdg/src/cdgparse/mod.rs
new file mode 100644
index 000000000..10cac351f
--- /dev/null
+++ b/video/cdg/src/cdgparse/mod.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use glib::prelude::*;
+
+mod imp;
+
+glib_wrapper! {
+ pub struct CdgParse(ObjectSubclass<imp::CdgParse>) @extends gst_base::BaseParse, 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 CdgParse {}
+unsafe impl Sync for CdgParse {}
+
+pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
+ gst::Element::register(
+ Some(plugin),
+ "cdgparse",
+ gst::Rank::Primary,
+ CdgParse::static_type(),
+ )
+}
diff --git a/video/cdg/src/lib.rs b/video/cdg/src/lib.rs
index 4083adc7b..c5e5bb513 100644
--- a/video/cdg/src/lib.rs
+++ b/video/cdg/src/lib.rs
@@ -18,91 +18,12 @@ extern crate lazy_static;
mod cdgdec;
mod cdgparse;
mod constants;
-
-use constants::{CDG_COMMAND, CDG_MASK, CDG_PACKET_PERIOD, CDG_PACKET_SIZE};
-use gst::{Caps, TypeFind, TypeFindProbability};
-use std::cmp;
-
-const NB_WINDOWS: u64 = 8;
-const TYPEFIND_SEARCH_WINDOW_SEC: i64 = 4;
-const TYPEFIND_SEARCH_WINDOW: i64 =
- TYPEFIND_SEARCH_WINDOW_SEC * (CDG_PACKET_SIZE as i64 * CDG_PACKET_PERIOD as i64); /* in bytes */
-
-/* Return the percentage of CDG packets in the first @len bytes of @typefind */
-fn cdg_packets_ratio(typefind: &mut TypeFind, start: i64, len: i64) -> i64 {
- let mut count = 0;
- let total = len / CDG_PACKET_SIZE as i64;
-
- for offset in (0..len).step_by(CDG_PACKET_SIZE as usize) {
- match typefind.peek(start + offset, CDG_PACKET_SIZE as u32) {
- Some(data) => {
- if data[0] & CDG_MASK == CDG_COMMAND {
- count += 1;
- }
- }
- None => break,
- }
- }
- (count * 100) / total
-}
-
-/* Some CDG files starts drawing right away and then pause for a while
- * (typically because of the song intro) while other wait for a few
- * seconds before starting to draw.
- * In order to support all variants, scan through all the file per block
- * of size TYPEFIND_SEARCH_WINDOW and keep the highest ratio of CDG packets
- * detected. */
-fn compute_probability(typefind: &mut TypeFind) -> TypeFindProbability {
- let mut best = TypeFindProbability::None;
- // Try looking at the start of the file if its length isn't available
- let len = typefind
- .get_length()
- .unwrap_or(TYPEFIND_SEARCH_WINDOW as u64 * NB_WINDOWS);
- let step = len / NB_WINDOWS;
-
- // Too short file
- if step == 0 {
- return TypeFindProbability::None;
- }
-
- for offset in (0..len).step_by(step as usize) {
- let proba = match cdg_packets_ratio(typefind, offset as i64, TYPEFIND_SEARCH_WINDOW) {
- 0..=5 => TypeFindProbability::None,
- 6..=10 => TypeFindProbability::Possible,
- _ => TypeFindProbability::Likely,
- };
-
- if proba == TypeFindProbability::Likely {
- return proba;
- }
-
- best = cmp::max(best, proba);
- }
-
- best
-}
-
-fn typefind_register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
- TypeFind::register(
- Some(plugin),
- "cdg_typefind",
- gst::Rank::None,
- Some("cdg"),
- Some(&Caps::new_simple("video/x-cdg", &[])),
- |mut typefind| {
- let proba = compute_probability(&mut typefind);
-
- if proba != gst::TypeFindProbability::None {
- typefind.suggest(proba, &Caps::new_simple("video/x-cdg", &[]));
- }
- },
- )
-}
+mod typefind;
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
cdgdec::register(plugin)?;
cdgparse::register(plugin)?;
- typefind_register(plugin)?;
+ typefind::register(plugin)?;
Ok(())
}
diff --git a/video/cdg/src/typefind.rs b/video/cdg/src/typefind.rs
new file mode 100644
index 000000000..e81438497
--- /dev/null
+++ b/video/cdg/src/typefind.rs
@@ -0,0 +1,87 @@
+// Copyright (C) 2019 Guillaume Desmottes <guillaume.desmottes@collabora.com>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::constants::{CDG_COMMAND, CDG_MASK, CDG_PACKET_PERIOD, CDG_PACKET_SIZE};
+use gst::{Caps, TypeFind, TypeFindProbability};
+use std::cmp;
+
+const NB_WINDOWS: u64 = 8;
+const TYPEFIND_SEARCH_WINDOW_SEC: i64 = 4;
+const TYPEFIND_SEARCH_WINDOW: i64 =
+ TYPEFIND_SEARCH_WINDOW_SEC * (CDG_PACKET_SIZE as i64 * CDG_PACKET_PERIOD as i64); /* in bytes */
+
+/* Return the percentage of CDG packets in the first @len bytes of @typefind */
+fn cdg_packets_ratio(typefind: &mut TypeFind, start: i64, len: i64) -> i64 {
+ let mut count = 0;
+ let total = len / CDG_PACKET_SIZE as i64;
+
+ for offset in (0..len).step_by(CDG_PACKET_SIZE as usize) {
+ match typefind.peek(start + offset, CDG_PACKET_SIZE as u32) {
+ Some(data) => {
+ if data[0] & CDG_MASK == CDG_COMMAND {
+ count += 1;
+ }
+ }
+ None => break,
+ }
+ }
+ (count * 100) / total
+}
+
+/* Some CDG files starts drawing right away and then pause for a while
+ * (typically because of the song intro) while other wait for a few
+ * seconds before starting to draw.
+ * In order to support all variants, scan through all the file per block
+ * of size TYPEFIND_SEARCH_WINDOW and keep the highest ratio of CDG packets
+ * detected. */
+fn compute_probability(typefind: &mut TypeFind) -> TypeFindProbability {
+ let mut best = TypeFindProbability::None;
+ // Try looking at the start of the file if its length isn't available
+ let len = typefind
+ .get_length()
+ .unwrap_or(TYPEFIND_SEARCH_WINDOW as u64 * NB_WINDOWS);
+ let step = len / NB_WINDOWS;
+
+ // Too short file
+ if step == 0 {
+ return TypeFindProbability::None;
+ }
+
+ for offset in (0..len).step_by(step as usize) {
+ let proba = match cdg_packets_ratio(typefind, offset as i64, TYPEFIND_SEARCH_WINDOW) {
+ 0..=5 => TypeFindProbability::None,
+ 6..=10 => TypeFindProbability::Possible,
+ _ => TypeFindProbability::Likely,
+ };
+
+ if proba == TypeFindProbability::Likely {
+ return proba;
+ }
+
+ best = cmp::max(best, proba);
+ }
+
+ best
+}
+
+pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
+ TypeFind::register(
+ Some(plugin),
+ "cdg_typefind",
+ gst::Rank::None,
+ Some("cdg"),
+ Some(&Caps::new_simple("video/x-cdg", &[])),
+ |mut typefind| {
+ let proba = compute_probability(&mut typefind);
+
+ if proba != gst::TypeFindProbability::None {
+ typefind.suggest(proba, &Caps::new_simple("video/x-cdg", &[]));
+ }
+ },
+ )
+}