textwrap: add support for gaps

When accumulate-time is non-zero, we need to drain our accumulated
text once the threshold is reached.

Implement support for gaps the simplest way, by transforming it into
an empty buffer and chaining it through ourself.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1436>
This commit is contained in:
Mathieu Duponchelle 2024-01-23 12:37:29 +01:00
parent 4bb867bf52
commit ad51c61ac8

View file

@ -148,7 +148,11 @@ impl TextWrap {
gst::FlowError::Error gst::FlowError::Error
})?; })?;
gst::log!(CAT, imp: self, "processing {data} in {buffer:?}"); if data.is_empty() {
gst::trace!(CAT, imp: self, "processing gap {buffer:?}");
} else {
gst::debug!(CAT, imp: self, "processing {data} in {buffer:?}");
}
let accumulate_time = self.settings.lock().unwrap().accumulate_time; let accumulate_time = self.settings.lock().unwrap().accumulate_time;
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
@ -164,13 +168,21 @@ impl TextWrap {
.unwrap_or(false); .unwrap_or(false);
if add_buffer { if add_buffer {
let mut buf = let drained = mem::take(&mut state.current_text);
gst::Buffer::from_mut_slice(mem::take(&mut state.current_text).into_bytes()); let duration = state.end_ts.opt_checked_sub(state.start_ts).ok().flatten();
gst::info!(
CAT,
imp: self,
"Outputting contents {}, ts: {}, duration: {}",
drained.to_string(),
state.start_ts.display(),
duration.display(),
);
let mut buf = gst::Buffer::from_mut_slice(drained.into_bytes());
{ {
let buf_mut = buf.get_mut().unwrap(); let buf_mut = buf.get_mut().unwrap();
buf_mut.set_pts(state.start_ts); buf_mut.set_pts(state.start_ts);
buf_mut buf_mut.set_duration(duration);
.set_duration(state.end_ts.opt_checked_sub(state.start_ts).ok().flatten());
} }
bufferlist.get_mut().unwrap().add(buf); bufferlist.get_mut().unwrap().add(buf);
@ -322,10 +334,27 @@ impl TextWrap {
use gst::EventView; use gst::EventView;
match event.view() { match event.view() {
EventView::Gap(_) => { EventView::Gap(gap) => {
let state = self.state.lock().unwrap(); let state = self.state.lock().unwrap();
/* We are currently accumulating text, no need to forward the gap */ /* We are currently accumulating text, no need to forward the gap */
if state.start_ts.is_some() { if state.start_ts.is_some() {
let (pts, duration) = gap.get();
let mut gap_buffer = gst::Buffer::new();
{
let buf_mut = gap_buffer.get_mut().expect("reference should be exclusive");
buf_mut.set_pts(pts);
buf_mut.set_duration(duration);
}
drop(state);
let res = self.sink_chain(pad, gap_buffer);
if res != Ok(gst::FlowSuccess::Ok) {
gst::warning!(CAT, "Failed to process gap: {:?}", res);
}
true true
} else { } else {
gst::Pad::event_default(pad, Some(&*self.obj()), event) gst::Pad::event_default(pad, Some(&*self.obj()), event)