transcriberbin: fix inspect with missing elements

Relax the dependency on `awstranscriber` by still building the initial
state when it is absent, this also means an alternative transcriber can
be linked even when `awstranscriber` was not available during
construction.

Also fix property getter / setters to avoid unwrapping the pad state,
and bubble up channel bin construction errors instead of unwrapping (eg
when textwrap was not available).

Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/584
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1783>
This commit is contained in:
Mathieu Duponchelle 2024-07-25 11:41:00 +02:00 committed by GStreamer Marge Bot
parent 1cdddf713d
commit ed8d700e23

View file

@ -74,7 +74,7 @@ struct State {
audio_tee: gst::Element, audio_tee: gst::Element,
transcriber_resample: gst::Element, transcriber_resample: gst::Element,
transcriber_aconv: gst::Element, transcriber_aconv: gst::Element,
transcriber: gst::Element, transcriber: Option<gst::Element>,
ccmux: gst::Element, ccmux: gst::Element,
ccmux_filter: gst::Element, ccmux_filter: gst::Element,
cccombiner: gst::Element, cccombiner: gst::Element,
@ -179,7 +179,6 @@ impl TranscriberBin {
&aqueue_transcription, &aqueue_transcription,
&state.transcriber_resample, &state.transcriber_resample,
&state.transcriber_aconv, &state.transcriber_aconv,
&state.transcriber,
&state.ccmux, &state.ccmux,
&state.ccmux_filter, &state.ccmux_filter,
&ccconverter, &ccconverter,
@ -187,13 +186,20 @@ impl TranscriberBin {
&state.transcription_valve, &state.transcription_valve,
])?; ])?;
if let Some(ref transcriber) = state.transcriber {
state.transcription_bin.add(transcriber)?;
}
gst::Element::link_many([ gst::Element::link_many([
&aqueue_transcription, &aqueue_transcription,
&state.transcriber_resample, &state.transcriber_resample,
&state.transcriber_aconv, &state.transcriber_aconv,
&state.transcriber,
])?; ])?;
if let Some(ref transcriber) = state.transcriber {
state.transcriber_aconv.link(transcriber)?;
}
gst::Element::link_many([ gst::Element::link_many([
&state.ccmux, &state.ccmux,
&state.ccmux_filter, &state.ccmux_filter,
@ -205,7 +211,9 @@ impl TranscriberBin {
for (padname, channel) in &state.transcription_channels { for (padname, channel) in &state.transcription_channels {
state.transcription_bin.add(&channel.bin)?; state.transcription_bin.add(&channel.bin)?;
channel.link_transcriber(&state.transcriber)?; if let Some(ref transcriber) = state.transcriber {
channel.link_transcriber(transcriber)?;
}
let ccmux_pad = state let ccmux_pad = state
.ccmux .ccmux
@ -355,13 +363,13 @@ impl TranscriberBin {
queue.set_property("max-size-time", max_size_time); queue.set_property("max-size-time", max_size_time);
} }
let latency_ms = settings.latency.mseconds() as u32; if let Some(ref transcriber) = state.transcriber {
state.transcriber.set_property("latency", latency_ms); let latency_ms = settings.latency.mseconds() as u32;
transcriber.set_property("latency", latency_ms);
let translate_latency_ms = settings.translate_latency.mseconds() as u32; let translate_latency_ms = settings.translate_latency.mseconds() as u32;
state transcriber.set_property("translate-latency", translate_latency_ms);
.transcriber }
.set_property("translate-latency", translate_latency_ms);
if !settings.passthrough { if !settings.passthrough {
state state
@ -482,7 +490,7 @@ impl TranscriberBin {
fn relink_transcriber( fn relink_transcriber(
&self, &self,
state: &mut State, state: &mut State,
old_transcriber: &gst::Element, old_transcriber: Option<&gst::Element>,
) -> Result<(), Error> { ) -> Result<(), Error> {
gst::debug!( gst::debug!(
CAT, CAT,
@ -492,20 +500,24 @@ impl TranscriberBin {
state.transcriber state.transcriber
); );
state.transcriber_aconv.unlink(old_transcriber); if let Some(old_transcriber) = old_transcriber {
state.transcriber_aconv.unlink(old_transcriber);
for channel in state.transcription_channels.values() { for channel in state.transcription_channels.values() {
old_transcriber.unlink(&channel.bin); old_transcriber.unlink(&channel.bin);
}
state.transcription_bin.remove(old_transcriber).unwrap();
old_transcriber.set_state(gst::State::Null).unwrap();
} }
state.transcription_bin.remove(old_transcriber).unwrap();
old_transcriber.set_state(gst::State::Null).unwrap();
state.transcription_bin.add(&state.transcriber)?; if let Some(ref transcriber) = state.transcriber {
state.transcriber.sync_state_with_parent().unwrap(); state.transcription_bin.add(transcriber)?;
state.transcriber_aconv.link(&state.transcriber)?; transcriber.sync_state_with_parent().unwrap();
state.transcriber_aconv.link(transcriber)?;
for channel in state.transcription_channels.values() { for channel in state.transcription_channels.values() {
channel.link_transcriber(&state.transcriber)?; channel.link_transcriber(transcriber)?;
}
} }
Ok(()) Ok(())
@ -535,9 +547,9 @@ impl TranscriberBin {
state.transcription_bin.set_locked_state(true); state.transcription_bin.set_locked_state(true);
state.transcription_bin.set_state(gst::State::Null).unwrap(); state.transcription_bin.set_state(gst::State::Null).unwrap();
state if let Some(ref transcriber) = state.transcriber {
.transcriber transcriber.set_property("language-code", &settings.language_code);
.set_property("language-code", &settings.language_code); }
if lang_code_only { if lang_code_only {
if !settings.passthrough { if !settings.passthrough {
@ -560,7 +572,9 @@ impl TranscriberBin {
if let Some(peer) = sinkpad.peer() { if let Some(peer) = sinkpad.peer() {
peer.unlink(&sinkpad)?; peer.unlink(&sinkpad)?;
if channel.language != "transcript" { if channel.language != "transcript" {
state.transcriber.release_request_pad(&peer); if let Some(ref transcriber) = state.transcriber {
transcriber.release_request_pad(&peer);
}
} }
} }
@ -585,20 +599,21 @@ impl TranscriberBin {
state.transcription_channels.insert( state.transcription_channels.insert(
channel.to_owned(), channel.to_owned(),
self.construct_channel_bin(&language_code).unwrap(), self.construct_channel_bin(&language_code)?,
); );
} }
} else { } else {
state.transcription_channels.insert( state
"cc1".to_string(), .transcription_channels
self.construct_channel_bin("transcript").unwrap(), .insert("cc1".to_string(), self.construct_channel_bin("transcript")?);
);
} }
for (padname, channel) in &state.transcription_channels { for (padname, channel) in &state.transcription_channels {
state.transcription_bin.add(&channel.bin)?; state.transcription_bin.add(&channel.bin)?;
channel.link_transcriber(&state.transcriber)?; if let Some(ref transcriber) = state.transcriber {
channel.link_transcriber(transcriber)?;
}
let ccmux_pad = state let ccmux_pad = state
.ccmux .ccmux
@ -738,7 +753,8 @@ impl TranscriberBin {
"language-code", "language-code",
&self.settings.lock().unwrap().language_code, &self.settings.lock().unwrap().language_code,
) )
.build()?; .build()
.ok();
let audio_queue_passthrough = gst::ElementFactory::make("queue").build()?; let audio_queue_passthrough = gst::ElementFactory::make("queue").build()?;
let video_queue = gst::ElementFactory::make("queue").build()?; let video_queue = gst::ElementFactory::make("queue").build()?;
let cccapsfilter = gst::ElementFactory::make("capsfilter").build()?; let cccapsfilter = gst::ElementFactory::make("capsfilter").build()?;
@ -762,14 +778,12 @@ impl TranscriberBin {
transcription_channels.insert( transcription_channels.insert(
channel.to_owned(), channel.to_owned(),
self.construct_channel_bin(&language_code).unwrap(), self.construct_channel_bin(&language_code)?,
); );
} }
} else { } else {
transcription_channels.insert( transcription_channels
"cc1".to_string(), .insert("cc1".to_string(), self.construct_channel_bin("transcript")?);
self.construct_channel_bin("transcript").unwrap(),
);
} }
Ok(State { Ok(State {
@ -998,7 +1012,7 @@ impl ObjectImpl for TranscriberBin {
let old_transcriber = state.transcriber.clone(); let old_transcriber = state.transcriber.clone();
state.transcriber = value.get().expect("type checked upstream"); state.transcriber = value.get().expect("type checked upstream");
if old_transcriber != state.transcriber { if old_transcriber != state.transcriber {
match self.relink_transcriber(state, &old_transcriber) { match self.relink_transcriber(state, old_transcriber.as_ref()) {
Ok(()) => (), Ok(()) => (),
Err(err) => { Err(err) => {
gst::error!(CAT, "invalid transcriber: {}", err); gst::error!(CAT, "invalid transcriber: {}", err);
@ -1254,7 +1268,7 @@ impl BinImpl for TranscriberBin {
let s = self.state.lock().unwrap(); let s = self.state.lock().unwrap();
if let Some(state) = s.as_ref() { if let Some(state) = s.as_ref() {
if msg.src() == Some(state.transcriber.upcast_ref()) { if msg.src() == state.transcriber.as_ref().map(|t| t.upcast_ref()) {
gst::error!( gst::error!(
CAT, CAT,
imp: self, imp: self,