transcriberbin: simplify latency query implementation

By always replying with a synthetic latency

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1925>
This commit is contained in:
Mathieu Duponchelle 2024-11-13 17:45:35 +01:00
parent 10a022e457
commit 4074f4c275

View file

@ -38,6 +38,7 @@ const DEFAULT_INPUT_LANG_CODE: &str = "en-US";
const DEFAULT_MUX_METHOD: MuxMethod = MuxMethod::Cea608; const DEFAULT_MUX_METHOD: MuxMethod = MuxMethod::Cea608;
const CEAX08MUX_LATENCY: gst::ClockTime = gst::ClockTime::from_mseconds(100); const CEAX08MUX_LATENCY: gst::ClockTime = gst::ClockTime::from_mseconds(100);
const CCCOMBINER_LATENCY: gst::ClockTime = gst::ClockTime::from_mseconds(100);
#[derive(Debug)] #[derive(Debug)]
enum TargetPassthroughState { enum TargetPassthroughState {
@ -421,7 +422,7 @@ impl TranscriberBin {
self.obj().add(&state.internal_bin)?; self.obj().add(&state.internal_bin)?;
state.cccombiner.set_property("latency", 100.mseconds()); state.cccombiner.set_property("latency", CCCOMBINER_LATENCY);
self.video_sinkpad self.video_sinkpad
.set_target(Some(&state.internal_bin.static_pad("video_sink").unwrap()))?; .set_target(Some(&state.internal_bin.static_pad("video_sink").unwrap()))?;
@ -1108,39 +1109,31 @@ impl TranscriberBin {
); );
} }
fn any_sink_is_translating(&self, state: &State) -> bool { fn query_upstream_latency(&self, state: &State) -> gst::ClockTime {
for pad in state.audio_sink_pads.values() { let mut min = gst::ClockTime::from_seconds(0);
let ps = pad.imp().state.lock().unwrap();
let pad_state = ps.as_ref().unwrap(); for pad in state
if pad_state .audio_sink_pads
.transcription_channels
.values() .values()
.any(|c| c.language != "transcript") .map(|p| p.upcast_ref::<gst::Pad>())
.chain(
[&self.video_sinkpad]
.iter()
.map(|p| p.upcast_ref::<gst::Pad>()),
)
{ {
return true; let mut upstream_query = gst::query::Latency::new();
if pad.query(&mut upstream_query) {
let (_, upstream_min, _) = upstream_query.result();
if min < upstream_min {
min = upstream_min;
} }
} }
false
} }
fn any_sink_is_rollup(&self, state: &State) -> bool { min
for pad in state.audio_sink_pads.values() {
let pad_settings = pad.imp().settings.lock().unwrap();
if pad_settings.mode.is_rollup() {
return true;
}
}
false
}
fn all_sinks_are_passthrough(&self, state: &State) -> bool {
for pad in state.audio_sink_pads.values() {
let pad_settings = pad.imp().settings.lock().unwrap();
if !pad_settings.passthrough {
return false;
}
}
true
} }
#[allow(clippy::single_match)] #[allow(clippy::single_match)]
@ -1151,49 +1144,31 @@ impl TranscriberBin {
match query.view_mut() { match query.view_mut() {
QueryViewMut::Latency(q) => { QueryViewMut::Latency(q) => {
let mut upstream_query = gst::query::Latency::new();
let ret = gst::Pad::query_default(pad, Some(&*self.obj()), &mut upstream_query);
if ret {
let (_, mut min, _) = upstream_query.result();
let state = self.state.lock().unwrap(); let state = self.state.lock().unwrap();
let (received_framerate, translating, all_passthrough) = {
if let Some(state) = state.as_ref() { if let Some(state) = state.as_ref() {
( let upstream_min = self.query_upstream_latency(state);
state.framerate,
self.any_sink_is_translating(state),
self.all_sinks_are_passthrough(state),
)
} else {
(None, false, true)
}
};
let settings = self.settings.lock().unwrap(); let settings = self.settings.lock().unwrap();
if all_passthrough || received_framerate.is_none() { let min = upstream_min
min += settings.latency + settings.accumulate_time + CEAX08MUX_LATENCY; + settings.latency
+ settings.accumulate_time
+ CEAX08MUX_LATENCY
+ settings.translate_latency
+ CCCOMBINER_LATENCY
+ state
.framerate
.map(|f| {
2 * gst::ClockTime::SECOND
.mul_div_floor(f.denom() as u64, f.numer() as u64)
.unwrap()
})
.unwrap_or(gst::ClockTime::from_seconds(0));
if translating { gst::debug!(CAT, imp = self, "calculated latency: {}", min);
min += settings.translate_latency;
}
/* The sub latency introduced by ceax08mux */
if let Some(framerate) = received_framerate {
min += gst::ClockTime::SECOND
.mul_div_floor(framerate.denom() as u64, framerate.numer() as u64)
.unwrap();
}
} else if let Some(state) = state.as_ref() {
if self.any_sink_is_rollup(state) {
min += settings.accumulate_time;
}
}
q.set(true, min, gst::ClockTime::NONE); q.set(true, min, gst::ClockTime::NONE);
} }
ret true
} }
_ => gst::Pad::query_default(pad, Some(&*self.obj()), query), _ => gst::Pad::query_default(pad, Some(&*self.obj()), query),
} }