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:
authorArun Raghavan <arun@asymptotic.io>2022-04-01 21:51:06 +0300
committerArun Raghavan <arun@asymptotic.io>2022-05-11 15:29:48 +0300
commit05258756ce52d005a2f0de4b45405da36d35e8cc (patch)
tree53d67dd6ef8703e3e64267a830512cd637c38b6e /video/dav1d
parent7d681c5ce428b2716c55c581a9a869c36ae292e8 (diff)
dav1ddec: Report latency based on frame delay
This is not strictly correct as we might not use the same mechanism that dav1d is using to detect the number of CPUs. We can drop the num_cpus based approach once https://code.videolan.org/videolan/dav1d/-/merge_requests/1407 is merged upstream. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/698>
Diffstat (limited to 'video/dav1d')
-rw-r--r--video/dav1d/Cargo.toml1
-rw-r--r--video/dav1d/src/dav1ddec/imp.rs71
2 files changed, 72 insertions, 0 deletions
diff --git a/video/dav1d/Cargo.toml b/video/dav1d/Cargo.toml
index a48e3100c..2db21cdf2 100644
--- a/video/dav1d/Cargo.toml
+++ b/video/dav1d/Cargo.toml
@@ -14,6 +14,7 @@ dav1d = "0.8"
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
+num_cpus = "1.0"
once_cell = "1.0"
[lib]
diff --git a/video/dav1d/src/dav1ddec/imp.rs b/video/dav1d/src/dav1ddec/imp.rs
index 7cdb0daf1..0adf01355 100644
--- a/video/dav1d/src/dav1ddec/imp.rs
+++ b/video/dav1d/src/dav1ddec/imp.rs
@@ -29,6 +29,7 @@ struct State {
Option<gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>>,
output_info: Option<gst_video::VideoInfo>,
video_meta_supported: bool,
+ n_cpus: usize,
}
// We make our own settings object so we don't have to deal with a Sync impl for dav1d::Settings
@@ -61,6 +62,17 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
});
impl Dav1dDec {
+ // FIXME: drop this once we have API from dav1d to query this value
+ // https://code.videolan.org/videolan/dav1d/-/merge_requests/1407
+ fn estimate_frame_delay(&self, max_frame_delay: u32, n_threads: u32) -> u32 {
+ if max_frame_delay > 0 {
+ std::cmp::min(max_frame_delay, n_threads)
+ } else {
+ let n_tc = n_threads as f64;
+ std::cmp::min(8, n_tc.sqrt().ceil() as u32)
+ }
+ }
+
fn gst_video_format_from_dav1d_picture(
&self,
element: &super::Dav1dDec,
@@ -601,12 +613,70 @@ impl ElementImpl for Dav1dDec {
}
impl VideoDecoderImpl for Dav1dDec {
+ fn src_query(&self, element: &Self::Type, query: &mut gst::QueryRef) -> bool {
+ if let gst::QueryViewMut::Latency(q) = query.view_mut() {
+ let state_guard = self.state.borrow();
+ let max_frame_delay = {
+ let settings = self.settings.lock().unwrap();
+ settings.max_frame_delay
+ };
+
+ match *state_guard {
+ Some(ref state) => match state.output_info {
+ Some(ref info) => {
+ let mut upstream_latency = gst::query::Latency::new();
+ let sinkpad = &element.static_pad("sink").expect("Failed to get sink pad");
+
+ if sinkpad.peer_query(&mut upstream_latency) {
+ let (live, mut min, mut max) = upstream_latency.result();
+ // For autodetection: 1 if live, else whatever dav1d gives us
+ let frame_latency: u64 = if max_frame_delay < 0 && live {
+ 1
+ } else {
+ self.estimate_frame_delay(
+ max_frame_delay as u32,
+ state.n_cpus as u32,
+ )
+ .into()
+ };
+
+ let latency = frame_latency
+ * (info.fps().denom() as u64)
+ * gst::ClockTime::SECOND
+ / (info.fps().numer() as u64);
+
+ gst::debug!(CAT, obj: element, "Reporting latency of {}", latency);
+
+ min += latency;
+ max = max.opt_add(latency);
+ q.set(live, min, max);
+
+ true
+ } else {
+ // peer latency query failed
+ false
+ }
+ }
+ // output info not available => fps unknown
+ None => false,
+ },
+ // no state yet
+ None => false,
+ }
+ } else {
+ VideoDecoderImplExt::parent_src_query(self, element, query)
+ }
+ }
+
fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
{
let mut state_guard = self.state.borrow_mut();
let settings = self.settings.lock().unwrap();
let mut decoder_settings = dav1d::Settings::new();
let max_frame_delay: u32;
+ let n_cpus = num_cpus::get();
+
+ gst::info!(CAT, obj: element, "Detected {} logical CPUs", n_cpus);
if settings.max_frame_delay == -1 {
let mut latency_query = gst::query::Latency::new();
@@ -644,6 +714,7 @@ impl VideoDecoderImpl for Dav1dDec {
input_state: None,
output_info: None,
video_meta_supported: false,
+ n_cpus,
});
}