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
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2022-01-08 03:26:50 +0300
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2022-01-12 19:49:24 +0300
commit0bc76976000ed745ffe00cac0311131e48835f8c (patch)
tree7cbf877798e109ff9e49203da4780393c232e741
parent16d35a789abab656b3c65cf4fb14c25fb1863156 (diff)
sccenc: add output-padding property
When set to False, sccenc will only output non-padding byte pairs. I cannot find reference documentation for the format, but the closest thing I find to it is http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/SCC_FORMAT.HTML, which doesn't have padding in the examples. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/635>
-rw-r--r--video/closedcaption/src/scc_enc/imp.rs87
1 files changed, 86 insertions, 1 deletions
diff --git a/video/closedcaption/src/scc_enc/imp.rs b/video/closedcaption/src/scc_enc/imp.rs
index 4bac57c45..5a7ac6277 100644
--- a/video/closedcaption/src/scc_enc/imp.rs
+++ b/video/closedcaption/src/scc_enc/imp.rs
@@ -28,6 +28,8 @@ use once_cell::sync::Lazy;
use std::io::Write;
use std::sync::Mutex;
+const DEFAULT_OUTPUT_PADDING: bool = true;
+
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"sccenc",
@@ -36,12 +38,26 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
)
});
+#[derive(Clone, Debug)]
+struct Settings {
+ output_padding: bool,
+}
+
+impl Default for Settings {
+ fn default() -> Self {
+ Self {
+ output_padding: DEFAULT_OUTPUT_PADDING,
+ }
+ }
+}
+
#[derive(Debug)]
struct State {
need_headers: bool,
expected_timecode: Option<ValidVideoTimeCode>,
internal_buffer: Vec<gst::Buffer>,
framerate: Option<gst::Fraction>,
+ settings: Settings,
}
impl Default for State {
@@ -51,6 +67,7 @@ impl Default for State {
expected_timecode: None,
internal_buffer: Vec::with_capacity(64),
framerate: None,
+ settings: Settings::default(),
}
}
}
@@ -88,6 +105,24 @@ impl State {
return Err(gst::FlowError::Error);
};
+ if !self.settings.output_padding {
+ let map = buffer.map_readable().map_err(|_| {
+ gst::element_error!(
+ element,
+ gst::StreamError::Format,
+ ["Failed to map buffer readable"]
+ );
+
+ gst::FlowError::Error
+ })?;
+
+ if map[0] == 0x80 && map[1] == 0x80 {
+ return Ok(None);
+ }
+
+ drop(map);
+ }
+
let mut timecode = buffer
.meta::<gst_video::VideoTimeCodeMeta>()
.ok_or_else(|| {
@@ -219,6 +254,7 @@ pub struct SccEnc {
srcpad: gst::Pad,
sinkpad: gst::Pad,
state: Mutex<State>,
+ settings: Mutex<Settings>,
}
impl SccEnc {
@@ -377,6 +413,7 @@ impl ObjectSubclass for SccEnc {
srcpad,
sinkpad,
state: Mutex::new(State::default()),
+ settings: Mutex::new(Settings::default()),
}
}
}
@@ -388,6 +425,48 @@ impl ObjectImpl for SccEnc {
obj.add_pad(&self.sinkpad).unwrap();
obj.add_pad(&self.srcpad).unwrap();
}
+
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpecBoolean::new(
+ "output-padding",
+ "Output padding",
+ "Whether the encoder should output padding captions. \
+ The element will never add padding, but will encode padding \
+ buffers it receives if this property is set to true.",
+ DEFAULT_OUTPUT_PADDING,
+ glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.name() {
+ "output-padding" => {
+ self.settings.lock().unwrap().output_padding =
+ value.get().expect("type checked upstream");
+ }
+ _ => unimplemented!(),
+ }
+ }
+
+ fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.name() {
+ "output-padding" => {
+ let settings = self.settings.lock().unwrap();
+ settings.output_padding.to_value()
+ }
+ _ => unimplemented!(),
+ }
+ }
}
impl GstObjectImpl for SccEnc {}
@@ -445,7 +524,13 @@ impl ElementImpl for SccEnc {
gst_trace!(CAT, obj: element, "Changing state {:?}", transition);
match transition {
- gst::StateChange::ReadyToPaused | gst::StateChange::PausedToReady => {
+ gst::StateChange::ReadyToPaused => {
+ // Reset the whole state
+ let mut state = self.state.lock().unwrap();
+ *state = State::default();
+ state.settings = self.settings.lock().unwrap().clone();
+ }
+ gst::StateChange::PausedToReady => {
// Reset the whole state
let mut state = self.state.lock().unwrap();
*state = State::default();