mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-20 14:46:24 +00:00
transcriberbin: expose language-filters property
When set, the bin will lookup the structure for either a bin description or an element to link in when linking the transcriber to a language tee. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1979>
This commit is contained in:
parent
5e4d5a3dc6
commit
ae90dd4afe
2 changed files with 91 additions and 8 deletions
|
@ -8785,6 +8785,17 @@
|
|||
"type": "gchararray",
|
||||
"writable": true
|
||||
},
|
||||
"language-filters": {
|
||||
"blurb": "A map of language codes to bin descriptions, e.g. text-filters=\"languages, fr=regex\" will filter words out of the transcriber through the regex element",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"mutable": "playing",
|
||||
"readable": true,
|
||||
"type": "GstStructure",
|
||||
"writable": true
|
||||
},
|
||||
"mode": {
|
||||
"blurb": "Which closed caption mode to operate in",
|
||||
"conditionally-available": false,
|
||||
|
|
|
@ -154,9 +154,13 @@ impl TranscriberBin {
|
|||
.get(language)
|
||||
.expect("language tee created");
|
||||
|
||||
let tee_sinkpad = language_tee.static_pad("sink").unwrap();
|
||||
let sinkpad = if let Some(filter) = pad_state.language_filters.get(language) {
|
||||
filter.static_pad("sink").unwrap()
|
||||
} else {
|
||||
language_tee.static_pad("sink").unwrap()
|
||||
};
|
||||
|
||||
if !tee_sinkpad.is_linked() {
|
||||
if !sinkpad.is_linked() {
|
||||
let transcriber_src_pad = match language {
|
||||
"transcript" => transcriber
|
||||
.static_pad("src")
|
||||
|
@ -176,7 +180,7 @@ impl TranscriberBin {
|
|||
"Linking transcriber source pad to language tee"
|
||||
);
|
||||
|
||||
transcriber_src_pad.link(&tee_sinkpad)?;
|
||||
transcriber_src_pad.link(&sinkpad)?;
|
||||
|
||||
pad_state.expose_unsynced_pads(topbin, state, transcriber_src_pad.name().as_str())?;
|
||||
}
|
||||
|
@ -993,6 +997,32 @@ impl TranscriberBin {
|
|||
|
||||
pad_state.transcription_bin.add(&tee)?;
|
||||
|
||||
if let Some(val) = pad_settings
|
||||
.language_filters
|
||||
.as_ref()
|
||||
.and_then(|f| f.value(k).ok())
|
||||
{
|
||||
let filter = if val.is::<String>() {
|
||||
let bin_description = val.get::<String>().unwrap();
|
||||
gst::parse::bin_from_description_full(
|
||||
&bin_description,
|
||||
true,
|
||||
None,
|
||||
gst::ParseFlags::NO_SINGLE_ELEMENT_BINS,
|
||||
)?
|
||||
} else if val.is::<gst::Element>() {
|
||||
val.get::<gst::Element>().unwrap()
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"Value for language filter map must be string or element"
|
||||
));
|
||||
};
|
||||
|
||||
pad_state.transcription_bin.add(&filter)?;
|
||||
filter.link(&tee)?;
|
||||
pad_state.language_filters.insert(k.clone(), filter);
|
||||
}
|
||||
|
||||
e.insert(tee);
|
||||
};
|
||||
}
|
||||
|
@ -1011,7 +1041,15 @@ impl TranscriberBin {
|
|||
|
||||
self.tear_down_synthesis_channels(&self.obj(), state, pad_state)?;
|
||||
|
||||
for (_, tee) in pad_state.language_tees.drain() {
|
||||
for (language, tee) in pad_state.language_tees.drain() {
|
||||
if let Some(filter) = pad_state.language_filters.remove(&language) {
|
||||
let _ = pad_state.transcription_bin.remove(&filter);
|
||||
let _ = filter.set_state(gst::State::Null);
|
||||
// At this point the filter is unlinked, removed from the bin and
|
||||
// its state is reset. If it was directly provided by the user then
|
||||
// it remains reffed in the settings structure, otherwise it goes
|
||||
// out of scope here and will get recreated.
|
||||
}
|
||||
let _ = pad_state.transcription_bin.remove(&tee);
|
||||
}
|
||||
|
||||
|
@ -2223,6 +2261,7 @@ impl BinImpl for TranscriberBin {
|
|||
struct TranscriberSinkPadSettings {
|
||||
translation_languages: Option<gst::Structure>,
|
||||
synthesis_languages: Option<gst::Structure>,
|
||||
language_filters: Option<gst::Structure>,
|
||||
language_code: String,
|
||||
mode: Cea608Mode,
|
||||
passthrough: bool,
|
||||
|
@ -2233,6 +2272,7 @@ impl Default for TranscriberSinkPadSettings {
|
|||
Self {
|
||||
translation_languages: None,
|
||||
synthesis_languages: None,
|
||||
language_filters: None,
|
||||
language_code: String::from(DEFAULT_INPUT_LANG_CODE),
|
||||
mode: DEFAULT_MODE,
|
||||
passthrough: DEFAULT_PASSTHROUGH,
|
||||
|
@ -2255,6 +2295,7 @@ struct TranscriberSinkPadState {
|
|||
target_passthrough_state: TargetPassthroughState,
|
||||
serial: Option<u32>,
|
||||
language_tees: HashMap<String, gst::Element>,
|
||||
language_filters: HashMap<String, gst::Element>,
|
||||
}
|
||||
|
||||
impl TranscriberSinkPadState {
|
||||
|
@ -2286,6 +2327,7 @@ impl TranscriberSinkPadState {
|
|||
target_passthrough_state: TargetPassthroughState::None,
|
||||
serial: None,
|
||||
language_tees: HashMap::new(),
|
||||
language_filters: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2329,8 +2371,12 @@ impl TranscriberSinkPadState {
|
|||
state: &State,
|
||||
pad_state: &TranscriberSinkPadState,
|
||||
) {
|
||||
for tee in pad_state.language_tees.values() {
|
||||
let sinkpad = tee.static_pad("sink").unwrap();
|
||||
for (language, tee) in pad_state.language_tees.iter() {
|
||||
let sinkpad = if let Some(filter) = pad_state.language_filters.get(language) {
|
||||
filter.static_pad("sink").unwrap()
|
||||
} else {
|
||||
tee.static_pad("sink").unwrap()
|
||||
};
|
||||
|
||||
if let Some(srcpad) = sinkpad.peer() {
|
||||
let _ = srcpad.unlink(&sinkpad);
|
||||
|
@ -2528,8 +2574,12 @@ impl ObjectImpl for TranscriberSinkPad {
|
|||
.build(),
|
||||
)
|
||||
.mutable_ready()
|
||||
.build()
|
||||
|
||||
.build(),
|
||||
glib::ParamSpecBoxed::builder::<gst::Structure>("language-filters")
|
||||
.nick("Language filters")
|
||||
.blurb("A map of language codes to bin descriptions, e.g. text-filters=\"languages, fr=regex\" will filter words out of the transcriber through the regex element")
|
||||
.mutable_playing()
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -2604,6 +2654,24 @@ impl ObjectImpl for TranscriberSinkPad {
|
|||
this.imp().update_languages(&self.obj(), false);
|
||||
}
|
||||
}
|
||||
"language-filters" => {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
settings.language_filters = value
|
||||
.get::<Option<gst::Structure>>()
|
||||
.expect("type checked upstream");
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp = self,
|
||||
"Updated language-filters {:?}",
|
||||
settings.language_filters
|
||||
);
|
||||
|
||||
drop(settings);
|
||||
|
||||
if let Some(this) = self.obj().parent().and_downcast::<super::TranscriberBin>() {
|
||||
this.imp().update_languages(&self.obj(), false);
|
||||
}
|
||||
}
|
||||
"mode" => {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
|
||||
|
@ -2712,6 +2780,10 @@ impl ObjectImpl for TranscriberSinkPad {
|
|||
let settings = self.settings.lock().unwrap();
|
||||
settings.synthesis_languages.to_value()
|
||||
}
|
||||
"language-filters" => {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
settings.language_filters.to_value()
|
||||
}
|
||||
"language-code" => {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
settings.language_code.to_value()
|
||||
|
|
Loading…
Reference in a new issue